mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-06 08:38:30 +09:00
recording and retrieving timestamps for save meta and world
This commit is contained in:
@@ -13,8 +13,8 @@ import net.torvald.terrarum.modulebasegame.IngameRenderer
|
|||||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
||||||
import net.torvald.terrarum.modulebasegame.ui.Notification
|
import net.torvald.terrarum.modulebasegame.ui.Notification
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UITooltip
|
import net.torvald.terrarum.modulebasegame.ui.UITooltip
|
||||||
import net.torvald.terrarum.tvda.VirtualDisk
|
|
||||||
import net.torvald.terrarum.realestate.LandUtil
|
import net.torvald.terrarum.realestate.LandUtil
|
||||||
|
import net.torvald.terrarum.tvda.VirtualDisk
|
||||||
import net.torvald.terrarum.ui.ConsoleWindow
|
import net.torvald.terrarum.ui.ConsoleWindow
|
||||||
import net.torvald.util.SortedArrayList
|
import net.torvald.util.SortedArrayList
|
||||||
import org.khelekore.prtree.*
|
import org.khelekore.prtree.*
|
||||||
@@ -120,6 +120,10 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
|||||||
|
|
||||||
val modifiedChunks = Array(16) { HashSet<Int>() }
|
val modifiedChunks = Array(16) { HashSet<Int>() }
|
||||||
|
|
||||||
|
internal var creationTime = App.getTIME_T() // cumulative value for the savegame
|
||||||
|
internal var lastPlayTime = App.getTIME_T() // cumulative value for the savegame
|
||||||
|
internal var totalPlayTime = 0L // cumulative value for the savegame
|
||||||
|
|
||||||
var loadedTime_t = App.getTIME_T()
|
var loadedTime_t = App.getTIME_T()
|
||||||
protected set
|
protected set
|
||||||
|
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
printdbg(this, "Demo world loaded")
|
printdbg(this, "Demo world loaded")
|
||||||
}
|
}
|
||||||
catch (e: IOException) {
|
catch (e: IOException) {
|
||||||
demoWorld = GameWorld(1, LandUtil.CHUNK_W, LandUtil.CHUNK_H, 0L, 0L, 0)
|
demoWorld = GameWorld(1, LandUtil.CHUNK_W, LandUtil.CHUNK_H, 0L, 0L)
|
||||||
printdbg(this, "Demo world not found, using empty world")
|
printdbg(this, "Demo world not found, using empty world")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,12 +43,15 @@ open class GameWorld() : Disposable {
|
|||||||
var width: Int = 999; private set
|
var width: Int = 999; private set
|
||||||
var height: Int = 999; private set
|
var height: Int = 999; private set
|
||||||
|
|
||||||
var creationTime: Long = App.getTIME_T()
|
/** Creation time for this world, NOT the entire savegame */
|
||||||
|
internal var creationTime: Long = App.getTIME_T()
|
||||||
internal set
|
internal set
|
||||||
var lastPlayTime: Long = App.getTIME_T()
|
/** Creation time for this world, NOT the entire savegame */
|
||||||
|
internal var lastPlayTime: Long = App.getTIME_T()
|
||||||
internal set // there's a case of save-and-continue-playing
|
internal set // there's a case of save-and-continue-playing
|
||||||
var totalPlayTime: Long = 0
|
/** Creation time for this world, NOT the entire savegame */
|
||||||
internal set
|
internal var totalPlayTime = 0L // cumulative value for this very world
|
||||||
|
|
||||||
|
|
||||||
//layers
|
//layers
|
||||||
@Transient lateinit open var layerWall: BlockLayer
|
@Transient lateinit open var layerWall: BlockLayer
|
||||||
@@ -116,7 +119,7 @@ open class GameWorld() : Disposable {
|
|||||||
/**
|
/**
|
||||||
* Create new world
|
* Create new world
|
||||||
*/
|
*/
|
||||||
constructor(worldIndex: Int, width: Int, height: Int, creationTIME_T: Long, lastPlayTIME_T: Long, totalPlayTime: Long): this() {
|
constructor(worldIndex: Int, width: Int, height: Int, creationTIME_T: Long, lastPlayTIME_T: Long): this() {
|
||||||
if (width <= 0 || height <= 0) throw IllegalArgumentException("Non-positive width/height: ($width, $height)")
|
if (width <= 0 || height <= 0) throw IllegalArgumentException("Non-positive width/height: ($width, $height)")
|
||||||
|
|
||||||
this.worldIndex = worldIndex
|
this.worldIndex = worldIndex
|
||||||
@@ -138,7 +141,6 @@ open class GameWorld() : Disposable {
|
|||||||
|
|
||||||
creationTime = creationTIME_T
|
creationTime = creationTIME_T
|
||||||
lastPlayTime = lastPlayTIME_T
|
lastPlayTime = lastPlayTIME_T
|
||||||
this.totalPlayTime = totalPlayTime
|
|
||||||
|
|
||||||
|
|
||||||
App.tileMaker.tags.forEach {
|
App.tileMaker.tags.forEach {
|
||||||
@@ -668,7 +670,7 @@ open class GameWorld() : Disposable {
|
|||||||
|
|
||||||
fun makeNullWorld(): GameWorld {
|
fun makeNullWorld(): GameWorld {
|
||||||
if (nullWorldInstance == null)
|
if (nullWorldInstance == null)
|
||||||
nullWorldInstance = GameWorld(1, 1, 1, 0, 0, 0)
|
nullWorldInstance = GameWorld(1, 1, 1, 0, 0)
|
||||||
|
|
||||||
return nullWorldInstance!!
|
return nullWorldInstance!!
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
private val timeNow = System.currentTimeMillis() / 1000
|
private val timeNow = System.currentTimeMillis() / 1000
|
||||||
|
|
||||||
val gameWorld = GameWorld(1, 1024, 256, timeNow, timeNow, 0)
|
val gameWorld = GameWorld(1, 1024, 256, timeNow, timeNow)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// ghetto world for building
|
// ghetto world for building
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
// init map as chosen size
|
// init map as chosen size
|
||||||
val timeNow = App.getTIME_T()
|
val timeNow = App.getTIME_T()
|
||||||
world = GameWorld(1, worldParams.width, worldParams.height, timeNow, timeNow, 0) // new game, so the creation time is right now
|
world = GameWorld(1, worldParams.width, worldParams.height, timeNow, timeNow) // new game, so the creation time is right now
|
||||||
world.generatorSeed = worldParams.worldGenSeed
|
world.generatorSeed = worldParams.worldGenSeed
|
||||||
gameworldIndices.add(world.worldIndex)
|
gameworldIndices.add(world.worldIndex)
|
||||||
world.extraFields["basegame.economy"] = GameEconomy()
|
world.extraFields["basegame.economy"] = GameEconomy()
|
||||||
|
|||||||
@@ -18,8 +18,7 @@ import java.io.IOException
|
|||||||
object ExportMeta : ConsoleCommand {
|
object ExportMeta : ConsoleCommand {
|
||||||
override fun execute(args: Array<String>) {
|
override fun execute(args: Array<String>) {
|
||||||
try {
|
try {
|
||||||
val currentPlayTime_t = App.getTIME_T() - ingame!!.loadedTime_t
|
val str = WriteMeta(ingame!! as TerrarumIngame, App.getTIME_T())
|
||||||
val str = WriteMeta(ingame!! as TerrarumIngame, currentPlayTime_t)
|
|
||||||
val writer = java.io.FileWriter(App.defaultDir + "/Exports/savegame.json", false)
|
val writer = java.io.FileWriter(App.defaultDir + "/Exports/savegame.json", false)
|
||||||
writer.write(str)
|
writer.write(str)
|
||||||
writer.close()
|
writer.close()
|
||||||
@@ -40,7 +39,7 @@ object ExportWorld : ConsoleCommand {
|
|||||||
override fun execute(args: Array<String>) {
|
override fun execute(args: Array<String>) {
|
||||||
if (args.size == 2) {
|
if (args.size == 2) {
|
||||||
try {
|
try {
|
||||||
val str = WriteWorld(ingame!! as TerrarumIngame)
|
val str = WriteWorld(ingame!! as TerrarumIngame, App.getTIME_T())
|
||||||
val writer = java.io.FileWriter(App.defaultDir + "/Exports/${args[1]}.json", false)
|
val writer = java.io.FileWriter(App.defaultDir + "/Exports/${args[1]}.json", false)
|
||||||
writer.write(str)
|
writer.write(str)
|
||||||
writer.close()
|
writer.close()
|
||||||
|
|||||||
@@ -45,8 +45,9 @@ class UILoadDemoSavefiles : UICanvas() {
|
|||||||
}
|
}
|
||||||
catch (e: Throwable) {
|
catch (e: Throwable) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
null
|
||||||
}
|
}
|
||||||
}.sortedByDescending { (it as VirtualDisk).entries[0]!!.modificationDate }.forEachIndexed { index, disk ->
|
}.filter { it != null }.sortedByDescending { (it as VirtualDisk).entries[0]!!.modificationDate }.forEachIndexed { index, disk ->
|
||||||
val x = (width - UIItemDemoSaveCells.WIDTH) / 2
|
val x = (width - UIItemDemoSaveCells.WIDTH) / 2
|
||||||
val y = 144 + (24 + UIItemDemoSaveCells.HEIGHT) * index
|
val y = 144 + (24 + UIItemDemoSaveCells.HEIGHT) * index
|
||||||
addUIitem(UIItemDemoSaveCells(this, x, y, disk as VirtualDisk))
|
addUIitem(UIItemDemoSaveCells(this, x, y, disk as VirtualDisk))
|
||||||
@@ -102,9 +103,21 @@ class UIItemDemoSaveCells(
|
|||||||
private val x = initialX.toFloat()
|
private val x = initialX.toFloat()
|
||||||
private val y = initialY.toFloat()
|
private val y = initialY.toFloat()
|
||||||
|
|
||||||
|
private fun parseDuration(seconds: Long): String {
|
||||||
|
val s = seconds % 60
|
||||||
|
val m = (seconds / 60) % 60
|
||||||
|
val h = (seconds / 3600) % 24
|
||||||
|
val d = seconds / 86400
|
||||||
|
return if (d == 0L)
|
||||||
|
"${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s"
|
||||||
|
else
|
||||||
|
"${d}d${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s"
|
||||||
|
}
|
||||||
|
|
||||||
private val lastPlayedTimestamp = Instant.ofEpochSecond(meta.lastplay_t)
|
private val lastPlayedTimestamp = Instant.ofEpochSecond(meta.lastplay_t)
|
||||||
.atZone(TimeZone.getDefault().toZoneId())
|
.atZone(TimeZone.getDefault().toZoneId())
|
||||||
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
|
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +
|
||||||
|
"/${parseDuration(meta.playtime_t)}"
|
||||||
|
|
||||||
init {
|
init {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.terrarum.serialise
|
package net.torvald.terrarum.serialise
|
||||||
|
|
||||||
|
import net.torvald.terrarum.App
|
||||||
import net.torvald.terrarum.ModMgr
|
import net.torvald.terrarum.ModMgr
|
||||||
import net.torvald.terrarum.gameactors.ActorID
|
import net.torvald.terrarum.gameactors.ActorID
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
@@ -15,8 +16,9 @@ import net.torvald.terrarum.weather.WeatherMixer
|
|||||||
*/
|
*/
|
||||||
object WriteMeta {
|
object WriteMeta {
|
||||||
|
|
||||||
operator fun invoke(ingame: TerrarumIngame, currentPlayTime_t: Long): String {
|
operator fun invoke(ingame: TerrarumIngame, time_t: Long): String {
|
||||||
val world = ingame.world
|
val world = ingame.world
|
||||||
|
val currentPlayTime_t = time_t - ingame.loadedTime_t
|
||||||
|
|
||||||
val meta = WorldMeta(
|
val meta = WorldMeta(
|
||||||
genver = Common.GENVER,
|
genver = Common.GENVER,
|
||||||
@@ -26,9 +28,9 @@ object WriteMeta {
|
|||||||
weatseed0 = WeatherMixer.RNG.state0,
|
weatseed0 = WeatherMixer.RNG.state0,
|
||||||
weatseed1 = WeatherMixer.RNG.state1,
|
weatseed1 = WeatherMixer.RNG.state1,
|
||||||
playerid = ingame.actorGamer.referenceID,
|
playerid = ingame.actorGamer.referenceID,
|
||||||
creation_t = world.creationTime,
|
creation_t = ingame.creationTime,
|
||||||
lastplay_t = world.lastPlayTime,
|
lastplay_t = App.getTIME_T(),
|
||||||
playtime_t = world.totalPlayTime + currentPlayTime_t,
|
playtime_t = ingame.totalPlayTime + currentPlayTime_t,
|
||||||
loadorder = ModMgr.loadOrder.toTypedArray(),
|
loadorder = ModMgr.loadOrder.toTypedArray(),
|
||||||
worlds = ingame.gameworldIndices.toTypedArray()
|
worlds = ingame.gameworldIndices.toTypedArray()
|
||||||
)
|
)
|
||||||
@@ -36,9 +38,9 @@ object WriteMeta {
|
|||||||
return Common.jsoner.toJson(meta)
|
return Common.jsoner.toJson(meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun encodeToByteArray64(ingame: TerrarumIngame, currentPlayTime_t: Long): ByteArray64 {
|
fun encodeToByteArray64(ingame: TerrarumIngame, time_t: Long): ByteArray64 {
|
||||||
val ba = ByteArray64()
|
val ba = ByteArray64()
|
||||||
this.invoke(ingame, currentPlayTime_t).toByteArray(Common.CHARSET).forEach { ba.add(it) }
|
this.invoke(ingame, time_t).toByteArray(Common.CHARSET).forEach { ba.add(it) }
|
||||||
return ba
|
return ba
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,13 +46,12 @@ object WriteSavegame {
|
|||||||
p.dispose()
|
p.dispose()
|
||||||
|
|
||||||
|
|
||||||
val creation_t = ingame.world.creationTime
|
val creation_t = ingame.creationTime
|
||||||
val time_t = App.getTIME_T()
|
val time_t = App.getTIME_T()
|
||||||
val currentPlayTime_t = time_t - ingame.loadedTime_t
|
|
||||||
|
|
||||||
|
|
||||||
// Write Meta //
|
// Write Meta //
|
||||||
val metaContent = EntryFile(WriteMeta.encodeToByteArray64(ingame, currentPlayTime_t))
|
val metaContent = EntryFile(WriteMeta.encodeToByteArray64(ingame, time_t))
|
||||||
val meta = DiskEntry(-1, 0, creation_t, time_t, metaContent)
|
val meta = DiskEntry(-1, 0, creation_t, time_t, metaContent)
|
||||||
addFile(disk, meta)
|
addFile(disk, meta)
|
||||||
|
|
||||||
@@ -98,7 +97,7 @@ object WriteSavegame {
|
|||||||
|
|
||||||
// Write World //
|
// Write World //
|
||||||
val worldNum = ingame.world.worldIndex
|
val worldNum = ingame.world.worldIndex
|
||||||
val worldMeta = EntryFile(WriteWorld.encodeToByteArray64(ingame))
|
val worldMeta = EntryFile(WriteWorld.encodeToByteArray64(ingame, time_t))
|
||||||
val world = DiskEntry(worldNum.toLong(), 0, creation_t, time_t, worldMeta)
|
val world = DiskEntry(worldNum.toLong(), 0, creation_t, time_t, worldMeta)
|
||||||
addFile(disk, world)
|
addFile(disk, world)
|
||||||
|
|
||||||
@@ -182,6 +181,9 @@ object LoadSavegame {
|
|||||||
newIngame.gameLoadInfoPayload = worldParam
|
newIngame.gameLoadInfoPayload = worldParam
|
||||||
newIngame.gameLoadMode = TerrarumIngame.GameLoadMode.LOAD_FROM
|
newIngame.gameLoadMode = TerrarumIngame.GameLoadMode.LOAD_FROM
|
||||||
newIngame.savegameArchive = disk
|
newIngame.savegameArchive = disk
|
||||||
|
newIngame.creationTime = meta.creation_t
|
||||||
|
newIngame.lastPlayTime = meta.lastplay_t
|
||||||
|
newIngame.totalPlayTime = meta.playtime_t
|
||||||
|
|
||||||
// load all the world blocklayer chunks
|
// load all the world blocklayer chunks
|
||||||
val worldnum = world.worldIndex.toLong()
|
val worldnum = world.worldIndex.toLong()
|
||||||
|
|||||||
@@ -25,10 +25,14 @@ object WriteWorld {
|
|||||||
actor != (CommonResourcePool.get("blockmarking_actor") as BlockMarkerActor)
|
actor != (CommonResourcePool.get("blockmarking_actor") as BlockMarkerActor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun preWrite(ingame: TerrarumIngame): GameWorld {
|
private fun preWrite(ingame: TerrarumIngame, time_t: Long): GameWorld {
|
||||||
val world = ingame.world
|
val world = ingame.world
|
||||||
|
val currentPlayTime_t = time_t - ingame.loadedTime_t
|
||||||
|
|
||||||
world.genver = Common.GENVER
|
world.genver = Common.GENVER
|
||||||
world.comp = Common.COMP_GZIP
|
world.comp = Common.COMP_GZIP
|
||||||
|
world.lastPlayTime = time_t
|
||||||
|
world.totalPlayTime += currentPlayTime_t
|
||||||
|
|
||||||
val actorIDbuf = ArrayList<ActorID>()
|
val actorIDbuf = ArrayList<ActorID>()
|
||||||
ingame.actorContainerActive.filter { actorAcceptable(it) }.forEach { actorIDbuf.add(it.referenceID) }
|
ingame.actorContainerActive.filter { actorAcceptable(it) }.forEach { actorIDbuf.add(it.referenceID) }
|
||||||
@@ -40,14 +44,14 @@ object WriteWorld {
|
|||||||
return world
|
return world
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun invoke(ingame: TerrarumIngame): String {
|
operator fun invoke(ingame: TerrarumIngame, time_t: Long): String {
|
||||||
return Common.jsoner.toJson(preWrite(ingame))
|
return Common.jsoner.toJson(preWrite(ingame, time_t))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun encodeToByteArray64(ingame: TerrarumIngame): ByteArray64 {
|
fun encodeToByteArray64(ingame: TerrarumIngame, time_t: Long): ByteArray64 {
|
||||||
val baw = ByteArray64Writer(Common.CHARSET)
|
val baw = ByteArray64Writer(Common.CHARSET)
|
||||||
|
|
||||||
Common.jsoner.toJson(preWrite(ingame), baw)
|
Common.jsoner.toJson(preWrite(ingame, time_t), baw)
|
||||||
baw.flush(); baw.close()
|
baw.flush(); baw.close()
|
||||||
|
|
||||||
return baw.toByteArray64()
|
return baw.toByteArray64()
|
||||||
|
|||||||
Reference in New Issue
Block a user