HTTPS
https://git.nageyqma.icu/nageyqma/odin_next.git
SSH
git@git.nageyqma.icu:nageyqma/odin_next.git
HTTPS 链接可直接 git clone;推送代码请使用 SSH。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
package com.odtheking.odin.config
import com.google.gson.*
import com.google.gson.reflect.TypeToken
import com.odtheking.odin.OdinMod
import com.odtheking.odin.features.impl.dungeon.dungeonwaypoints.DungeonWaypoints
import com.odtheking.odin.features.impl.dungeon.dungeonwaypoints.DungeonWaypoints.DungeonWaypoint
import com.odtheking.odin.utils.Color
import net.minecraft.core.BlockPos
import net.minecraft.world.phys.AABB
import java.io.ByteArrayOutputStream
import java.lang.reflect.Type
import java.util.zip.GZIPInputStream
import java.util.zip.GZIPOutputStream
import kotlin.io.encoding.Base64
object DungeonWaypointConfig {
val gson: Gson = GsonBuilder()
.registerTypeAdapter(AABB::class.java, AABBSerializer())
.registerTypeAdapter(DungeonWaypoint::class.java, DungeonWaypointDeserializer())
.registerTypeAdapter(BlockPos::class.java, BlockPosSerializer())
.setPrettyPrinting().create()
fun encodeWaypoints(waypointsMap: MutableMap<String, MutableList<DungeonWaypoint>>): String? {
return try {
Base64.encode(compress(gson.toJson(waypointsMap)))
} catch (e: Exception) {
e.printStackTrace()
null
}
}
private fun compress(input: String): ByteArray {
ByteArrayOutputStream().use { byteArrayOutputStream ->
GZIPOutputStream(byteArrayOutputStream).use { gzipOutputStream ->
gzipOutputStream.write(input.toByteArray())
}
return byteArrayOutputStream.toByteArray()
}
}
fun decodeWaypoints(input: String): MutableMap<String, MutableList<DungeonWaypoint>>? {
return try {
gson.fromJson(
if (input.startsWith("{")) input else decompress(Base64.decode(input)),
object : TypeToken<MutableMap<String, MutableList<DungeonWaypoint>>>() {}.type
)
} catch (_: Exception) {
null
}
}
private fun decompress(compressed: ByteArray): String {
GZIPInputStream(compressed.inputStream()).use { gzipInputStream ->
return gzipInputStream.bufferedReader().use { it.readText() }
}
}
internal class DungeonWaypointDeserializer : JsonDeserializer<DungeonWaypoint> {
override fun deserialize(json: JsonElement, type: Type, context: JsonDeserializationContext): DungeonWaypoint {
val jsonObj = json.asJsonObject
val blockPos = if (jsonObj.has("blockPos")) context.deserialize(jsonObj["blockPos"], BlockPos::class.java)
else BlockPos(jsonObj["x"].asInt, jsonObj["y"].asInt, jsonObj["z"].asInt)
val color = context.deserialize<Color>(jsonObj["color"], Color::class.java)
val filled = jsonObj["filled"].asBoolean
val depth = jsonObj["depth"].asBoolean
val aabb = context.deserialize<AABB>(jsonObj["aabb"], AABB::class.java)
val title = jsonObj["title"]?.asString?.ifBlank { null }
val waypointType = jsonObj["type"]?.asString?.let {
runCatching { DungeonWaypoints.WaypointType.valueOf(it) }.getOrNull()
}
val waypoint = DungeonWaypoint(blockPos, color, filled, depth, aabb, title, type = waypointType)
if (waypointType == null && jsonObj.has("secret") && jsonObj["secret"]?.asBoolean == true)
waypoint.type = DungeonWaypoints.WaypointType.SECRET
return waypoint
}
}
internal class AABBSerializer : JsonSerializer<AABB>, JsonDeserializer<AABB> {
override fun deserialize(json: JsonElement, type: Type, context: JsonDeserializationContext): AABB {
val jsonObj = json.asJsonObject
if (jsonObj.has("minX")) {
val minX = jsonObj["minX"].asDouble
val minY = jsonObj["minY"].asDouble
val minZ = jsonObj["minZ"].asDouble
val maxX = jsonObj["maxX"].asDouble
val maxY = jsonObj["maxY"].asDouble
val maxZ = jsonObj["maxZ"].asDouble
return AABB(minX, minY, minZ, maxX, maxY, maxZ)
}
if (jsonObj.has("field_1323")) {
val minX = jsonObj["field_1323"].asDouble
val minY = jsonObj["field_1322"].asDouble
val minZ = jsonObj["field_1321"].asDouble
val maxX = jsonObj["field_1320"].asDouble
val maxY = jsonObj["field_1325"].asDouble
val maxZ = jsonObj["field_1324"].asDouble
return AABB(minX, minY, minZ, maxX, maxY, maxZ)
}
if (jsonObj.has("field_72340_a")) {
val minX = jsonObj["field_72340_a"].asDouble
val minY = jsonObj["field_72338_b"].asDouble
val minZ = jsonObj["field_72339_c"].asDouble
val maxX = jsonObj["field_72336_d"].asDouble
val maxY = jsonObj["field_72337_e"].asDouble
val maxZ = jsonObj["field_72334_f"].asDouble
return AABB(minX, minY, minZ, maxX, maxY, maxZ)
}
return AABB(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
}
override fun serialize(src: AABB, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement {
val jsonObject = JsonObject()
jsonObject.addProperty("minX", src.minX)
jsonObject.addProperty("minY", src.minY)
jsonObject.addProperty("minZ", src.minZ)
jsonObject.addProperty("maxX", src.maxX)
jsonObject.addProperty("maxY", src.maxY)
jsonObject.addProperty("maxZ", src.maxZ)
return jsonObject
}
}
internal class BlockPosSerializer : JsonSerializer<BlockPos>, JsonDeserializer<BlockPos> {
override fun serialize(
src: BlockPos,
typeOfSrc: Type,
context: JsonSerializationContext
): JsonElement {
val obj = JsonObject()
obj.addProperty("x", src.x)
obj.addProperty("y", src.y)
obj.addProperty("z", src.z)
return obj
}
override fun deserialize(
json: JsonElement,
typeOfT: Type,
context: JsonDeserializationContext
): BlockPos {
val obj = json.asJsonObject
if (obj.has("field_11173")) {
val x = obj["field_11175"].asInt
val y = obj["field_11174"].asInt
val z = obj["field_11173"].asInt
return BlockPos(x, y, z)
}
if (obj.has("x")) {
val x = obj["x"].asInt
val y = obj["y"].asInt
val z = obj["z"].asInt
return BlockPos(x, y, z)
}
OdinMod.logger.debug("Failed to deserialize BlockPos\n$json")
return BlockPos(0, 0, 0)
}
}
}