bytearray64reader: read length of zero and EOF are properly distinguished (gdx is somewhat pedantic); changed an ascii85 charset; working meta (de)serialisation

This commit is contained in:
minjaesong
2021-09-01 17:23:12 +09:00
parent 07f26a7716
commit f08296b3be
11 changed files with 109 additions and 315 deletions

View File

@@ -1,19 +1,13 @@
package net.torvald.terrarum.serialise
import com.badlogic.gdx.utils.compression.Lzma
import net.torvald.terrarum.ModMgr
import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameworld.BlockLayer
import net.torvald.terrarum.gameactors.ActorID
import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.worldgenerator.RoguelikeRandomiser
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64GrowableOutputStream
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64InputStream
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64Reader
import net.torvald.terrarum.weather.WeatherMixer
import java.io.ByteArrayInputStream
import java.io.StringReader
import java.util.zip.GZIPInputStream
import java.util.zip.GZIPOutputStream
/**
* Created by minjaesong on 2021-08-23.
@@ -23,51 +17,51 @@ open class WriteMeta(val ingame: TerrarumIngame) {
open fun invoke(): String {
val world = ingame.world
val json = """{
"genver": ${Common.GENVER},
"savename": "${world.worldName}",
"terrseed": ${world.generatorSeed},
"randseed0": ${RoguelikeRandomiser.RNG.state0},
"randseed1": ${RoguelikeRandomiser.RNG.state1},
"weatseed0": ${WeatherMixer.RNG.state0},
"weatseed1": ${WeatherMixer.RNG.state1},
"playerid": ${ingame.actorGamer.referenceID},
"creation_t": ${world.creationTime},
"lastplay_t": ${world.lastPlayTime},
"playtime_t": ${world.totalPlayTime},
"blocks": "${StringBuilder().let {
ModMgr.getFilesFromEveryMod("blocks/blocks.csv").forEach { (modname, file) ->
it.append("\n\n## module: $modname ##\n\n")
it.append(file.readText())
}
zipStrAndEnascii(it.toString())
}}",
"items": "${StringBuilder().let {
ModMgr.getFilesFromEveryMod("items/itemid.csv").forEach { (modname, file) ->
it.append("\n\n## module: $modname ##\n\n")
it.append(file.readText())
}
zipStrAndEnascii(it.toString())
}}",
"wires": "${StringBuilder().let {
ModMgr.getFilesFromEveryMod("wires/wires.csv").forEach { (modname, file) ->
it.append("\n\n## module: $modname ##\n\n")
it.append(file.readText())
}
zipStrAndEnascii(it.toString())
}}",
"materials": "${StringBuilder().let {
ModMgr.getFilesFromEveryMod("materials/materials.csv").forEach { (modname, file) ->
it.append("\n\n## module: $modname ##\n\n")
it.append(file.readText())
}
zipStrAndEnascii(it.toString())
}}",
"loadorder": [${ModMgr.loadOrder.map { "\"${it}\"" }.joinToString()}],
"worlds": [${ingame.gameworldIndices.joinToString()}]
}"""
return json
val meta = WorldMeta(
genver = Common.GENVER,
savename = world.worldName,
terrseed = world.generatorSeed,
randseed0 = RoguelikeRandomiser.RNG.state0,
randseed1 = RoguelikeRandomiser.RNG.state1,
weatseed0 = WeatherMixer.RNG.state0,
weatseed1 = WeatherMixer.RNG.state1,
playerid = ingame.actorGamer.referenceID,
creation_t = world.creationTime,
lastplay_t = world.lastPlayTime,
playtime_t = world.totalPlayTime,
blocks = StringBuilder().let {
ModMgr.getFilesFromEveryMod("blocks/blocks.csv").forEach { (modname, file) ->
it.append(modnameToOrnamentalHeader(modname))
it.append(file.readText())
}
zipStrAndEnascii(it.toString())
},
items = StringBuilder().let {
ModMgr.getFilesFromEveryMod("items/itemid.csv").forEach { (modname, file) ->
it.append(modnameToOrnamentalHeader(modname))
it.append(file.readText())
}
zipStrAndEnascii(it.toString())
},
wires = StringBuilder().let {
ModMgr.getFilesFromEveryMod("wires/wires.csv").forEach { (modname, file) ->
it.append(modnameToOrnamentalHeader(modname))
it.append(file.readText())
}
zipStrAndEnascii(it.toString())
},
materials = StringBuilder().let {
ModMgr.getFilesFromEveryMod("materials/materials.csv").forEach { (modname, file) ->
it.append(modnameToOrnamentalHeader(modname))
it.append(file.readText())
}
zipStrAndEnascii(it.toString())
},
loadorder = ModMgr.loadOrder.toTypedArray(),
worlds = ingame.gameworldIndices.toTypedArray()
)
return Common.jsoner.toJson(meta)
}
fun encodeToByteArray64(): ByteArray64 {
@@ -77,20 +71,46 @@ open class WriteMeta(val ingame: TerrarumIngame) {
}
data class WorldMeta(
val genver: Int,
val savename: String
)
/**
* @param [s] a String
* @return UTF-8 encoded [s] which are GZip'd then Ascii85-encoded
*/
fun zipStrAndEnascii(s: String): String {
return Common.bytesToZipdStr(s.toByteArray(Common.CHARSET).iterator())
val genver: Int = -1,
val savename: String = "",
val terrseed: Long = 0,
val randseed0: Long = 0,
val randseed1: Long = 0,
val weatseed0: Long = 0,
val weatseed1: Long = 0,
val playerid: ActorID = 0,
val creation_t: Long = 0,
val lastplay_t: Long = 0,
val playtime_t: Long = 0,
val blocks: String = "",
val items: String = "",
val wires: String = "",
val materials: String = "",
val loadorder: Array<String> = arrayOf(), // do not use list; Could not instantiate instance of class: java.util.Collections$SingletonList
val worlds: Array<Int> = arrayOf() // do not use list; Could not instantiate instance of class: java.util.Collections$SingletonList
) {
override fun equals(other: Any?): Boolean {
throw UnsupportedOperationException()
}
}
fun unasciiAndUnzipStr(s: String): String {
return ByteArray64Reader(Common.strToBytes(StringReader(s)), Common.CHARSET).readText()
companion object {
private fun modnameToOrnamentalHeader(s: String) =
"\n\n${"#".repeat(16 + s.length)}\n" +
"## module: $s ##\n" +
"${"#".repeat(16 + s.length)}\n\n"
/**
* @param [s] a String
* @return UTF-8 encoded [s] which are GZip'd then Ascii85-encoded
*/
fun zipStrAndEnascii(s: String): String {
return Common.bytesToZipdStr(s.toByteArray(Common.CHARSET).iterator())
}
fun unasciiAndUnzipStr(s: String): String {
return ByteArray64Reader(Common.strToBytes(StringReader(s)), Common.CHARSET).readText()
}
}
}