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.ByteArray64GrowableOutputStream
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64InputStream import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64InputStream
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64Reader import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64Reader
import net.torvald.terrarum.tail
import net.torvald.terrarum.utils.* import net.torvald.terrarum.utils.*
import org.apache.commons.codec.digest.DigestUtils import org.apache.commons.codec.digest.DigestUtils
import java.io.InputStream
import java.io.Reader import java.io.Reader
import java.io.StringReader import java.io.StringReader
import java.io.Writer
import java.math.BigInteger 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.GZIPInputStream
import java.util.zip.GZIPOutputStream import java.util.zip.GZIPOutputStream
@@ -216,8 +212,10 @@ object Common {
return layer return layer
} }
fun bytesToZipdStr(byteIterator: Iterator<Byte>): String { fun bytesToZipdStr(byteIterator: Iterator<Byte>): String = enasciiToString(zip(byteIterator))
val sb = StringBuilder()
fun zip(ba: ByteArray64) = Common.zip(ba.iterator())
fun zip(byteIterator: Iterator<Byte>): ByteArray64 {
val bo = ByteArray64GrowableOutputStream() val bo = ByteArray64GrowableOutputStream()
val zo = GZIPOutputStream(bo) val zo = GZIPOutputStream(bo)
@@ -226,9 +224,13 @@ object Common {
zo.write(it.toInt()) zo.write(it.toInt())
} }
zo.flush(); zo.close() 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 // enascii
val ba = bo.toByteArray64()
var bai = 0 var bai = 0
val buf = IntArray(4) { Ascii85.PAD_BYTE } val buf = IntArray(4) { Ascii85.PAD_BYTE }
ba.forEach { ba.forEach {
@@ -245,9 +247,20 @@ object Common {
return sb.toString() return sb.toString()
} }
fun strToBytes(reader: Reader): ByteArray64 { fun unzip(bytes: ByteArray64): ByteArray64 {
val unasciidBytes = ByteArray64()
val unzipdBytes = 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 // unascii
var bai = 0 var bai = 0
@@ -265,18 +278,15 @@ object Common {
bai += 1 bai += 1
}; Ascii85.decode(buf[0], buf[1], buf[2], buf[3], buf[4]).forEach { unasciidBytes.add(it) } }; Ascii85.decode(buf[0], buf[1], buf[2], buf[3], buf[4]).forEach { unasciidBytes.add(it) }
// unzip return unasciidBytes
val zi = GZIPInputStream(ByteArray64InputStream(unasciidBytes))
while (true) {
val byte = zi.read()
if (byte == -1) break
unzipdBytes.add(byte.toByte())
}
zi.close()
return unzipdBytes
} }
fun getUnzipInputStream(bytes: ByteArray64): InputStream {
return GZIPInputStream(ByteArray64InputStream(bytes))
}
fun strToBytes(reader: Reader): ByteArray64 = unzip(unasciiToBytes(reader))
/** /**
* @param [s] a String * @param [s] a String
* @return UTF-8 encoded [s] which are GZip'd then Ascii85-encoded * @return UTF-8 encoded [s] which are GZip'd then Ascii85-encoded
@@ -288,4 +298,5 @@ object Common {
fun unasciiAndUnzipStr(s: String): String { fun unasciiAndUnzipStr(s: String): String {
return ByteArray64Reader(strToBytes(StringReader(s)), CHARSET).readText() 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.TerrarumIngame
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.* 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 net.torvald.terrarum.serialise.WriteWorld.actorAcceptable
import java.io.File 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. * 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) addFile(disk, meta)
// Write BlockCodex// // 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) val blocks = DiskEntry(-16, 0, "blocks".toByteArray(), creation_t, time_t, blockCodexContent)
addFile(disk, blocks) addFile(disk, blocks)
// Write ItemCodex// // 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) val items = DiskEntry(-17, 0, "items".toByteArray(), creation_t, time_t, itemCodexContent)
addFile(disk, items) addFile(disk, items)
// Write WireCodex// // 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) val wires = DiskEntry(-18, 0, "wires".toByteArray(), creation_t, time_t, wireCodexContent)
addFile(disk, wires) addFile(disk, wires)
// Write MaterialCodex// // 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) val materials = DiskEntry(-19, 0, "materials".toByteArray(), creation_t, time_t, materialCodexContent)
addFile(disk, materials) addFile(disk, materials)
// Write FactionCodex// // 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) val factions = DiskEntry(-20, 0, "factions".toByteArray(), creation_t, time_t, factionCodexContent)
addFile(disk, factions) addFile(disk, factions)
// Write Apocryphas// // 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) val apocryphas = DiskEntry(-1024, 0, "modprops".toByteArray(), creation_t, time_t, apocryphasContent)
addFile(disk, apocryphas) addFile(disk, apocryphas)
@@ -98,20 +101,23 @@ object WriteSavegame {
*/ */
object LoadSavegame { 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) { operator fun invoke(disk: VirtualDisk) {
val meta = ReadMeta(disk) val meta = ReadMeta(disk)
val player = ReadActor.readActorOnly( val player = ReadActor.readActorOnly(getFileReader(disk, 9545698)) as IngamePlayer
ByteArray64Reader(VDUtil.getAsNormalFile(disk, 9545698).getContent(), Common.CHARSET) val world = ReadWorld.readWorldOnly(getFileReader(disk, player.worldCurrentlyPlaying))
) as IngamePlayer val actors = world.actors.map { ReadActor.readActorOnly(getFileReader(disk, it)) }
val world = ReadWorld.readWorldOnly( val block = Common.jsoner.fromJson(BlockCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -16)))
ByteArray64Reader(VDUtil.getAsNormalFile(disk, player.worldCurrentlyPlaying).getContent(), Common.CHARSET) val item = Common.jsoner.fromJson(ItemCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -17)))
) val wire = Common.jsoner.fromJson(WireCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -18)))
val actors = world.actors.map { val material = Common.jsoner.fromJson(MaterialCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -19)))
ReadActor.readActorOnly(ByteArray64Reader(VDUtil.getAsNormalFile(disk, it).getContent(), Common.CHARSET)) 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 ingame = TerrarumIngame(AppLoader.batch)
val worldParam = meta val worldParam = TerrarumIngame.Codices(meta, block, item, wire, material, faction, apocryphas)
ingame.world = world ingame.world = world
ingame.gameLoadInfoPayload = worldParam ingame.gameLoadInfoPayload = worldParam
ingame.gameLoadMode = TerrarumIngame.GameLoadMode.LOAD_FROM ingame.gameLoadMode = TerrarumIngame.GameLoadMode.LOAD_FROM
@@ -123,4 +129,5 @@ object LoadSavegame {
val loadScreen = SanicLoadScreen val loadScreen = SanicLoadScreen
AppLoader.setLoadScreen(loadScreen) AppLoader.setLoadScreen(loadScreen)
} }
} }