diff options
Diffstat (limited to 'src/main/java/de/cowtipper/cowlection/util/GsonUtils.java')
-rw-r--r-- | src/main/java/de/cowtipper/cowlection/util/GsonUtils.java | 89 |
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(); |