mirror of
https://github.com/tr7zw/Item-NBT-API.git
synced 2026-11-04 16:50:12 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05da1c6b1c | ||
|
|
8b861f6c7a | ||
|
|
58c744dab7 | ||
|
|
8c75990918 | ||
|
|
e6fa7bca63 | ||
|
|
6eff3d9cdc | ||
|
|
492372519a | ||
|
|
054a7f5173 | ||
|
|
a7b73fda9d | ||
|
|
fd9bbe093b | ||
|
|
92108a218c | ||
|
|
340fd2ae63 | ||
|
|
371d55cd1f | ||
|
|
fe8e50d788 | ||
|
|
834d0bc6e3 | ||
|
|
0a31d709e3 | ||
|
|
19254b5214 | ||
|
|
188942887e | ||
|
|
ab1b6e5fa8 | ||
|
|
c684f9f288 | ||
|
|
4a3fbf135b | ||
|
|
1e3e8dc5d9 | ||
|
|
be0fc09cb3 | ||
|
|
a9a248c7cf | ||
|
|
26e3c5b913 | ||
|
|
2585ef0a50 | ||
|
|
0754250af9 | ||
|
|
922c32c91b | ||
|
|
c7e01f2660 | ||
|
|
cb67076324 | ||
|
|
b691c6972c | ||
|
|
cec0222114 | ||
|
|
61fd8669f0 | ||
|
|
aa54a91c40 | ||
|
|
739b449254 | ||
|
|
d97a050e1a | ||
|
|
e3da9bf20e | ||
|
|
259b184829 | ||
|
|
58bbcbe888 | ||
|
|
8479479c84 | ||
|
|
6129125dd9 | ||
|
|
43baa7c2ef | ||
|
|
c6cbc3b309 | ||
|
|
39fd158c56 | ||
|
|
2202dc38e0 | ||
|
|
656b7caff2 | ||
|
|
0918f25716 | ||
|
|
662ad04a5e | ||
|
|
daf684931f | ||
|
|
99b5775855 | ||
|
|
87a6fce52f | ||
|
|
0a46bce99c | ||
|
|
a1a3c0be33 | ||
|
|
bbf5064a15 | ||
|
|
437c69b7f4 | ||
|
|
ede8ebba6b | ||
|
|
54d1ed019f | ||
|
|
4491709645 | ||
|
|
34abb0aefb | ||
|
|
2522edac6b | ||
|
|
f64ac8e3ac | ||
|
|
5d3188a813 | ||
|
|
fc85d7f4ec | ||
|
|
6063f8a27d | ||
|
|
f203a0c8bc | ||
|
|
0bec8d4025 | ||
|
|
56abfad7a1 | ||
|
|
e96ae3227e | ||
|
|
b727e33227 | ||
|
|
be13f4bd5e | ||
|
|
18d03036a9 | ||
|
|
edeb9051e7 | ||
|
|
5b17a25c23 | ||
|
|
9f8208347b | ||
|
|
6e3ab1fb7e | ||
|
|
7587df8ef2 |
No files matched your search
@@ -0,0 +1,163 @@
|
||||
{
|
||||
"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": [
|
||||
"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/"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
|
||||
custom: https://paypal.me/tr7zw
|
||||
patreon: tr7zw
|
||||
custom: https://tr7zw.dev/donate/
|
||||
@@ -0,0 +1,17 @@
|
||||
name: Java CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Build with Maven
|
||||
run: mvn --file pom.xml
|
||||
@@ -1,8 +1,46 @@
|
||||
# Item-NBT-API
|
||||
Add custom NBT tags to Items without NMS!
|
||||
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)
|
||||
|
||||
### 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)
|
||||
[](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)
|
||||
|
||||
[](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).
|
||||
|
||||
## 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://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>
|
||||
</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!
|
||||
+53
-13
@@ -1,20 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>item-nbt-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<artifactId>item-nbt-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean install javadoc:javadoc</defaultGoal>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>functional-annotations</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean install javadoc:javadoc</defaultGoal>
|
||||
<resources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>shade</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>de.tr7zw.annotations</pattern>
|
||||
<shadedPattern>de.tr7zw.changeme.nbtapi.utils.annotations</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -1,8 +1,11 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
@@ -23,6 +26,11 @@ public class NBTCompound {
|
||||
this.parent = owner;
|
||||
}
|
||||
|
||||
protected void saveCompound(){
|
||||
if(parent != null)
|
||||
parent.saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Compound name
|
||||
*/
|
||||
@@ -56,6 +64,7 @@ public class NBTCompound {
|
||||
*/
|
||||
public void mergeCompound(NBTCompound comp) {
|
||||
NBTReflectionUtil.mergeOtherNBTCompound(this, comp);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,6 +75,7 @@ public class NBTCompound {
|
||||
*/
|
||||
public void setString(String key, String value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_STRING, key, value);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,6 +100,7 @@ public class NBTCompound {
|
||||
*/
|
||||
public void setInteger(String key, Integer value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_INT, key, value);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,6 +121,7 @@ public class NBTCompound {
|
||||
*/
|
||||
public void setDouble(String key, Double value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_DOUBLE, key, value);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,6 +142,7 @@ public class NBTCompound {
|
||||
*/
|
||||
public void setByte(String key, Byte value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_BYTE, key, value);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,6 +163,7 @@ public class NBTCompound {
|
||||
*/
|
||||
public void setShort(String key, Short value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_SHORT, key, value);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,6 +184,7 @@ public class NBTCompound {
|
||||
*/
|
||||
public void setLong(String key, Long value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_LONG, key, value);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,6 +205,7 @@ public class NBTCompound {
|
||||
*/
|
||||
public void setFloat(String key, Float value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_FLOAT, key, value);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,6 +226,7 @@ public class NBTCompound {
|
||||
*/
|
||||
public void setByteArray(String key, byte[] value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_BYTEARRAY, key, value);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,6 +247,7 @@ public class NBTCompound {
|
||||
*/
|
||||
public void setIntArray(String key, int[] value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_INTARRAY, key, value);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,10 +268,12 @@ public class NBTCompound {
|
||||
*/
|
||||
public void setBoolean(String key, Boolean value) {
|
||||
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_BOOLEAN, key, value);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
protected void set(String key, Object val) {
|
||||
NBTReflectionUtil.set(this, key, val);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,6 +294,7 @@ public class NBTCompound {
|
||||
*/
|
||||
public void setObject(String key, Object value) {
|
||||
NBTReflectionUtil.setObject(this, key, value);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -286,6 +307,28 @@ public class NBTCompound {
|
||||
public <T> T getObject(String key, Class<T> type) {
|
||||
return NBTReflectionUtil.getObject(this, key, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an ItemStack as a compound under a given key
|
||||
*
|
||||
* @param key
|
||||
* @param item
|
||||
*/
|
||||
public void setItemStack(String key, ItemStack item){
|
||||
removeKey(key);
|
||||
addCompound(key).mergeCompound(NBTItem.convertItemtoNBT(item));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an ItemStack that was saved at the given key
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public ItemStack getItemStack(String key){
|
||||
NBTCompound comp = getCompound(key);
|
||||
return NBTItem.convertNBTtoItem(comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
@@ -303,6 +346,7 @@ public class NBTCompound {
|
||||
*/
|
||||
public void removeKey(String key) {
|
||||
NBTReflectionUtil.remove(this, key);
|
||||
saveCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,6 +369,7 @@ public class NBTCompound {
|
||||
NBTCompound comp = getCompound(name);
|
||||
if(comp == null)
|
||||
throw new NbtApiException("Error while adding Compound, got null!");
|
||||
saveCompound();
|
||||
return comp;
|
||||
}
|
||||
|
||||
@@ -346,7 +391,9 @@ public class NBTCompound {
|
||||
* @return The retrieved String List
|
||||
*/
|
||||
public NBTList<String> getStringList(String name) {
|
||||
return NBTReflectionUtil.getList(this, name, NBTType.NBTTagString, String.class);
|
||||
NBTList<String> list = NBTReflectionUtil.getList(this, name, NBTType.NBTTagString, String.class);
|
||||
saveCompound();
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -354,7 +401,39 @@ public class NBTCompound {
|
||||
* @return The retrieved Integer List
|
||||
*/
|
||||
public NBTList<Integer> getIntegerList(String name) {
|
||||
return NBTReflectionUtil.getList(this, name, NBTType.NBTTagInt, Integer.class);
|
||||
NBTList<Integer> list = NBTReflectionUtil.getList(this, name, NBTType.NBTTagInt, Integer.class);
|
||||
saveCompound();
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Float List
|
||||
*/
|
||||
public NBTList<Float> getFloatList(String name) {
|
||||
NBTList<Float> list = NBTReflectionUtil.getList(this, name, NBTType.NBTTagFloat, Float.class);
|
||||
saveCompound();
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Double List
|
||||
*/
|
||||
public NBTList<Double> getDoubleList(String name) {
|
||||
NBTList<Double> list = NBTReflectionUtil.getList(this, name, NBTType.NBTTagDouble, Double.class);
|
||||
saveCompound();
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Long List
|
||||
*/
|
||||
public NBTList<Long> getLongList(String name) {
|
||||
NBTList<Long> list = NBTReflectionUtil.getList(this, name, NBTType.NBTTagLong, Long.class);
|
||||
saveCompound();
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -362,7 +441,9 @@ public class NBTCompound {
|
||||
* @return The retrieved Compound List
|
||||
*/
|
||||
public NBTCompoundList getCompoundList(String name) {
|
||||
return (NBTCompoundList) NBTReflectionUtil.getList(this, name, NBTType.NBTTagCompound, NBTListCompound.class);
|
||||
NBTCompoundList list = (NBTCompoundList) NBTReflectionUtil.getList(this, name, NBTType.NBTTagCompound, NBTListCompound.class);
|
||||
saveCompound();
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -377,22 +458,29 @@ public class NBTCompound {
|
||||
return null;
|
||||
return NBTType.valueOf((byte) o);
|
||||
}
|
||||
|
||||
public void writeCompound(OutputStream stream) {
|
||||
NBTReflectionUtil.writeApiNBT(this, stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
/*StringBuilder result = new StringBuilder();
|
||||
for (String key : getKeys()) {
|
||||
result.append(toString(key));
|
||||
}
|
||||
return result.toString();
|
||||
return result.toString();*/
|
||||
return asNBTString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Just use toString()
|
||||
* @param key
|
||||
* @return A string representation of the given key
|
||||
*/
|
||||
@Deprecated
|
||||
public String toString(String key) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
/*StringBuilder result = new StringBuilder();
|
||||
NBTCompound compound = this;
|
||||
while (compound.getParent() != null) {
|
||||
result.append(" ");
|
||||
@@ -402,12 +490,15 @@ public class NBTCompound {
|
||||
return this.getCompound(key).toString();
|
||||
} else {
|
||||
return result + "-" + key + ": " + getContent(key) + System.lineSeparator();
|
||||
}
|
||||
}*/
|
||||
return asNBTString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Just use toString()
|
||||
* @return A json valid nbt string for this Compound
|
||||
*/
|
||||
@Deprecated
|
||||
public String asNBTString() {
|
||||
Object comp = NBTReflectionUtil.gettoCompount(getCompound(), this);
|
||||
if (comp == null)
|
||||
@@ -415,4 +506,22 @@ public class NBTCompound {
|
||||
return comp.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the nbt-string to match this compound with another object.
|
||||
* This allows two "technically" different Compounds to match, if they have the same content
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
return toString().equals(obj.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,6 +24,17 @@ public class NBTCompoundList extends NBTList<NBTListCompound> {
|
||||
* @return The added {@link NBTListCompound}
|
||||
*/
|
||||
public NBTListCompound addCompound() {
|
||||
return (NBTListCompound) addCompound(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a copy of the Compound to the end of the List and returns it.
|
||||
* When null is given, a new Compound will be created
|
||||
*
|
||||
* @param comp
|
||||
* @return
|
||||
*/
|
||||
public NBTCompound addCompound(NBTCompound comp) {
|
||||
try {
|
||||
Object compound = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
|
||||
@@ -31,7 +42,12 @@ public class NBTCompoundList extends NBTList<NBTListCompound> {
|
||||
} else {
|
||||
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, compound);
|
||||
}
|
||||
return new NBTListCompound(this, compound);
|
||||
getParent().saveCompound();
|
||||
NBTListCompound listcomp = new NBTListCompound(this, compound);
|
||||
if(comp != null){
|
||||
listcomp.mergeCompound(comp);
|
||||
}
|
||||
return listcomp;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
@@ -40,25 +56,15 @@ public class NBTCompoundList extends NBTList<NBTListCompound> {
|
||||
/**
|
||||
* Adds a new Compound to the end of the List.
|
||||
*
|
||||
* @param empty This has to be null!
|
||||
*
|
||||
* @deprecated Please use addCompound!
|
||||
* @param empty
|
||||
* @return True, if compound was added
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean add(NBTListCompound empty) {
|
||||
if (empty != null) {
|
||||
throw new NotImplementedException("You need to pass null! ListCompounds from other lists won't work.");
|
||||
}
|
||||
try {
|
||||
Object compound = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
|
||||
ReflectionMethod.LIST_ADD.run(listObject, 0, compound);
|
||||
} else {
|
||||
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, compound);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
return addCompound(empty) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,6 +79,7 @@ public class NBTCompoundList extends NBTList<NBTListCompound> {
|
||||
} else {
|
||||
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, compound);
|
||||
}
|
||||
super.getParent().saveCompound();
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
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;
|
||||
|
||||
@@ -29,9 +32,25 @@ public class NBTContainer extends NBTCompound {
|
||||
*/
|
||||
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.
|
||||
@@ -40,6 +59,9 @@ public class NBTContainer extends NBTCompound {
|
||||
*/
|
||||
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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,11 @@ package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import de.tr7zw.annotations.FAUtil;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.annotations.AvaliableSince;
|
||||
import de.tr7zw.changeme.nbtapi.utils.annotations.CheckUtil;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -19,6 +24,9 @@ public class NBTEntity extends NBTCompound {
|
||||
*/
|
||||
public NBTEntity(Entity entity) {
|
||||
super(null, null);
|
||||
if (entity == null || entity.isDead()) {
|
||||
throw new NullPointerException("Entity can't be null/dead!");
|
||||
}
|
||||
ent = entity;
|
||||
}
|
||||
|
||||
@@ -32,4 +40,24 @@ public class NBTEntity extends NBTCompound {
|
||||
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
|
||||
*/
|
||||
@AvaliableSince(version = MinecraftVersion.MC1_14_R1)
|
||||
public NBTCompound getPersistentDataContainer() {
|
||||
FAUtil.check(this::getPersistentDataContainer, CheckUtil::isAvaliable);
|
||||
if (hasKey("BukkitValues")) {
|
||||
return getCompound("BukkitValues");
|
||||
} else {
|
||||
NBTContainer container = new NBTContainer();
|
||||
container.addCompound("BukkitValues").setString("__nbtapi",
|
||||
"Marker to make the PersistentDataContainer have content");
|
||||
mergeCompound(container);
|
||||
return getCompound("BukkitValues");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,10 +27,13 @@ public class NBTFile extends NBTCompound {
|
||||
*/
|
||||
public NBTFile(File file) throws IOException {
|
||||
super(null, null);
|
||||
if (file == null) {
|
||||
throw new NullPointerException("File can't be null!");
|
||||
}
|
||||
this.file = file;
|
||||
if (file.exists()) {
|
||||
FileInputStream inputsteam = new FileInputStream(file);
|
||||
nbt = NBTReflectionUtil.readNBTFile(inputsteam);
|
||||
nbt = NBTReflectionUtil.readNBT(inputsteam);
|
||||
} else {
|
||||
nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
save();
|
||||
@@ -49,7 +52,7 @@ public class NBTFile extends NBTCompound {
|
||||
throw new IOException("Unable to create file at " + file.getAbsolutePath());
|
||||
}
|
||||
FileOutputStream outStream = new FileOutputStream(file);
|
||||
NBTReflectionUtil.saveNBTFile(nbt, outStream);
|
||||
NBTReflectionUtil.writeNBT(nbt, outStream);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,30 @@
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
@@ -20,10 +21,12 @@ public class NBTIntegerList extends NBTList<Integer> {
|
||||
@Override
|
||||
protected Object asTag(Integer object) {
|
||||
try {
|
||||
return ClassWrapper.NMS_NBTTAGINT.getClazz().getConstructor(int.class).newInstance(object);
|
||||
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 Oject " + object + " to it's NMS object!", e);
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
@@ -22,8 +23,8 @@ public class NBTItem extends NBTCompound {
|
||||
*/
|
||||
public NBTItem(ItemStack item) {
|
||||
super(null, null);
|
||||
if (item == null) {
|
||||
throw new NullPointerException("ItemStack can't be null!");
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
throw new NullPointerException("ItemStack can't be null/Air!");
|
||||
}
|
||||
bukkitItem = item.clone();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,20 @@ public abstract class NBTList<T> implements List<T> {
|
||||
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;
|
||||
}
|
||||
|
||||
protected void save() {
|
||||
parent.set(listName, listObject);
|
||||
@@ -208,7 +222,7 @@ public abstract class NBTList<T> implements List<T> {
|
||||
public Iterator<T> iterator() {
|
||||
return new Iterator<T>() {
|
||||
|
||||
private int index = 0;
|
||||
private int index = -1;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
@@ -234,7 +248,7 @@ public abstract class NBTList<T> implements List<T> {
|
||||
final NBTList<T> list = this;
|
||||
return new ListIterator<T>() {
|
||||
|
||||
int index = startIndex;
|
||||
int index = startIndex - 1;
|
||||
|
||||
@Override
|
||||
public void add(T e) {
|
||||
@@ -248,7 +262,7 @@ public abstract class NBTList<T> implements List<T> {
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return index > 0;
|
||||
return index >= 0 && index <= size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -265,7 +279,9 @@ public abstract class NBTList<T> implements List<T> {
|
||||
|
||||
@Override
|
||||
public T previous() {
|
||||
return get(--index);
|
||||
if (!hasPrevious())
|
||||
throw new NoSuchElementException("Id: " + (index - 1));
|
||||
return get(index--);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -318,4 +334,10 @@ public abstract class NBTList<T> implements List<T> {
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return listObject.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,9 +1,5 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Cut down version of the {@link NBTCompound} for inside
|
||||
* {@link NBTCompoundList} This Compound implementation is missing the ability
|
||||
@@ -13,144 +9,34 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTListCompound {
|
||||
public class NBTListCompound extends NBTCompound {
|
||||
|
||||
private NBTList<?> owner;
|
||||
private Object compound;
|
||||
|
||||
protected NBTListCompound(NBTList<?> parent, Object obj) {
|
||||
super(null, null);
|
||||
owner = parent;
|
||||
compound = obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* String setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setString(String key, String value) {
|
||||
if (value == null) {
|
||||
remove(key);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
compound.getClass().getMethod("setString", String.class, String.class).invoke(compound, key, value);
|
||||
owner.save();
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
|
||||
public NBTList<?> getListParent() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* int setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setInteger(String key, int value) {
|
||||
try {
|
||||
compound.getClass().getMethod("setInt", String.class, int.class).invoke(compound, key, value);
|
||||
owner.save();
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return compound;
|
||||
}
|
||||
|
||||
/**
|
||||
* int getter
|
||||
*
|
||||
* @param value
|
||||
* @return Saved value or NMS fallback
|
||||
*/
|
||||
public int getInteger(String value) {
|
||||
try {
|
||||
return (int) compound.getClass().getMethod("getInt", String.class).invoke(compound, value);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
this.compound = compound;
|
||||
}
|
||||
|
||||
/**
|
||||
* double setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void setDouble(String key, double value) {
|
||||
try {
|
||||
compound.getClass().getMethod("setDouble", String.class, double.class).invoke(compound, key, value);
|
||||
owner.save();
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* double getter
|
||||
*
|
||||
* @param key
|
||||
* @return Saved value or NMS fallback
|
||||
*/
|
||||
public double getDouble(String key) {
|
||||
try {
|
||||
return (double) compound.getClass().getMethod("getDouble", String.class).invoke(compound, key);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String getter
|
||||
*
|
||||
* @param key
|
||||
* @return Saved value or NMS fallback
|
||||
*/
|
||||
public String getString(String key) {
|
||||
try {
|
||||
return (String) compound.getClass().getMethod("getString", String.class).invoke(compound, key);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for a given key
|
||||
*
|
||||
* @param key
|
||||
* @return true if the Compound has this key, else false
|
||||
*/
|
||||
public boolean hasKey(String key) {
|
||||
try {
|
||||
return (boolean) compound.getClass().getMethod("hasKey", String.class).invoke(compound, key);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Set containing all keys
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<String> getKeys() {
|
||||
try {
|
||||
return (Set<String>) ReflectionMethod.LISTCOMPOUND_GET_KEYS.run(compound);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a key from the Compound
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
public void remove(String key) {
|
||||
try {
|
||||
compound.getClass().getMethod("remove", String.class).invoke(compound, key);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
}
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
@@ -47,12 +47,12 @@ public class NBTReflectionUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in a FileInputStream as NMS Compound
|
||||
* Reads in a InputStream as NMS Compound
|
||||
*
|
||||
* @param stream InputStream of any NBT file
|
||||
* @return NMS Compound
|
||||
*/
|
||||
public static Object readNBTFile(FileInputStream stream) {
|
||||
public static Object readNBT(InputStream stream) {
|
||||
try {
|
||||
return ReflectionMethod.NBTFILE_READ.run(null, stream);
|
||||
} catch (Exception e) {
|
||||
@@ -61,17 +61,38 @@ public class NBTReflectionUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a NMS Compound to a FileOutputStream
|
||||
* Writes a NMS Compound to an OutputStream
|
||||
*
|
||||
* @param nbt NMS Compound
|
||||
* @param stream Stream to write to
|
||||
* @return ???
|
||||
*/
|
||||
public static Object saveNBTFile(Object nbt, FileOutputStream stream) {
|
||||
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 saving a NBT File!", e);
|
||||
throw new NbtApiException("Exception while writing NBT!", 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 nbttag = comp.getCompound();
|
||||
if (nbttag == null) {
|
||||
nbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(comp))
|
||||
return;
|
||||
Object workingtag = gettoCompount(nbttag, comp);
|
||||
ReflectionMethod.NBTFILE_WRITE.run(null, workingtag, stream);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while writing NBT!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,10 +120,11 @@ public class NBTReflectionUtil {
|
||||
*/
|
||||
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(nbtcompound.getCompound());
|
||||
return ObjectCreator.NMS_COMPOUNDFROMITEM.getInstance(nmsComp);
|
||||
} else {
|
||||
return ReflectionMethod.NMSITEM_CREATESTACK.run(null, nbtcompound.getCompound());
|
||||
return ReflectionMethod.NMSITEM_CREATESTACK.run(null, nmsComp);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while converting NBTCompound to NMS ItemStack!", e);
|
||||
@@ -277,10 +299,10 @@ public class NBTReflectionUtil {
|
||||
/**
|
||||
* Merges the second {@link NBTCompound} into the first one
|
||||
*
|
||||
* @param comp Target for the merge
|
||||
* @param nbtcompound Data to merge
|
||||
* @param comp Target for the merge
|
||||
* @param nbtcompoundSrc Data to merge
|
||||
*/
|
||||
public static void mergeOtherNBTCompound(NBTCompound comp, NBTCompound nbtcompound) {
|
||||
public static void mergeOtherNBTCompound(NBTCompound comp, NBTCompound nbtcompoundSrc) {
|
||||
Object rootnbttag = comp.getCompound();
|
||||
if (rootnbttag == null) {
|
||||
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
@@ -288,8 +310,15 @@ public class NBTReflectionUtil {
|
||||
if (!valideCompound(comp))
|
||||
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
||||
Object workingtag = gettoCompount(rootnbttag, comp);
|
||||
Object rootnbttagSrc = nbtcompoundSrc.getCompound();
|
||||
if (rootnbttagSrc == null) {
|
||||
rootnbttagSrc = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
if (!valideCompound(nbtcompoundSrc))
|
||||
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
|
||||
Object workingtagSrc = gettoCompount(rootnbttagSrc, nbtcompoundSrc);
|
||||
try {
|
||||
ReflectionMethod.COMPOUND_MERGE.run(workingtag, nbtcompound.getCompound());
|
||||
ReflectionMethod.COMPOUND_MERGE.run(workingtag, workingtagSrc);
|
||||
comp.setCompound(rootnbttag);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while merging two NBTCompounds!", e);
|
||||
@@ -372,6 +401,12 @@ public class NBTReflectionUtil {
|
||||
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 {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
@@ -29,10 +30,12 @@ public class NBTStringList extends NBTList<String> {
|
||||
@Override
|
||||
protected Object asTag(String object) {
|
||||
try {
|
||||
return ClassWrapper.NMS_NBTTAGSTRING.getClazz().getConstructor(String.class).newInstance(object);
|
||||
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 Oject " + object + " to it's NMS object!", e);
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,11 @@ package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import de.tr7zw.annotations.FAUtil;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.annotations.AvaliableSince;
|
||||
import de.tr7zw.changeme.nbtapi.utils.annotations.CheckUtil;
|
||||
|
||||
/**
|
||||
* NBT class to access vanilla tags from TileEntities. TileEntities don't
|
||||
* support custom tags. Use the NBTInjector for custom tags. Changes will be
|
||||
@@ -20,6 +25,9 @@ public class NBTTileEntity extends NBTCompound {
|
||||
*/
|
||||
public NBTTileEntity(BlockState tile) {
|
||||
super(null, null);
|
||||
if (tile == null || !tile.isPlaced()) {
|
||||
throw new NullPointerException("Tile can't be null/not placed!");
|
||||
}
|
||||
this.tile = tile;
|
||||
}
|
||||
|
||||
@@ -33,4 +41,24 @@ public class NBTTileEntity extends NBTCompound {
|
||||
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
|
||||
*/
|
||||
@AvaliableSince(version = MinecraftVersion.MC1_14_R1)
|
||||
public NBTCompound getPersistentDataContainer() {
|
||||
FAUtil.check(this::getPersistentDataContainer, CheckUtil::isAvaliable);
|
||||
if (hasKey("PublicBukkitValues")) {
|
||||
return getCompound("PublicBukkitValues");
|
||||
} else {
|
||||
NBTContainer container = new NBTContainer();
|
||||
container.addCompound("PublicBukkitValues").setString("__nbtapi",
|
||||
"Marker to make the PersistentDataContainer have content");
|
||||
mergeCompound(container);
|
||||
return getCompound("PublicBukkitValues");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,377 +1,387 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.logger;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
* <p>
|
||||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*
|
||||
* This class is modified by tr7zw to work when the api is shaded into other peoples plugins.
|
||||
*/
|
||||
public class ApiMetricsLite {
|
||||
|
||||
private static final String PLUGINNAME = "ItemNBTAPI"; // DO NOT CHANGE THE NAME! else it won't link the data on bStats
|
||||
private static final String PLUGINVERSION = "2.0.0"; // In case you fork the nbt-api for internal use in your network, plugins and so on, you *may* add that to the version here. (2.x.x-Timolia or something like that?)
|
||||
// Not sure how good of an idea that is, so maybe just leave it as is ¯\_(ツ)_/¯
|
||||
|
||||
// The version of this bStats class
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
|
||||
// The version of the NBT-Api bStats
|
||||
public static final int NBT_BSTATS_VERSION = 1;
|
||||
|
||||
// The url to which the data is sent
|
||||
private static final String URL = "https://bStats.org/submitData/bukkit";
|
||||
|
||||
// Is bStats enabled on this server?
|
||||
private boolean enabled;
|
||||
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests;
|
||||
|
||||
// Should the sent data be logged?
|
||||
private static boolean logSentData;
|
||||
|
||||
// Should the response text be logged?
|
||||
private static boolean logResponseStatusText;
|
||||
|
||||
// The uuid of the server
|
||||
private static String serverUUID;
|
||||
|
||||
// The plugin
|
||||
private Plugin plugin;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
*/
|
||||
public ApiMetricsLite() {
|
||||
|
||||
// The register method just uses any enabled plugin it can find to register. This *shouldn't* cause any problems, since the plugin isn't used any other way.
|
||||
// Register our service
|
||||
for(Plugin plug : Bukkit.getPluginManager().getPlugins()) {
|
||||
plugin = plug;
|
||||
if(plugin != null)
|
||||
break;
|
||||
}
|
||||
if(plugin == null) {
|
||||
return;// Didn't find any plugin that could work
|
||||
}
|
||||
|
||||
// Get the config file
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
|
||||
// Check if the config file exists
|
||||
if (!config.isSet("serverUuid")) {
|
||||
|
||||
// Add default values
|
||||
config.addDefault("enabled", true);
|
||||
// Every server gets it's unique random id.
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||
// Should failed request be logged?
|
||||
config.addDefault("logFailedRequests", false);
|
||||
// Should the sent data be logged?
|
||||
config.addDefault("logSentData", false);
|
||||
// Should the response text be logged?
|
||||
config.addDefault("logResponseStatusText", false);
|
||||
|
||||
// Inform the server owners about bStats
|
||||
config.options().header(
|
||||
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
|
||||
"To honor their work, you should not disable it.\n" +
|
||||
"This has nearly no effect on the server performance!\n" +
|
||||
"Check out https://bStats.org/ to learn more :)"
|
||||
).copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) { }
|
||||
}
|
||||
|
||||
// Load the data
|
||||
serverUUID = config.getString("serverUuid");
|
||||
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||
enabled = config.getBoolean("enabled", true);
|
||||
logSentData = config.getBoolean("logSentData", false);
|
||||
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
if (enabled) {
|
||||
boolean found = false;
|
||||
// Search for all other bStats Metrics classes to see if we are the first one
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("NBT_BSTATS_VERSION"); // Create only one instance of the nbt-api bstats.
|
||||
return;
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
found = true; // We aren't the first
|
||||
break;
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
// Register our service
|
||||
Bukkit.getServicesManager().register(ApiMetricsLite.class, this, plugin, ServicePriority.Normal);
|
||||
if (!found) {
|
||||
logger.info("[NBTAPI] Using the plugin '" + plugin.getName() + "' to create a bStats instance!");
|
||||
// We are the first!
|
||||
startSubmitting();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if bStats is enabled.
|
||||
*
|
||||
* @return Whether bStats is enabled or not.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Scheduler which submits our data every 30 minutes.
|
||||
*/
|
||||
private void startSubmitting() {
|
||||
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
|
||||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!plugin.isEnabled()) { // Plugin was disabled
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
|
||||
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
|
||||
Bukkit.getScheduler().runTask(plugin, () -> submitData());
|
||||
}
|
||||
}, 1000l * 60l * 5l, 1000l * 60l * 30l);
|
||||
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
|
||||
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
||||
// WARNING: Just don't do it!
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the plugin specific data.
|
||||
* This method is called using Reflection.
|
||||
*
|
||||
* @return The plugin specific data.
|
||||
*/
|
||||
public JsonObject getPluginData() {
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
data.addProperty("pluginName", PLUGINNAME); // Append the name of the plugin
|
||||
data.addProperty("pluginVersion", PLUGINVERSION); // Append the version of the plugin
|
||||
data.add("customCharts", new JsonArray());
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server specific data.
|
||||
*
|
||||
* @return The server specific data.
|
||||
*/
|
||||
private JsonObject getServerData() {
|
||||
// Minecraft specific data
|
||||
int playerAmount;
|
||||
try {
|
||||
// Around MC 1.8 the return type was changed to a collection from an array,
|
||||
// This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
||||
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
||||
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
|
||||
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||
} catch (Exception e) {
|
||||
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
|
||||
}
|
||||
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
|
||||
String bukkitVersion = Bukkit.getVersion();
|
||||
String bukkitName = Bukkit.getName();
|
||||
|
||||
// OS/Java specific data
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
String osName = System.getProperty("os.name");
|
||||
String osArch = System.getProperty("os.arch");
|
||||
String osVersion = System.getProperty("os.version");
|
||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
data.addProperty("serverUUID", serverUUID);
|
||||
|
||||
data.addProperty("playerAmount", playerAmount);
|
||||
data.addProperty("onlineMode", onlineMode);
|
||||
data.addProperty("bukkitVersion", bukkitVersion);
|
||||
data.addProperty("bukkitName", bukkitName);
|
||||
|
||||
data.addProperty("javaVersion", javaVersion);
|
||||
data.addProperty("osName", osName);
|
||||
data.addProperty("osArch", osArch);
|
||||
data.addProperty("osVersion", osVersion);
|
||||
data.addProperty("coreCount", coreCount);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the data and sends it afterwards.
|
||||
*/
|
||||
private void submitData() {
|
||||
final JsonObject data = getServerData();
|
||||
|
||||
JsonArray pluginData = new JsonArray();
|
||||
// Search for all other bStats Metrics classes to get their plugin data
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
|
||||
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
|
||||
try {
|
||||
Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider());
|
||||
if (plugin instanceof JsonObject) {
|
||||
pluginData.add((JsonObject) plugin);
|
||||
} else { // old bstats version compatibility
|
||||
try {
|
||||
Class<?> jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject");
|
||||
if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) {
|
||||
Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString");
|
||||
jsonStringGetter.setAccessible(true);
|
||||
String jsonString = (String) jsonStringGetter.invoke(plugin);
|
||||
JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject();
|
||||
pluginData.add(object);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
// minecraft version 1.14+
|
||||
if (logFailedRequests) {
|
||||
logger.log(Level.WARNING, "[NBTAPI][BSTATS] Encountered exception while posting request!", e);
|
||||
// Not using the plugins logger since the plugin isn't the plugin containing the NBT-Api most of the time
|
||||
//this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception ", e);
|
||||
}
|
||||
continue; // continue looping since we cannot do any other thing.
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
|
||||
data.add("plugins", pluginData);
|
||||
|
||||
// Create a new thread for the connection to the bStats server
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(plugin, data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logFailedRequests) {
|
||||
logger.log(Level.WARNING, "[NBTAPI][BSTATS] Could not submit plugin stats of " + plugin.getName(), e);
|
||||
// Not using the plugins logger since the plugin isn't the plugin containing the NBT-Api most of the time
|
||||
//plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data to the bStats server.
|
||||
*
|
||||
* @param plugin Any plugin. It's just used to get a logger instance.
|
||||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(Plugin plugin, JsonObject data) throws Exception {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("Data cannot be null!");
|
||||
}
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
throw new IllegalAccessException("This method must not be called from the main thread!");
|
||||
}
|
||||
if (logSentData) {
|
||||
System.out.println("[NBTAPI][BSTATS] Sending data to bStats: " + data.toString());
|
||||
// Not using the plugins logger since the plugin isn't the plugin containing the NBT-Api most of the time
|
||||
//plugin.getLogger().info("Sending data to bStats: " + data.toString());
|
||||
}
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
||||
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
|
||||
// Add headers
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
||||
|
||||
// Send data
|
||||
connection.setDoOutput(true);
|
||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
||||
outputStream.write(compressedData);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
bufferedReader.close();
|
||||
if (logResponseStatusText) {
|
||||
logger.info("[NBTAPI][BSTATS] Sent data to bStats and received response: " + builder.toString());
|
||||
// Not using the plugins logger since the plugin isn't the plugin containing the NBT-Api most of the time
|
||||
//plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given String.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped String.
|
||||
* @throws IOException If the compression failed.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException {
|
||||
if (str == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
||||
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||
gzip.close();
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
package de.tr7zw.changeme.nbtapi.utils;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.logger;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
* <p>
|
||||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*
|
||||
* This class is modified by tr7zw to work when the api is shaded into other peoples plugins.
|
||||
*/
|
||||
public class ApiMetricsLite {
|
||||
|
||||
private static final String PLUGINNAME = "ItemNBTAPI"; // DO NOT CHANGE THE NAME! else it won't link the data on bStats
|
||||
|
||||
// The version of this bStats class
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
|
||||
// The version of the NBT-Api bStats
|
||||
public static final int NBT_BSTATS_VERSION = 1;
|
||||
|
||||
// The url to which the data is sent
|
||||
private static final String URL = "https://bStats.org/submitData/bukkit";
|
||||
|
||||
// Is bStats enabled on this server?
|
||||
private boolean enabled;
|
||||
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests;
|
||||
|
||||
// Should the sent data be logged?
|
||||
private static boolean logSentData;
|
||||
|
||||
// Should the response text be logged?
|
||||
private static boolean logResponseStatusText;
|
||||
|
||||
// The uuid of the server
|
||||
private static String serverUUID;
|
||||
|
||||
// The plugin
|
||||
private Plugin plugin;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
*/
|
||||
public ApiMetricsLite() {
|
||||
|
||||
// The register method just uses any enabled plugin it can find to register. This *shouldn't* cause any problems, since the plugin isn't used any other way.
|
||||
// Register our service
|
||||
for(Plugin plug : Bukkit.getPluginManager().getPlugins()) {
|
||||
plugin = plug;
|
||||
if(plugin != null)
|
||||
break;
|
||||
}
|
||||
if(plugin == null) {
|
||||
return;// Didn't find any plugin that could work
|
||||
}
|
||||
|
||||
// Get the config file
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
|
||||
// Check if the config file exists
|
||||
if (!config.isSet("serverUuid")) {
|
||||
|
||||
// Add default values
|
||||
config.addDefault("enabled", true);
|
||||
// Every server gets it's unique random id.
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||
// Should failed request be logged?
|
||||
config.addDefault("logFailedRequests", false);
|
||||
// Should the sent data be logged?
|
||||
config.addDefault("logSentData", false);
|
||||
// Should the response text be logged?
|
||||
config.addDefault("logResponseStatusText", false);
|
||||
|
||||
// Inform the server owners about bStats
|
||||
config.options().header(
|
||||
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
|
||||
"To honor their work, you should not disable it.\n" +
|
||||
"This has nearly no effect on the server performance!\n" +
|
||||
"Check out https://bStats.org/ to learn more :)"
|
||||
).copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) { }
|
||||
}
|
||||
|
||||
// Load the data
|
||||
serverUUID = config.getString("serverUuid");
|
||||
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||
enabled = config.getBoolean("enabled", true);
|
||||
logSentData = config.getBoolean("logSentData", false);
|
||||
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
if (enabled) {
|
||||
boolean found = false;
|
||||
// Search for all other bStats Metrics classes to see if we are the first one
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("NBT_BSTATS_VERSION"); // Create only one instance of the nbt-api bstats.
|
||||
return;
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
found = true; // We aren't the first
|
||||
break;
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
boolean fFound = found;
|
||||
// Register our service
|
||||
if(Bukkit.isPrimaryThread()){
|
||||
Bukkit.getServicesManager().register(ApiMetricsLite.class, this, plugin, ServicePriority.Normal);
|
||||
if (!fFound) {
|
||||
logger.info("[NBTAPI] Using the plugin '" + plugin.getName() + "' to create a bStats instance!");
|
||||
// We are the first!
|
||||
startSubmitting();
|
||||
}
|
||||
}else{
|
||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||
Bukkit.getServicesManager().register(ApiMetricsLite.class, this, plugin, ServicePriority.Normal);
|
||||
if (!fFound) {
|
||||
logger.info("[NBTAPI] Using the plugin '" + plugin.getName() + "' to create a bStats instance!");
|
||||
// We are the first!
|
||||
startSubmitting();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if bStats is enabled.
|
||||
*
|
||||
* @return Whether bStats is enabled or not.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Scheduler which submits our data every 30 minutes.
|
||||
*/
|
||||
private void startSubmitting() {
|
||||
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
|
||||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!plugin.isEnabled()) { // Plugin was disabled
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
|
||||
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
|
||||
Bukkit.getScheduler().runTask(plugin, () -> submitData());
|
||||
}
|
||||
}, 1000l * 60l * 5l, 1000l * 60l * 30l);
|
||||
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
|
||||
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
||||
// WARNING: Just don't do it!
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the plugin specific data.
|
||||
* This method is called using Reflection.
|
||||
*
|
||||
* @return The plugin specific data.
|
||||
*/
|
||||
public JsonObject getPluginData() {
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
data.addProperty("pluginName", PLUGINNAME); // Append the name of the plugin
|
||||
data.addProperty("pluginVersion", MinecraftVersion.VERSION); // Append the version of the plugin
|
||||
data.add("customCharts", new JsonArray());
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server specific data.
|
||||
*
|
||||
* @return The server specific data.
|
||||
*/
|
||||
private JsonObject getServerData() {
|
||||
// Minecraft specific data
|
||||
int playerAmount;
|
||||
try {
|
||||
// Around MC 1.8 the return type was changed to a collection from an array,
|
||||
// This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
||||
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
||||
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
|
||||
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||
} catch (Exception e) {
|
||||
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
|
||||
}
|
||||
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
|
||||
String bukkitVersion = Bukkit.getVersion();
|
||||
String bukkitName = Bukkit.getName();
|
||||
|
||||
// OS/Java specific data
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
String osName = System.getProperty("os.name");
|
||||
String osArch = System.getProperty("os.arch");
|
||||
String osVersion = System.getProperty("os.version");
|
||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
data.addProperty("serverUUID", serverUUID);
|
||||
|
||||
data.addProperty("playerAmount", playerAmount);
|
||||
data.addProperty("onlineMode", onlineMode);
|
||||
data.addProperty("bukkitVersion", bukkitVersion);
|
||||
data.addProperty("bukkitName", bukkitName);
|
||||
|
||||
data.addProperty("javaVersion", javaVersion);
|
||||
data.addProperty("osName", osName);
|
||||
data.addProperty("osArch", osArch);
|
||||
data.addProperty("osVersion", osVersion);
|
||||
data.addProperty("coreCount", coreCount);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the data and sends it afterwards.
|
||||
*/
|
||||
private void submitData() {
|
||||
final JsonObject data = getServerData();
|
||||
|
||||
JsonArray pluginData = new JsonArray();
|
||||
// Search for all other bStats Metrics classes to get their plugin data
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
|
||||
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
|
||||
try {
|
||||
Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider());
|
||||
if (plugin instanceof JsonObject) {
|
||||
pluginData.add((JsonObject) plugin);
|
||||
} else { // old bstats version compatibility
|
||||
try {
|
||||
Class<?> jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject");
|
||||
if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) {
|
||||
Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString");
|
||||
jsonStringGetter.setAccessible(true);
|
||||
String jsonString = (String) jsonStringGetter.invoke(plugin);
|
||||
JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject();
|
||||
pluginData.add(object);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
// minecraft version 1.14+
|
||||
if (logFailedRequests) {
|
||||
logger.log(Level.WARNING, "[NBTAPI][BSTATS] Encountered exception while posting request!", e);
|
||||
// Not using the plugins logger since the plugin isn't the plugin containing the NBT-Api most of the time
|
||||
//this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception ", e);
|
||||
}
|
||||
continue; // continue looping since we cannot do any other thing.
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
|
||||
data.add("plugins", pluginData);
|
||||
|
||||
// Create a new thread for the connection to the bStats server
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(plugin, data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logFailedRequests) {
|
||||
logger.log(Level.WARNING, "[NBTAPI][BSTATS] Could not submit plugin stats of " + plugin.getName(), e);
|
||||
// Not using the plugins logger since the plugin isn't the plugin containing the NBT-Api most of the time
|
||||
//plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data to the bStats server.
|
||||
*
|
||||
* @param plugin Any plugin. It's just used to get a logger instance.
|
||||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(Plugin plugin, JsonObject data) throws Exception {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("Data cannot be null!");
|
||||
}
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
throw new IllegalAccessException("This method must not be called from the main thread!");
|
||||
}
|
||||
if (logSentData) {
|
||||
System.out.println("[NBTAPI][BSTATS] Sending data to bStats: " + data.toString());
|
||||
// Not using the plugins logger since the plugin isn't the plugin containing the NBT-Api most of the time
|
||||
//plugin.getLogger().info("Sending data to bStats: " + data.toString());
|
||||
}
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
||||
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
|
||||
// Add headers
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
||||
|
||||
// Send data
|
||||
connection.setDoOutput(true);
|
||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
||||
outputStream.write(compressedData);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
bufferedReader.close();
|
||||
if (logResponseStatusText) {
|
||||
logger.info("[NBTAPI][BSTATS] Sent data to bStats and received response: " + builder.toString());
|
||||
// Not using the plugins logger since the plugin isn't the plugin containing the NBT-Api most of the time
|
||||
//plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given String.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped String.
|
||||
* @throws IOException If the compression failed.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException {
|
||||
if (str == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
||||
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||
gzip.close();
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,16 +25,21 @@ public enum MinecraftVersion {
|
||||
MC1_12_R1(1121),
|
||||
MC1_13_R1(1131),
|
||||
MC1_13_R2(1132),
|
||||
MC1_14_R1(1141);
|
||||
MC1_14_R1(1141),
|
||||
MC1_15_R1(1151);
|
||||
|
||||
private static MinecraftVersion version;
|
||||
private static Boolean hasGsonSupport;
|
||||
private static boolean bStatsDisabled = false;
|
||||
private static boolean disablePackageWarning = false;
|
||||
private static boolean updateCheckDisabled = false;
|
||||
/**
|
||||
* Logger used by the api
|
||||
*/
|
||||
public static final Logger logger = Logger.getLogger("NBTAPI");
|
||||
|
||||
// NBT-API Version
|
||||
protected static final String VERSION = "2.3.0";
|
||||
|
||||
private final int versionId;
|
||||
|
||||
@@ -82,6 +87,12 @@ public enum MinecraftVersion {
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "[NBTAPI] Error enabeling Metrics!", ex);
|
||||
}
|
||||
try {
|
||||
if(!updateCheckDisabled)
|
||||
VersionChecker.checkForUpdates();
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "[NBTAPI] Error while checking for updates!", ex);
|
||||
}
|
||||
// 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',
|
||||
@@ -126,6 +137,14 @@ public enum MinecraftVersion {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forcefully disables the log message for plugins not shading the API to
|
||||
|
||||
@@ -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,106 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import 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";
|
||||
|
||||
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.logger.log(Level.WARNING,
|
||||
"[NBTAPI] The NBT-API at '" + NBTItem.class.getPackage() + "' seems to be outdated!");
|
||||
MinecraftVersion.logger.log(Level.WARNING, "[NBTAPI] Current Version: '" + MinecraftVersion.VERSION
|
||||
+ "' Newest Version: " + latest.get("name").getAsString() + "'");
|
||||
MinecraftVersion.logger.log(Level.WARNING,
|
||||
"[NBTAPI] Please update the nbt-api or the plugin that contains the api!");
|
||||
|
||||
} else if (versionDifference == 0) {
|
||||
MinecraftVersion.logger.log(Level.INFO, "[NBTAPI] The NBT-API seems to be up-to-date!");
|
||||
} else if (versionDifference == 1) {
|
||||
MinecraftVersion.logger.log(Level.WARNING, "[NBTAPI] The NBT-API at '" + NBTItem.class.getPackage()
|
||||
+ "' seems to be a future Version, not yet released on Spigot!");
|
||||
MinecraftVersion.logger.log(Level.WARNING, "[NBTAPI] Current Version: '" + MinecraftVersion.VERSION
|
||||
+ "' Newest Version: " + latest.get("name").getAsString() + "'");
|
||||
}
|
||||
} else {
|
||||
// wut?!
|
||||
MinecraftVersion.logger.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;
|
||||
}
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils.annotations;
|
||||
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
|
||||
@Retention(RUNTIME)
|
||||
@Target({ METHOD })
|
||||
public @interface AvaliableSince {
|
||||
|
||||
MinecraftVersion version();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils.annotations;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
|
||||
public class CheckUtil {
|
||||
|
||||
public static boolean isAvaliable(Method method) {
|
||||
if(MinecraftVersion.getVersion().getVersionId() < method.getAnnotation(AvaliableSince.class).version().getVersionId())
|
||||
throw new NbtApiException("The Method '" + method.getName() + "' is only avaliable for the Versions " + method.getAnnotation(AvaliableSince.class).version() + "+, but still got called!");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+4
-1
@@ -20,6 +20,9 @@ CRAFT_WORLD(PackageWrapper.CRAFTBUKKIT, "CraftWorld"),
|
||||
NMS_NBTBASE(PackageWrapper.NMS, "NBTBase"),
|
||||
NMS_NBTTAGSTRING(PackageWrapper.NMS, "NBTTagString"),
|
||||
NMS_NBTTAGINT(PackageWrapper.NMS, "NBTTagInt"),
|
||||
NMS_NBTTAGFLOAT(PackageWrapper.NMS, "NBTTagFloat"),
|
||||
NMS_NBTTAGDOUBLE(PackageWrapper.NMS, "NBTTagDouble"),
|
||||
NMS_NBTTAGLONG(PackageWrapper.NMS, "NBTTagLong"),
|
||||
NMS_ITEMSTACK(PackageWrapper.NMS, "ItemStack"),
|
||||
NMS_NBTTAGCOMPOUND(PackageWrapper.NMS, "NBTTagCompound"),
|
||||
NMS_NBTTAGLIST(PackageWrapper.NMS, "NBTTagList"),
|
||||
@@ -36,7 +39,7 @@ NMS_REGISTRYSIMPLE(PackageWrapper.NMS, "RegistrySimple", MinecraftVersion.MC1_11
|
||||
NMS_REGISTRYMATERIALS(PackageWrapper.NMS, "RegistryMaterials"),
|
||||
NMS_IREGISTRY(PackageWrapper.NMS, "IRegistry"),
|
||||
NMS_MINECRAFTKEY(PackageWrapper.NMS, "MinecraftKey"),
|
||||
|
||||
NMS_GAMEPROFILESERIALIZER(PackageWrapper.NMS, "GameProfileSerializer")
|
||||
;
|
||||
|
||||
private Class<?> clazz;
|
||||
|
||||
+11
-7
@@ -3,13 +3,13 @@ package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.logger;
|
||||
|
||||
/**
|
||||
* This class caches method reflections, keeps track of method name changes between versions and allows early checking for problems
|
||||
@@ -53,7 +53,7 @@ public enum ReflectionMethod {
|
||||
|
||||
COMPOUND_REMOVE_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "remove")),
|
||||
COMPOUND_HAS_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "hasKey")),
|
||||
COMPOUND_GET_TYPE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "b"), new Since(MinecraftVersion.MC1_9_R1, "d")), //FIXME: No Spigot mapping!
|
||||
COMPOUND_GET_TYPE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "b"), new Since(MinecraftVersion.MC1_9_R1, "d"), new Since(MinecraftVersion.MC1_15_R1, "e")), //FIXME: No Spigot mapping!
|
||||
COMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys")),
|
||||
|
||||
LISTCOMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys")),
|
||||
@@ -99,8 +99,10 @@ public enum ReflectionMethod {
|
||||
REGISTRY_GET_INVERSE (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{Object.class}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "b")), //FIXME: No Spigot mapping!
|
||||
REGISTRYMATERIALS_KEYSET (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{}, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_13_R1, "keySet")),
|
||||
REGISTRYMATERIALS_GET (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{ClassWrapper.NMS_MINECRAFTKEY.getClazz()}, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_13_R1, "get")),
|
||||
REGISTRYMATERIALS_GETKEY (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{Object.class}, MinecraftVersion.MC1_13_R2, new Since(MinecraftVersion.MC1_13_R2, "getKey")),
|
||||
|
||||
|
||||
GAMEPROFILE_DESERIALIZE (ClassWrapper.NMS_GAMEPROFILESERIALIZER.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "deserialize")),
|
||||
GAMEPROFILE_SERIALIZE (ClassWrapper.NMS_GAMEPROFILESERIALIZER.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), GameProfile.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "serialize")),
|
||||
;
|
||||
|
||||
private MinecraftVersion removedAfter;
|
||||
@@ -127,7 +129,7 @@ public enum ReflectionMethod {
|
||||
loaded = true;
|
||||
methodName = targetVersion.name;
|
||||
}catch(NullPointerException | NoSuchMethodException | SecurityException ex){
|
||||
System.out.println("[NBTAPI] Unable to find the method '" + targetVersion.name + "' in '" + targetClass.getSimpleName() + "'"); //NOSONAR This gets loaded before the logger is loaded
|
||||
System.out.println("[NBTAPI] Unable to find the method '" + targetVersion.name + "' in '" + targetClass.getSimpleName() + "' Enum: " + this); //NOSONAR This gets loaded before the logger is loaded
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,10 +145,12 @@ public enum ReflectionMethod {
|
||||
* @return Value returned by the method
|
||||
*/
|
||||
public Object run(Object target, Object... args){
|
||||
try{
|
||||
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 + ".", ex);
|
||||
throw new NbtApiException("Error while calling the method '" + methodName + "', loaded: " + loaded + ", Enum: " + this, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-7
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>2.3.0</version>
|
||||
</parent>
|
||||
<artifactId>item-nbt-api-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
@@ -12,13 +12,19 @@
|
||||
<dependency>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-api</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>2.3.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>nbt-injector</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>2.3.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>nbt-data-api</artifactId>
|
||||
<version>2.3.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -33,7 +39,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<version>3.2.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>shade</id>
|
||||
@@ -73,11 +79,11 @@
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<!-- 1.8.8-R0.1-SNAPSHOT-latest, 1.9.2-R0.1-SNAPSHOT-latest, 1.9.4-R0.1-SNAPSHOT-latest, 1.10.2-R0.1-SNAPSHOT-latest,1.11.2,1.12.2,1.13.2,1.14.1,1.14.2,1.14.3,1.14.4 -->
|
||||
<versions>1.8.8-R0.1-SNAPSHOT-latest, 1.9.2-R0.1-SNAPSHOT-latest, 1.9.4-R0.1-SNAPSHOT-latest, 1.10.2-R0.1-SNAPSHOT-latest,1.11.2,1.12.2,1.13.2,1.14.1,1.14.2,1.14.3,1.14.4</versions>
|
||||
<!-- 1.8.8-R0.1-SNAPSHOT-latest, 1.9.2-R0.1-SNAPSHOT-latest, 1.9.4-R0.1-SNAPSHOT-latest, 1.10.2-R0.1-SNAPSHOT-latest,1.11.2,1.12.2,1.13.2,1.14.4,1.15.1 -->
|
||||
<versions>1.8.8-R0.1-SNAPSHOT-latest, 1.9.2-R0.1-SNAPSHOT-latest, 1.9.4-R0.1-SNAPSHOT-latest, 1.10.2-R0.1-SNAPSHOT-latest,1.11.2,1.12.2,1.13.2,1.14.4,1.15.1,1.15.2</versions>
|
||||
<works>Success! This version of NBT-API</works>
|
||||
<error>WARNING! This version of NBT-API</error>
|
||||
<filename>item-nbt-api-plugin-2.1.0.jar</filename>
|
||||
<filename>item-nbt-api-plugin-${project.version}.jar</filename>
|
||||
<foldername>item-nbt-plugin</foldername>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@@ -12,18 +12,27 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
import de.tr7zw.nbtapi.plugin.tests.GameprofileTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.NBTFileTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.EqualsTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.ForEachTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.GetterSetterTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.ListTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.MergeTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.RemovingKeys;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.StreamTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.SubCompoundsTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.TypeTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.entities.EntityCustomNbtTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.data.WorldDataTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.entities.EntityCustomNbtPersistentTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.entities.EntityTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.injector.EntityCustomNbtInjectorTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.injector.MergeTileSubCompoundTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.injector.SpawnEntityCustomNbtInjectorTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.injector.TilesCustomNBTInjectorTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.items.EmptyItemTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.items.ItemConvertionTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.tiles.TilesCustomNBTTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.tiles.TilesCustomNBTPersistentTest;
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class NBTAPI extends JavaPlugin {
|
||||
@@ -57,6 +66,9 @@ public class NBTAPI extends JavaPlugin {
|
||||
apiTests.add(new ListTest());
|
||||
apiTests.add(new SubCompoundsTest());
|
||||
apiTests.add(new MergeTest());
|
||||
apiTests.add(new ForEachTest());
|
||||
apiTests.add(new StreamTest());
|
||||
apiTests.add(new EqualsTest());
|
||||
|
||||
// Items
|
||||
apiTests.add(new ItemConvertionTest());
|
||||
@@ -64,13 +76,24 @@ public class NBTAPI extends JavaPlugin {
|
||||
|
||||
// Entity
|
||||
apiTests.add(new EntityTest());
|
||||
apiTests.add(new EntityCustomNbtTest());
|
||||
apiTests.add(new EntityCustomNbtPersistentTest());
|
||||
|
||||
// Tiles
|
||||
apiTests.add(new TilesCustomNBTTest());
|
||||
apiTests.add(new TilesCustomNBTPersistentTest());
|
||||
|
||||
// Files
|
||||
apiTests.add(new NBTFileTest());
|
||||
|
||||
// Data
|
||||
apiTests.add(new WorldDataTest());
|
||||
|
||||
// Injector
|
||||
apiTests.add(new TilesCustomNBTInjectorTest());
|
||||
apiTests.add(new MergeTileSubCompoundTest());
|
||||
apiTests.add(new EntityCustomNbtInjectorTest());
|
||||
apiTests.add(new SpawnEntityCustomNbtInjectorTest());
|
||||
|
||||
apiTests.add(new GameprofileTest());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTGameProfile;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
|
||||
public class GameprofileTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
GameProfile profile = new GameProfile(uuid, "random");
|
||||
NBTCompound nbt = NBTGameProfile.toNBT(profile);
|
||||
profile = null;
|
||||
profile = NBTGameProfile.fromNBT(nbt);
|
||||
if (profile == null || !profile.getId().equals(uuid)) {
|
||||
throw new NbtApiException("Error when converting a GameProfile from/to NBT!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,9 @@ public class NBTFileTest implements Test {
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTAPI.getInstance().getDataFolder().mkdirs();
|
||||
NBTFile file = new NBTFile(new File(NBTAPI.getInstance().getDataFolder(), "test.nbt"));
|
||||
File testFile = new File(NBTAPI.getInstance().getDataFolder(), "test.nbt");
|
||||
Files.deleteIfExists(testFile.toPath());
|
||||
NBTFile file = new NBTFile(testFile);
|
||||
file.addCompound("testcomp").setString("test1", "ok");
|
||||
NBTCompound comp = file.getCompound("testcomp");
|
||||
comp.setString("test2", "ok");
|
||||
@@ -30,7 +32,7 @@ public class NBTFileTest implements Test {
|
||||
throw new NbtApiException("SubCompounds did not work!");
|
||||
}
|
||||
|
||||
NBTFile fileLoaded = new NBTFile(new File(NBTAPI.getInstance().getDataFolder(), "test.nbt"));
|
||||
NBTFile fileLoaded = new NBTFile(testFile);
|
||||
if (!fileLoaded.getString("test").equals("test")) {
|
||||
throw new NbtApiException("Wasn't able to load NBT File with the correct content!");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.compounds;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTContainer;
|
||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class EqualsTest implements Test{
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer cont = new NBTContainer();
|
||||
cont.setString("hello", "world");
|
||||
cont.setInteger("theAnswer", 42);
|
||||
cont.addCompound("sub").setString("me", "too");
|
||||
ItemStack item = new ItemStack(Material.STONE);
|
||||
NBTItem nbti = new NBTItem(item);
|
||||
NBTCompound customData = nbti.addCompound("customData");
|
||||
// reverse order
|
||||
customData.addCompound("sub").setString("me", "too");
|
||||
customData.setInteger("theAnswer", 42);
|
||||
customData.setString("hello", "world");
|
||||
if(!customData.equals(cont)) {
|
||||
throw new NbtApiException("Compounds did not match! " + customData + " " + cont);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.compounds;
|
||||
|
||||
import java.util.ListIterator;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompoundList;
|
||||
import de.tr7zw.changeme.nbtapi.NBTContainer;
|
||||
import de.tr7zw.changeme.nbtapi.NBTListCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
/**
|
||||
* Test requested by TAU on Discord
|
||||
*
|
||||
*/
|
||||
public class ForEachTest implements Test {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer comp = new NBTContainer();
|
||||
NBTCompoundList compList = comp.getCompoundList("testkey");
|
||||
if (compList != null) {
|
||||
compList.addCompound().setInteger("id", 1);
|
||||
compList.addCompound().setInteger("id", 2);
|
||||
compList.addCompound().setInteger("id", 3);
|
||||
int count = 0;
|
||||
for (NBTListCompound listComp : compList) {
|
||||
count++;
|
||||
}
|
||||
if(count != compList.size())
|
||||
throw new NbtApiException("For loop did not get all Entries!");
|
||||
count = 0;
|
||||
ListIterator<NBTListCompound> lit = compList.listIterator();
|
||||
while(lit.hasNext()){
|
||||
lit.next();
|
||||
count++;
|
||||
}
|
||||
if(count != compList.size())
|
||||
throw new NbtApiException("ListIterator did not get all Entries!");
|
||||
count = 0;
|
||||
while(lit.hasPrevious()){
|
||||
lit.previous();
|
||||
count++;
|
||||
}
|
||||
if(count != compList.size())
|
||||
throw new NbtApiException("ListIterator previous did not get all Entries!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,10 +2,12 @@ package de.tr7zw.nbtapi.plugin.tests.compounds;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompoundList;
|
||||
import de.tr7zw.changeme.nbtapi.NBTContainer;
|
||||
import de.tr7zw.changeme.nbtapi.NBTList;
|
||||
import de.tr7zw.changeme.nbtapi.NBTListCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTType;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
@@ -34,19 +36,33 @@ public class ListTest implements Test {
|
||||
lcomp.setInteger("int1", 42);
|
||||
lcomp.setString("test1", "test1");
|
||||
lcomp.setString("test2", "test2");
|
||||
lcomp.remove("test1");
|
||||
lcomp.removeKey("test1");
|
||||
NBTCompound subsubcomp = lcomp.addCompound("listsubkey");
|
||||
subsubcomp.setString("deep", "String");
|
||||
subsubcomp.getCompoundList("deeplist").addCompound().setString("test", "test");
|
||||
subsubcomp.getCompoundList("clonelist").addCompound(comp);
|
||||
|
||||
taglist = null;
|
||||
lcomp = null;
|
||||
subsubcomp = null;
|
||||
|
||||
taglist = comp.getCompoundList("complist");
|
||||
if (taglist.size() == 1) {
|
||||
lcomp = taglist.get(0);
|
||||
if (lcomp.getKeys().size() != 3) {
|
||||
if (lcomp.getKeys().size() != 4) {
|
||||
throw new NbtApiException("Wrong key amount in Taglist (" + lcomp.getKeys().size() + ")!");
|
||||
} else if (!(lcomp.getDouble("double1") == 0.3333 && lcomp.getInteger("int1") == 42
|
||||
&& lcomp.getString("test2").equals("test2") && !lcomp.hasKey("test1"))) {
|
||||
throw new NbtApiException("One key in the Taglist changed! The Item-NBT-API may not work!");
|
||||
} else if (lcomp.getCompound("listsubkey") == null
|
||||
|| !"String".equals(lcomp.getCompound("listsubkey").getString("deep"))) {
|
||||
throw new NbtApiException(
|
||||
"The Compound nested in the listcompound was not correct! The Item-NBT-API may not work!");
|
||||
} else if (lcomp.getCompound("listsubkey").getType("deep") != NBTType.NBTTagString) {
|
||||
throw new NbtApiException("The nested key's type wasn't correct! The Item-NBT-API may not work!");
|
||||
} else if (lcomp.getCompound("listsubkey").getType("deeplist") != NBTType.NBTTagList) {
|
||||
throw new NbtApiException("The nested list's type wasn't correct '"
|
||||
+ lcomp.getCompound("listsubkey").getType("deeplist") + "'! The Item-NBT-API may not work!");
|
||||
}
|
||||
} else {
|
||||
throw new NbtApiException("Taglist is empty! The Item-NBT-API may not work!");
|
||||
@@ -62,6 +78,36 @@ public class ListTest implements Test {
|
||||
throw new NbtApiException("IntList is not correct! " + Arrays.toString(intlist.toArray(new Integer[0])));
|
||||
}
|
||||
|
||||
// Double
|
||||
NBTList<Double> doublelist = comp.getDoubleList("doubletest");
|
||||
doublelist.add(42.23d);
|
||||
doublelist.add(69.69d);
|
||||
if (doublelist.size() == 2 && doublelist.get(0) == 42.23d && doublelist.get(1) == 69.69d) {
|
||||
// ok
|
||||
} else {
|
||||
throw new NbtApiException("DoubleList is not correct! " + Arrays.toString(doublelist.toArray(new Double[0])));
|
||||
}
|
||||
|
||||
// Float
|
||||
NBTList<Float> floatlist = comp.getFloatList("floattest");
|
||||
floatlist.add(42.23f);
|
||||
floatlist.add(69.69f);
|
||||
if (floatlist.size() == 2 && floatlist.get(0) == 42.23f && floatlist.get(1) == 69.69f) {
|
||||
// ok
|
||||
} else {
|
||||
throw new NbtApiException("FloatList is not correct! " + Arrays.toString(floatlist.toArray(new Float[0])));
|
||||
}
|
||||
|
||||
// Long
|
||||
NBTList<Long> longlist = comp.getLongList("longtest");
|
||||
longlist.add(1241234124124l);
|
||||
longlist.add(1231454321312l);
|
||||
if (longlist.size() == 2 && longlist.get(0) == 1241234124124l && longlist.get(1) == 1231454321312l) {
|
||||
// ok
|
||||
} else {
|
||||
throw new NbtApiException("LongList is not correct! " + Arrays.toString(longlist.toArray(new Long[0])));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.compounds;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTContainer;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class StreamTest implements Test{
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer base = new NBTContainer();
|
||||
base.addCompound("sub").setString("hello", "world");
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||
base.getCompound("sub").writeCompound(outStream);
|
||||
byte[] data = outStream.toByteArray();
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
|
||||
NBTContainer container = new NBTContainer(inputStream);
|
||||
if(!container.toString().equals(base.getCompound("sub").toString())) {
|
||||
throw new NbtApiException("Component content did not match! " + base.getCompound("sub") + " " + container);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.data;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.data.NBTData;
|
||||
import de.tr7zw.changeme.nbtapi.data.WorldData;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class WorldDataTest implements Test{
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
for(World world : Bukkit.getWorlds()){
|
||||
if(!new File(world.getWorldFolder(), "level.dat").exists())continue;
|
||||
WorldData data = NBTData.getWorldData(world);
|
||||
if(data.getWorldName() == null || data.getSpawnPosition() == null)throw new NbtApiException("Got Null");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.entities;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Monster;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTEntity;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class EntityCustomNbtPersistentTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if(MinecraftVersion.getVersion().getVersionId() < MinecraftVersion.MC1_14_R1.getVersionId())return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) {
|
||||
Entity ent = world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next();
|
||||
NBTEntity nbtEnt = new NBTEntity(ent);
|
||||
NBTCompound comp = nbtEnt.getPersistentDataContainer();
|
||||
comp.setString("Hello", "World");
|
||||
NBTEntity nbtent = new NBTEntity(ent);
|
||||
if (!nbtent.toString().contains("Hello:\"World\"")) {
|
||||
throw new NbtApiException("Custom Data did not save to the Entity!");
|
||||
}
|
||||
comp.removeKey("Hello");
|
||||
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+41
-41
@@ -1,41 +1,41 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.entities;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Monster;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTEntity;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class EntityCustomNbtTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if(!NBTInjector.isInjected())return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) {
|
||||
Entity ent = world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next();
|
||||
ent = NBTInjector.patchEntity(ent);
|
||||
NBTCompound comp = NBTInjector.getNbtData(ent);
|
||||
comp.setString("Hello", "World");
|
||||
NBTEntity nbtent = new NBTEntity(ent);
|
||||
if (!nbtent.asNBTString().contains("__extraData:{Hello:\"World\"}")) {
|
||||
throw new NbtApiException("Custom Data did not save to the Entity!");
|
||||
}
|
||||
comp.removeKey("Hello");
|
||||
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package de.tr7zw.nbtapi.plugin.tests.injector;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Monster;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTEntity;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class EntityCustomNbtInjectorTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if(!NBTInjector.isInjected())return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) {
|
||||
Entity ent = world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next();
|
||||
ent = NBTInjector.patchEntity(ent);
|
||||
NBTCompound comp = NBTInjector.getNbtData(ent);
|
||||
comp.setString("Hello", "World");
|
||||
NBTEntity nbtent = new NBTEntity(ent);
|
||||
if (!nbtent.toString().contains("__extraData:{Hello:\"World\"}")) {
|
||||
throw new NbtApiException("Custom Data did not save to the Entity!");
|
||||
}
|
||||
comp.removeKey("Hello");
|
||||
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.injector;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTContainer;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class MergeTileSubCompoundTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (!NBTInjector.isInjected())
|
||||
return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
boolean failed = false;
|
||||
Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 255,
|
||||
world.getSpawnLocation().getBlockZ());
|
||||
if (block.getType() == Material.AIR) {
|
||||
block.setType(Material.CHEST);
|
||||
NBTCompound comp = NBTInjector.getNbtData(block.getState());
|
||||
comp.addCompound("subcomp").setString("hello", "world");
|
||||
NBTContainer cont = new NBTContainer();
|
||||
cont.mergeCompound(comp.getCompound("subcomp"));
|
||||
if (!(cont.hasKey("hello") && "world".equals(cont.getString("hello")))) {
|
||||
failed = true;
|
||||
}
|
||||
block.setType(Material.AIR);
|
||||
if(failed) {
|
||||
throw new NbtApiException("Data was not correct! " + cont);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTTiles!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.injector;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTEntity;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class SpawnEntityCustomNbtInjectorTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (!NBTInjector.isInjected())
|
||||
return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
Entity entity = world.spawnEntity(new Location(world, 0, 0, 0), EntityType.ARMOR_STAND);
|
||||
entity = NBTInjector.patchEntity(entity);
|
||||
NBTCompound comp = NBTInjector.getNbtData(entity);
|
||||
comp.setString("Hello", "World");
|
||||
NBTEntity nbtent = new NBTEntity(entity);
|
||||
if (!nbtent.toString().contains("__extraData:{Hello:\"World\"}")) {
|
||||
throw new NbtApiException("Custom Data did not save to the Entity!");
|
||||
}
|
||||
comp.removeKey("Hello");
|
||||
entity.remove();
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+40
-40
@@ -1,40 +1,40 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.tiles;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTTileEntity;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class TilesCustomNBTTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if(!NBTInjector.isInjected())return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 255,
|
||||
world.getSpawnLocation().getBlockZ());
|
||||
if (block.getType() == Material.AIR) {
|
||||
block.setType(Material.CHEST);
|
||||
NBTCompound comp = NBTInjector.getNbtData(block.getState());
|
||||
comp.setString("Foo", "Bar");
|
||||
if (!new NBTTileEntity(block.getState()).asNBTString().contains("__extraData:{Foo:\"Bar\"}")) {
|
||||
block.setType(Material.AIR);
|
||||
throw new NbtApiException("Custom Data did not save to the Tile!");
|
||||
}
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTTiles!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package de.tr7zw.nbtapi.plugin.tests.injector;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTTileEntity;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class TilesCustomNBTInjectorTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if(!NBTInjector.isInjected())return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 255,
|
||||
world.getSpawnLocation().getBlockZ());
|
||||
if (block.getType() == Material.AIR) {
|
||||
block.setType(Material.CHEST);
|
||||
NBTCompound comp = NBTInjector.getNbtData(block.getState());
|
||||
comp.setString("Foo", "Bar");
|
||||
if (!new NBTTileEntity(block.getState()).toString().contains("__extraData:{Foo:\"Bar\"}")) {
|
||||
block.setType(Material.AIR);
|
||||
throw new NbtApiException("Custom Data did not save to the Tile!");
|
||||
}
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTTiles!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+6
-1
@@ -19,12 +19,17 @@ public class ItemConvertionTest implements Test {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
meta.setLore(Lists.newArrayList("Firest Line", "Second Line"));
|
||||
item.setItemMeta(meta);
|
||||
String nbt = NBTItem.convertItemtoNBT(item).asNBTString();
|
||||
String nbt = NBTItem.convertItemtoNBT(item).toString();
|
||||
if (!nbt.contains("Firest Line") || !nbt.contains("Second Line"))
|
||||
throw new NbtApiException("The Item nbt '" + nbt + "' didn't contain the lore");
|
||||
ItemStack rebuild = NBTItem.convertNBTtoItem(new NBTContainer(nbt));
|
||||
if (!item.isSimilar(rebuild))
|
||||
throw new NbtApiException("Rebuilt item did not match the original!");
|
||||
|
||||
NBTContainer cont = new NBTContainer();
|
||||
cont.setItemStack("testItem", item);
|
||||
if(!cont.getItemStack("testItem").isSimilar(item))
|
||||
throw new NbtApiException("Rebuilt item did not match the original!");
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.tiles;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTTileEntity;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class TilesCustomNBTPersistentTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if(MinecraftVersion.getVersion().getVersionId() < MinecraftVersion.MC1_14_R1.getVersionId())return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 255,
|
||||
world.getSpawnLocation().getBlockZ());
|
||||
if (block.getType() == Material.AIR) {
|
||||
block.setType(Material.CHEST);
|
||||
NBTTileEntity comp = new NBTTileEntity(block.getState());
|
||||
NBTCompound persistentData = comp.getPersistentDataContainer();
|
||||
persistentData.setString("Foo", "Bar");
|
||||
if (!new NBTTileEntity(block.getState()).getPersistentDataContainer().toString().contains("Foo:\"Bar\"")) {
|
||||
block.setType(Material.AIR);
|
||||
throw new NbtApiException("Custom Data did not save to the Tile!");
|
||||
}
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTTiles!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 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.
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>nbt-data-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-api</artifactId>
|
||||
<version>2.3.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean install javadoc:javadoc</defaultGoal>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,66 @@
|
||||
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 de.tr7zw.changeme.nbtapi.NBTFile;
|
||||
import de.tr7zw.changeme.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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package de.tr7zw.changeme.nbtapi.data;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTFile;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
|
||||
public class PlayerData {
|
||||
|
||||
private final NBTFile file;
|
||||
|
||||
protected PlayerData(File playerFile) throws IOException {
|
||||
file = new NBTFile(playerFile);
|
||||
}
|
||||
|
||||
public NBTFile getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public NBTCompound 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package de.tr7zw.changeme.nbtapi.data;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTFile;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
|
||||
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 NBTCompound 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(){
|
||||
NBTCompound data = file.getCompound("Data");
|
||||
return new Vector(data.getInteger("SpawnX"), data.getInteger("SpawnY"), data.getInteger("SpawnZ"));
|
||||
}
|
||||
|
||||
public void setSpawnPosition(Vector vec){
|
||||
NBTCompound data = file.getCompound("Data");
|
||||
data.setInteger("SpawnX", vec.getBlockX());
|
||||
data.setInteger("SpawnY", vec.getBlockY());
|
||||
data.setInteger("SpawnZ", vec.getBlockZ());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>2.3.0</version>
|
||||
</parent>
|
||||
<artifactId>nbt-injector</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
@@ -12,13 +12,13 @@
|
||||
<dependency>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-api</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>2.3.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.25.0-GA</version>
|
||||
<version>3.27.0-GA</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.bukkit.Bukkit;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.ReflectionUtil;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
import de.tr7zw.nbtinjector.NBTInjector.Entity;
|
||||
@@ -36,6 +37,7 @@ public class InternalInjectors {
|
||||
private static final List<String> skippingEntities = Arrays.asList("minecraft:player", "minecraft:fishing_bobber",
|
||||
"minecraft:lightning_bolt"); // These are broken/won't work, used by 1.14+
|
||||
private static final Map<String, String> classMappings = new HashMap<>();
|
||||
protected static final Map<Class<?>, Object> classToMCKey = new HashMap<Class<?>, Object>();
|
||||
|
||||
static {
|
||||
classMappings.put("minecraft:wandering_trader", "VillagerTrader");
|
||||
@@ -64,6 +66,8 @@ public class InternalInjectors {
|
||||
classMappings.put("minecraft:illusioner", "IllagerIllusioner");
|
||||
classMappings.put("minecraft:pufferfish", "PufferFish");
|
||||
classMappings.put("minecraft:cave_spider", "CaveSpider");
|
||||
classMappings.put("minecraft:item_frame", "ItemFrame");
|
||||
classMappings.put("minecraft:leash_knot", "Leash");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,12 +114,13 @@ public class InternalInjectors {
|
||||
inverse.put(wrapped, mckey);
|
||||
int id = (int) registryId.getClass().getMethod("getId", new Class[] {Object.class}).invoke(registryId, entclass);
|
||||
registryId.getClass().getMethod("a", new Class[] {Object.class, int.class}).invoke(registryId, wrapped, id);
|
||||
classToMCKey.put(entclass, mckey);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + mckey, e);
|
||||
}
|
||||
}
|
||||
Field inverseField = registry.getClass().getDeclaredField("b");
|
||||
NBTInjector.setFinal(registry, inverseField, inverse);
|
||||
ReflectionUtil.setFinal(registry, inverseField, inverse);
|
||||
}
|
||||
|
||||
protected static void entity1v13Below(ClassPool classPool) throws ReflectiveOperationException {
|
||||
@@ -134,8 +139,8 @@ public class InternalInjectors {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapEntity(classPool, nmsclass, "__extraData");
|
||||
NBTInjector.setFinal(entityTypesObj, classField, wrapped);
|
||||
NBTInjector.setFinal(entityTypesObj, supplierField, new Function<Object, Object>() {
|
||||
ReflectionUtil.setFinal(entityTypesObj, classField, wrapped);
|
||||
ReflectionUtil.setFinal(entityTypesObj, supplierField, new Function<Object, Object>() {
|
||||
|
||||
@Override
|
||||
public Object apply(Object t) {
|
||||
@@ -147,6 +152,7 @@ public class InternalInjectors {
|
||||
}
|
||||
}
|
||||
});
|
||||
classToMCKey.put(nmsclass, mckey);
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + mckey, e);
|
||||
}
|
||||
@@ -162,7 +168,10 @@ public class InternalInjectors {
|
||||
continue;
|
||||
}
|
||||
Object entityTypesObj = ReflectionMethod.REGISTRYMATERIALS_GET.run(entityRegistry, mckey);
|
||||
Field creatorField = entityTypesObj.getClass().getDeclaredField("aZ");
|
||||
String creatorFieldName = "aZ";
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_15_R1.getVersionId())
|
||||
creatorFieldName = "ba";
|
||||
Field creatorField = entityTypesObj.getClass().getDeclaredField(creatorFieldName);
|
||||
creatorField.setAccessible(true);
|
||||
Object creator = creatorField.get(entityTypesObj);
|
||||
Method createEntityMethod = creator.getClass().getMethod("create", ClassWrapper.NMS_ENTITYTYPES.getClazz(),
|
||||
@@ -193,12 +202,13 @@ public class InternalInjectors {
|
||||
"Wasn't able to create an Entity instace, won't be able add NBT to '" + mckey + "' entities!");
|
||||
continue;
|
||||
}
|
||||
classToMCKey.put(nmsclass, mckey);
|
||||
try {
|
||||
if (INBTWrapper.class.isAssignableFrom(nmsclass)) {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapEntity(classPool, nmsclass, "__extraData");
|
||||
NBTInjector.setFinal(entityTypesObj, creatorField,
|
||||
ReflectionUtil.setFinal(entityTypesObj, creatorField,
|
||||
ClassGenerator.createEntityTypeWrapper(classPool, wrapped).newInstance());
|
||||
} catch (Exception e) {
|
||||
throw new NbtApiException("Exception while injecting " + mckey, e);
|
||||
@@ -240,7 +250,7 @@ public class InternalInjectors {
|
||||
}
|
||||
}
|
||||
Field inverseField = registry.getClass().getDeclaredField("b");
|
||||
NBTInjector.setFinal(registry, inverseField, inverse);
|
||||
ReflectionUtil.setFinal(registry, inverseField, inverse);
|
||||
}
|
||||
|
||||
protected static void tile1v13(ClassPool classPool) throws ReflectiveOperationException {
|
||||
@@ -249,8 +259,10 @@ public class InternalInjectors {
|
||||
for (Object mckey : registryentries) {
|
||||
Object tileEntityTypesObj = ReflectionMethod.REGISTRYMATERIALS_GET.run(tileRegistry, mckey);
|
||||
String supplierFieldName = "A";
|
||||
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId())
|
||||
if (MinecraftVersion.getVersion().getVersionId() == MinecraftVersion.MC1_14_R1.getVersionId())
|
||||
supplierFieldName = "H";
|
||||
else if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_15_R1.getVersionId())
|
||||
supplierFieldName = "I";
|
||||
Field supplierField = tileEntityTypesObj.getClass().getDeclaredField(supplierFieldName);
|
||||
supplierField.setAccessible(true);
|
||||
Supplier<Object> supplier = (Supplier<Object>) supplierField.get(tileEntityTypesObj);
|
||||
@@ -260,7 +272,7 @@ public class InternalInjectors {
|
||||
continue;
|
||||
} // Already injected
|
||||
Class<?> wrapped = ClassGenerator.wrapTileEntity(classPool, nmsclass, "__extraData");
|
||||
NBTInjector.setFinal(tileEntityTypesObj, supplierField, new Supplier<Object>() {
|
||||
ReflectionUtil.setFinal(tileEntityTypesObj, supplierField, new Supplier<Object>() {
|
||||
@Override
|
||||
public Object get() {
|
||||
try {
|
||||
|
||||
@@ -2,7 +2,6 @@ package de.tr7zw.nbtinjector;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -37,6 +36,9 @@ public class NBTInjector {
|
||||
|
||||
static Logger logger = Logger.getLogger("NBTInjector");
|
||||
private static boolean isInjected = false;
|
||||
private static final String NOT_INJECTED_MESSAGE = "The NBTInjector has not been enabled!\n"
|
||||
+ "You need to call 'NBTInjector.inject()' during the Method 'onLoad' of your Plugin!"
|
||||
+ " Check the Wiki/Pluginpage for more information!";
|
||||
|
||||
/**
|
||||
* Replaces the vanilla classes with Wrapped classes that support custom NBT.
|
||||
@@ -105,6 +107,7 @@ public class NBTInjector {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
if(!isInjected)throw new NbtApiException(NOT_INJECTED_MESSAGE);
|
||||
try {
|
||||
Object ent = NBTReflectionUtil.getNMSEntity(entity);
|
||||
if (!(ent instanceof INBTWrapper)) {// Replace Entity with custom one
|
||||
@@ -116,8 +119,10 @@ public class NBTInjector {
|
||||
String id = "";
|
||||
if (MinecraftVersion.getVersion().getVersionId() <= MinecraftVersion.MC1_10_R1.getVersionId()) {
|
||||
id = Entity.getBackupMap().get(ent.getClass());
|
||||
} else if (MinecraftVersion.getVersion().getVersionId() <= MinecraftVersion.MC1_13_R2.getVersionId()) {
|
||||
} else if (MinecraftVersion.getVersion().getVersionId() <= MinecraftVersion.MC1_12_R1.getVersionId()) {
|
||||
id = ReflectionMethod.REGISTRY_GET_INVERSE.run(Entity.getRegistry(), ent.getClass()).toString();
|
||||
} else if (MinecraftVersion.getVersion().getVersionId() <= MinecraftVersion.MC1_13_R2.getVersionId()) {
|
||||
id = InternalInjectors.classToMCKey.get(ent.getClass()).toString();
|
||||
} else {
|
||||
id = (String) ReflectionMethod.NMS_ENTITY_GETSAVEID.run(ent);
|
||||
}
|
||||
@@ -152,6 +157,7 @@ public class NBTInjector {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
if(!isInjected)throw new NbtApiException(NOT_INJECTED_MESSAGE);
|
||||
try {
|
||||
Object ent = NBTReflectionUtil.getNMSEntity(entity);
|
||||
if (!(ent instanceof INBTWrapper)) {
|
||||
@@ -176,6 +182,7 @@ public class NBTInjector {
|
||||
if (tile == null) {
|
||||
return null;
|
||||
}
|
||||
if(!isInjected)throw new NbtApiException(NOT_INJECTED_MESSAGE);
|
||||
try {
|
||||
Object pos = ObjectCreator.NMS_BLOCKPOSITION.getInstance(tile.getX(), tile.getY(), tile.getZ());
|
||||
Object cworld = ClassWrapper.CRAFT_WORLD.getClazz().cast(tile.getWorld());
|
||||
@@ -212,17 +219,6 @@ public class NBTInjector {
|
||||
}
|
||||
}
|
||||
|
||||
protected static void setFinal(Object obj, Field field, Object newValue)
|
||||
throws NoSuchFieldException, IllegalAccessException {
|
||||
field.setAccessible(true);
|
||||
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
||||
|
||||
field.set(obj, newValue);
|
||||
}
|
||||
|
||||
private static Field getAccessable(Field field) {
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
@@ -248,11 +244,11 @@ public class NBTInjector {
|
||||
throw new NbtApiException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Object getRegistry() throws ReflectiveOperationException {
|
||||
return getAccessable(ClassWrapper.NMS_ENTITYTYPES.getClazz().getDeclaredField("b")).get(null);
|
||||
}
|
||||
|
||||
|
||||
static Object getRegistryId(Object reg) throws ReflectiveOperationException {
|
||||
return getAccessable(reg.getClass().getDeclaredField("a")).get(reg);
|
||||
}
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>2.3.0</version>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>item-nbt-api</module>
|
||||
<module>nbt-injector</module>
|
||||
<module>nbt-data-api</module>
|
||||
<module>item-nbt-plugin</module>
|
||||
</modules>
|
||||
<properties>
|
||||
@@ -26,6 +27,12 @@
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mojang</groupId>
|
||||
<artifactId>authlib</artifactId>
|
||||
<version>1.5.25</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<!-- CodeMC -->
|
||||
@@ -34,13 +41,27 @@
|
||||
<url>https://repo.codemc.org/repository/maven-public/</url>
|
||||
<layout>default</layout>
|
||||
</repository>
|
||||
<!-- CodeMC NMS -->
|
||||
<!-- CodeMC NMS -->
|
||||
<repository>
|
||||
<id>codemc-nms-repo</id>
|
||||
<url>https://repo.codemc.org/repository/nms/</url>
|
||||
<layout>default</layout>
|
||||
</repository>
|
||||
<!-- Mojang -->
|
||||
<repository>
|
||||
<id>mojang-libraries</id>
|
||||
<url>https://libraries.minecraft.net/</url>
|
||||
<layout>default</layout>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<!-- CodeMC -->
|
||||
<pluginRepository>
|
||||
<id>codemc-repo</id>
|
||||
<url>https://repo.codemc.org/repository/maven-public/</url>
|
||||
<layout>default</layout>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
<build>
|
||||
<defaultGoal>clean install</defaultGoal>
|
||||
<resources>
|
||||
@@ -65,7 +86,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
@@ -78,7 +99,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<version>3.2.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
@@ -87,11 +108,14 @@
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.github.ekryd.sortpom</groupId>
|
||||
<artifactId>sortpom-maven-plugin</artifactId>
|
||||
<version>2.10.0</version>
|
||||
<version>2.11.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sortpom</id>
|
||||
@@ -101,6 +125,19 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>allcontributors</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>update-contributors</id>
|
||||
<goals>
|
||||
<goal>update</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
Reference in new issue
Block a user