Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bugs, now works with Vanilla servers #36

Open
wants to merge 51 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
5ea8b92
fix bug, now works with Vanilla servers
artfable Oct 5, 2019
a742008
fix testcase
artfable Oct 5, 2019
4252314
MSON deserializer prototype
Querz Mar 5, 2019
24ebe04
mson / nbt serialization / deserialization with working but incomplet…
Querz Mar 15, 2019
80cc260
ignore patch files
Querz Apr 24, 2020
7123cb2
the big refactoring: better package names / fix mca biome functions /…
Querz Apr 24, 2020
f7996c0
rename mson to snbt / fix tag unit tests
Querz Apr 24, 2020
f8e6b9b
unit tests
Querz Apr 24, 2020
44457a5
more unit tests for snbt parser and writer
Querz Apr 25, 2020
82190ca
update version, util classes and readme
Querz Apr 25, 2020
6a27b44
reintroduce fixes from 4.1 / fix wrong increase of block states array…
Querz Apr 27, 2020
9db0d64
update version to 5.1
Querz Apr 27, 2020
09ff422
fix biome index calculation
Querz Apr 27, 2020
539748e
update version to 5.2
Querz Apr 27, 2020
eaa1714
fix some old bugs
Querz Apr 29, 2020
4b6301d
add information how to integrate NBT using gradle or maven
Querz Apr 29, 2020
38173f6
make newMCAFile public / check if palette is null
Querz May 4, 2020
ad2205e
Update build.gradle
Querz May 9, 2020
d0ae207
sync flush for GZIPOutputStream
Querz May 25, 2020
f77e287
update version to 5.4
Querz May 25, 2020
f693559
Fixed Heightmap tag typo and added maven plugin
prydin May 28, 2020
173115e
Performance improvements
prydin Jun 2, 2020
6653bd3
Added support for partial chunk/region load
prydin Jun 2, 2020
7e1be3e
Use ALL_DATA instead of -1
prydin Jun 2, 2020
aa2561b
Fixed logical operation bugs. Added tests. Added check for partial ch…
prydin Jun 6, 2020
96c78c5
remove intellij module file
Querz Jun 8, 2020
6b8e7fa
update gradle-wrapper.jar to actual 6.5
Querz Jun 8, 2020
1517877
ignore .iml files
Querz Jun 8, 2020
5fd7dcd
formatting and cleanup
Querz Jun 8, 2020
62de632
update version to 5.5
Querz Jun 17, 2020
8cdd197
add support for little endian input and output
Querz Jul 15, 2020
d65f60d
add load flag to only load raw data and skip loading specifics
Querz Aug 7, 2020
da55957
incorrectly set list type of empty list when casting / fix unit tests
Querz Sep 2, 2020
cc9202c
remove commented out code
Querz Sep 2, 2020
35adf83
update version to 6.0
Querz Jan 11, 2021
172f259
add lenient mode for snbt parser
Querz Feb 17, 2021
a78b794
make SNBTParser public, remove static methods and add methods to get …
Querz Feb 17, 2021
edb0403
add helper method to get abstract number tag from compound tag
Querz Feb 26, 2021
de94fa5
setting a chunks data version should update the sections data version…
Querz Apr 6, 2021
d93ec55
new BlockStates array length is not calculated correctly for DataVers…
Querz Apr 6, 2021
b5973eb
update version to 6.1
Querz Apr 6, 2021
6d0980f
fix version for maven snippet
Querz Apr 7, 2021
10f85c2
Add initial capacity to List and Compound tags
urielsalis Apr 9, 2021
67c0f39
Clone with correct size to avoid resizing
urielsalis Apr 16, 2021
36329fe
Clone with correct size to avoid resizing
urielsalis Apr 16, 2021
e679810
Update src/main/java/net/querz/nbt/tag/CompoundTag.java
urielsalis Apr 19, 2021
53d2bff
Add put if not null to CompoundTag
urielsalis Apr 9, 2021
e7f260d
make MCAFile, Chunk and Section iterable
Querz Apr 7, 2021
e08a0eb
add block states null check before attempting to cleanup palette
Querz Apr 12, 2021
930e04e
use implementation instead of compile for gradle dependency
Querz Jul 20, 2021
19ca4eb
attempt to make compatible with 1.19
artfable Jun 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,13 @@ local.properties
# IDEA folder
.idea/

# .iml files
*.iml

# ignore javadoc for now
doc/

# ignore out
out/

