From 9797094cae2ac9a4d348cdaca3f517f91b74163c Mon Sep 17 00:00:00 2001 From: minjaesong Date: Wed, 12 Jan 2022 11:10:57 +0900 Subject: [PATCH] savegames array itself is correctly sorted but the UI is not and lastmodified time is also not written --- src/net/torvald/terrarum/Terrarum.kt | 17 ++++----- .../modulebasegame/ui/UILoadDemoSavefiles.kt | 9 +++-- .../torvald/terrarum/savegame/DiskSkimmer.kt | 35 +++++++++++++++++-- .../torvald/terrarum/savegame/VirtualDisk.kt | 10 ++++-- .../terrarum/serialise/GameSavingThread.kt | 1 + 5 files changed, 57 insertions(+), 15 deletions(-) diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index b62542c7f..bd3797394 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -677,10 +677,10 @@ fun AppUpdateListOfSavegames() { App.savegameWorlds.clear() App.savegameWorldsName.clear() - println("listing savegames...") + println("Listing saved worlds...") // create list of worlds - (File(worldsDir).listFiles().filter { !it.isDirectory && !it.name.contains('.') }.mapNotNull { file -> + File(worldsDir).listFiles().filter { !it.isDirectory && !it.name.contains('.') }.mapNotNull { file -> try { DiskSkimmer(file, Common.CHARSET, true) } @@ -689,8 +689,8 @@ fun AppUpdateListOfSavegames() { e.printStackTrace() null } - }.sortedByDescending { it.getLastModifiedOfFirstFile() }).forEach { - println(it.diskFile.absolutePath) + }.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it -> + println("${index+1}.\t${it.diskFile.absolutePath}") it.rebuild() // disk skimmer was created without initialisation, so do it now // TODO write simple and dumb SAX parser for JSON @@ -702,8 +702,10 @@ fun AppUpdateListOfSavegames() { } + println("Listing saved players...") + // create list of players - (File(playersDir).listFiles().filter { !it.isDirectory && !it.name.contains('.') }.mapNotNull { file -> + File(playersDir).listFiles().filter { !it.isDirectory && !it.name.contains('.') }.mapNotNull { file -> try { DiskSkimmer(file, Common.CHARSET, true) } @@ -712,8 +714,8 @@ fun AppUpdateListOfSavegames() { e.printStackTrace() null } - }.sortedByDescending { it.getLastModifiedOfFirstFile() }).forEach { - println(it.diskFile.absolutePath) + }.sortedByDescending { it.getLastModifiedTime() }.forEachIndexed { index, it -> + println("${index+1}.\t${it.diskFile.absolutePath}") it.rebuild() // disk skimmer was created without initialisation, so do it now // TODO write simple and dumb SAX parser for JSON @@ -722,7 +724,6 @@ fun AppUpdateListOfSavegames() { val playerUUID = UUID.fromString(json.getString("uuid")) App.savegamePlayers[playerUUID] = it App.savegamePlayersName[playerUUID] = it.getDiskName(Common.CHARSET) -// App.savegamePlayersName[playerUUID] = json.get("actorValue")?.get(AVKey.NAME)?.asString() ?: "NULL!" } } diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt b/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt index c12db45d9..c32131b70 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt @@ -500,11 +500,14 @@ class UIItemPlayerCells( App.savegamePlayersName[playerUUID]?.let { if (it.isNotBlank()) playerName = it else "(name)" } App.savegameWorldsName[worldUUID]?.let { if (it.isNotBlank()) worldName = it } - json["lastPlayTime"]?.asString()?.let { + /*json["lastPlayTime"]?.asString()?.let { lastPlayTime = Instant.ofEpochSecond(it.toLong()) .atZone(TimeZone.getDefault().toZoneId()) .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) - } + }*/ + lastPlayTime = Instant.ofEpochSecond(skimmer.getLastModifiedTime()) + .atZone(TimeZone.getDefault().toZoneId()) + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) json["totalPlayTime"]?.asString()?.let { totalPlayTime = parseDuration(it.toLong()) } @@ -642,7 +645,7 @@ class UIItemWorldCells( if (metaFile != null) { val worldJson = JsonReader().parse(ByteArray64Reader(metaFile.bytes, Common.CHARSET)) - val lastplay_t = worldJson["lastPlayTime"].asLong() + val lastplay_t = skimmer.getLastModifiedTime()//worldJson["lastPlayTime"].asLong() val playtime_t = worldJson["totalPlayTime"].asLong() lastPlayedTimestamp = Instant.ofEpochSecond(lastplay_t) diff --git a/src/net/torvald/terrarum/savegame/DiskSkimmer.kt b/src/net/torvald/terrarum/savegame/DiskSkimmer.kt index 5a8ac9bf1..d4ceaab11 100644 --- a/src/net/torvald/terrarum/savegame/DiskSkimmer.kt +++ b/src/net/torvald/terrarum/savegame/DiskSkimmer.kt @@ -92,7 +92,7 @@ removefile: val fis = FileInputStream(diskFile) var currentPosition = fis.skip(VirtualDisk.HEADER_SIZE) // skip disk header - println("[DiskSkimmer] loading the diskfile ${diskFile.canonicalPath}") +// println("[DiskSkimmer] loading the diskfile ${diskFile.canonicalPath}") fun skipRead(bytes: Long) { currentPosition += fis.skip(bytes) @@ -353,13 +353,44 @@ removefile: return bytes.toCanonicalString(charset) } - fun getLastModifiedOfFirstFile(): Long { + /** + * @return creation time of the root directory + */ + fun getCreationTime(): Long { + val bytes = ByteArray(6) + fa.seek(320L) + fa.read(bytes) + return bytes.toInt48() + } + + /** + * @return last modified time of the root directory + */ + fun getLastModifiedTime(): Long { val bytes = ByteArray(6) fa.seek(326L) fa.read(bytes) return bytes.toInt48() } + /** + * redefines creation time of the root directory + */ + fun setCreationTime(time_t: Long) { + val bytes = ByteArray(6) + fa.seek(320L) + fa.write(time_t.toInt48()) + } + + /** + * redefines last modified time of the root directory + */ + fun setLastModifiedTime(time_t: Long) { + val bytes = ByteArray(6) + fa.seek(326L) + fa.write(time_t.toInt48()) + } + /////////////////////////////////////////////////////// // THESE ARE METHODS TO SUPPORT ON-LINE MODIFICATION // /////////////////////////////////////////////////////// diff --git a/src/net/torvald/terrarum/savegame/VirtualDisk.kt b/src/net/torvald/terrarum/savegame/VirtualDisk.kt index f1e51800c..9c81e18c3 100644 --- a/src/net/torvald/terrarum/savegame/VirtualDisk.kt +++ b/src/net/torvald/terrarum/savegame/VirtualDisk.kt @@ -148,9 +148,15 @@ class VirtualDisk( private fun serializeEntriesOnly(): ByteArray64 { val buffer = ByteArray64() + + // make sure to write root directory first + entries[0L]!!.let { rootDir -> + rootDir.serialize().forEach { buffer.add(it) } + } entries.forEach { - val serialised = it.value.serialize() - serialised.forEach { buffer.add(it) } + if (it.key != 0L) { + it.value.serialize().forEach { buffer.add(it) } + } } return buffer diff --git a/src/net/torvald/terrarum/serialise/GameSavingThread.kt b/src/net/torvald/terrarum/serialise/GameSavingThread.kt index 1d0463d7e..e5e9aa985 100644 --- a/src/net/torvald/terrarum/serialise/GameSavingThread.kt +++ b/src/net/torvald/terrarum/serialise/GameSavingThread.kt @@ -136,6 +136,7 @@ class WorldSavingThread( Echo("Writing file to disk...") + disk.entries[0]!!.creationDate = creation_t disk.entries[0]!!.modificationDate = time_t // entry zero MUST NOT be used to get lastPlayDate, but we'll update it anyway // use entry -1 for that purpose!