mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-14 04:24:05 +09:00
added snapshot to versioning scheme
This commit is contained in:
@@ -64,8 +64,11 @@ public class App implements ApplicationListener {
|
|||||||
public static final String VERSION_TAG = TerrarumAppConfiguration.VERSION_TAG;
|
public static final String VERSION_TAG = TerrarumAppConfiguration.VERSION_TAG;
|
||||||
|
|
||||||
public static final String getVERSION_STRING() {
|
public static final String getVERSION_STRING() {
|
||||||
|
|
||||||
|
var snap = TerrarumAppConfiguration.INSTANCE.getVERSION_SNAPSHOT();
|
||||||
|
|
||||||
return String.format("%d.%d.%d", VERSION_RAW >>> 48, (VERSION_RAW & 0xffff000000L) >>> 24, VERSION_RAW & 0xffffffL) +
|
return String.format("%d.%d.%d", VERSION_RAW >>> 48, (VERSION_RAW & 0xffff000000L) >>> 24, VERSION_RAW & 0xffffffL) +
|
||||||
(VERSION_TAG.isBlank() ? "" : "-"+VERSION_TAG);
|
(VERSION_TAG.isBlank() ? "" : "-"+VERSION_TAG) + (snap == null ? "" : (" (" + snap + ")"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package net.torvald.terrarum
|
package net.torvald.terrarum
|
||||||
|
|
||||||
import net.torvald.terrarum.langpack.Lang
|
import net.torvald.terrarum.langpack.Lang
|
||||||
|
import net.torvald.terrarum.serialise.toUint
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* You directly modify the source code to tune the engine to suit your needs.
|
* You directly modify the source code to tune the engine to suit your needs.
|
||||||
@@ -68,6 +70,8 @@ basegame
|
|||||||
// Commit counts up to the Release 0.3.2: 2732
|
// Commit counts up to the Release 0.3.2: 2732
|
||||||
// Commit counts up to the Release 0.3.3: ????
|
// Commit counts up to the Release 0.3.3: ????
|
||||||
|
|
||||||
|
val VERSION_SNAPSHOT = if (App.IS_DEVELOPMENT_BUILD) Snapshot(0) else null
|
||||||
|
|
||||||
const val VERSION_TAG: String = ""
|
const val VERSION_TAG: String = ""
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////
|
||||||
@@ -77,4 +81,35 @@ basegame
|
|||||||
const val TILE_SIZE = 16
|
const val TILE_SIZE = 16
|
||||||
const val TILE_SIZEF = TILE_SIZE.toFloat()
|
const val TILE_SIZEF = TILE_SIZE.toFloat()
|
||||||
const val TILE_SIZED = TILE_SIZE.toDouble()
|
const val TILE_SIZED = TILE_SIZE.toDouble()
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Snapshot(var revision: Int) {
|
||||||
|
private var today = Calendar.getInstance();
|
||||||
|
private var year = today.get(Calendar.YEAR) - 2000
|
||||||
|
private var week = today.get(Calendar.WEEK_OF_YEAR)
|
||||||
|
|
||||||
|
private var string = ""
|
||||||
|
private var bytes = byteArrayOf()
|
||||||
|
|
||||||
|
private fun update() {
|
||||||
|
string = "${year}w${week}${Char(0x61 + revision)}"
|
||||||
|
bytes = byteArrayOf(
|
||||||
|
revision.and(4).shl(7).or(year.and(127)).toByte(),
|
||||||
|
week.shl(2).or(revision.and(3)).toByte()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
update()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString() = string
|
||||||
|
fun toBytes() = bytes
|
||||||
|
|
||||||
|
constructor(b: ByteArray) : this(0) {
|
||||||
|
year = b[0].toUint() and 127
|
||||||
|
week = b[1].toUint() ushr 2
|
||||||
|
revision = (b[0].toUint() ushr 7 shl 2) or b[1].toUint().and(3)
|
||||||
|
update()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.modulebasegame.serialise
|
|||||||
|
|
||||||
import net.torvald.gdx.graphics.PixmapIO2
|
import net.torvald.gdx.graphics.PixmapIO2
|
||||||
import net.torvald.terrarum.App
|
import net.torvald.terrarum.App
|
||||||
|
import net.torvald.terrarum.TerrarumAppConfiguration
|
||||||
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
import net.torvald.terrarum.savegame.*
|
import net.torvald.terrarum.savegame.*
|
||||||
@@ -41,6 +42,7 @@ class PlayerSavingThread(
|
|||||||
disk.saveKind = VDSaveKind.PLAYER_DATA
|
disk.saveKind = VDSaveKind.PLAYER_DATA
|
||||||
disk.saveOrigin = disk.saveOrigin and 15 // remove flag "imported" if applicable
|
disk.saveOrigin = disk.saveOrigin and 15 // remove flag "imported" if applicable
|
||||||
disk.capacity = 0L
|
disk.capacity = 0L
|
||||||
|
disk.snapshot = TerrarumAppConfiguration.VERSION_SNAPSHOT
|
||||||
|
|
||||||
WriteSavegame.saveProgress = 0f
|
WriteSavegame.saveProgress = 0f
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.modulebasegame.serialise
|
|||||||
|
|
||||||
import net.torvald.gdx.graphics.PixmapIO2
|
import net.torvald.gdx.graphics.PixmapIO2
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
|
import net.torvald.terrarum.TerrarumAppConfiguration
|
||||||
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
||||||
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
|
||||||
@@ -150,6 +151,7 @@ class QuickSingleplayerWorldSavingThread(
|
|||||||
skimmer.injectDiskCRC(disk.hashCode())
|
skimmer.injectDiskCRC(disk.hashCode())
|
||||||
skimmer.setSaveMode(1 + 2 * isAuto.toInt())
|
skimmer.setSaveMode(1 + 2 * isAuto.toInt())
|
||||||
skimmer.setSaveKind(VDSaveKind.WORLD_DATA)
|
skimmer.setSaveKind(VDSaveKind.WORLD_DATA)
|
||||||
|
skimmer.setSaveSnapshotVersion(TerrarumAppConfiguration.VERSION_SNAPSHOT)
|
||||||
skimmer.setSaveOrigin(skimmer.getSaveOrigin() and 15) // remove flag "imported" if applicable
|
skimmer.setSaveOrigin(skimmer.getSaveOrigin() and 15) // remove flag "imported" if applicable
|
||||||
skimmer.setLastModifiedTime(time_t)
|
skimmer.setLastModifiedTime(time_t)
|
||||||
skimmer.setCreationTime(creation_t)
|
skimmer.setCreationTime(creation_t)
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ class WorldSavingThread(
|
|||||||
disk.saveMode = 2 * isAuto.toInt() // no quick
|
disk.saveMode = 2 * isAuto.toInt() // no quick
|
||||||
disk.saveKind = VDSaveKind.WORLD_DATA
|
disk.saveKind = VDSaveKind.WORLD_DATA
|
||||||
disk.saveOrigin = disk.saveOrigin and 15 // remove flag "imported" if applicable
|
disk.saveOrigin = disk.saveOrigin and 15 // remove flag "imported" if applicable
|
||||||
|
disk.snapshot = TerrarumAppConfiguration.VERSION_SNAPSHOT
|
||||||
|
|
||||||
// wait for screencap
|
// wait for screencap
|
||||||
var emergencyStopCnt = 0
|
var emergencyStopCnt = 0
|
||||||
|
|||||||
@@ -526,14 +526,18 @@ class UIItemPlayerCells(
|
|||||||
loadable.rebuild()
|
loadable.rebuild()
|
||||||
loadable.getFile(SAVEGAMEINFO)?.bytes?.let {
|
loadable.getFile(SAVEGAMEINFO)?.bytes?.let {
|
||||||
var lastPlayTime0 = 0L
|
var lastPlayTime0 = 0L
|
||||||
|
var genver = ""
|
||||||
|
|
||||||
JsonFetcher.readFromJsonString(ByteArray64Reader(it, Common.CHARSET)).forEachSiblings { name, value ->
|
JsonFetcher.readFromJsonString(ByteArray64Reader(it, Common.CHARSET)).forEachSiblings { name, value ->
|
||||||
if (name == "worldCurrentlyPlaying") worldUUID = UUID.fromString(value.asString())
|
if (name == "worldCurrentlyPlaying") worldUUID = UUID.fromString(value.asString())
|
||||||
if (name == "totalPlayTime") totalPlayTime = parseDuration(value.asLong())
|
if (name == "totalPlayTime") totalPlayTime = parseDuration(value.asLong())
|
||||||
if (name == "lastPlayTime") lastPlayTime0 = value.asLong()
|
if (name == "lastPlayTime") lastPlayTime0 = value.asLong()
|
||||||
if (name == "genver") versionString = value.asLong().let { "${it.ushr(48)}.${it.ushr(24).and(0xFFFFFF)}.${it.and(0xFFFFFF)}" }
|
if (name == "genver") genver = value.asLong().let { "${it.ushr(48)}.${it.ushr(24).and(0xFFFFFF)}.${it.and(0xFFFFFF)}" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val snap = loadable.getSaveSnapshotVersion()
|
||||||
|
versionString = genver + (if (snap != null) "-$snap" else "")
|
||||||
|
|
||||||
App.savegamePlayersName[playerUUID]?.let { if (it.isNotBlank()) playerName = it else "(name)" }
|
App.savegamePlayersName[playerUUID]?.let { if (it.isNotBlank()) playerName = it else "(name)" }
|
||||||
App.savegameWorldsName[worldUUID]?.let { if (it.isNotBlank()) worldName = it }
|
App.savegameWorldsName[worldUUID]?.let { if (it.isNotBlank()) worldName = it }
|
||||||
lastPlayTime = Instant.ofEpochSecond(lastPlayTime0)
|
lastPlayTime = Instant.ofEpochSecond(lastPlayTime0)
|
||||||
@@ -749,6 +753,7 @@ class UIItemWorldCells(
|
|||||||
private val metaFile: EntryFile?
|
private val metaFile: EntryFile?
|
||||||
private val saveName: String
|
private val saveName: String
|
||||||
private val saveMode: Int
|
private val saveMode: Int
|
||||||
|
private val snapshot: String
|
||||||
private val isQuick: Boolean
|
private val isQuick: Boolean
|
||||||
private val isAuto: Boolean
|
private val isAuto: Boolean
|
||||||
private var saveDamaged: Boolean = false
|
private var saveDamaged: Boolean = false
|
||||||
@@ -760,6 +765,7 @@ class UIItemWorldCells(
|
|||||||
|
|
||||||
saveName = skimmer.getDiskName(Common.CHARSET)
|
saveName = skimmer.getDiskName(Common.CHARSET)
|
||||||
saveMode = skimmer.getSaveMode()
|
saveMode = skimmer.getSaveMode()
|
||||||
|
snapshot = skimmer.getSaveSnapshotVersion()?.toString() ?: ""
|
||||||
isQuick = (saveMode % 2 == 1)
|
isQuick = (saveMode % 2 == 1)
|
||||||
isAuto = (saveMode.ushr(1) != 0)
|
isAuto = (saveMode.ushr(1) != 0)
|
||||||
|
|
||||||
|
|||||||
@@ -447,12 +447,16 @@ class UILoadManage(val full: UILoadSavegame) : UICanvas() {
|
|||||||
if (!this.initialised) this.rebuild()
|
if (!this.initialised) this.rebuild()
|
||||||
this.getFile(SAVEGAMEINFO)!!.bytes.let {
|
this.getFile(SAVEGAMEINFO)!!.bytes.let {
|
||||||
var lastPlayTime = 0L
|
var lastPlayTime = 0L
|
||||||
var versionString = ""
|
var genver = ""
|
||||||
val isAuto = (this.getSaveMode() and 0b10 != 0)
|
val isAuto = (this.getSaveMode() and 0b10 != 0)
|
||||||
JsonFetcher.readFromJsonString(ByteArray64Reader(it, Common.CHARSET)).forEachSiblings { name, value ->
|
JsonFetcher.readFromJsonString(ByteArray64Reader(it, Common.CHARSET)).forEachSiblings { name, value ->
|
||||||
if (name == "lastPlayTime") lastPlayTime = value.asLong()
|
if (name == "lastPlayTime") lastPlayTime = value.asLong()
|
||||||
if (name == "genver") versionString = value.asLong().let { "${it.ushr(48)}.${it.ushr(24).and(0xFFFFFF)}.${it.and(0xFFFFFF)}" }
|
if (name == "genver") genver = value.asLong().let { "${it.ushr(48)}.${it.ushr(24).and(0xFFFFFF)}.${it.and(0xFFFFFF)}" }
|
||||||
}
|
}
|
||||||
|
val snap = this.getSaveSnapshotVersion()?.toString()
|
||||||
|
|
||||||
|
// val versionString = genver + (if (snap != null) "-$snap" else "")
|
||||||
|
val versionString = if (snap != null) "$snap" else genver
|
||||||
|
|
||||||
return SavegameMeta(
|
return SavegameMeta(
|
||||||
lastPlayTime,
|
lastPlayTime,
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ class UINewCharacter(val remoCon: UIRemoCon) : UICanvas() {
|
|||||||
disk.saveMode = 2 // auto, no quick
|
disk.saveMode = 2 // auto, no quick
|
||||||
disk.capacity = 0L
|
disk.capacity = 0L
|
||||||
disk.saveOrigin = VDSaveOrigin.INGAME
|
disk.saveOrigin = VDSaveOrigin.INGAME
|
||||||
|
disk.snapshot = TerrarumAppConfiguration.VERSION_SNAPSHOT
|
||||||
|
|
||||||
WritePlayer(player, disk, null, time_t)
|
WritePlayer(player, disk, null, time_t)
|
||||||
VDUtil.dumpToRealMachine(disk, outFile)
|
VDUtil.dumpToRealMachine(disk, outFile)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.torvald.terrarum.savegame
|
package net.torvald.terrarum.savegame
|
||||||
|
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
|
import net.torvald.terrarum.Snapshot
|
||||||
import net.torvald.terrarum.serialise.toUint
|
import net.torvald.terrarum.serialise.toUint
|
||||||
import net.torvald.terrarum.serialise.toUlong
|
import net.torvald.terrarum.serialise.toUlong
|
||||||
import java.io.*
|
import java.io.*
|
||||||
@@ -389,6 +390,16 @@ removefile:
|
|||||||
fa.close()
|
fa.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setSaveSnapshotVersion(snapshot: Snapshot?) {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
|
fa.seek(51L)
|
||||||
|
if (snapshot == null)
|
||||||
|
fa.write(byteArrayOf(0, 0))
|
||||||
|
else
|
||||||
|
fa.write(snapshot.toBytes())
|
||||||
|
fa.close()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Save type (0b 0000 00ab)
|
* @return Save type (0b 0000 00ab)
|
||||||
* b: unset - full save; set - quicksave (only applicable to worlds -- quicksave just means the disk is in dirty state)
|
* b: unset - full save; set - quicksave (only applicable to worlds -- quicksave just means the disk is in dirty state)
|
||||||
@@ -418,6 +429,17 @@ removefile:
|
|||||||
return fa.read().also { fa.close() }
|
return fa.read().also { fa.close() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getSaveSnapshotVersion(): Snapshot? {
|
||||||
|
val fa = RandomAccessFile(diskFile, "rwd")
|
||||||
|
fa.seek(52L)
|
||||||
|
|
||||||
|
val b1 = fa.read().toByte()
|
||||||
|
val b2 = fa.read().toByte().also { fa.close() }
|
||||||
|
|
||||||
|
return if (b1 == b2 && b1 == 0.toByte()) null
|
||||||
|
else Snapshot(byteArrayOf(b1, b2))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun getDiskName(charset: Charset): String {
|
override fun getDiskName(charset: Charset): String {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.torvald.terrarum.savegame
|
package net.torvald.terrarum.savegame
|
||||||
|
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
|
import net.torvald.terrarum.Snapshot
|
||||||
import net.torvald.terrarum.savegame.VDSaveKind.PLAYER_DATA
|
import net.torvald.terrarum.savegame.VDSaveKind.PLAYER_DATA
|
||||||
import net.torvald.terrarum.savegame.VDSaveKind.WORLD_DATA
|
import net.torvald.terrarum.savegame.VDSaveKind.WORLD_DATA
|
||||||
import net.torvald.terrarum.serialise.Common
|
import net.torvald.terrarum.serialise.Common
|
||||||
@@ -79,7 +80,15 @@ Version 254 is a customised version of TEVD tailored to be used as a savegame fo
|
|||||||
Int8 Savefile Origin Flags (lower nybble: persistent, upper nybble: can be removed if conditions are met)
|
Int8 Savefile Origin Flags (lower nybble: persistent, upper nybble: can be removed if conditions are met)
|
||||||
0: Created in-game
|
0: Created in-game
|
||||||
16: Imported (will be removed once the file is loaded by the player and saved in-game)
|
16: Imported (will be removed once the file is loaded by the player and saved in-game)
|
||||||
Int8[12] Extra info bytes reserved for future usage
|
Int16 Snapshot Number
|
||||||
|
0b A_yyyyyyy wwwwww_aa
|
||||||
|
where:
|
||||||
|
y: Current Year - 2000 (2023 -> 23)
|
||||||
|
w: ISO Week Number (1-53)
|
||||||
|
Aaa: Alphabet (a->000, b->001, ... e->100, f->101, ..., h->111)
|
||||||
|
e.g. 23w40f is encoded as 1_0010111 101000_01
|
||||||
|
Int8[10] Extra info bytes reserved for future usage
|
||||||
|
|
||||||
-- END extraInfoBytes --
|
-- END extraInfoBytes --
|
||||||
UInt8[236] Rest of the long disk name (268 bytes total)
|
UInt8[236] Rest of the long disk name (268 bytes total)
|
||||||
|
|
||||||
@@ -156,6 +165,25 @@ class VirtualDisk(
|
|||||||
var saveOrigin: Int
|
var saveOrigin: Int
|
||||||
set(value) { extraInfoBytes[3] = value.toByte() }
|
set(value) { extraInfoBytes[3] = value.toByte() }
|
||||||
get() = extraInfoBytes[3].toUint()
|
get() = extraInfoBytes[3].toUint()
|
||||||
|
var snapshot: Snapshot?
|
||||||
|
set(value) {
|
||||||
|
if (value == null) {
|
||||||
|
extraInfoBytes[4] = 0
|
||||||
|
extraInfoBytes[5] = 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
value.toBytes().forEachIndexed { index, byte ->
|
||||||
|
extraInfoBytes[4+index] = byte
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get() {
|
||||||
|
return if (extraInfoBytes[4] == extraInfoBytes[5] && extraInfoBytes[4] == 0.toByte()) null
|
||||||
|
else {
|
||||||
|
Snapshot(extraInfoBytes.sliceArray(4..5))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun getDiskName(charset: Charset) = diskName.toCanonicalString(charset)
|
override fun getDiskName(charset: Charset) = diskName.toCanonicalString(charset)
|
||||||
val root: DiskEntry
|
val root: DiskEntry
|
||||||
get() = entries[0]!!
|
get() = entries[0]!!
|
||||||
|
|||||||
@@ -113,8 +113,8 @@ internal class UnsafePtr(pointer: Long, allocSize: Long) {
|
|||||||
// appear (e.g. getting garbage values when it fucking shouldn't)
|
// appear (e.g. getting garbage values when it fucking shouldn't)
|
||||||
|
|
||||||
// using ifs instead of assertions: inactive assert statements still slows down the app
|
// using ifs instead of assertions: inactive assert statements still slows down the app
|
||||||
if (destroyed) { throw DanglingPointerException("The pointer is already destroyed ($this)") }
|
// if (destroyed) { throw DanglingPointerException("The pointer is already destroyed ($this)") }
|
||||||
if (index !in 0 until size) { throw AddressOverflowException("Index: $index; alloc size: $size") }
|
// if (index !in 0 until size) { throw AddressOverflowException("Index: $index; alloc size: $size") }
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun get(index: Long): Byte {
|
operator fun get(index: Long): Byte {
|
||||||
|
|||||||
Reference in New Issue
Block a user