aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/cowtipper/cowlection/util/GsonUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/cowtipper/cowlection/util/GsonUtils.java')
-rw-r--r--src/main/java/de/cowtipper/cowlection/util/GsonUtils.java89
1 files changed, 83 insertions, 6 deletions
diff --git a/src/main/java/de/cowtipper/cowlection/util/GsonUtils.java b/src/main/java/de/cowtipper/cowlection/util/GsonUtils.java
index c0b2735..e97a88d 100644
--- a/src/main/java/de/cowtipper/cowlection/util/GsonUtils.java
+++ b/src/main/java/de/cowtipper/cowlection/util/GsonUtils.java
@@ -3,14 +3,19 @@ package de.cowtipper.cowlection.util;
import com.google.gson.*;
import com.mojang.util.UUIDTypeAdapter;
import de.cowtipper.cowlection.data.HyPlayerData;
-import net.minecraft.nbt.NBTBase;
-import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.nbt.NBTTagList;
-import net.minecraft.nbt.NBTTagString;
+import net.minecraft.nbt.*;
import net.minecraftforge.common.util.Constants;
+import org.apache.commons.codec.binary.Base64;
import java.io.Reader;
import java.lang.reflect.Type;
+import java.time.DateTimeException;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Map;
+import java.util.TreeMap;
import java.util.UUID;
public final class GsonUtils {
@@ -29,13 +34,51 @@ public final class GsonUtils {
}
public static String toJson(Object object) {
+ return toJson(object, false);
+ }
+
+ public static String toJson(Object object, boolean sort) {
if (object instanceof NBTBase) {
- return gsonPrettyPrinter.toJson(nbtToJson((NBTBase) object));
+ JsonElement jsonElement = nbtToJson((NBTBase) object);
+ if (sort && (jsonElement instanceof JsonObject || jsonElement instanceof JsonArray)) {
+ jsonElement = sortJsonElement(jsonElement);
+ }
+ return gsonPrettyPrinter.toJson(jsonElement);
} else {
return gson.toJson(object);
}
}
+ private static JsonElement sortJsonElement(JsonElement jsonElement) {
+ if (jsonElement instanceof JsonArray) {
+ // sort each element of array
+ JsonArray sortedJsonArray = new JsonArray();
+ for (JsonElement arrayElement : (JsonArray) jsonElement) {
+ sortedJsonArray.add(sortJsonElement(arrayElement));
+ }
+ return sortedJsonArray;
+ } else if (jsonElement instanceof JsonObject) {
+ // sort json by key
+ TreeMap<String, JsonElement> sortedJsonObject = new TreeMap<>(String::compareToIgnoreCase);
+ for (Map.Entry<String, JsonElement> jsonEntry : ((JsonObject) jsonElement).entrySet()) {
+ JsonElement sortedJsonElement = jsonEntry.getValue();
+ if (sortedJsonElement instanceof JsonObject) {
+ sortedJsonElement = sortJsonElement(sortedJsonElement);
+ }
+ sortedJsonObject.put(jsonEntry.getKey(), sortedJsonElement);
+ }
+ // overwrite jsonElement with json sorted by key alphabetically
+ JsonObject sortedJsonElement = new JsonObject();
+ for (Map.Entry<String, JsonElement> jsonEntrySorted : sortedJsonObject.entrySet()) {
+ sortedJsonElement.add(jsonEntrySorted.getKey(), jsonEntrySorted.getValue());
+ }
+ return sortedJsonElement;
+ } else {
+ // neither array, nor object: return original element
+ return jsonElement;
+ }
+ }
+
private static JsonElement nbtToJson(NBTBase nbtElement) {
if (nbtElement instanceof NBTBase.NBTPrimitive) {
NBTBase.NBTPrimitive nbtNumber = (NBTBase.NBTPrimitive) nbtElement;
@@ -56,7 +99,34 @@ public final class GsonUtils {
return new JsonObject();
}
} else if (nbtElement instanceof NBTTagString) {
- return new JsonPrimitive(((NBTTagString) nbtElement).getString());
+ String str = ((NBTTagString) nbtElement).getString();
+ if (str.length() > 100 && (str.startsWith("eyJ") || str.startsWith("ewo")) && Base64.isBase64(str)) {
+ // base64 decode NBTTagStrings starting with {" or {\n
+ try {
+ JsonElement base64DecodedJson = new JsonParser().parse(new String(Base64.decodeBase64(str)));
+ if (base64DecodedJson.isJsonObject()) {
+ JsonObject jsonObject = base64DecodedJson.getAsJsonObject();
+ JsonElement timestamp = jsonObject.get("timestamp");
+ if (timestamp != null) {
+ // convert unix timestamp to human-readable dates
+ try {
+ ZonedDateTime utcDateTime = ZonedDateTime.ofInstant(Instant.ofEpochMilli(timestamp.getAsLong()), ZoneOffset.UTC);
+ ZonedDateTime localDateTime = utcDateTime.withZoneSameInstant(ZoneOffset.systemDefault());
+ String zoneOffset = localDateTime.getOffset().toString();
+
+ DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss O");
+ jsonObject.add("timeInUTC", new JsonPrimitive(utcDateTime.format(dateTimeFormatter)));
+ jsonObject.add("timeInLocalZone (UTC" + ("Z".equals(zoneOffset) ? "" : zoneOffset) + ")", new JsonPrimitive(localDateTime.format(dateTimeFormatter)));
+ } catch (DateTimeException | NumberFormatException ignored) {
+ }
+ }
+ }
+ return base64DecodedJson;
+ } catch (JsonParseException ignored) {
+ // failed to parse as json; leaving original string unmodified
+ }
+ }
+ return new JsonPrimitive(str);
} else if (nbtElement instanceof NBTTagList) {
NBTTagList nbtList = (NBTTagList) nbtElement;
JsonArray jsonArray = new JsonArray();
@@ -64,6 +134,13 @@ public final class GsonUtils {
jsonArray.add(nbtToJson(nbtList.get(tagId)));
}
return jsonArray;
+ } else if (nbtElement instanceof NBTTagIntArray) {
+ int[] intArray = ((NBTTagIntArray) nbtElement).getIntArray();
+ JsonArray jsonArray = new JsonArray();
+ for (int number : intArray) {
+ jsonArray.add(new JsonPrimitive(number));
+ }
+ return jsonArray;
} else if (nbtElement instanceof NBTTagCompound) {
NBTTagCompound nbtCompound = (NBTTagCompound) nbtElement;
JsonObject jsonObject = new JsonObject();