Compare commits
246
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 |
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
|
||||
@@ -1,7 +1,14 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: gradle
|
||||
- package-ecosystem: maven
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
ignore:
|
||||
- dependency-name: com.github.ekryd.sortpom:sortpom-maven-plugin
|
||||
versions:
|
||||
- 2.13.1
|
||||
- 2.14.0
|
||||
- 2.14.1
|
||||
- 2.15.0
|
||||
@@ -1,16 +0,0 @@
|
||||
name: Java CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: 8.0.292
|
||||
- name: Build project
|
||||
run: ./gradlew build
|
||||
@@ -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
|
||||
@@ -0,0 +1,18 @@
|
||||
name: Java CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: zulu
|
||||
java-version: 8
|
||||
- name: Build with Maven
|
||||
run: mvn install --file pom.xml
|
||||
@@ -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
-109
@@ -1,109 +1,106 @@
|
||||
### Java files ###
|
||||
*.class
|
||||
|
||||
# Package Files
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# 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
|
||||
|
||||
### VSCode
|
||||
*.pdf
|
||||
### 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,18 +1,20 @@
|
||||
# WIP Indev Branch!
|
||||
Version 3.0 is not done, not ready for production and will still change! Please keep using the latest 2.x builds for now!
|
||||
# Item-NBT-API
|
||||
|
||||
# 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
|
||||
@@ -20,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!
|
||||
@@ -1,42 +0,0 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
maven {
|
||||
url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
def version = project.nbtapi_version
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven {
|
||||
name = 'Spigot'
|
||||
url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/'
|
||||
}
|
||||
maven {
|
||||
name = 'CodeMC'
|
||||
url = 'https://repo.codemc.org/repository/maven-public/'
|
||||
}
|
||||
maven {
|
||||
name = 'CodeMC NMS'
|
||||
url = 'https://repo.codemc.org/repository/nms/'
|
||||
}
|
||||
maven {
|
||||
name = 'Mojang'
|
||||
url = 'https://libraries.minecraft.net/'
|
||||
}
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property("version", version)
|
||||
|
||||
expand([version: version])
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
plugins {
|
||||
id 'java-library'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api 'de.tr7zw:functional-annotations:0.1-SNAPSHOT'
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
@@ -1 +0,0 @@
|
||||
rootProject.name = 'nbt-api'
|
||||
@@ -1,7 +0,0 @@
|
||||
package dev.tr7zw.nbtapi;
|
||||
|
||||
public interface INBTItemStack<I> extends NBTCompoundAccessor, NBTCompound {
|
||||
|
||||
public I getItemStack();
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package dev.tr7zw.nbtapi;
|
||||
|
||||
/**
|
||||
* A generic {@link RuntimeException} that can be thrown by most methods in the
|
||||
* NBT-API in case of compatibility or logic issues.
|
||||
*
|
||||
* @author tr7zw
|
||||
*/
|
||||
public class NBTApiException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -993309714559452334L;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public NBTApiException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
*/
|
||||
public NBTApiException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cause
|
||||
*/
|
||||
public NBTApiException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package dev.tr7zw.nbtapi;
|
||||
|
||||
public interface NBTCompound extends NBTCompoundAccessor, Writeable<NBTCompound> {
|
||||
|
||||
/**
|
||||
* Gets an existing compound, or creates it if it
|
||||
* doesn't exist yet.
|
||||
*
|
||||
* @param name The key of the compound.
|
||||
*/
|
||||
NBTCompound getOrCreateCompound(String name);
|
||||
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package dev.tr7zw.nbtapi;
|
||||
|
||||
public interface NBTCompoundAccessor extends Readable {
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package dev.tr7zw.nbtapi;
|
||||
|
||||
/**
|
||||
* Double implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public abstract class NBTDoubleList extends NBTList<Double> {
|
||||
|
||||
@Override
|
||||
public NBTType getType() {
|
||||
return NBTType.NBTTagDouble;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package dev.tr7zw.nbtapi;
|
||||
|
||||
/**
|
||||
* Float implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public abstract class NBTFloatList extends NBTList<Float> {
|
||||
|
||||
@Override
|
||||
public NBTType getType() {
|
||||
return NBTType.NBTTagFloat;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package dev.tr7zw.nbtapi;
|
||||
|
||||
/**
|
||||
* Integer implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public abstract class NBTIntegerList extends NBTList<Integer> {
|
||||
|
||||
@Override
|
||||
public NBTType getType() {
|
||||
return NBTType.NBTTagInt;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package dev.tr7zw.nbtapi;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract List implementation for ListCompounds
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class NBTList<T> implements List<T> {
|
||||
|
||||
|
||||
protected abstract Object asTag(T object);
|
||||
|
||||
/**
|
||||
* @return The type that this list contains
|
||||
*/
|
||||
public abstract NBTType getType();
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package dev.tr7zw.nbtapi;
|
||||
|
||||
/**
|
||||
* Enum of all NBT Types Minecraft contains
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public enum NBTType {
|
||||
NBTTagEnd(),
|
||||
NBTTagByte(),
|
||||
NBTTagShort(),
|
||||
NBTTagInt(),
|
||||
NBTTagLong(),
|
||||
NBTTagFloat(),
|
||||
NBTTagDouble(),
|
||||
NBTTagByteArray(),
|
||||
NBTTagString(),
|
||||
NBTTagList(),
|
||||
NBTTagCompound(),
|
||||
NBTTagIntArray(),
|
||||
NBTTagLongArray();
|
||||
|
||||
/**
|
||||
* @return Id used by Minecraft internally
|
||||
*/
|
||||
public int getId() {
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id Internal Minecraft ID
|
||||
* @return Enum representing the ID, NBTTagEnd for invalid IDs
|
||||
*/
|
||||
public static NBTType valueOf(int id) {
|
||||
NBTType[] values = values();
|
||||
if (id >= values.length || id < 0)
|
||||
return NBTTagEnd;
|
||||
return values[id];
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
package dev.tr7zw.nbtapi;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface Readable {
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
String getString(String key);
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
Integer getInteger(String key);
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
Double getDouble(String key);
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
Byte getByte(String key);
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
Short getShort(String key);
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
Long getLong(String key);
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
Float getFloat(String key);
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
byte[] getByteArray(String key);
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
int[] getIntArray(String key);
|
||||
|
||||
/**
|
||||
* Getter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
Boolean getBoolean(String key);
|
||||
|
||||
/**
|
||||
* Get the UUID at {@code key}.
|
||||
*
|
||||
* @param key The String key.
|
||||
* @return The stored value or NMS fallback
|
||||
*/
|
||||
UUID getUUID(String key);
|
||||
|
||||
/**
|
||||
* Get all keys of this tag.
|
||||
*
|
||||
* @return Set of all stored Keys
|
||||
*/
|
||||
Set<String> getKeys();
|
||||
|
||||
/**
|
||||
* @param name The String key.
|
||||
* @return The Compound instance or null
|
||||
*/
|
||||
Readable getCompound(String name);
|
||||
|
||||
/**
|
||||
* @param name The String key.
|
||||
* @return The retrieved String List
|
||||
*/
|
||||
NBTList<String> getStringList(String name);
|
||||
|
||||
/**
|
||||
* @param name The String key.
|
||||
* @return The retrieved Integer List
|
||||
*/
|
||||
NBTList<Integer> getIntegerList(String name);
|
||||
|
||||
/**
|
||||
* @param name The String key.
|
||||
* @return The retrieved Float List
|
||||
*/
|
||||
NBTList<Float> getFloatList(String name);
|
||||
|
||||
/**
|
||||
* @param name The String key.
|
||||
* @return The retrieved Double List
|
||||
*/
|
||||
NBTList<Double> getDoubleList(String name);
|
||||
|
||||
/**
|
||||
* @param name The String key.
|
||||
* @return The retrieved Long List
|
||||
*/
|
||||
NBTList<Long> getLongList(String name);
|
||||
|
||||
/**
|
||||
* Returns the type of the list, null if not a list
|
||||
*
|
||||
* @param name The String key.
|
||||
* @return The retrieved type.
|
||||
*/
|
||||
NBTType getListType(String name);
|
||||
|
||||
/**
|
||||
* @param name The String key.
|
||||
* @return The retrieved Compound List
|
||||
*/
|
||||
//NBTCompoundList getCompoundList(String name); //FIXME
|
||||
|
||||
/**
|
||||
* @param name The String key.
|
||||
* @return The type of the given stored key or null
|
||||
*/
|
||||
NBTType getType(String name);
|
||||
|
||||
/**
|
||||
* @param name The String key.
|
||||
* @return True when this key is available
|
||||
*/
|
||||
boolean hasKey(String name);
|
||||
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
package dev.tr7zw.nbtapi;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface Writeable<W extends Writeable<W>> {
|
||||
|
||||
/**
|
||||
* 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(Readable comp);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @param value
|
||||
*/
|
||||
W setString(String key, String value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @param value
|
||||
*/
|
||||
W setInteger(String key, Integer value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @param value
|
||||
*/
|
||||
W setDouble(String key, Double value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @param value
|
||||
*/
|
||||
W setByte(String key, Byte value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @param value
|
||||
*/
|
||||
W setShort(String key, Short value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @param value
|
||||
*/
|
||||
W setLong(String key, Long value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @param value
|
||||
*/
|
||||
W setFloat(String key, Float value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @param value
|
||||
*/
|
||||
W setByteArray(String key, byte[] value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @param value
|
||||
*/
|
||||
W setIntArray(String key, int[] value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key The String key.
|
||||
* @param value
|
||||
*/
|
||||
W setBoolean(String key, Boolean value);
|
||||
|
||||
/**
|
||||
* Set a UUID.
|
||||
*
|
||||
* @param key The String key.
|
||||
* @param value The UUID value.
|
||||
*/
|
||||
W setUUID(String key, UUID value);
|
||||
|
||||
/**
|
||||
* Removes the given key and its value.
|
||||
*
|
||||
* @param key The key to delete.
|
||||
*/
|
||||
W removeKey(String key);
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved String List
|
||||
*/
|
||||
NBTList<String> getStringList(String name);
|
||||
|
||||
/**
|
||||
* Get the type of a key.
|
||||
*
|
||||
* @param name The String key.
|
||||
* @return The type of the given stored key or null
|
||||
*/
|
||||
NBTType getType(String name);
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package dev.tr7zw.nbtapi.handler;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import dev.tr7zw.nbtapi.NBTCompound;
|
||||
import dev.tr7zw.nbtapi.NBTCompoundAccessor;
|
||||
|
||||
public interface EntityHandler<E> {
|
||||
|
||||
public NBTCompound getEntity(E entity);
|
||||
|
||||
public void modifyEntity(E entity, Consumer<NBTCompound> consumer);
|
||||
|
||||
public <T> T modifyEntity(E entity, Function<NBTCompound, T> consumer);
|
||||
|
||||
public <T> T parseEntity(E entity, Function<NBTCompoundAccessor, T> function);
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package dev.tr7zw.nbtapi.handler;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import dev.tr7zw.nbtapi.INBTItemStack;
|
||||
import dev.tr7zw.nbtapi.NBTCompound;
|
||||
import dev.tr7zw.nbtapi.NBTCompoundAccessor;
|
||||
|
||||
public interface ItemHandler<I, W extends INBTItemStack<I>> {
|
||||
|
||||
public W getItemStack(I item);
|
||||
|
||||
public void modifyItemStack(I item, Consumer<NBTCompound> consumer);
|
||||
|
||||
public <T> T modifyItemStack(I item, Function<NBTCompound, T> consumer);
|
||||
|
||||
public <T> T parseItemStack(I item, Function<NBTCompoundAccessor, T> function);
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package de.tr7zw.changeme.nbtapi.data;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import dev.tr7zw.nbtapi.NBTFile;
|
||||
import dev.tr7zw.nbtapi.NBTApiException;
|
||||
|
||||
public class NBTData {
|
||||
|
||||
public static WorldData getWorldData(World world) {
|
||||
try {
|
||||
return new WorldData(world.getWorldFolder());
|
||||
} catch (IOException e) {
|
||||
throw new NBTApiException("Error loading World Data!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static WorldData getWorldData(File worldFolder) {
|
||||
try {
|
||||
return new WorldData(worldFolder);
|
||||
} catch (IOException e) {
|
||||
throw new NBTApiException("Error loading World Data!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static PlayerData getOfflinePlayerData(UUID uuid) {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
File dataFolder = new File(world.getWorldFolder(), "playerdata");
|
||||
File playerFile = new File(dataFolder, uuid.toString() + ".dat");
|
||||
if (playerFile.exists()) {
|
||||
try {
|
||||
return new PlayerData(playerFile);
|
||||
} catch (IOException e) {
|
||||
throw new NBTApiException("Error loading player data!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static NBTFile getPluginPlayerData(Plugin plugin, UUID uuid) {
|
||||
try {
|
||||
File dataFolder = new File(plugin.getDataFolder(), "nbt-playerdata");
|
||||
dataFolder.mkdirs();
|
||||
return new NBTFile(new File(dataFolder, uuid.toString() + ".dat"));
|
||||
} catch (IOException e) {
|
||||
throw new NBTApiException("Error getting Player Plugin data!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static NBTFile getPluginData(Plugin plugin) {
|
||||
try {
|
||||
plugin.getDataFolder().mkdirs();
|
||||
return new NBTFile(new File(plugin.getDataFolder(), "settings.dat"));
|
||||
} catch (IOException e) {
|
||||
throw new NBTApiException("Error getting Plugin data!", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package de.tr7zw.changeme.nbtapi.data;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import dev.tr7zw.nbtapi.NBTFile;
|
||||
import dev.tr7zw.nbtapi.NBTApiException;
|
||||
import dev.tr7zw.nbtapi.Readable;
|
||||
|
||||
public class PlayerData {
|
||||
|
||||
private final NBTFile file;
|
||||
|
||||
protected PlayerData(File playerFile) throws IOException {
|
||||
file = new NBTFile(playerFile);
|
||||
}
|
||||
|
||||
public NBTFile getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public Readable getCompound() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void saveChanges() {
|
||||
try {
|
||||
file.save();
|
||||
} catch (IOException e) {
|
||||
throw new NBTApiException("Error when saving level data!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public float getHealth(){
|
||||
return file.getFloat("Health");
|
||||
}
|
||||
|
||||
public void setHealth(float health){
|
||||
file.setFloat("Health", health);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package de.tr7zw.changeme.nbtapi.data;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import dev.tr7zw.nbtapi.NBTFile;
|
||||
import dev.tr7zw.nbtapi.NBTApiException;
|
||||
import dev.tr7zw.nbtapi.Readable;
|
||||
import dev.tr7zw.nbtapi.Writeable;
|
||||
|
||||
public class WorldData {
|
||||
|
||||
private final NBTFile file;
|
||||
|
||||
protected WorldData(File worldFolder) throws IOException {
|
||||
if(!new File(worldFolder, "level.dat").exists())throw new FileNotFoundException("Level.dat at: " + new File(worldFolder, "level.dat").getAbsolutePath());
|
||||
file = new NBTFile(new File(worldFolder, "level.dat"));
|
||||
}
|
||||
|
||||
public NBTFile getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public Readable getCompound() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void saveChanges() {
|
||||
try {
|
||||
file.save();
|
||||
} catch (IOException e) {
|
||||
throw new NBTApiException("Error when saving level data!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getWorldName(){
|
||||
return file.getCompound("Data").getString("LevelName");
|
||||
}
|
||||
|
||||
public void setWorldName(String name){
|
||||
file.getCompound("Data").setString("LevelName", name);
|
||||
}
|
||||
|
||||
public Vector getSpawnPosition(){
|
||||
Readable data = file.getCompound("Data");
|
||||
return new Vector(data.getInteger("SpawnX"), data.getInteger("SpawnY"), data.getInteger("SpawnZ"));
|
||||
}
|
||||
|
||||
public void setSpawnPosition(Vector vec){
|
||||
Writeable data = file.getCompound("Data");
|
||||
data.setInteger("SpawnX", vec.getBlockX());
|
||||
data.setInteger("SpawnY", vec.getBlockY());
|
||||
data.setInteger("SpawnZ", vec.getBlockZ());
|
||||
}
|
||||
|
||||
}
|
||||
+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)
|
||||
@@ -1,86 +0,0 @@
|
||||
plugins {
|
||||
id 'fabric-loom' version '0.9-SNAPSHOT'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_16
|
||||
targetCompatibility = JavaVersion.VERSION_16
|
||||
|
||||
archivesBaseName = project.archives_base_name
|
||||
version = project.nbtapi_version
|
||||
group = project.maven_group
|
||||
|
||||
repositories {
|
||||
// Add repositories to retrieve artifacts from in here.
|
||||
// You should only use this when depending on other mods because
|
||||
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
|
||||
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
|
||||
// for more information about repositories.
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// To change the versions see the gradle.properties file
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings loom.officialMojangMappings()
|
||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
|
||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||
|
||||
implementation project(':nbt-api')
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
|
||||
filesMatching("fabric.mod.json") {
|
||||
expand "version": project.version
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
// ensure that the encoding is set to UTF-8, no matter what the system default is
|
||||
// this fixes some edge cases with special characters not displaying correctly
|
||||
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
|
||||
// If Javadoc is generated, this must be specified in that task too.
|
||||
it.options.encoding = "UTF-8"
|
||||
|
||||
// Minecraft 1.17 (21w19a) upwards uses Java 16.
|
||||
it.options.release = 16
|
||||
}
|
||||
|
||||
java {
|
||||
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
|
||||
// if it is present.
|
||||
// If you remove this line, sources will not be generated.
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
jar {
|
||||
from("LICENSE") {
|
||||
rename { "${it}_${project.archivesBaseName}"}
|
||||
}
|
||||
}
|
||||
|
||||
// configure the maven publication
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
// add all the jars that should be included when publishing to maven
|
||||
artifact(remapJar) {
|
||||
builtBy remapJar
|
||||
}
|
||||
artifact(sourcesJar) {
|
||||
builtBy remapSourcesJar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
||||
repositories {
|
||||
// Add repositories to publish to here.
|
||||
// Notice: This block does NOT have the same function as the block in the top level.
|
||||
// The repositories here will be used for publishing your artifact, not for
|
||||
// retrieving dependencies.
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
# Done to increase the memory available to gradle.
|
||||
org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/versions.html
|
||||
minecraft_version=1.17.1
|
||||
yarn_mappings=1.17.1+build.14
|
||||
loader_version=0.11.6
|
||||
|
||||
# Mod Properties
|
||||
archives_base_name = nbtapi
|
||||
|
||||
# Dependencies
|
||||
fabric_version=0.37.0+1.17
|
||||
@@ -1 +0,0 @@
|
||||
rootProject.name = 'fabric1-17'
|
||||
@@ -1,14 +0,0 @@
|
||||
package net.fabricmc.example;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
|
||||
public class ExampleMod implements ModInitializer {
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
// This code runs as soon as Minecraft is in a mod-load-ready state.
|
||||
// However, some things (like resources) may still be uninitialized.
|
||||
// Proceed with mild caution.
|
||||
|
||||
System.out.println("Hello Fabric world!");
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package net.fabricmc.example.mixin;
|
||||
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(TitleScreen.class)
|
||||
public class ExampleMixin {
|
||||
@Inject(at = @At("HEAD"), method = "init()V")
|
||||
private void init(CallbackInfo info) {
|
||||
System.out.println("This line is printed by an example mod mixin!");
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 453 B |
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "modid",
|
||||
"version": "${version}",
|
||||
|
||||
"name": "Example Mod",
|
||||
"description": "This is an example description! Tell everyone what your mod is about!",
|
||||
"authors": [
|
||||
"Me!"
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "https://fabricmc.net/",
|
||||
"sources": "https://github.com/FabricMC/fabric-example-mod"
|
||||
},
|
||||
|
||||
"license": "CC0-1.0",
|
||||
"icon": "assets/modid/icon.png",
|
||||
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"net.fabricmc.example.ExampleMod"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
"modid.mixins.json"
|
||||
],
|
||||
|
||||
"depends": {
|
||||
"fabricloader": ">=0.11.3",
|
||||
"fabric": "*",
|
||||
"minecraft": "1.17.x",
|
||||
"java": ">=16"
|
||||
},
|
||||
"suggests": {
|
||||
"another-mod": "*"
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "net.fabricmc.example.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
"ExampleMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
// These repositories are only for Gradle plugins, put any other repositories in the repository block further below
|
||||
maven { url = 'https://maven.minecraftforge.net' }
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
|
||||
}
|
||||
}
|
||||
apply plugin: 'net.minecraftforge.gradle'
|
||||
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
version = project.nbtapi_version
|
||||
group = project.maven_group // http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
archivesBaseName = 'nbtapi'
|
||||
|
||||
// Mojang ships Java 16 to end users in 1.17+ instead of Java 8 in 1.16 or lower, so your mod should target Java 16.
|
||||
java.toolchain.languageVersion = JavaLanguageVersion.of(16)
|
||||
|
||||
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
|
||||
minecraft {
|
||||
// The mappings can be changed at any time and must be in the following format.
|
||||
// Channel: Version:
|
||||
// snapshot YYYYMMDD Snapshot are built nightly.
|
||||
// stable # Stables are built at the discretion of the MCP team.
|
||||
// official MCVersion Official field/method names from Mojang mapping files
|
||||
//
|
||||
// You must be aware of the Mojang license when using the 'official' mappings.
|
||||
// See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md
|
||||
//
|
||||
// Use non-default mappings at your own risk. They may not always work.
|
||||
// Simply re-run your setup task after changing the mappings to update your workspace.
|
||||
mappings channel: 'official', version: '1.17.1'
|
||||
|
||||
// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default.
|
||||
|
||||
// Default run configurations.
|
||||
// These can be tweaked, removed, or duplicated as needed.
|
||||
runs {
|
||||
client {
|
||||
workingDirectory project.file('run')
|
||||
|
||||
// Recommended logging data for a userdev environment
|
||||
// The markers can be added/remove as needed separated by commas.
|
||||
// "SCAN": For mods scan.
|
||||
// "REGISTRIES": For firing of registry events.
|
||||
// "REGISTRYDUMP": For getting the contents of all registries.
|
||||
property 'forge.logging.markers', 'REGISTRIES'
|
||||
|
||||
// Recommended logging level for the console
|
||||
// You can set various levels here.
|
||||
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
|
||||
mods {
|
||||
examplemod {
|
||||
source sourceSets.main
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
workingDirectory project.file('run')
|
||||
|
||||
// Recommended logging data for a userdev environment
|
||||
// The markers can be added/remove as needed separated by commas.
|
||||
// "SCAN": For mods scan.
|
||||
// "REGISTRIES": For firing of registry events.
|
||||
// "REGISTRYDUMP": For getting the contents of all registries.
|
||||
property 'forge.logging.markers', 'REGISTRIES'
|
||||
|
||||
// Recommended logging level for the console
|
||||
// You can set various levels here.
|
||||
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
|
||||
mods {
|
||||
examplemod {
|
||||
source sourceSets.main
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data {
|
||||
workingDirectory project.file('run')
|
||||
|
||||
// Recommended logging data for a userdev environment
|
||||
// The markers can be added/remove as needed separated by commas.
|
||||
// "SCAN": For mods scan.
|
||||
// "REGISTRIES": For firing of registry events.
|
||||
// "REGISTRYDUMP": For getting the contents of all registries.
|
||||
property 'forge.logging.markers', 'REGISTRIES'
|
||||
|
||||
// Recommended logging level for the console
|
||||
// You can set various levels here.
|
||||
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
|
||||
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
|
||||
args '--mod', 'examplemod', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
|
||||
|
||||
mods {
|
||||
examplemod {
|
||||
source sourceSets.main
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Include resources generated by data generators.
|
||||
sourceSets.main.resources { srcDir 'src/generated/resources' }
|
||||
|
||||
repositories {
|
||||
// Put repositories for dependencies here
|
||||
// ForgeGradle automatically adds the Forge maven and Maven Central for you
|
||||
|
||||
// If you have mod jar dependencies in ./libs, you can declare them as a repository like so:
|
||||
// flatDir {
|
||||
// dir 'libs'
|
||||
// }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Specify the version of Minecraft to use. If this is any group other than 'net.minecraft', it is assumed
|
||||
// that the dep is a ForgeGradle 'patcher' dependency, and its patches will be applied.
|
||||
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
|
||||
minecraft 'net.minecraftforge:forge:1.17.1-37.0.13'
|
||||
|
||||
// Real mod deobf dependency examples - these get remapped to your current mappings
|
||||
// compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency
|
||||
// runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") // Adds the full JEI mod as a runtime dependency
|
||||
// implementation fg.deobf("com.tterrag.registrate:Registrate:MC${mc_version}-${registrate_version}") // Adds registrate as a dependency
|
||||
|
||||
implementation project(':nbt-api')
|
||||
|
||||
// Examples using mod jars from ./libs
|
||||
// implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}")
|
||||
|
||||
// For more info...
|
||||
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
|
||||
// http://www.gradle.org/docs/current/userguide/dependency_management.html
|
||||
}
|
||||
|
||||
// Example for how to get properties into the manifest for reading at runtime.
|
||||
jar {
|
||||
manifest {
|
||||
attributes([
|
||||
"Specification-Title" : "nbtapi",
|
||||
"Specification-Vendor" : "tr7zw",
|
||||
"Specification-Version" : "1", // We are version 1 of ourselves
|
||||
"Implementation-Title" : project.name,
|
||||
"Implementation-Version" : project.jar.archiveVersion,
|
||||
"Implementation-Vendor" : "tr7zw",
|
||||
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
// Example configuration to allow publishing using the maven-publish plugin
|
||||
// This is the preferred method to reobfuscate your jar file
|
||||
jar.finalizedBy('reobfJar')
|
||||
// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing
|
||||
// publish.dependsOn('reobfJar')
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
artifact jar
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
maven {
|
||||
url "file://${project.projectDir}/mcmodsrepo"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
|
||||
# This is required to provide enough memory for the Minecraft decompilation process.
|
||||
org.gradle.jvmargs=-Xmx3G
|
||||
org.gradle.daemon=false
|
||||
@@ -1 +0,0 @@
|
||||
rootProject.name = 'forge1-17'
|
||||
@@ -1,76 +0,0 @@
|
||||
package com.example.examplemod;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.InterModComms;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
|
||||
import net.minecraftforge.fmlserverevents.FMLServerStartingEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
// The value here should match an entry in the META-INF/mods.toml file
|
||||
@Mod("examplemod")
|
||||
public class ExampleMod
|
||||
{
|
||||
// Directly reference a log4j logger.
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
public ExampleMod() {
|
||||
// Register the setup method for modloading
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
|
||||
// Register the enqueueIMC method for modloading
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC);
|
||||
// Register the processIMC method for modloading
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC);
|
||||
|
||||
// Register ourselves for server and other game events we are interested in
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
}
|
||||
|
||||
private void setup(final FMLCommonSetupEvent event)
|
||||
{
|
||||
// some preinit code
|
||||
LOGGER.info("HELLO FROM PREINIT");
|
||||
LOGGER.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName());
|
||||
}
|
||||
|
||||
private void enqueueIMC(final InterModEnqueueEvent event)
|
||||
{
|
||||
// some example code to dispatch IMC to another mod
|
||||
InterModComms.sendTo("examplemod", "helloworld", () -> { LOGGER.info("Hello world from the MDK"); return "Hello world";});
|
||||
}
|
||||
|
||||
private void processIMC(final InterModProcessEvent event)
|
||||
{
|
||||
// some example code to receive and process InterModComms from other mods
|
||||
LOGGER.info("Got IMC {}", event.getIMCStream().
|
||||
map(m->m.messageSupplier().get()).
|
||||
collect(Collectors.toList()));
|
||||
}
|
||||
// You can use SubscribeEvent and let the Event Bus discover methods to call
|
||||
@SubscribeEvent
|
||||
public void onServerStarting(FMLServerStartingEvent event) {
|
||||
// do something when the server starts
|
||||
LOGGER.info("HELLO from server starting");
|
||||
}
|
||||
|
||||
// You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD
|
||||
// Event bus for receiving Registry Events)
|
||||
@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
|
||||
public static class RegistryEvents {
|
||||
@SubscribeEvent
|
||||
public static void onBlocksRegistry(final RegistryEvent.Register<Block> blockRegistryEvent) {
|
||||
// register a new block here
|
||||
LOGGER.info("HELLO from Register Block");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
# This is an example mods.toml file. It contains the data relating to the loading mods.
|
||||
# There are several mandatory fields (#mandatory), and many more that are optional (#optional).
|
||||
# The overall format is standard TOML format, v0.5.0.
|
||||
# Note that there are a couple of TOML lists in this file.
|
||||
# Find more information on toml format here: https://github.com/toml-lang/toml
|
||||
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
|
||||
modLoader="javafml" #mandatory
|
||||
# A version range to match for said mod loader - for regular FML @Mod it will be the forge version
|
||||
loaderVersion="[37,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions.
|
||||
# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties.
|
||||
# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here.
|
||||
license="All rights reserved"
|
||||
# A URL to refer people to when problems occur with this mod
|
||||
#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional
|
||||
# A list of mods - how many allowed here is determined by the individual mod loader
|
||||
[[mods]] #mandatory
|
||||
# The modid of the mod
|
||||
modId="examplemod" #mandatory
|
||||
# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
|
||||
# ${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata
|
||||
# see the associated build.gradle script for how to populate this completely automatically during a build
|
||||
version="${file.jarVersion}" #mandatory
|
||||
# A display name for the mod
|
||||
displayName="Example Mod" #mandatory
|
||||
# A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/
|
||||
#updateJSONURL="https://change.me.example.invalid/updates.json" #optional
|
||||
# A URL for the "homepage" for this mod, displayed in the mod UI
|
||||
#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional
|
||||
# A file name (in the root of the mod JAR) containing a logo for display
|
||||
logoFile="examplemod.png" #optional
|
||||
# A text field displayed in the mod UI
|
||||
credits="Thanks for this example mod goes to Java" #optional
|
||||
# A text field displayed in the mod UI
|
||||
authors="Love, Cheese and small house plants" #optional
|
||||
# The description text for the mod (multi line!) (#mandatory)
|
||||
description='''
|
||||
This is a long form description of the mod. You can write whatever you want here
|
||||
|
||||
Have some lorem ipsum.
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis lacinia magna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed sagittis luctus odio eu tempus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque volutpat ligula eget lacus auctor sagittis. In hac habitasse platea dictumst. Nunc gravida elit vitae sem vehicula efficitur. Donec mattis ipsum et arcu lobortis, eleifend sagittis sem rutrum. Cras pharetra quam eget posuere fermentum. Sed id tincidunt justo. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
'''
|
||||
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
|
||||
[[dependencies.examplemod]] #optional
|
||||
# the modid of the dependency
|
||||
modId="forge" #mandatory
|
||||
# Does this dependency have to exist - if not, ordering below must be specified
|
||||
mandatory=true #mandatory
|
||||
# The version range of the dependency
|
||||
versionRange="[37,)" #mandatory
|
||||
# An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory
|
||||
ordering="NONE"
|
||||
# Side this dependency is applied on - BOTH, CLIENT or SERVER
|
||||
side="BOTH"
|
||||
# Here's another dependency
|
||||
[[dependencies.examplemod]]
|
||||
modId="minecraft"
|
||||
mandatory=true
|
||||
# This version range declares a minimum of the current minecraft version up to but not including the next major version
|
||||
versionRange="[1.17.1,1.18)"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"pack": {
|
||||
"description": "examplemod resources",
|
||||
"pack_format": 6,
|
||||
"_comment": "A pack_format of 6 requires json lang files and some texture changes from 1.16.2. Note: we require v6 pack meta for all mods."
|
||||
}
|
||||
}
|
||||
+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>
|
||||
@@ -1,8 +0,0 @@
|
||||
nbtapi_version=3.0.0
|
||||
maven_group=dev.tr7zw.nbtapi
|
||||
spigot_api=1.17.1-R0.1-SNAPSHOT
|
||||
authlib_version=1.5.25
|
||||
|
||||
# Gradle
|
||||
|
||||
org.gradle.parallel=true
|
||||
Vendored
BIN
Binary file not shown.
-5
@@ -1,5 +0,0 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -1,185 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
Vendored
-89
@@ -1,89 +0,0 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 - 2021, tr7zw
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -3,23 +3,14 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>dev.tr7zw</groupId>
|
||||
<artifactId>nbt-api-parent</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.12.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>item-nbt-api-legacy</artifactId>
|
||||
<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>
|
||||
@@ -32,15 +23,9 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<version>3.5.0</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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.CheckUtil;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
|
||||
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
|
||||
*/
|
||||
public NBTCompound getPersistentDataContainer() {
|
||||
CheckUtil.assertAvailable(MinecraftVersion.MC1_16_R3);
|
||||
return new NBTPersistentDataContainer(chunk.getPersistentDataContainer());
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,121 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* {@link NBTListCompound} implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTCompoundList extends NBTList<ReadWriteNBT> implements ReadWriteNBTCompoundList {
|
||||
|
||||
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) {
|
||||
if (getParent().isReadOnly()) {
|
||||
throw new NbtApiException("Tried setting data in read only mode!");
|
||||
}
|
||||
try {
|
||||
Object compound = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
|
||||
ReflectionMethod.LIST_ADD.run(listObject, size(), compound);
|
||||
} else {
|
||||
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, compound);
|
||||
}
|
||||
getParent().saveCompound();
|
||||
NBTListCompound listcomp = new NBTListCompound(this, compound);
|
||||
if (comp != null) {
|
||||
listcomp.mergeCompound(comp);
|
||||
}
|
||||
return listcomp;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public NBTCompound addCompound(ReadWriteNBT comp) {
|
||||
if (comp instanceof NBTCompound) {
|
||||
return addCompound((NBTCompound) comp);
|
||||
}
|
||||
return 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(ReadWriteNBT empty) {
|
||||
return addCompound(empty) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, ReadWriteNBT element) {
|
||||
if (element != null) {
|
||||
throw new NbtApiException("You need to pass null! ListCompounds from other lists won't work.");
|
||||
}
|
||||
if (getParent().isReadOnly()) {
|
||||
throw new NbtApiException("Tried setting data in read only mode!");
|
||||
}
|
||||
try {
|
||||
Object compound = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
|
||||
ReflectionMethod.LIST_ADD.run(listObject, index, compound);
|
||||
} else {
|
||||
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, compound);
|
||||
}
|
||||
super.getParent().saveCompound();
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTListCompound get(int index) {
|
||||
try {
|
||||
Object compound = ReflectionMethod.LIST_GET_COMPOUND.run(listObject, index);
|
||||
return new NBTListCompound(this, compound);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTListCompound set(int index, ReadWriteNBT element) {
|
||||
throw new NbtApiException("This method doesn't work in the ListCompound context.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object asTag(ReadWriteNBT object) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* A Standalone {@link NBTCompound} implementation. All data is just kept inside
|
||||
* this Object.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTContainer extends NBTCompound {
|
||||
|
||||
private Object nbt;
|
||||
private boolean closed;
|
||||
private boolean readOnly;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompound(Object tag) {
|
||||
nbt = tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setClosed() {
|
||||
this.closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
protected boolean isReadOnly() {
|
||||
return readOnly;
|
||||
}
|
||||
|
||||
protected NBTContainer setReadOnly(boolean readOnly) {
|
||||
this.readOnly = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* Double implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTDoubleList extends NBTList<Double> {
|
||||
|
||||
protected NBTDoubleList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
super(owner, name, type, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object asTag(Double object) {
|
||||
try {
|
||||
Constructor<?> con = ClassWrapper.NMS_NBTTAGDOUBLE.getClazz().getDeclaredConstructor(double.class);
|
||||
con.setAccessible(true);
|
||||
return con.newInstance(object);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
||||
| NoSuchMethodException | SecurityException e) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.CheckUtil;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
|
||||
/**
|
||||
* NBT class to access vanilla tags from Entities. Entities don't support custom
|
||||
* tags. Use the NBTInjector for custom tags. Changes will be instantly applied
|
||||
* to the Entity, use the merge method to do many things at once.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTEntity extends NBTCompound {
|
||||
|
||||
private final Entity ent;
|
||||
private final boolean readonly;
|
||||
private final Object compound;
|
||||
private boolean closed = false;
|
||||
|
||||
/**
|
||||
* @param entity Any valid Bukkit Entity
|
||||
* @param 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 setClosed() {
|
||||
this.closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReadOnly() {
|
||||
return readonly;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
// this runs before async check, since it's just a copy
|
||||
if (readonly && compound != null) {
|
||||
return compound;
|
||||
}
|
||||
if (!Bukkit.isPrimaryThread())
|
||||
throw new NbtApiException("Entity NBT needs to be accessed sync!");
|
||||
return NBTReflectionUtil.getEntityNBTTagCompound(NBTReflectionUtil.getNMSEntity(ent));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
if (readonly) {
|
||||
throw new NbtApiException("Tried setting data in read only mode!");
|
||||
}
|
||||
if (!Bukkit.isPrimaryThread())
|
||||
throw new NbtApiException("Entity NBT needs to be accessed sync!");
|
||||
NBTReflectionUtil.setEntityNBTTag(compound, NBTReflectionUtil.getNMSEntity(ent));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator;
|
||||
|
||||
/**
|
||||
* {@link NBTCompound} implementation backed by a {@link File}
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTFile extends NBTCompound {
|
||||
|
||||
private final File file;
|
||||
private Object nbt;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
saveTo(file, this);
|
||||
} finally {
|
||||
getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The File used to store the data
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@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()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* Float implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTFloatList extends NBTList<Float> {
|
||||
|
||||
protected NBTFloatList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
super(owner, name, type, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object asTag(Float object) {
|
||||
try {
|
||||
Constructor<?> con = ClassWrapper.NMS_NBTTAGFLOAT.getClazz().getDeclaredConstructor(float.class);
|
||||
con.setAccessible(true);
|
||||
return con.newInstance(object);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
||||
| NoSuchMethodException | SecurityException e) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator;
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
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 NBTIntegerList extends NBTList<Integer> {
|
||||
|
||||
protected NBTIntegerList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
super(owner, name, type, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object asTag(Integer object) {
|
||||
try {
|
||||
Constructor<?> con = ClassWrapper.NMS_NBTTAGINT.getClazz().getDeclaredConstructor(int.class);
|
||||
con.setAccessible(true);
|
||||
return con.newInstance(object);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
||||
| NoSuchMethodException | SecurityException e) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* NBT class to access vanilla/custom tags on ItemStacks. This class doesn't
|
||||
* autosave to the Itemstack, use getItem to get the changed ItemStack
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTItem extends NBTCompound implements ReadWriteItemNBT {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
if (closed) {
|
||||
throw new NbtApiException("Tried using closed NBT data!");
|
||||
}
|
||||
if (isReadOnly() && (cachedCompound != null
|
||||
|| ClassWrapper.CRAFT_ITEMSTACK.getClazz().isAssignableFrom(bukkitItem.getClass()))) {
|
||||
if (cachedCompound == null) {
|
||||
cachedCompound = NBTReflectionUtil
|
||||
.getItemRootNBTTagCompound(NBTReflectionUtil.getCraftItemHandle(bukkitItem));
|
||||
}
|
||||
return cachedCompound;
|
||||
}
|
||||
if (finalizer) {
|
||||
if (cachedCompound == null) {
|
||||
updateCachedCompound();
|
||||
}
|
||||
return cachedCompound;
|
||||
}
|
||||
return NBTReflectionUtil.getItemRootNBTTagCompound(ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem));
|
||||
}
|
||||
|
||||
private void updateCachedCompound() {
|
||||
if (finalizer) {
|
||||
cachedCompound = NBTReflectionUtil
|
||||
.getItemRootNBTTagCompound(ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem));
|
||||
}
|
||||
}
|
||||
|
||||
protected void finalizeChanges() {
|
||||
if (!finalizer || cachedCompound == null) {
|
||||
return;
|
||||
}
|
||||
// There was data, but not anymore, delete the tag from the itemstack
|
||||
if (NBTReflectionUtil.getKeys(this).isEmpty()) {
|
||||
cachedCompound = null;
|
||||
}
|
||||
if (ClassWrapper.CRAFT_ITEMSTACK.getClazz().isAssignableFrom(originalSrcStack.getClass())) {
|
||||
Object nmsStack = NBTReflectionUtil.getCraftItemHandle(originalSrcStack);
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setClosed() {
|
||||
this.closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,474 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Abstract List implementation for ListCompounds
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class NBTList<T> implements List<T>, ReadWriteNBTList<T> {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Name of this list-compound
|
||||
*/
|
||||
public String getName() {
|
||||
return listName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Compound's parent Object
|
||||
*/
|
||||
public NBTCompound getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
private void validateClosed() {
|
||||
if (parent.isClosed()) {
|
||||
throw new NbtApiException("Tried using closed NBT data!");
|
||||
}
|
||||
}
|
||||
|
||||
private void validateWritable() {
|
||||
if (getParent().isReadOnly()) {
|
||||
throw new NbtApiException("Tried setting data in read only mode!");
|
||||
}
|
||||
}
|
||||
|
||||
protected void save() {
|
||||
validateClosed();
|
||||
parent.set(listName, listObject);
|
||||
}
|
||||
|
||||
protected abstract Object asTag(T object);
|
||||
|
||||
@Override
|
||||
public boolean add(T element) {
|
||||
validateClosed();
|
||||
validateWritable();
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
|
||||
ReflectionMethod.LIST_ADD.run(listObject, size(), asTag(element));
|
||||
} else {
|
||||
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, asTag(element));
|
||||
}
|
||||
save();
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, T element) {
|
||||
validateClosed();
|
||||
validateWritable();
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
|
||||
ReflectionMethod.LIST_ADD.run(listObject, index, asTag(element));
|
||||
} else {
|
||||
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, asTag(element));
|
||||
}
|
||||
save();
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T set(int index, T element) {
|
||||
validateClosed();
|
||||
validateWritable();
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
T prev = get(index);
|
||||
ReflectionMethod.LIST_SET.run(listObject, index, asTag(element));
|
||||
save();
|
||||
return prev;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T remove(int i) {
|
||||
validateClosed();
|
||||
validateWritable();
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
T old = get(i);
|
||||
ReflectionMethod.LIST_REMOVE_KEY.run(listObject, i);
|
||||
save();
|
||||
return old;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
return (int) ReflectionMethod.LIST_SIZE.run(listObject);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The type that this list contains
|
||||
*/
|
||||
@Override
|
||||
public NBTType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
while (!isEmpty()) {
|
||||
remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (o.equals(get(i)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (o.equals(get(i)))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends T> c) {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
int size = size();
|
||||
for (T ele : c) {
|
||||
add(ele);
|
||||
}
|
||||
return size != size();
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends T> c) {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
int size = size();
|
||||
for (T ele : c) {
|
||||
add(index++, ele);
|
||||
}
|
||||
return size != size();
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
for (Object ele : c) {
|
||||
if (!contains(ele))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
int index = -1;
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (o.equals(get(i)))
|
||||
index = i;
|
||||
}
|
||||
return index;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
int size = size();
|
||||
for (Object obj : c) {
|
||||
remove(obj);
|
||||
}
|
||||
return size != size();
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
int size = size();
|
||||
for (Object obj : c) {
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (!obj.equals(get(i))) {
|
||||
remove(i--);
|
||||
}
|
||||
}
|
||||
}
|
||||
return size != size();
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
int size = size();
|
||||
int id = -1;
|
||||
while ((id = indexOf(o)) != -1) {
|
||||
remove(id);
|
||||
}
|
||||
return size != size();
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new Iterator<T>() {
|
||||
|
||||
private int index = -1;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return size() > index + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
return get(++index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
NBTList.this.remove(index);
|
||||
index--;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<T> listIterator() {
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<T> listIterator(int startIndex) {
|
||||
final NBTList<T> list = this;
|
||||
return new ListIterator<T>() {
|
||||
|
||||
int index = startIndex - 1;
|
||||
|
||||
@Override
|
||||
public void add(T e) {
|
||||
list.add(index, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return size() > index + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return index >= 0 && index <= size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
return get(++index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T previous() {
|
||||
if (!hasPrevious())
|
||||
throw new NoSuchElementException("Id: " + (index - 1));
|
||||
return get(index--);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return index - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
list.remove(index);
|
||||
index--;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(T e) {
|
||||
list.set(index, e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
Object[] ar = new Object[size()];
|
||||
for (int i = 0; i < size(); i++)
|
||||
ar[i] = get(i);
|
||||
return ar;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <E> E[] toArray(E[] a) {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
E[] ar = Arrays.copyOf(a, size());
|
||||
Arrays.fill(ar, null);
|
||||
Class<?> arrayclass = a.getClass().getComponentType();
|
||||
for (int i = 0; i < size(); i++) {
|
||||
T obj = get(i);
|
||||
if (arrayclass.isInstance(obj)) {
|
||||
ar[i] = (E) get(i);
|
||||
} else {
|
||||
throw new ArrayStoreException("The array does not match the objects stored in the List.");
|
||||
}
|
||||
}
|
||||
return ar;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> subList(int fromIndex, int toIndex) {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
ArrayList<T> list = new ArrayList<>();
|
||||
for (int i = fromIndex; i < toIndex; i++)
|
||||
list.add(get(i));
|
||||
return list;
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeIf(Predicate<? super T> filter) {
|
||||
return List.super.removeIf(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
validateClosed();
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
return listObject.toString();
|
||||
} finally {
|
||||
parent.getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
/**
|
||||
* Cut down version of the {@link NBTCompound} for inside
|
||||
* {@link NBTCompoundList} This Compound implementation is missing the ability
|
||||
* for further subCompounds and Lists. This class probably will change in the
|
||||
* future
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTListCompound extends NBTCompound {
|
||||
|
||||
private NBTList<?> owner;
|
||||
private Object compound;
|
||||
|
||||
protected NBTListCompound(NBTList<?> parent, Object obj) {
|
||||
super(null, null);
|
||||
owner = parent;
|
||||
compound = obj;
|
||||
}
|
||||
|
||||
public NBTList<?> getListParent() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isClosed() {
|
||||
return owner.getParent().isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReadOnly() {
|
||||
return owner.getParent().isReadOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
if (isClosed()) {
|
||||
throw new NbtApiException("Tried using closed NBT data!");
|
||||
}
|
||||
return compound;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
if (isClosed()) {
|
||||
throw new NbtApiException("Tried using closed NBT data!");
|
||||
}
|
||||
if (isReadOnly()) {
|
||||
throw new NbtApiException("Tried setting data in read only mode!");
|
||||
}
|
||||
this.compound = compound;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveCompound() {
|
||||
owner.save();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* Long implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTLongList extends NBTList<Long> {
|
||||
|
||||
protected NBTLongList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
super(owner, name, type, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object asTag(Long object) {
|
||||
try {
|
||||
Constructor<?> con = ClassWrapper.NMS_NBTTAGLONG.getClazz().getDeclaredConstructor(long.class);
|
||||
con.setAccessible(true);
|
||||
return con.newInstance(object);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
||||
| NoSuchMethodException | SecurityException e) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
public class NBTPersistentDataContainer extends NBTCompound {
|
||||
|
||||
private final PersistentDataContainer container;
|
||||
|
||||
public NBTPersistentDataContainer(PersistentDataContainer container) {
|
||||
super(null, null);
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return ReflectionMethod.CRAFT_PERSISTENT_DATA_CONTAINER_TO_TAG.run(container);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Object, Object> map = (Map<Object, Object>) ReflectionMethod.CRAFT_PERSISTENT_DATA_CONTAINER_GET_MAP
|
||||
.run(container);
|
||||
map.clear();
|
||||
ReflectionMethod.CRAFT_PERSISTENT_DATA_CONTAINER_PUT_ALL.run(container, compound);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,637 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.GsonWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Utility class for translating NBTApi calls to reflections into NMS code All
|
||||
* methods are allowed to throw {@link NbtApiException}
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class NBTReflectionUtil {
|
||||
|
||||
private static Field field_unhandledTags = null;
|
||||
private static Field field_handle = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
field_unhandledTags = ClassWrapper.CRAFT_METAITEM.getClazz().getDeclaredField("unhandledTags");
|
||||
field_unhandledTags.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
|
||||
}
|
||||
try {
|
||||
field_handle = ClassWrapper.CRAFT_ITEMSTACK.getClazz().getDeclaredField("handle");
|
||||
field_handle.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hidden constructor
|
||||
*/
|
||||
private NBTReflectionUtil() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NMS Entity for a given Bukkit Entity
|
||||
*
|
||||
* @param entity Bukkit Entity
|
||||
* @return NMS Entity
|
||||
*/
|
||||
public static Object getNMSEntity(Entity entity) {
|
||||
try {
|
||||
return ReflectionMethod.CRAFT_ENTITY_GET_HANDLE.run(ClassWrapper.CRAFT_ENTITY.getClazz().cast(entity));
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting the NMS Entity from a Bukkit Entity!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in a InputStream as NMS Compound
|
||||
*
|
||||
* @param stream InputStream of any NBT file
|
||||
* @return NMS Compound
|
||||
*/
|
||||
public static Object readNBT(InputStream stream) {
|
||||
try {
|
||||
return ReflectionMethod.NBTFILE_READ.run(null, stream);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
throw new NbtApiException("Exception while reading a NBT File!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a NMS Compound to an OutputStream
|
||||
*
|
||||
* @param nbt NMS Compound
|
||||
* @param stream Stream to write to
|
||||
* @return ???
|
||||
*/
|
||||
public static Object writeNBT(Object nbt, OutputStream stream) {
|
||||
try {
|
||||
return ReflectionMethod.NBTFILE_WRITE.run(null, nbt, stream);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while writing NBT!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nms handle ItemStack from a CraftItemStack. Passing Spigot
|
||||
* ItemStacks will cause an error!
|
||||
*
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
public static Object getCraftItemHandle(ItemStack item) {
|
||||
try {
|
||||
return field_handle.get(item);
|
||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||
throw new NbtApiException("Error getting handle from " + item.getClass(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a Compound to an OutputStream
|
||||
*
|
||||
* @param comp Compound
|
||||
* @param stream Stream to write to
|
||||
*/
|
||||
public static void writeApiNBT(NBTCompound comp, OutputStream stream) {
|
||||
try {
|
||||
Object workingtag = comp.getResolvedObject();
|
||||
ReflectionMethod.NBTFILE_WRITE.run(null, workingtag, stream);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while writing NBT!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates getOrCreateTag. If an Item doesn't yet have a Tag, it will return a
|
||||
* new empty tag.
|
||||
*
|
||||
* @param nmsitem
|
||||
* @return NMS Compound
|
||||
*/
|
||||
public static Object getItemRootNBTTagCompound(Object nmsitem) {
|
||||
try {
|
||||
Object answer = ReflectionMethod.NMSITEM_GETTAG.run(nmsitem);
|
||||
return answer;
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting an Itemstack's NBTCompound!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts {@link NBTCompound} to NMS ItemStacks
|
||||
*
|
||||
* @param nbtcompound Any valid {@link NBTCompound}
|
||||
* @return NMS ItemStack
|
||||
*/
|
||||
public static Object convertNBTCompoundtoNMSItem(NBTCompound nbtcompound) {
|
||||
try {
|
||||
Object nmsComp = gettoCompount(nbtcompound.getCompound(), nbtcompound);
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_11_R1.getVersionId()) {
|
||||
return ObjectCreator.NMS_COMPOUNDFROMITEM.getInstance(nmsComp);
|
||||
} else {
|
||||
return ReflectionMethod.NMSITEM_CREATESTACK.run(null, nmsComp);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while converting NBTCompound to NMS ItemStack!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts NMS ItemStacks to {@link NBTContainer}
|
||||
*
|
||||
* @param nmsitem NMS ItemStack
|
||||
* @return {@link NBTContainer} with all the data
|
||||
*/
|
||||
public static NBTContainer convertNMSItemtoNBTCompound(Object nmsitem) {
|
||||
try {
|
||||
Object answer = ReflectionMethod.NMSITEM_SAVE.run(nmsitem, ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance());
|
||||
return new NBTContainer(answer);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while converting NMS ItemStack to NBTCompound!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a live copy of non-vanilla NBT tags.
|
||||
*
|
||||
* @param meta ItemMeta from which tags should be retrieved
|
||||
* @return Map containing unhandled (custom) NBT tags
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Object> getUnhandledNBTTags(ItemMeta meta) {
|
||||
try {
|
||||
return (Map<String, Object>) field_unhandledTags.get(meta);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting unhandled tags from ItemMeta!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Vanilla NBT Compound from a given NMS Entity
|
||||
*
|
||||
* @param nmsEntity
|
||||
* @return NMS NBT Compound
|
||||
*/
|
||||
public static Object getEntityNBTTagCompound(Object nmsEntity) {
|
||||
try {
|
||||
Object nbt = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
Object answer = ReflectionMethod.NMS_ENTITY_GET_NBT.run(nmsEntity, nbt);
|
||||
if (answer == null)
|
||||
answer = nbt;
|
||||
return answer;
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting NBTCompound from NMS Entity!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all Vanilla tags from a NMS Compound into a NMS Entity
|
||||
*
|
||||
* @param nbtTag
|
||||
* @param nmsEntity
|
||||
* @return The NMS Entity
|
||||
*/
|
||||
public static Object setEntityNBTTag(Object nbtTag, Object nmsEntity) {
|
||||
try {
|
||||
ReflectionMethod.NMS_ENTITY_SET_NBT.run(nmsEntity, nbtTag);
|
||||
return nmsEntity;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Exception while setting the NBTCompound of an Entity", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NMS Compound from a given TileEntity
|
||||
*
|
||||
* @param tile
|
||||
* @return NMS Compound with the Vanilla data
|
||||
*/
|
||||
public static Object getTileEntityNBTTagCompound(BlockState tile) {
|
||||
try {
|
||||
Object cworld = ClassWrapper.CRAFT_WORLD.getClazz().cast(tile.getWorld());
|
||||
Object nmsworld = ReflectionMethod.CRAFT_WORLD_GET_HANDLE.run(cworld);
|
||||
Object o = null;
|
||||
if (MinecraftVersion.getVersion() == MinecraftVersion.MC1_7_R4) {
|
||||
o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY_1_7_10.run(nmsworld, tile.getX(), tile.getY(),
|
||||
tile.getZ());
|
||||
} else {
|
||||
Object pos = ObjectCreator.NMS_BLOCKPOSITION.getInstance(tile.getX(), tile.getY(), tile.getZ());
|
||||
o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY.run(nmsworld, pos);
|
||||
}
|
||||
|
||||
Object answer = null;
|
||||
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_18_R1)) {
|
||||
answer = ReflectionMethod.TILEENTITY_GET_NBT_1181.run(o);
|
||||
} else {
|
||||
answer = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
ReflectionMethod.TILEENTITY_GET_NBT.run(o, answer);
|
||||
}
|
||||
if (answer == null) {
|
||||
throw new NbtApiException("Unable to get NBTCompound from TileEntity! " + tile + " " + o);
|
||||
}
|
||||
return answer;
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting NBTCompound from TileEntity!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets Vanilla tags from a NMS Compound to a TileEntity
|
||||
*
|
||||
* @param tile
|
||||
* @param comp
|
||||
*/
|
||||
public static void setTileEntityNBTTagCompound(BlockState tile, Object comp) {
|
||||
try {
|
||||
Object cworld = ClassWrapper.CRAFT_WORLD.getClazz().cast(tile.getWorld());
|
||||
Object nmsworld = ReflectionMethod.CRAFT_WORLD_GET_HANDLE.run(cworld);
|
||||
Object o = null;
|
||||
if (MinecraftVersion.getVersion() == MinecraftVersion.MC1_7_R4) {
|
||||
o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY_1_7_10.run(nmsworld, tile.getX(), tile.getY(),
|
||||
tile.getZ());
|
||||
} else {
|
||||
Object pos = ObjectCreator.NMS_BLOCKPOSITION.getInstance(tile.getX(), tile.getY(), tile.getZ());
|
||||
o = ReflectionMethod.NMS_WORLD_GET_TILEENTITY.run(nmsworld, pos);
|
||||
}
|
||||
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_17_R1)) {
|
||||
ReflectionMethod.TILEENTITY_SET_NBT.run(o, comp);
|
||||
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1)) {
|
||||
Object blockData = ReflectionMethod.TILEENTITY_GET_BLOCKDATA.run(o);
|
||||
ReflectionMethod.TILEENTITY_SET_NBT_LEGACY1161.run(o, blockData, comp);
|
||||
} else {
|
||||
ReflectionMethod.TILEENTITY_SET_NBT_LEGACY1151.run(o, comp);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while setting NBTData for a TileEntity!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the subCompound with a given name from a NMS Compound
|
||||
*
|
||||
* @param compound
|
||||
* @param name
|
||||
* @return NMS Compound or null
|
||||
*/
|
||||
public static Object getSubNBTTagCompound(Object compound, String name) {
|
||||
try {
|
||||
if ((boolean) ReflectionMethod.COMPOUND_HAS_KEY.run(compound, name)) {
|
||||
return ReflectionMethod.COMPOUND_GET_COMPOUND.run(compound, name);
|
||||
} else {
|
||||
throw new NbtApiException("Tried getting invalid compound '" + name + "' from '" + compound + "'!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting NBT subcompounds!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a subCompound with a given name in the given NMS Compound
|
||||
*
|
||||
* @param comp
|
||||
* @param name
|
||||
*/
|
||||
public static void addNBTTagCompound(NBTCompound comp, String name) {
|
||||
if (name == null) {
|
||||
remove(comp, name);
|
||||
return;
|
||||
}
|
||||
Object nbttag = comp.getCompound();
|
||||
if (nbttag == null) {
|
||||
nbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp)) {
|
||||
return;
|
||||
}
|
||||
Object workingtag = gettoCompount(nbttag, comp);
|
||||
try {
|
||||
ReflectionMethod.COMPOUND_SET.run(workingtag, name,
|
||||
ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance());
|
||||
comp.setCompound(nbttag);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while adding a Compound!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the Compound is correctly linked to it's roots
|
||||
*
|
||||
* @param comp
|
||||
* @return true if this is a valide Compound, else false
|
||||
*/
|
||||
public static boolean valideCompound(NBTCompound comp) {
|
||||
Object root = comp.getCompound();
|
||||
if (root == null) {
|
||||
root = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
Object tmp = gettoCompount(root, comp);
|
||||
comp.setResolvedObject(tmp);
|
||||
return tmp != null;
|
||||
}
|
||||
|
||||
protected static Object gettoCompount(Object nbttag, NBTCompound comp) {
|
||||
Deque<String> structure = new ArrayDeque<>();
|
||||
while (comp.getParent() != null) {
|
||||
structure.add(comp.getName());
|
||||
comp = comp.getParent();
|
||||
}
|
||||
while (!structure.isEmpty()) {
|
||||
String target = structure.pollLast();
|
||||
nbttag = getSubNBTTagCompound(nbttag, target);
|
||||
if (nbttag == null) {
|
||||
throw new NbtApiException("Unable to find tag '" + target + "' in " + nbttag);
|
||||
}
|
||||
}
|
||||
return nbttag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the second {@link NBTCompound} into the first one
|
||||
*
|
||||
* @param comp Target for the merge
|
||||
* @param nbtcompoundSrc Data to merge
|
||||
*/
|
||||
public static void mergeOtherNBTCompound(NBTCompound comp, NBTCompound nbtcompoundSrc) {
|
||||
Object workingtagSrc = nbtcompoundSrc.getResolvedObject();
|
||||
if (workingtagSrc == null) {
|
||||
return;
|
||||
}
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp))
|
||||
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
try {
|
||||
ReflectionMethod.COMPOUND_MERGE.run(workingtag, workingtagSrc);
|
||||
comp.setCompound(rootnbttag);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while merging two NBTCompounds!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content for a given key inside a Compound
|
||||
*
|
||||
* @param comp
|
||||
* @param key
|
||||
* @return Content saved under this key
|
||||
*/
|
||||
public static String getContent(NBTCompound comp, String key) {
|
||||
Object workingtag = comp.getResolvedObject();
|
||||
try {
|
||||
return ReflectionMethod.COMPOUND_GET.run(workingtag, key).toString();
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while getting the Content for key '" + key + "'!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a key in a {@link NBTCompound} to a given value
|
||||
*
|
||||
* @param comp
|
||||
* @param key
|
||||
* @param val
|
||||
*/
|
||||
public static void set(NBTCompound comp, String key, Object val) {
|
||||
if (val == null) {
|
||||
remove(comp, key);
|
||||
return;
|
||||
}
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp)) {
|
||||
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
||||
}
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
try {
|
||||
ReflectionMethod.COMPOUND_SET.run(workingtag, key, val);
|
||||
comp.setCompound(rootnbttag);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while setting key '" + key + "' to '" + val + "'!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the List saved with a given key.
|
||||
*
|
||||
* @param comp
|
||||
* @param key
|
||||
* @param type
|
||||
* @param clazz
|
||||
* @return The list at that key. Null if it's an invalid type
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> NBTList<T> getList(NBTCompound comp, String key, NBTType type, Class<T> clazz) {
|
||||
Object workingtag = comp.getResolvedObject();
|
||||
if (workingtag == null) {
|
||||
workingtag = dummyNBT.getCompound(); // it creates a new ListTag if needed, but its unlinked
|
||||
}
|
||||
try {
|
||||
Object nbt = ReflectionMethod.COMPOUND_GET_LIST.run(workingtag, key, type.getId());
|
||||
if (clazz == String.class) {
|
||||
return (NBTList<T>) new NBTStringList(comp, key, type, nbt);
|
||||
} else if (clazz == NBTListCompound.class) {
|
||||
return (NBTList<T>) new NBTCompoundList(comp, key, type, nbt);
|
||||
} else if (clazz == Integer.class) {
|
||||
return (NBTList<T>) new NBTIntegerList(comp, key, type, nbt);
|
||||
} else if (clazz == Float.class) {
|
||||
return (NBTList<T>) new NBTFloatList(comp, key, type, nbt);
|
||||
} else if (clazz == Double.class) {
|
||||
return (NBTList<T>) new NBTDoubleList(comp, key, type, nbt);
|
||||
} else if (clazz == Long.class) {
|
||||
return (NBTList<T>) new NBTLongList(comp, key, type, nbt);
|
||||
} else if (clazz == int[].class) {
|
||||
return (NBTList<T>) new NBTIntArrayList(comp, key, type, nbt);
|
||||
} else if (clazz == UUID.class) {
|
||||
return (NBTList<T>) new NBTUUIDList(comp, key, type, nbt);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Exception while getting a list with the type '" + type + "'!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static NBTType getListType(NBTCompound comp, String key) {
|
||||
Object workingtag = comp.getResolvedObject();
|
||||
if (workingtag == null) {
|
||||
workingtag = dummyNBT.getCompound(); // it creates a new ListTag if needed, but its unlinked
|
||||
}
|
||||
try {
|
||||
Object nbt = ReflectionMethod.COMPOUND_GET.run(workingtag, key);
|
||||
String fieldname = "type";
|
||||
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_17_R1)) {
|
||||
fieldname = "w";
|
||||
}
|
||||
Field f;
|
||||
try {
|
||||
f = nbt.getClass().getDeclaredField(fieldname);
|
||||
} catch (NoSuchFieldException ignore) {
|
||||
// fallback try mojang mapped/legacy
|
||||
f = nbt.getClass().getDeclaredField("type");
|
||||
}
|
||||
f.setAccessible(true);
|
||||
return NBTType.valueOf(f.getByte(nbt));
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Exception while getting the list type!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getEntry(NBTCompound comp, String key) {
|
||||
Object workingtag = comp.getResolvedObject();
|
||||
try {
|
||||
return ReflectionMethod.COMPOUND_GET.run(workingtag, key);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Exception while getting an Entry!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses Gson to set a {@link Serializable} value in a Compound
|
||||
*
|
||||
* @param comp
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setObject(NBTCompound comp, String key, Object value) {
|
||||
if (!MinecraftVersion.hasGsonSupport())
|
||||
return;
|
||||
try {
|
||||
String json = GsonWrapper.getString(value);
|
||||
setData(comp, ReflectionMethod.COMPOUND_SET_STRING, key, json);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while setting the Object '" + value + "'!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses Gson to load back a {@link Serializable} object from the Compound
|
||||
*
|
||||
* @param comp
|
||||
* @param key
|
||||
* @param type
|
||||
* @return The loaded Object or null, if not found
|
||||
*/
|
||||
public static <T> T getObject(NBTCompound comp, String key, Class<T> type) {
|
||||
if (!MinecraftVersion.hasGsonSupport())
|
||||
return null;
|
||||
String json = (String) getData(comp, ReflectionMethod.COMPOUND_GET_STRING, key);
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
return GsonWrapper.deserializeJson(json, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the given key
|
||||
*
|
||||
* @param comp
|
||||
* @param key
|
||||
*/
|
||||
public static void remove(NBTCompound comp, String key) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp))
|
||||
return;
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
ReflectionMethod.COMPOUND_REMOVE_KEY.run(workingtag, key);
|
||||
comp.setCompound(rootnbttag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Keyset inside this Compound
|
||||
*
|
||||
* @param comp
|
||||
* @return Set of all keys
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Set<String> getKeys(NBTCompound comp) {
|
||||
Object workingtag = comp.getResolvedObject();
|
||||
return (Set<String>) ReflectionMethod.COMPOUND_GET_KEYS.run(workingtag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets data inside the Compound
|
||||
*
|
||||
* @param comp
|
||||
* @param type
|
||||
* @param key
|
||||
* @param data
|
||||
*/
|
||||
public static void setData(NBTCompound comp, ReflectionMethod type, String key, Object data) {
|
||||
if (data == null) {
|
||||
remove(comp, key);
|
||||
return;
|
||||
}
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp))
|
||||
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
type.run(workingtag, key, data);
|
||||
comp.setCompound(rootnbttag);
|
||||
}
|
||||
|
||||
private final static NBTContainer dummyNBT = new NBTContainer();
|
||||
|
||||
/**
|
||||
* Gets data from the Compound
|
||||
*
|
||||
* @param comp
|
||||
* @param type
|
||||
* @param key
|
||||
* @return The value or default fallback from NMS
|
||||
*/
|
||||
public static Object getData(NBTCompound comp, ReflectionMethod type, String key) {
|
||||
Object workingtag = comp.getResolvedObject();
|
||||
// return default behavior data as if there was a compound
|
||||
if (workingtag == null) {
|
||||
workingtag = dummyNBT.getCompound();
|
||||
}
|
||||
return type.run(workingtag, key);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* String implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTStringList extends NBTList<String> {
|
||||
|
||||
protected NBTStringList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
super(owner, name, type, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(int index) {
|
||||
try {
|
||||
return (String) ReflectionMethod.LIST_GET_STRING.run(listObject, index);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object asTag(String object) {
|
||||
try {
|
||||
Constructor<?> con = ClassWrapper.NMS_NBTTAGSTRING.getClazz().getDeclaredConstructor(String.class);
|
||||
con.setAccessible(true);
|
||||
return con.newInstance(object);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
||||
| NoSuchMethodException | SecurityException e) {
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.CheckUtil;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
|
||||
/**
|
||||
* NBT class to access vanilla tags from TileEntities. TileEntities don't
|
||||
* support custom tags. Use the NBTInjector for custom tags. Changes will be
|
||||
* instantly applied to the Tile, use the merge method to do many things at
|
||||
* once.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTTileEntity extends NBTCompound {
|
||||
|
||||
private final BlockState tile;
|
||||
private final boolean readonly;
|
||||
private final Object compound;
|
||||
private boolean closed = false;
|
||||
|
||||
/**
|
||||
* @param tile BlockState from any TileEntity
|
||||
* @param 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 setClosed() {
|
||||
this.closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReadOnly() {
|
||||
return readonly;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
// this runs before async check, since it's just a copy
|
||||
if (readonly && compound != null) {
|
||||
return compound;
|
||||
}
|
||||
if (!Bukkit.isPrimaryThread())
|
||||
throw new NbtApiException("BlockEntity NBT needs to be accessed sync!");
|
||||
return NBTReflectionUtil.getTileEntityNBTTagCompound(tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
if (readonly) {
|
||||
throw new NbtApiException("Tried setting data in read only mode!");
|
||||
}
|
||||
if (!Bukkit.isPrimaryThread())
|
||||
throw new NbtApiException("BlockEntity NBT needs to be accessed sync!");
|
||||
NBTReflectionUtil.setTileEntityNBTTagCompound(tile, compound);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
/**
|
||||
* Enum of all NBT Types Minecraft contains
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum NBTType {
|
||||
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;
|
||||
}
|
||||
|
||||
private final int 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
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.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NbtApiException extends RuntimeException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(generateMessage(message), cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
*/
|
||||
public NbtApiException(String message) {
|
||||
super(generateMessage(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cause
|
||||
*/
|
||||
public NbtApiException(Throwable cause) {
|
||||
super(generateMessage(cause == null ? null : cause.toString()), cause);
|
||||
}
|
||||
|
||||
private static String generateMessage(String message) {
|
||||
if (message == null)
|
||||
return null;
|
||||
if (confirmedBroken == null) {
|
||||
return "[?][" + 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
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 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);
|
||||
}
|
||||
|
||||
public static void overwriteGsonInstance(Gson replacement) {
|
||||
gson = replacement;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils;
|
||||
|
||||
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
|
||||
* other classes,registers bStats and checks rather Maven shading was done
|
||||
* correctly.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum MinecraftVersion {
|
||||
UNKNOWN(Integer.MAX_VALUE), // Use the newest known mappings
|
||||
MC1_7_R4(174), MC1_8_R3(183), MC1_9_R1(191), MC1_9_R2(192), MC1_10_R1(1101), MC1_11_R1(1111), MC1_12_R1(1121),
|
||||
MC1_13_R1(1131), MC1_13_R2(1132), MC1_14_R1(1141), MC1_15_R1(1151), MC1_16_R1(1161), MC1_16_R2(1162),
|
||||
MC1_16_R3(1163), MC1_17_R1(1171), MC1_18_R1(1181, true), MC1_18_R2(1182, true), MC1_19_R1(1191, true),
|
||||
MC1_19_R2(1192, true), MC1_19_R3(1193, true), MC1_20_R1(1201, true);
|
||||
|
||||
private static MinecraftVersion version;
|
||||
private static Boolean hasGsonSupport;
|
||||
private static Boolean isForgePresent;
|
||||
private static Boolean isFoliaPresent;
|
||||
private static boolean bStatsDisabled = false;
|
||||
private static boolean disablePackageWarning = false;
|
||||
private static boolean updateCheckDisabled = true;
|
||||
/**
|
||||
* Logger used by the api
|
||||
*/
|
||||
private static Logger logger = Logger.getLogger("NBTAPI");
|
||||
|
||||
// NBT-API Version
|
||||
protected static final String VERSION = "2.12.0-SNAPSHOT";
|
||||
|
||||
private final int versionId;
|
||||
private final boolean mojangMapping;
|
||||
|
||||
MinecraftVersion(int versionId) {
|
||||
this(versionId, false);
|
||||
}
|
||||
|
||||
MinecraftVersion(int versionId, boolean mojangMapping) {
|
||||
this.versionId = versionId;
|
||||
this.mojangMapping = mojangMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A simple comparable Integer, representing the version.
|
||||
*/
|
||||
public int getVersionId() {
|
||||
return versionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if method names are in Mojang format and need to be remapped
|
||||
* internally
|
||||
*/
|
||||
public boolean isMojangMapping() {
|
||||
return mojangMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
|
||||
public final class ReflectionUtil {
|
||||
|
||||
private static Field field_modifiers;
|
||||
|
||||
static {
|
||||
try {
|
||||
field_modifiers = Field.class.getDeclaredField("modifiers");
|
||||
field_modifiers.setAccessible(true);
|
||||
} catch (NoSuchFieldException ex) {
|
||||
try {
|
||||
// This hacky workaround is for newer jdk versions 11+?
|
||||
Method fieldGetter = Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class);
|
||||
fieldGetter.setAccessible(true);
|
||||
Field[] fields = (Field[]) fieldGetter.invoke(Field.class, false);
|
||||
for (Field f : fields)
|
||||
if (f.getName().equals("modifiers")) {
|
||||
field_modifiers = f;
|
||||
field_modifiers.setAccessible(true);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException(e);
|
||||
}
|
||||
}
|
||||
if (field_modifiers == null) {
|
||||
throw new NbtApiException("Unable to init the modifiers Field.");
|
||||
}
|
||||
}
|
||||
|
||||
public static Field makeNonFinal(Field field) throws IllegalArgumentException, IllegalAccessException {
|
||||
int mods = field.getModifiers();
|
||||
if (Modifier.isFinal(mods)) {
|
||||
field_modifiers.set(field, mods & ~Modifier.FINAL);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
public static void setFinal(Object obj, Field field, Object newValue)
|
||||
throws IllegalArgumentException, IllegalAccessException {
|
||||
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 };
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
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;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
|
||||
/**
|
||||
* This class uses the Spiget API to check for updates
|
||||
*
|
||||
*/
|
||||
public class VersionChecker {
|
||||
|
||||
private static final String USER_AGENT = "nbt-api Version check";
|
||||
private static final String REQUEST_URL = "https://api.spiget.org/v2/resources/7939/versions?size=100";
|
||||
public static boolean hideOk = false;
|
||||
|
||||
protected static void checkForUpdates() throws Exception {
|
||||
URL url = new URL(REQUEST_URL);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.addRequestProperty("User-Agent", USER_AGENT);// Set
|
||||
// User-Agent
|
||||
|
||||
// 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 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
|
||||
|
||||
import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.getLogger;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
|
||||
/**
|
||||
* Wraps NMS and CRAFT classes
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum ClassWrapper {
|
||||
CRAFT_ITEMSTACK(PackageWrapper.CRAFTBUKKIT, "inventory.CraftItemStack", null, null),
|
||||
CRAFT_METAITEM(PackageWrapper.CRAFTBUKKIT, "inventory.CraftMetaItem", null, null),
|
||||
CRAFT_ENTITY(PackageWrapper.CRAFTBUKKIT, "entity.CraftEntity", null, null),
|
||||
CRAFT_WORLD(PackageWrapper.CRAFTBUKKIT, "CraftWorld", null, null),
|
||||
CRAFT_PERSISTENTDATACONTAINER(PackageWrapper.CRAFTBUKKIT, "persistence.CraftPersistentDataContainer",
|
||||
MinecraftVersion.MC1_14_R1, null),
|
||||
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",
|
||||
"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.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, null);
|
||||
}
|
||||
|
||||
ClassWrapper(PackageWrapper packageId, String clazzName, MinecraftVersion from, MinecraftVersion to,
|
||||
String mojangMap, String mojangName) {
|
||||
this.mojangName = mojangName;
|
||||
if (from != null && MinecraftVersion.getVersion().getVersionId() < from.getVersionId()) {
|
||||
return;
|
||||
}
|
||||
if (to != null && MinecraftVersion.getVersion().getVersionId() > to.getVersionId()) {
|
||||
return;
|
||||
}
|
||||
enabled = true;
|
||||
try {
|
||||
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_18_R1) && mojangName != null) {
|
||||
// check for Mojmapped enviroment
|
||||
try {
|
||||
clazz = Class.forName(mojangName);
|
||||
return;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
// ignored, not mojang mapped
|
||||
}
|
||||
}
|
||||
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_17_R1) && mojangMap != null) {
|
||||
clazz = Class.forName(mojangMap + "." + clazzName);
|
||||
} else if (packageId == PackageWrapper.NONE) {
|
||||
clazz = Class.forName(clazzName);
|
||||
} else if (MinecraftVersion.isForgePresent() && MinecraftVersion.getVersion() == MinecraftVersion.MC1_7_R4
|
||||
&& Forge1710Mappings.getClassMappings().get(this.name()) != null) {
|
||||
clazz = Class.forName(clazzName = Forge1710Mappings.getClassMappings().get(this.name()));
|
||||
} else {
|
||||
String version = MinecraftVersion.getVersion().getPackageName();
|
||||
clazz = Class.forName(packageId.getUri() + "." + version + "." + clazzName);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
getLogger().log(Level.WARNING, "[NBTAPI] Error while trying to resolve the class '" + clazzName + "'!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The wrapped class
|
||||
*/
|
||||
public Class<?> getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Is this class available in this Version
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Package+Class name used by Mojang
|
||||
*/
|
||||
public String getMojangName() {
|
||||
return mojangName;
|
||||
}
|
||||
|
||||
}
|
||||
+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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
|
||||
import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.getLogger;
|
||||
|
||||
/**
|
||||
* This Enum wraps Constructors for NMS classes
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@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()),;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
|
||||
|
||||
/**
|
||||
* Package enum
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@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;
|
||||
|
||||
private PackageWrapper(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Uri for that package
|
||||
*/
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
}
|
||||
+421
@@ -0,0 +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.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);
|
||||
}
|
||||
}
|
||||
Loaded 100 of 245 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user