From 43d9785db8c6731797dce89a3441a2142f404ec3 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 18 Sep 2021 11:55:38 +0900 Subject: [PATCH] quick and dirty solution deployed for the load screen dereferencing the dead pointer --- src/net/torvald/UnsafePtr.kt | 9 +++++++++ .../torvald/terrarum/gameworld/GameWorld.kt | 18 ++---------------- .../modulebasegame/WorldgenLoadScreen.kt | 9 ++++++--- .../terrarum/serialise/WriteSavegame.kt | 18 ++++++++++-------- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/net/torvald/UnsafePtr.kt b/src/net/torvald/UnsafePtr.kt index ca95aaafb..cbe9a571a 100644 --- a/src/net/torvald/UnsafePtr.kt +++ b/src/net/torvald/UnsafePtr.kt @@ -1,5 +1,6 @@ package net.torvald +import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.printStackTrace import sun.misc.Unsafe import java.io.IOException @@ -30,6 +31,10 @@ internal object UnsafeHelper { */ fun allocate(size: Long): UnsafePtr { val ptr = unsafe.allocateMemory(size) + + printdbg(this, "Allocating 0x${ptr.toString(16)} with size $size, called by:") + printStackTrace(this) + return UnsafePtr(ptr, size) } @@ -94,6 +99,10 @@ internal class UnsafePtr(pointer: Long, allocSize: Long) { UnsafeHelper.unsafeAllocatedSize -= size } + else { + println("[UnsafePtr] Destroy() is called but the pointer $this is already been destroyed; called from:") + printStackTrace(this) + } } private inline fun checkNullPtr(index: Long) { // ignore what IDEA says and do inline this diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt index 748bd3a05..21c4624d5 100644 --- a/src/net/torvald/terrarum/gameworld/GameWorld.kt +++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt @@ -208,14 +208,7 @@ open class GameWorld() : Disposable { */ fun getTileFromWall(rawX: Int, rawY: Int): ItemID { val (x, y) = coerceXY(rawX, rawY) - - try { - return tileNumberToNameMap[layerWall.unsafeGetTile(x, y).toLong()]!! - } - catch (e: NullPointerException) { - val msg = "No tile name mapping for wall ${layerWall.unsafeGetTile(x, y)} in ($x, $y) from $layerWall" - throw NoSuchElementException(msg) - } + return tileNumberToNameMap[layerWall.unsafeGetTile(x, y).toLong()] ?: throw NoSuchElementException("No tile name mapping for wall ${layerWall.unsafeGetTile(x, y)} in ($x, $y) from $layerWall") } /** @@ -223,14 +216,7 @@ open class GameWorld() : Disposable { */ fun getTileFromTerrain(rawX: Int, rawY: Int): ItemID { val (x, y) = coerceXY(rawX, rawY) - - try { - return tileNumberToNameMap[layerTerrain.unsafeGetTile(x, y).toLong()]!! - } - catch (e: NullPointerException) { - val msg = "No tile name mapping for terrain ${layerTerrain.unsafeGetTile(x, y)} in ($x, $y) from $layerTerrain" - throw NoSuchElementException(msg) - } + return tileNumberToNameMap[layerTerrain.unsafeGetTile(x, y).toLong()] ?: throw NoSuchElementException("No tile name mapping for terrain ${layerTerrain.unsafeGetTile(x, y)} in ($x, $y) from $layerTerrain") } /** diff --git a/src/net/torvald/terrarum/modulebasegame/WorldgenLoadScreen.kt b/src/net/torvald/terrarum/modulebasegame/WorldgenLoadScreen.kt index a0e4ccec5..99751068e 100644 --- a/src/net/torvald/terrarum/modulebasegame/WorldgenLoadScreen.kt +++ b/src/net/torvald/terrarum/modulebasegame/WorldgenLoadScreen.kt @@ -93,12 +93,15 @@ class WorldgenLoadScreen(screenToBeLoaded: IngameInstance, private val worldwidt val wx = (world.width.toFloat() / previewWidth * x).roundToInt() val wy = (world.height.toFloat() / previewHeight * y).roundToInt() - val outCol = if (BlockCodex[world.getTileFromTerrain(wx, wy)].isSolid) COL_TERR + try { // q&d solution for the dangling pointer; i'm doing this only because it's this fucking load screen that's fucking the dead pointer + val outCol = if (BlockCodex[world.getTileFromTerrain(wx, wy)].isSolid) COL_TERR else if (BlockCodex[world.getTileFromWall(wx, wy)].isSolid) COL_WALLED else COL_AIR - previewPixmap.setColor(outCol) - previewPixmap.drawPixel(x, previewHeight - 1 - y) // this flips Y + previewPixmap.setColor(outCol) + previewPixmap.drawPixel(x, previewHeight - 1 - y) // this flips Y + } + catch (e: NoSuchElementException) {} } } diff --git a/src/net/torvald/terrarum/serialise/WriteSavegame.kt b/src/net/torvald/terrarum/serialise/WriteSavegame.kt index d2db01cc0..2174e4c23 100644 --- a/src/net/torvald/terrarum/serialise/WriteSavegame.kt +++ b/src/net/torvald/terrarum/serialise/WriteSavegame.kt @@ -90,6 +90,15 @@ object LoadSavegame { val currentWorld = (ReadActor.readActorBare(getFileReader(disk, Terrarum.PLAYER_REF_ID.toLong())) as IngamePlayer).worldCurrentlyPlaying val world = ReadWorld(getFileReader(disk, currentWorld.toLong())) + // set lateinit vars on the gameworld FIRST + world.layerTerrain = BlockLayer(world.width, world.height) + world.layerWall = BlockLayer(world.width, world.height) + + newIngame.savegameArchive = disk + newIngame.creationTime = meta.creation_t + newIngame.lastPlayTime = meta.lastplay_t + newIngame.totalPlayTime = meta.playtime_t + newIngame.world = world // must be set before the loadscreen, otherwise the loadscreen will try to read from the NullWorld which is already destroyed @@ -107,18 +116,11 @@ object LoadSavegame { val apocryphas = Common.jsoner.fromJson(Apocryphas.javaClass, getUnzipInputStream(getFileBytes(disk, -1024))) - // set lateinit vars on the gameworld - world.layerTerrain = BlockLayer(world.width, world.height) - world.layerWall = BlockLayer(world.width, world.height) val worldParam = TerrarumIngame.Codices(disk, meta, item, apocryphas, actors) - newIngame.world = world newIngame.gameLoadInfoPayload = worldParam newIngame.gameLoadMode = TerrarumIngame.GameLoadMode.LOAD_FROM - newIngame.savegameArchive = disk - newIngame.creationTime = meta.creation_t - newIngame.lastPlayTime = meta.lastplay_t - newIngame.totalPlayTime = meta.playtime_t + // load all the world blocklayer chunks val worldnum = world.worldIndex.toLong()