will store codices gzipped in the savegame

This commit is contained in:
minjaesong
2021-09-05 01:52:46 +09:00
parent a7026167b4
commit 6b86f65681
2 changed files with 54 additions and 36 deletions

View File

@@ -11,16 +11,12 @@ 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.tail
import net.torvald.terrarum.utils.*
import org.apache.commons.codec.digest.DigestUtils
import java.io.InputStream
import java.io.Reader
import java.io.StringReader
import java.io.Writer
import java.math.BigInteger
import java.nio.channels.ClosedChannelException
import java.nio.charset.Charset
import java.nio.charset.UnsupportedCharsetException
import java.util.zip.GZIPInputStream
import java.util.zip.GZIPOutputStream
@@ -216,8 +212,10 @@ object Common {
return layer
}
fun bytesToZipdStr(byteIterator: Iterator<Byte>): String {
val sb = StringBuilder()
fun bytesToZipdStr(byteIterator: Iterator<Byte>): String = enasciiToString(zip(byteIterator))
fun zip(ba: ByteArray64) = Common.zip(ba.iterator())
fun zip(byteIterator: Iterator<Byte>): ByteArray64 {
val bo = ByteArray64GrowableOutputStream()
val zo = GZIPOutputStream(bo)
@@ -226,9 +224,13 @@ object Common {
zo.write(it.toInt())
}
zo.flush(); zo.close()
return bo.toByteArray64()
}
fun enasciiToString(ba: ByteArray64): String = enasciiToString(ba.iterator())
fun enasciiToString(ba: Iterator<Byte>): String {
val sb = StringBuilder()
// enascii
val ba = bo.toByteArray64()
var bai = 0
val buf = IntArray(4) { Ascii85.PAD_BYTE }
ba.forEach {
@@ -245,9 +247,20 @@ object Common {
return sb.toString()
}
fun strToBytes(reader: Reader): ByteArray64 {
val unasciidBytes = ByteArray64()
fun unzip(bytes: ByteArray64): ByteArray64 {
val unzipdBytes = ByteArray64()
val zi = GZIPInputStream(ByteArray64InputStream(bytes))
while (true) {
val byte = zi.read()
if (byte == -1) break
unzipdBytes.add(byte.toByte())
}
zi.close()
return unzipdBytes
}
fun unasciiToBytes(reader: Reader): ByteArray64 {
val unasciidBytes = ByteArray64()
// unascii
var bai = 0
@@ -265,18 +278,15 @@ object Common {
bai += 1
}; Ascii85.decode(buf[0], buf[1], buf[2], buf[3], buf[4]).forEach { unasciidBytes.add(it) }
// unzip
val zi = GZIPInputStream(ByteArray64InputStream(unasciidBytes))
while (true) {
val byte = zi.read()
if (byte == -1) break
unzipdBytes.add(byte.toByte())
}
zi.close()
return unzipdBytes
return unasciidBytes
}
fun getUnzipInputStream(bytes: ByteArray64): InputStream {
return GZIPInputStream(ByteArray64InputStream(bytes))
}
fun strToBytes(reader: Reader): ByteArray64 = unzip(unasciiToBytes(reader))
/**
* @param [s] a String
* @return UTF-8 encoded [s] which are GZip'd then Ascii85-encoded
@@ -288,4 +298,5 @@ object Common {
fun unasciiAndUnzipStr(s: String): String {
return ByteArray64Reader(strToBytes(StringReader(s)), CHARSET).readText()
}
}

View File

@@ -4,8 +4,11 @@ import net.torvald.terrarum.*
import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.*
import net.torvald.terrarum.serialise.Common.getUnzipInputStream
import net.torvald.terrarum.serialise.Common.zip
import net.torvald.terrarum.serialise.WriteWorld.actorAcceptable
import java.io.File
import java.io.Reader
/**
* It's your responsibility to create a new VirtualDisk if your save is new, and create a backup for modifying existing save.
@@ -36,32 +39,32 @@ object WriteSavegame {
addFile(disk, meta)
// Write BlockCodex//
val blockCodexContent = EntryFile(ByteArray64.fromByteArray(Common.jsoner.toJson(BlockCodex).toByteArray(Common.CHARSET)))
val blockCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(BlockCodex).toByteArray(Common.CHARSET))))
val blocks = DiskEntry(-16, 0, "blocks".toByteArray(), creation_t, time_t, blockCodexContent)
addFile(disk, blocks)
// Write ItemCodex//
val itemCodexContent = EntryFile(ByteArray64.fromByteArray(Common.jsoner.toJson(ItemCodex).toByteArray(Common.CHARSET)))
val itemCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(ItemCodex).toByteArray(Common.CHARSET))))
val items = DiskEntry(-17, 0, "items".toByteArray(), creation_t, time_t, itemCodexContent)
addFile(disk, items)
// Write WireCodex//
val wireCodexContent = EntryFile(ByteArray64.fromByteArray(Common.jsoner.toJson(WireCodex).toByteArray(Common.CHARSET)))
val wireCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(WireCodex).toByteArray(Common.CHARSET))))
val wires = DiskEntry(-18, 0, "wires".toByteArray(), creation_t, time_t, wireCodexContent)
addFile(disk, wires)
// Write MaterialCodex//
val materialCodexContent = EntryFile(ByteArray64.fromByteArray(Common.jsoner.toJson(MaterialCodex).toByteArray(Common.CHARSET)))
val materialCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(MaterialCodex).toByteArray(Common.CHARSET))))
val materials = DiskEntry(-19, 0, "materials".toByteArray(), creation_t, time_t, materialCodexContent)
addFile(disk, materials)
// Write FactionCodex//
val factionCodexContent = EntryFile(ByteArray64.fromByteArray(Common.jsoner.toJson(FactionCodex).toByteArray(Common.CHARSET)))
val factionCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(FactionCodex).toByteArray(Common.CHARSET))))
val factions = DiskEntry(-20, 0, "factions".toByteArray(), creation_t, time_t, factionCodexContent)
addFile(disk, factions)
// Write Apocryphas//
val apocryphasContent = EntryFile(ByteArray64.fromByteArray(Common.jsoner.toJson(Apocryphas).toByteArray(Common.CHARSET)))
val apocryphasContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(Apocryphas).toByteArray(Common.CHARSET))))
val apocryphas = DiskEntry(-1024, 0, "modprops".toByteArray(), creation_t, time_t, apocryphasContent)
addFile(disk, apocryphas)
@@ -98,20 +101,23 @@ object WriteSavegame {
*/
object LoadSavegame {
private fun getFileBytes(disk: VirtualDisk, id: Int): ByteArray64 = VDUtil.getAsNormalFile(disk, id).getContent()
private fun getFileReader(disk: VirtualDisk, id: Int): Reader = ByteArray64Reader(getFileBytes(disk, id), Common.CHARSET)
operator fun invoke(disk: VirtualDisk) {
val meta = ReadMeta(disk)
val player = ReadActor.readActorOnly(
ByteArray64Reader(VDUtil.getAsNormalFile(disk, 9545698).getContent(), Common.CHARSET)
) as IngamePlayer
val world = ReadWorld.readWorldOnly(
ByteArray64Reader(VDUtil.getAsNormalFile(disk, player.worldCurrentlyPlaying).getContent(), Common.CHARSET)
)
val actors = world.actors.map {
ReadActor.readActorOnly(ByteArray64Reader(VDUtil.getAsNormalFile(disk, it).getContent(), Common.CHARSET))
}
val player = ReadActor.readActorOnly(getFileReader(disk, 9545698)) as IngamePlayer
val world = ReadWorld.readWorldOnly(getFileReader(disk, player.worldCurrentlyPlaying))
val actors = world.actors.map { ReadActor.readActorOnly(getFileReader(disk, it)) }
val block = Common.jsoner.fromJson(BlockCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -16)))
val item = Common.jsoner.fromJson(ItemCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -17)))
val wire = Common.jsoner.fromJson(WireCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -18)))
val material = Common.jsoner.fromJson(MaterialCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -19)))
val faction = Common.jsoner.fromJson(FactionCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -20)))
val apocryphas = Common.jsoner.fromJson(Apocryphas.javaClass, getUnzipInputStream(getFileBytes(disk, -1024)))
val ingame = TerrarumIngame(AppLoader.batch)
val worldParam = meta
val worldParam = TerrarumIngame.Codices(meta, block, item, wire, material, faction, apocryphas)
ingame.world = world
ingame.gameLoadInfoPayload = worldParam
ingame.gameLoadMode = TerrarumIngame.GameLoadMode.LOAD_FROM
@@ -123,4 +129,5 @@ object LoadSavegame {
val loadScreen = SanicLoadScreen
AppLoader.setLoadScreen(loadScreen)
}
}