Skip to content

Commit

Permalink
Add Mojangson serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
wode490390 committed May 12, 2024
1 parent 2f42b75 commit 101423f
Show file tree
Hide file tree
Showing 15 changed files with 242 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.jupiter.version>5.10.2</junit.jupiter.version>
<log4j2.version>2.23.0</log4j2.version>
<jackson.version>2.16.1</jackson.version>
<jackson.version>2.17.1</jackson.version>
<jline.version>3.25.1</jline.version>
<!-- 本地测试服务端插件目录 -->
<dir.api>../../_api</dir.api>
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/cn/nukkit/nbt/tag/ByteArrayTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

import java.io.IOException;
import java.util.Arrays;
import java.util.StringJoiner;
import java.util.function.IntFunction;

public class ByteArrayTag extends Tag {
public byte[] data;
Expand Down Expand Up @@ -75,4 +77,22 @@ public Tag copy() {
public byte[] parseValue() {
return this.data;
}

@Override
public String toJson(boolean pretty) {
return asJson(String::valueOf, pretty);
}

@Override
public String toMojangson(boolean pretty) {
return asJson(n -> n + "B", pretty);
}

private String asJson(IntFunction<String> elementStringifier, boolean pretty) {
StringJoiner joiner = new StringJoiner(pretty ? ", " : ",");
for (int n : data) {
joiner.add(elementStringifier.apply(n));
}
return "[" + joiner + "]";
}
}
10 changes: 10 additions & 0 deletions src/main/java/cn/nukkit/nbt/tag/ByteTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,14 @@ public boolean equals(Object obj) {
public Tag copy() {
return new ByteTag(getName(), data);
}

@Override
public String toJson(boolean pretty) {
return String.valueOf(data);
}

@Override
public String toMojangson(boolean pretty) {
return data + "b";
}
}
56 changes: 56 additions & 0 deletions src/main/java/cn/nukkit/nbt/tag/CompoundTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -469,4 +469,60 @@ public CompoundTag clone() {
this.tags.forEach((key, value) -> nbt.put(key, value.copy()));
return nbt;
}

@Override
public String toJson(boolean pretty) {
return asJson(Tag::toJson, pretty);
}

@Override
public String toMojangson(boolean pretty) {
return asJson(Tag::toMojangson, pretty);
}

private String asJson(Stringifier stringifier, boolean pretty) {
Iterator<Entry<String, Tag>> iterator = tags.entrySet().iterator();
if (!iterator.hasNext()) {
return "{}";
}

StringBuilder builder = new StringBuilder();
if (pretty) {
builder.append('{').append('\n');
for (; ; ) {
Entry<String, Tag> entry = iterator.next();
builder.append(indent("\"" + entry.getKey() + "\": " + stringifier.stringify(entry.getValue(), true)));
if (!iterator.hasNext()) {
return builder.append('\n').append('}').toString();
}
builder.append(',').append('\n');
}
} else {
builder.append('{');
for (; ; ) {
Entry<String, Tag> entry = iterator.next();
builder.append("\"").append(entry.getKey()).append("\":").append(stringifier.stringify(entry.getValue(), false));
if (!iterator.hasNext()) {
return builder.append('}').toString();
}
builder.append(',');
}
}
}

static String indent(String string) {
StringBuilder builder = new StringBuilder(" " + string);
for (int i = 4; i < builder.length(); i++) {
if (builder.charAt(i) == '\n') {
builder.insert(i + 1, " ");
i += 4;
}
}
return builder.toString();
}

@FunctionalInterface
interface Stringifier {
String stringify(Tag tag, boolean pretty);
}
}
9 changes: 9 additions & 0 deletions src/main/java/cn/nukkit/nbt/tag/DoubleTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,13 @@ public boolean equals(Object obj) {
return false;
}

@Override
public String toJson(boolean pretty) {
return String.valueOf(data);
}

@Override
public String toMojangson(boolean pretty) {
return data + "d";
}
}
13 changes: 13 additions & 0 deletions src/main/java/cn/nukkit/nbt/tag/EndTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,17 @@ public Tag copy() {
public Object parseValue() {
return null;
}

@Override
public String toJson(boolean pretty) {
return "null";
}

@Override
public String toMojangson(boolean pretty) {
if (pretty) {
return "";
}
return "\n";
}
}
9 changes: 9 additions & 0 deletions src/main/java/cn/nukkit/nbt/tag/FloatTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,13 @@ public boolean equals(Object obj) {
return false;
}

@Override
public String toJson(boolean pretty) {
return String.valueOf(data);
}

@Override
public String toMojangson(boolean pretty) {
return data + "f";
}
}
20 changes: 20 additions & 0 deletions src/main/java/cn/nukkit/nbt/tag/IntArrayTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import java.io.IOException;
import java.util.Arrays;
import java.util.StringJoiner;
import java.util.function.IntFunction;

