GameWorld: adding "worldIndex"; more save/load stuffs

This commit is contained in:
minjaesong
2018-10-03 23:15:24 +09:00
parent b380fa7ce7
commit 071dc85b94
14 changed files with 1301 additions and 58 deletions

View File

@@ -4,13 +4,12 @@ import net.torvald.terrarum.gameworld.BlockAddress
import net.torvald.terrarum.gameworld.BlockDamage
import net.torvald.terrarum.gameworld.MapLayer
import net.torvald.terrarum.gameworld.PairedMapLayer
import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension
import net.torvald.terrarum.realestate.LandUtil
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.DiskSkimmer.Companion.read
import java.io.*
import java.nio.charset.Charset
import java.util.*
import java.util.zip.Inflater
import java.util.zip.InflaterOutputStream
import kotlin.IllegalArgumentException
import kotlin.collections.HashMap
@@ -27,13 +26,6 @@ internal object ReadLayerDataZip {
val magicBytes = ByteArray(4)
val versionNumber = ByteArray(1)
val layerCount = ByteArray(1)
val payloadCountByte = ByteArray(1)
val compression = ByteArray(1)
val worldWidth = ByteArray(4)
val worldHeight = ByteArray(4)
val spawnAddress = ByteArray(6)
//////////////////
@@ -47,18 +39,16 @@ internal object ReadLayerDataZip {
throw IllegalArgumentException("File not a Layer Data")
}
inputStream.read(versionNumber)
inputStream.read(layerCount)
inputStream.read(payloadCountByte)
inputStream.read(compression)
inputStream.read(worldWidth)
inputStream.read(worldHeight)
inputStream.read(spawnAddress)
val versionNumber = inputStream.read(1)[0].toUint()
val layerCount = inputStream.read(1)[0].toUint()
val payloadCount = inputStream.read(1)[0].toUint()
val compression = inputStream.read(1)[0].toUint()
val width = inputStream.read(4).toLittleInt()
val height = inputStream.read(4).toLittleInt()
val spawnAddress = inputStream.read(6).toLittleInt48()
// read payloads
val payloadCount = payloadCountByte[0].toUint()
val pldBuffer4 = ByteArray(4)
val pldBuffer6 = ByteArray(6)
val pldBuffer8 = ByteArray(8)
@@ -114,8 +104,6 @@ internal object ReadLayerDataZip {
// END OF FILE READ //
//////////////////////
val width = worldWidth.toLittleInt()
val height = worldHeight.toLittleInt()
val worldSize = width.toLong() * height
val payloadBytes = HashMap<String, ByteArray>()
@@ -140,7 +128,7 @@ internal object ReadLayerDataZip {
}
}
val spawnPoint = LandUtil.resolveBlockAddr(width, spawnAddress.toLittleInt48())
val spawnPoint = LandUtil.resolveBlockAddr(width, spawnAddress)
val terrainDamages = HashMap<BlockAddress, BlockDamage>()
val wallDamages = HashMap<BlockAddress, BlockDamage>()

View File

@@ -0,0 +1,10 @@
package net.torvald.terrarum.serialise
/**
* Created by minjaesong on 2018-10-03.
*/
object SavegameLoader {
// TODO read TEVd, load necessary shits
}

View File

@@ -0,0 +1,60 @@
package net.torvald.terrarum.serialise
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.DiskEntry
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.DiskSkimmer
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.VDUtil
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.VirtualDisk
import java.io.File
import java.nio.charset.Charset
/**
* Created by minjaesong on 2018-10-03.
*/
object SavegameWriter {
// TODO create temporary files (worldinfo), create JSON files on RAM, pack those into TEVd as per Savegame container.txt
private val charset = Charset.forName("UTF-8")
operator fun invoke(): Boolean {
val diskImage = generateDiskImage(null)
return false
}
private fun generateDiskImage(oldDiskFile: File?): VirtualDisk {
val disk = VDUtil.createNewDisk(0x7FFFFFFFFFFFFFFFL, "TerrarumSave", charset)
val oldDiskSkimmer = oldDiskFile?.let { DiskSkimmer(oldDiskFile) }
val ROOT = disk.root.entryID
val ingame = Terrarum.ingame!!
val gameworld = ingame.world
// serialise current world (stage)
val world = WriteLayerDataZip() // filename can be anything that is "tmp_world[n]" where [n] is any number
val worldFile = VDUtil.importFile(world!!, gameworld.worldIndex, charset)
// add current world (stage) to the disk
VDUtil.addFile(disk, ROOT, worldFile)
// put other worlds (stages) to the disk (without loading whole oldDiskFile onto the disk)
oldDiskSkimmer?.let {
// skim-and-write other worlds
for (c in 1..ingame.gameworldCount) {
if (c != gameworld.worldIndex) {
val oldWorldFile = oldDiskSkimmer.requestFile(c)
VDUtil.addFile(disk, ROOT, oldWorldFile!!)
}
}
}
// TODO world[n] is done, needs whole other things
return disk
}
}

View File

@@ -14,7 +14,12 @@ import java.util.zip.DeflaterOutputStream
import java.util.zip.GZIPOutputStream
/**
* TODO this one does not use TerranVirtualDisk
* This object only writes a file named 'worldinfo1'.
*
* The intended operation is as follows:
* 1. This and others write
*
* TODO temporarily dump on the disk THEN pack? Or put all the files (in ByteArray64) in the RAM THEN pack?
*
* Created by minjaesong on 2016-03-18.
*/
@@ -23,7 +28,7 @@ internal object WriteLayerDataZip {
// FIXME UNTESTED !!
val LAYERS_FILENAME = "worldinfo1"
val LAYERS_FILENAME = "world"
val MAGIC = byteArrayOf(0x54, 0x45, 0x4D, 0x7A)
val VERSION_NUMBER = 3.toByte()
@@ -34,29 +39,36 @@ internal object WriteLayerDataZip {
val PAYLOAD_FOOTER = byteArrayOf(0x45, 0x6E, 0x64, 0x50, 0x59, 0x4C, 0x64, -1)
val FILE_FOOTER = byteArrayOf(0x45, 0x6E, 0x64, 0x54, 0x45, 0x4D, -1, -2)
val NULL: Byte = 0
//val NULL: Byte = 0
internal operator fun invoke(saveDirectoryName: String): Boolean {
val path = "${Terrarum.defaultSaveDir}/$saveDirectoryName/${LAYERS_FILENAME}"
val tempPath = "${path}_bak"
/**
* TODO currently it'll dump the temporary file (tmp_worldinfo1) onto the disk and will return the temp file.
*
* @return File on success; `null` on failure
*/
internal operator fun invoke(): File? {
val world = (Terrarum.ingame!!.world)
val parentDir = File("${Terrarum.defaultSaveDir}/$saveDirectoryName")
val path = "${Terrarum.defaultSaveDir}/tmp_$LAYERS_FILENAME${world.worldIndex}"
// TODO let's try dump-on-the-disk-then-pack method...
/*val parentDir = File("${Terrarum.defaultSaveDir}/$saveDirectoryName")
if (!parentDir.exists()) {
parentDir.mkdir()
}
else if (!parentDir.isDirectory) {
EchoError("Savegame directory is not actually a directory, aborting...")
return false
}
}*/
val tempFile = File(tempPath)
val outFile = File(path)
tempFile.createNewFile()
if (outFile.exists()) outFile.delete()
outFile.createNewFile()
val outputStream = BufferedOutputStream(FileOutputStream(tempFile), 8192)
val outputStream = BufferedOutputStream(FileOutputStream(outFile), 8192)
val deflater = DeflaterOutputStream(outputStream, true)
fun wb(byteArray: ByteArray) { outputStream.write(byteArray) }
@@ -152,12 +164,8 @@ internal object WriteLayerDataZip {
outputStream.flush()
outputStream.close()
outFile.delete()
tempFile.copyTo(outFile, overwrite = true)
tempFile.delete()
println("Saved map data '$LAYERS_FILENAME' to $saveDirectoryName.")
return true
return outFile
}
catch (e: IOException) {
e.printStackTrace()
@@ -166,7 +174,7 @@ internal object WriteLayerDataZip {
outputStream.close()
}
return false
return null
}