seemingly working savewriter with fixed TEVD

This commit is contained in:
minjaesong
2019-02-23 05:03:20 +09:00
parent a10d54c314
commit 8ffdf5fbc5
8 changed files with 124 additions and 40 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -58,7 +58,7 @@ object CommandDict {
"imtest" to JavaIMTest, "imtest" to JavaIMTest,
"cheatmotherfuckernootnoot" to CheatWarnTest, "cheatmotherfuckernootnoot" to CheatWarnTest,
"spawnlunarlander" to SpawnPhysTestLunarLander, "spawnlunarlander" to SpawnPhysTestLunarLander,
"savetest" to SavegameWriterTest,
/* !! */"exportlayer" to ExportLayerData, /* !! */"exportlayer" to ExportLayerData,
/* !! */"importlayer" to ImportLayerData, /* !! */"importlayer" to ImportLayerData,

View File

@@ -1,11 +1,11 @@
package net.torvald.terrarum.modulebasegame.console package net.torvald.terrarum.modulebasegame.console
import com.google.gson.GsonBuilder
import net.torvald.terrarum.AppLoader import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.console.ConsoleCommand import net.torvald.terrarum.console.ConsoleCommand
import net.torvald.terrarum.console.Echo import net.torvald.terrarum.console.Echo
import net.torvald.terrarum.modulebasegame.Ingame import net.torvald.terrarum.modulebasegame.Ingame
import net.torvald.terrarum.serialise.SavegameWriter
import java.io.BufferedWriter import java.io.BufferedWriter
import java.io.FileWriter import java.io.FileWriter
import java.io.IOException import java.io.IOException
@@ -17,18 +17,7 @@ internal object GsonTest : ConsoleCommand {
override fun execute(args: Array<String>) { override fun execute(args: Array<String>) {
if (args.size == 2) { if (args.size == 2) {
val jsonBuilder = if (AppLoader.IS_DEVELOPMENT_BUILD) { val jsonBuilder = SavegameWriter.getJsonBuilder()
GsonBuilder()
.setPrettyPrinting()
.serializeNulls()
.create()
}
else {
GsonBuilder()
.serializeNulls()
.create()
}
val jsonString = jsonBuilder.toJson((Terrarum.ingame!! as Ingame).actorNowPlaying) val jsonString = jsonBuilder.toJson((Terrarum.ingame!! as Ingame).actorNowPlaying)

View File

@@ -0,0 +1,23 @@
package net.torvald.terrarum.modulebasegame.console
import net.torvald.terrarum.console.ConsoleCommand
import net.torvald.terrarum.console.Echo
import net.torvald.terrarum.console.EchoError
import net.torvald.terrarum.serialise.SavegameWriter
/**
* Created by minjaesong on 2019-02-22.
*/
internal object SavegameWriterTest: ConsoleCommand {
override fun execute(args: Array<String>) {
val r = SavegameWriter.invoke(args.getOrNull(1))
if (!r) {
EchoError("Saving failed")
}
}
override fun printUsage() {
Echo("savetest [optional out name}")
}
}

View File

@@ -1,7 +1,7 @@
package net.torvald.terrarum.serialise package net.torvald.terrarum.serialise
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import com.google.gson.Gson import com.google.gson.GsonBuilder
import net.torvald.terrarum.AppLoader import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameactors.AVKey
@@ -24,8 +24,8 @@ object SavegameWriter {
private lateinit var playerName: String private lateinit var playerName: String
operator fun invoke(): Boolean { operator fun invoke(pnameOverride: String? = null): Boolean {
playerName = "${Terrarum.ingame!!.actorGamer!!.actorValue[AVKey.NAME]}" playerName = pnameOverride ?: "${Terrarum.ingame!!.actorGamer!!.actorValue[AVKey.NAME]}"
if (playerName.isEmpty()) playerName = "Test subject ${Math.random().times(0x7FFFFFFF).roundInt()}" if (playerName.isEmpty()) playerName = "Test subject ${Math.random().times(0x7FFFFFFF).roundInt()}"
try { try {
@@ -58,6 +58,14 @@ object SavegameWriter {
throw Error("Serialising world failed") throw Error("Serialising world failed")
} }
if (!worldBytes.sliceArray(0..3).contentEquals(WriteLayerDataZip.MAGIC)) {
worldBytes.forEach {
print(it.toUInt().and(255u).toString(16).toUpperCase().padStart(2, '0'))
print(' ')
}; println()
throw Error()
}
// add current world (stage) to the disk // add current world (stage) to the disk
VDUtil.registerFile(disk, DiskEntry( VDUtil.registerFile(disk, DiskEntry(
gameworld.worldIndex, ROOT, gameworld.worldIndex, ROOT,
@@ -91,7 +99,7 @@ object SavegameWriter {
// actors // actors
ingame.actorContainerActive.forEach { ingame.actorContainerActive.forEach {
VDUtil.registerFile(disk, DiskEntry( VDUtil.registerFile(disk, DiskEntry(
gameworld.worldIndex, ROOT, it.referenceID!!, ROOT,
it.referenceID!!.toString(16).toUpperCase().toByteArray(charset), it.referenceID!!.toString(16).toUpperCase().toByteArray(charset),
creationDate, creationDate, creationDate, creationDate,
EntryFile(serialiseActor(it)) EntryFile(serialiseActor(it))
@@ -99,7 +107,7 @@ object SavegameWriter {
} }
ingame.actorContainerInactive.forEach { ingame.actorContainerInactive.forEach {
VDUtil.registerFile(disk, DiskEntry( VDUtil.registerFile(disk, DiskEntry(
gameworld.worldIndex, ROOT, it.referenceID!!, ROOT,
it.referenceID!!.toString(16).toUpperCase().toByteArray(charset), it.referenceID!!.toString(16).toUpperCase().toByteArray(charset),
creationDate, creationDate, creationDate, creationDate,
EntryFile(serialiseActor(it)) EntryFile(serialiseActor(it))
@@ -109,7 +117,7 @@ object SavegameWriter {
// items // items
ItemCodex.dynamicItemDescription.forEach { dynamicID, item -> ItemCodex.dynamicItemDescription.forEach { dynamicID, item ->
VDUtil.registerFile(disk, DiskEntry( VDUtil.registerFile(disk, DiskEntry(
gameworld.worldIndex, ROOT, item.dynamicID, ROOT,
dynamicID.toString(16).toUpperCase().toByteArray(charset), dynamicID.toString(16).toUpperCase().toByteArray(charset),
creationDate, creationDate, creationDate, creationDate,
EntryFile(serialiseItem(item)) EntryFile(serialiseItem(item))
@@ -125,13 +133,26 @@ object SavegameWriter {
TODO() TODO()
} }
fun getJsonBuilder() = if (AppLoader.IS_DEVELOPMENT_BUILD) {
GsonBuilder()
.setPrettyPrinting()
.serializeNulls()
.create()
}
else {
GsonBuilder()
.serializeNulls()
.create()
}
private fun serialiseActor(a: Actor): ByteArray64 { private fun serialiseActor(a: Actor): ByteArray64 {
val gson = Gson().toJsonTree(a).toString().toByteArray(charset) val gson = getJsonBuilder().toJson(a).toByteArray(charset)
return ByteArray64.fromByteArray(gson) return ByteArray64.fromByteArray(gson)
} }
private fun serialiseItem(i: GameItem): ByteArray64 { private fun serialiseItem(i: GameItem): ByteArray64 {
val gson = Gson().toJsonTree(i).toString().toByteArray(charset) val gson = getJsonBuilder().toJson(i).toByteArray(charset)
return ByteArray64.fromByteArray(gson) return ByteArray64.fromByteArray(gson)
} }
} }

View File

@@ -4,7 +4,6 @@ import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64 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.realestate.LandUtil import net.torvald.terrarum.realestate.LandUtil
import java.io.IOException
import java.util.zip.Deflater import java.util.zip.Deflater
import java.util.zip.DeflaterOutputStream import java.util.zip.DeflaterOutputStream
@@ -99,12 +98,13 @@ internal object WriteLayerDataZip {
wi48(LandUtil.getBlockAddr(world, world.spawnX, world.spawnY)) wi48(LandUtil.getBlockAddr(world, world.spawnX, world.spawnY))
// write payloads // // write payloads //
outputStream.flush()
// TERR payload // TERR payload
// PRO Debug tip: every deflated bytes must begin with 0x789C or 0x78DA // PRO Debug tip: every deflated bytes must begin with 0x789C or 0x78DA
// Thus, \0pLd + [10] must be either of these. // Thus, \0pLd + [10] must be either of these.
// TODO serialised payloads have bit too much zeros, should I be worried?
wb(PAYLOAD_HEADER); wb("TERR".toByteArray()) wb(PAYLOAD_HEADER); wb("TERR".toByteArray())
wi48(world.width * world.height * 3L / 2) wi48(world.width * world.height * 3L / 2)
deflater = DeflaterOutputStream(outputStream, Deflater(Deflater.BEST_COMPRESSION), true) deflater = DeflaterOutputStream(outputStream, Deflater(Deflater.BEST_COMPRESSION), true)
@@ -187,8 +187,6 @@ internal object WriteLayerDataZip {
wb(PAYLOAD_FOOTER) wb(PAYLOAD_FOOTER)
// write footer // write footer
wb(FILE_FOOTER) wb(FILE_FOOTER)
@@ -197,21 +195,10 @@ internal object WriteLayerDataZip {
// END OF WRITE // // END OF WRITE //
////////////////// //////////////////
try { outputStream.flush()
outputStream.flush() outputStream.close()
outputStream.close()
return outputStream.toByteArray64()
return outputStream.toByteArray64()
}
catch (e: IOException) {
e.printStackTrace()
}
finally {
outputStream.close()
}
return null
} }

View File

@@ -0,0 +1,64 @@
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64GrowableOutputStream
import net.torvald.terrarum.serialise.WriteLayerDataZip
import net.torvald.terrarum.serialise.toLittle
import net.torvald.terrarum.serialise.toULittle48
import java.util.zip.Deflater
import java.util.zip.DeflaterOutputStream
/**
* Created by minjaesong on 2019-02-22.
*/
object ByteArray64Test {
val testOut1 = "TESTING ".toByteArray()
val testOut2 = byteArrayOf(-1, -2)
val testOut3 = """According to all known laws of aviation, there is no way a bee should be able to fly.
Its wings are too small to get its fat little body off the ground.
The bee, of course, flies anyway because bees don't care what humans think is impossible.
Yellow, black. Yellow, black. Yellow, black. Yellow, black.
Ooh, black and yellow! Let's shake it up a little.""".trimIndent().toByteArray()
operator fun invoke() {
val outputStream = ByteArray64GrowableOutputStream(16)
fun wb(byteArray: ByteArray) { outputStream.write(byteArray) }
fun wb(byte: Byte) { outputStream.write(byte.toInt()) }
//fun wb(byte: Int) { outputStream.write(byte) }
fun wi32(int: Int) { wb(int.toLittle()) }
fun wi48(long: Long) { wb(long.toULittle48()) }
fun wi64(long: Long) { wb(long.toLittle()) }
fun wf32(float: Float) { wi32(float.toRawBits()) }
wb(WriteLayerDataZip.MAGIC); wb(WriteLayerDataZip.VERSION_NUMBER); wb(WriteLayerDataZip.NUMBER_OF_LAYERS); wb(WriteLayerDataZip.NUMBER_OF_PAYLOADS); wb(WriteLayerDataZip.COMPRESSION_ALGORITHM); wb(WriteLayerDataZip.GENERATOR_VERSION)
val deflater = DeflaterOutputStream(outputStream, Deflater(Deflater.BEST_COMPRESSION), true)
repeat(20001) {
deflater.write(Math.random().times(256).toInt().and(255))
}
deflater.flush(); deflater.finish()
wb(testOut2)
outputStream.flush()
outputStream.close()
val osa = outputStream.toByteArray64()
osa.forEach {
print(it.toUInt().and(255u).toString(16).toUpperCase().padStart(2, '0'))
print(' ')
}
println()
osa.forEach {
print(it.toChar())
}
println()
}
}
fun main() {
ByteArray64Test.invoke()
}