public class IntArrayTag extends Tag {
public int[] data;
Expand Down Expand Up @@ -74,4 +76,22 @@ public Tag copy() {
System.arraycopy(data, 0, cp, 0, data.length);
return new IntArrayTag(getName(), cp);
}

@Override
public String toJson(boolean pretty) {
return asJson(String::valueOf, pretty);
}

@Override
public String toMojangson(boolean pretty) {
return asJson(n -> n + "I", pretty);
}

private String asJson(IntFunction<String> elementStringifier, boolean pretty) {
StringJoiner joiner = new StringJoiner(pretty ? ", " : ",");
for (int n : data) {
joiner.add(elementStringifier.apply(n));
}
return "[" + joiner + "]";
}
}
9 changes: 9 additions & 0 deletions src/main/java/cn/nukkit/nbt/tag/IntTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,13 @@ public boolean equals(Object obj) {
return false;
}

@Override
public String toJson(boolean pretty) {
return String.valueOf(data);
}

@Override
public String toMojangson(boolean pretty) {
return String.valueOf(data);
}
}
38 changes: 38 additions & 0 deletions src/main/java/cn/nukkit/nbt/tag/ListTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -430,4 +430,42 @@ public Vector3 asFloatPos() {
public BlockVector3 asBlockPos() {
return BlockVector3.fromNbt((ListTag<IntTag>) this);
}

@Override
public String toJson(boolean pretty) {
return asJson(Tag::toJson, pretty);
}

@Override
public String toMojangson(boolean pretty) {
return asJson(Tag::toMojangson, pretty);
}

private String asJson(CompoundTag.Stringifier stringifier, boolean pretty) {
Iterator<T> iterator = iterator();
if (!iterator.hasNext()) {
return "[]";
}

StringBuilder builder = new StringBuilder();
if (pretty) {
builder.append('[').append('\n');
for (; ; ) {
builder.append(CompoundTag.indent(stringifier.stringify(iterator.next(), true)));
if (!iterator.hasNext()) {
return builder.append('\n').append(']').toString();
}
builder.append(',').append('\n');
}
} else {
builder.append('[');
for (; ; ) {
builder.append(stringifier.stringify(iterator.next(), false));
if (!iterator.hasNext()) {
return builder.append(']').toString();
}
builder.append(',');
}
}
}
}
9 changes: 9 additions & 0 deletions src/main/java/cn/nukkit/nbt/tag/LongTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,13 @@ public boolean equals(Object obj) {
return false;
}

@Override
public String toJson(boolean pretty) {
return String.valueOf(data);
}

@Override
public String toMojangson(boolean pretty) {
return data + "l";
}
}
9 changes: 9 additions & 0 deletions src/main/java/cn/nukkit/nbt/tag/ShortTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,13 @@ public boolean equals(Object obj) {
return false;
}

@Override
public String toJson(boolean pretty) {
return String.valueOf(data);
}

@Override
public String toMojangson(boolean pretty) {
return data + "s";
}
}
9 changes: 9 additions & 0 deletions src/main/java/cn/nukkit/nbt/tag/StringTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,13 @@ public boolean equals(Object obj) {
return false;
}

@Override
public String toJson(boolean pretty) {
return "\"" + data + "\"";
}

@Override
public String toMojangson(boolean pretty) {
return "\"" + data + "\"";
}
}
12 changes: 12 additions & 0 deletions src/main/java/cn/nukkit/nbt/tag/Tag.java
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,16 @@ public static String getTagName(byte type) {
public abstract Tag copy();

public abstract Object parseValue();

public String toJson() {
return toJson(false);
}

public abstract String toJson(boolean pretty);

public String toMojangson() {
return toMojangson(false);
}

public abstract String toMojangson(boolean pretty);
}
18 changes: 18 additions & 0 deletions src/main/java/cn/nukkit/utils/JsonUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,35 @@
import com.fasterxml.jackson.core.StreamReadConstraints;
import com.fasterxml.jackson.core.StreamWriteConstraints;
import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter.Indenter;
import com.fasterxml.jackson.core.util.Separators;
import com.fasterxml.jackson.core.util.Separators.Spacing;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.datatype.guava.GuavaModule;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;

public class JsonUtil {
public static final Indenter PRETTY_INDENTER = new DefaultIndenter(" ", "\n");

public static final JsonMapper COMMON_JSON_MAPPER = JsonMapper.builder()
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.enable(JsonReadFeature.ALLOW_JAVA_COMMENTS)
.addModule(new Jdk8Module())
.addModule(new GuavaModule())
.defaultPrettyPrinter(new DefaultPrettyPrinter(new Separators()
.withObjectFieldValueSpacing(Spacing.AFTER)
.withArrayEmptySeparator("")
.withObjectEmptySeparator(""))
.withArrayIndenter(PRETTY_INDENTER)
.withObjectIndenter(PRETTY_INDENTER))
.build();
public static final JsonMapper TRUSTED_JSON_MAPPER = COMMON_JSON_MAPPER.copy();
public static final ObjectMapper PRETTY_JSON_MAPPER;

static {
TRUSTED_JSON_MAPPER.getFactory()
Expand All @@ -29,5 +45,7 @@ public class JsonUtil {
.setStreamWriteConstraints(StreamWriteConstraints.builder()
.maxNestingDepth(Integer.MAX_VALUE)
.build());
PRETTY_JSON_MAPPER = TRUSTED_JSON_MAPPER.copy()
.enable(SerializationFeature.INDENT_OUTPUT);
}
}

0 comments on commit 101423f

Please sign in to comment.