# ignore patches
*.patch
*.patch
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2016 Querz
Copyright (c) 2016 - 2020 Querz

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
73 changes: 42 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NBT
[![Build Status](https://travis-ci.org/Querz/NBT.svg?branch=master)](https://travis-ci.org/Querz/NBT) [![Coverage Status](https://img.shields.io/coveralls/github/Querz/NBT/master.svg)](https://coveralls.io/github/Querz/NBT?branch=master) [![Release](https://jitpack.io/v/Querz/NBT.svg)](https://jitpack.io/#Querz/NBT)
#### A java implementation of the [NBT protocol](http://minecraft.gamepedia.com/NBT_format), including a way to implement custom tags.
#### A java implementation of the [NBT protocol](http://minecraft.gamepedia.com/NBT_format) for Minecraft Java Edition.
---
### Specification
According to the [specification](https://minecraft.gamepedia.com/NBT_format), there are currently 13 different types of tags:
Expand All @@ -25,6 +25,41 @@ According to the [specification](https://minecraft.gamepedia.com/NBT_format), th

* The maximum depth of the NBT structure is 512. If the depth exceeds this restriction during serialization, deserialization or String conversion, a `MaxDepthReachedException` is thrown. This usually happens when a circular reference exists in the NBT structure. The NBT specification does not allow circular references, as there is no tag to represent this.

### Add the library as a dependency using Gradle:
Add Jitpack to your `repositories`:
```
repositories {
...
maven { url 'https://jitpack.io/' }
}
```
And then add it as a dependency as usual:
```
dependencies {
...
implementation 'com.github.Querz:NBT:6.1'
}
```

### Add the library as a dependency using Maven:
Add Jitpack:
```
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
```
Dependency:
```
<dependency>
<groupId>com.github.Querz</groupId>
<artifactId>NBT</artifactId>
<version>6.1</version>
</dependency>
```

---
### Example usage:
The following code snippet shows how to create a `CompoundTag`:
Expand Down Expand Up @@ -56,33 +91,31 @@ Some methods do not provide a parameter to specify the maximum depth, but instea
### Utility
There are several utility methods to make your life easier if you use this library.
#### NBTUtil
`NBTUtil.writeTag()` lets you write a Tag into a gzip compressed or uncompressed file in one line (not counting exception handling). Files are gzip compressed by default.
`NBTUtil.write()` lets you write a Tag into a gzip compressed or uncompressed file in one line (not counting exception handling). Files are gzip compressed by default.

Example usage:
```java
NBTUtil.writeTag(tag, "filename.dat");
NBTUtil.write(namedTag, "filename.dat");
```
`NBTUtil.readTag()` reads any file containing NBT data. No worry about compression, it will automatically uncompress gzip compressed files.
`NBTUtil.read()` reads any file containing NBT data. No worry about compression, it will automatically uncompress gzip compressed files.

Example usage:
```java
Tag<?> tag = NBTUtil.readTag("filename.dat");
NamedTag namedTag = NBTUtil.read("filename.dat");
```
#### Playing Minecraft?
Each tag can be converted into a JSON-like NBT String used in Minecraft commands.
Each tag can be converted into an NBT String (SNBT) used in Minecraft commands.

Example usage:
```java
CompoundTag c = new CompoundTag();
c.putByte("blah", (byte) 5);
c.putString("foo", "bär");
System.out.println(c.toTagString()); // {blah:5b,foo:"bär"}

ListTag<StringTag> s = new ListTag<>(StringTag.class);
s.addString("test");
s.add(new StringTag("text"));
c.add("list", s);
System.out.println(c.toTagString()); // {blah:5b,foo:"bär",list:[test,text]}
System.out.println(SNBTUtil.toSNBT(c)); // {blah:5b,foo:"bär",list:[test,text]}

```
There is also a tool to read, change and write MCA files.
Expand Down Expand Up @@ -117,25 +150,3 @@ mcaFile.cleanupPalettesAndBlockStates();
chunk.cleanupPalettesAndBlockStates();
section.cleanupPaletteAndBlockStates();
```

---
### Custom tags
Interested in more advanced features, and the default NBT protocol just isn't enough? Simply create your own tags!
There are 4 example classes in `net.querz.nbt.custom` that show how to implement custom tags:

| Class | ID | Description |
| ------------- | :-: | ----------- |
| [ObjectTag](src/main/java/net/querz/nbt/custom/ObjectTag.java) | 90 | A wrapper tag that serializes and deserializes any object using the default java serialization. |
| [ShortArrayTag](src/main/java/net/querz/nbt/custom/ShortArrayTag.java) | 100 | In addition to the already existing `ByteArrayTag`, `IntArrayTag` and `LongArrayTag`. |
| [CharTag](src/main/java/net/querz/nbt/custom/CharTag.java) | 110 | `Character` (char) tag. |
| [StructTag](src/main/java/net/querz/nbt/custom/StructTag.java) | 120 | Similar to the `ListTag`, but with the ability to store multiple types. |

To be able to use a custom tag with deserialization, a `Supplier` and the custom tag class must be registered at runtime alongside its id with `TagFactory.registerCustomTag()`. The `Supplier` can be anything that returns a new instance of this custom tag. Here is an example using the custom tags no-args constructor:
```java
TagFactory.registerCustomTag(90, ObjectTag::new, ObjectTag.class);
```

#### Nesting
As mentioned before, serialization and deserialization methods are provided with a parameter indicating the maximum processing depth of the structure. This is not guaranteed when using custom tags, it is the responsibility of the creator of that custom tag to call `Tag#decrementMaxDepth(int)` to correctly update the nesting depth.

It is also highly encouraged to document the custom tag behaviour when it does so to make users aware of the possible exceptions thrown by `Tag#decrementMaxDepth(int)`.
10 changes: 3 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
id 'com.github.kt3k.coveralls' version '2.4.0'
id 'maven'
}

apply plugin: 'java'
Expand All @@ -9,12 +10,13 @@ apply plugin: 'jacoco'

group = 'net.querz.nbt'
archivesBaseName = 'nbt'
version = '4.1'
version = '6.1-SNAPSHOT'
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
compileJava.options.encoding = 'UTF-8'

repositories {
mavenLocal()
jcenter()
}

Expand Down Expand Up @@ -53,9 +55,3 @@ artifacts {
archives sourcesJar
archives javadocJar
}

jar {
manifest {
attributes('Automatic-Module-Name': 'net.querz.nbt')
}
}
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
3 changes: 1 addition & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#Wed Mar 29 16:28:10 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
59 changes: 36 additions & 23 deletions gradlew
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
#!/usr/bin/env sh

#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

##############################################################################
##
## Gradle start up script for UN*X
Expand Down Expand Up @@ -28,16 +44,16 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
warn () {
echo "$*"
}

die ( ) {
die () {
echo
echo "$*"
echo
Expand Down Expand Up @@ -66,6 +82,7 @@ esac

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar


# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
Expand Down Expand Up @@ -109,10 +126,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`

JAVACMD=`cygpath --unix "$JAVACMD"`

# We build the pattern for arguments to be converted via cygpath
Expand All @@ -138,35 +156,30 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi

# Escape application args
save ( ) {
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
APP_ARGS=`save "$@"`

# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"

# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi

exec "$JAVACMD" "$@"
22 changes: 21 additions & 1 deletion gradlew.bat
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem

@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
Expand All @@ -13,8 +29,11 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
Expand Down Expand Up @@ -65,6 +84,7 @@ set CMD_LINE_ARGS=%*

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar


@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

Expand Down
42 changes: 42 additions & 0 deletions src/main/java/net/querz/io/Deserializer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package net.querz.io;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public interface Deserializer<T> {

T fromStream(InputStream stream) throws IOException;

default T fromFile(File file) throws IOException {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
return fromStream(bis);
}
}

default T fromBytes(byte[] data) throws IOException {
ByteArrayInputStream stream = new ByteArrayInputStream(data);
return fromStream(stream);
}

default T fromResource(Class<?> clazz, String path) throws IOException {
try (InputStream stream = clazz.getClassLoader().getResourceAsStream(path)) {
if (stream == null) {
throw new IOException("resource \"" + path + "\" not found");
}
return fromStream(stream);
}
}

default T fromURL(URL url) throws IOException {
try (InputStream stream = url.openStream()) {
return fromStream(stream);
}
}


}
7 changes: 7 additions & 0 deletions src/main/java/net/querz/io/ExceptionBiFunction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package net.querz.io;

@FunctionalInterface
public interface ExceptionBiFunction <T, U, R, E extends Exception> {

R accept(T t, U u) throws E;
}
7 changes: 7 additions & 0 deletions src/main/java/net/querz/io/ExceptionTriConsumer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package net.querz.io;

@FunctionalInterface
public interface ExceptionTriConsumer<T, U, V, E extends Exception> {

void accept(T t, U u, V v) throws E;
}
Loading