diff --git a/.idea/artifacts/TerrarumBuild.xml b/.idea/artifacts/TerrarumBuild.xml
index e5ea8e246..92f057a0f 100644
--- a/.idea/artifacts/TerrarumBuild.xml
+++ b/.idea/artifacts/TerrarumBuild.xml
@@ -46,7 +46,6 @@
-
diff --git a/.idea/libraries/com_google_code_gson_gson_2_8_7.xml b/.idea/libraries/com_google_code_gson_gson_2_8_7.xml
deleted file mode 100644
index ff204fce5..000000000
--- a/.idea/libraries/com_google_code_gson_gson_2_8_7.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index f25fbb93c..a8ad65539 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,5 @@
buildscript {
- ext.kotlin_version = '1.3.72'
+ ext.kotlin_version = '1.5.21'
repositories {
mavenCentral()
@@ -14,6 +14,9 @@ apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'idea'
apply plugin: 'kotlin'
+plugins {
+ kotlin("plugin.serialization") version "1.5.21"
+}
sourceSets.main.java.srcDirs = ['src'] // because I'm not setting up proper /src/main/java/...
@@ -31,6 +34,7 @@ dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib"
compile fileTree(dir: 'lib', include: ['*.jar'])
implementation 'org.junit:junit-bom:5.2.0'
+ implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0'
}
compileKotlin {
diff --git a/ingamemodule_basegame/ingamemodule_basegame.iml b/ingamemodule_basegame/ingamemodule_basegame.iml
index cd8dbc66b..4c0d19460 100644
--- a/ingamemodule_basegame/ingamemodule_basegame.iml
+++ b/ingamemodule_basegame/ingamemodule_basegame.iml
@@ -11,7 +11,6 @@
-
@@ -20,7 +19,6 @@
-
diff --git a/lib/gson-2.8.7-javadoc.jar b/lib/gson-2.8.7-javadoc.jar
deleted file mode 100644
index 7b2ba6406..000000000
Binary files a/lib/gson-2.8.7-javadoc.jar and /dev/null differ
diff --git a/lib/gson-2.8.7-sources.jar b/lib/gson-2.8.7-sources.jar
deleted file mode 100644
index 116bf95b5..000000000
Binary files a/lib/gson-2.8.7-sources.jar and /dev/null differ
diff --git a/lib/gson-2.8.7.jar b/lib/gson-2.8.7.jar
deleted file mode 100644
index 215e82328..000000000
Binary files a/lib/gson-2.8.7.jar and /dev/null differ
diff --git a/lib/kotlin-stdlib-sources.jar b/lib/kotlin-stdlib-sources.jar
deleted file mode 100644
index acb8ff171..000000000
Binary files a/lib/kotlin-stdlib-sources.jar and /dev/null differ
diff --git a/src/module-info.java.wtf b/src/module-info.java.wtf
index b9d1df39e..f0af35259 100644
--- a/src/module-info.java.wtf
+++ b/src/module-info.java.wtf
@@ -5,7 +5,6 @@ module terrarum.terrarum {
requires jdk.unsupported; // sun.misc.Unsafe
// kotlin
- requires kotlin.stdlib;
requires kotlin.test;
// gdx
@@ -22,7 +21,9 @@ module terrarum.terrarum {
// etc
requires GetCpuName;
- requires com.google.gson;
+ requires kotlinx.serialization.core.jvm;
+ requires kotlinx.serialization.json;
+ requires kotlinx.serialization.json.jvm;
requires org.apache.commons.codec;
requires commons.csv;
requires jxinput;
diff --git a/src/net/torvald/parametricsky/datasets/DatasetOp.kt b/src/net/torvald/parametricsky/datasets/DatasetOp.kt
index 2be469357..eb9aa3e8e 100644
--- a/src/net/torvald/parametricsky/datasets/DatasetOp.kt
+++ b/src/net/torvald/parametricsky/datasets/DatasetOp.kt
@@ -21,4 +21,6 @@ object DatasetOp {
fis.close()
return ret
}
+
+
}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/AppLoader.java b/src/net/torvald/terrarum/AppLoader.java
index efa46714b..ae2922b59 100644
--- a/src/net/torvald/terrarum/AppLoader.java
+++ b/src/net/torvald/terrarum/AppLoader.java
@@ -12,12 +12,9 @@ import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.utils.Disposable;
-import com.badlogic.gdx.utils.GdxRuntimeException;
+import com.badlogic.gdx.utils.JsonValue;
import com.badlogic.gdx.utils.ScreenUtils;
import com.github.strikerx3.jxinput.XInputDevice;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
import net.torvald.gdx.graphics.PixmapIO2;
import net.torvald.getcpuname.GetCpuName;
import net.torvald.terrarum.concurrent.ThreadExecutor;
@@ -37,18 +34,10 @@ import net.torvald.terrarum.utils.JsonWriter;
import net.torvald.terrarum.worlddrawer.CreateTileAtlas;
import net.torvald.terrarumsansbitmap.gdx.GameFontBase;
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack;
-import net.torvald.util.ArrayListMap;
import net.torvald.util.DebugTimers;
-import org.lwjgl.opengl.GL11;
-
import java.io.File;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Random;
-
-import static net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED;
+import java.util.*;
import static net.torvald.terrarum.TerrarumKt.gdxClearAndSetBlend;
import static net.torvald.terrarum.TerrarumKt.printStackTrace;
@@ -973,7 +962,7 @@ public class AppLoader implements ApplicationListener {
File configFile = new File(configDir);
if (!configFile.exists() || configFile.length() == 0L) {
- JsonWriter.INSTANCE.writeToFile(DefaultConfig.INSTANCE.fetch(), configDir);
+ JsonWriter.INSTANCE.writeToFile(DefaultConfig.INSTANCE.getHashMap(), configDir);
}
}
@@ -984,12 +973,18 @@ public class AppLoader implements ApplicationListener {
private static Boolean readConfigJson() {
try {
// read from disk and build config from it
- JsonObject jsonObject = JsonFetcher.INSTANCE.invoke(configDir);
+ JsonValue map = JsonFetcher.INSTANCE.invoke(configDir);
// make config
- jsonObject.entrySet().forEach((entry) ->
- gameConfig.set(entry.getKey(), entry.getValue())
- );
+ for (JsonValue entry = map.child; entry != null; entry = entry.next) {
+ gameConfig.set(entry.name,
+ entry.isArray() ? entry.asDoubleArray() :
+ entry.isDouble() ? entry.asDouble() :
+ entry.isBoolean() ? entry.asBoolean() :
+ entry.isLong() ? entry.asInt() :
+ entry.asString()
+ );
+ }
return true;
}
@@ -1018,10 +1013,7 @@ public class AppLoader implements ApplicationListener {
*/
public static int getConfigInt(String key) {
Object cfg = getConfigMaster(key);
- if (cfg instanceof JsonPrimitive)
- return ((JsonPrimitive) cfg).getAsInt();
- else
- return Integer.parseInt(((String) cfg));
+ return ((int) cfg);
}
/**
@@ -1034,10 +1026,7 @@ public class AppLoader implements ApplicationListener {
*/
public static String getConfigString(String key) {
Object cfg = getConfigMaster(key);
- if (cfg instanceof JsonPrimitive)
- return ((JsonPrimitive) cfg).getAsString();
- else
- return ((String) cfg);
+ return ((String) cfg);
}
/**
@@ -1049,17 +1038,14 @@ public class AppLoader implements ApplicationListener {
public static boolean getConfigBoolean(String key) {
try {
Object cfg = getConfigMaster(key);
- if (cfg instanceof JsonPrimitive)
- return ((JsonPrimitive) cfg).getAsBoolean();
- else
- return ((boolean) cfg);
+ return ((boolean) cfg);
}
catch (NullPointerException keyNotFound) {
return false;
}
}
- public static int[] getConfigIntArray(String key) {
+ /*public static int[] getConfigIntArray(String key) {
Object cfg = getConfigMaster(key);
if (cfg instanceof JsonArray) {
JsonArray jsonArray = ((JsonArray) cfg).getAsJsonArray();
@@ -1072,24 +1058,23 @@ public class AppLoader implements ApplicationListener {
}
else
return ((int[]) cfg);
- }
+ }*/
- public static float[] getConfigFloatArray(String key) {
+ public static double[] getConfigDoubleArray(String key) {
Object cfg = getConfigMaster(key);
- if (cfg instanceof JsonArray) {
- JsonArray jsonArray = ((JsonArray) cfg).getAsJsonArray();
- //return IntArray(jsonArray.size(), { i -> jsonArray[i].asInt })
- float[] floatArray = new float[jsonArray.size()];
- for (int i = 0; i < jsonArray.size(); i++) {
- floatArray[i] = jsonArray.get(i).getAsInt();
- }
- return floatArray;
- }
- else
- return ((float[]) cfg);
+ return ((double[]) cfg);
}
- public static String[] getConfigStringArray(String key) {
+ public static int[] getConfigIntArray(String key) {
+ double[] a = getConfigDoubleArray(key);
+ int[] r = new int[a.length];
+ for (int i = 0; i < a.length; i++) {
+ r[i] = ((int) a[i]);
+ }
+ return r;
+ }
+
+ /*public static String[] getConfigStringArray(String key) {
Object cfg = getConfigMaster(key);
if (cfg instanceof JsonArray) {
JsonArray jsonArray = ((JsonArray) cfg).getAsJsonArray();
@@ -1102,13 +1087,13 @@ public class AppLoader implements ApplicationListener {
}
else
return ((String[]) cfg);
- }
+ }*/
/**
* Get config from config file. If the entry does not exist, get from defaults; if the entry is not in the default, NullPointerException will be thrown
*/
- private static JsonObject getDefaultConfig() {
- return DefaultConfig.INSTANCE.fetch();
+ private static HashMap getDefaultConfig() {
+ return DefaultConfig.INSTANCE.getHashMap();
}
private static Object getConfigMaster(String key1) {
diff --git a/src/net/torvald/terrarum/DefaultConfig.kt b/src/net/torvald/terrarum/DefaultConfig.kt
index 1cd0ad50a..d110c8c49 100644
--- a/src/net/torvald/terrarum/DefaultConfig.kt
+++ b/src/net/torvald/terrarum/DefaultConfig.kt
@@ -1,8 +1,7 @@
package net.torvald.terrarum
import com.badlogic.gdx.Input
-import com.google.gson.JsonArray
-import com.google.gson.JsonObject
+import com.badlogic.gdx.utils.Json
import net.torvald.terrarum.blockproperties.Block
/**
@@ -11,126 +10,110 @@ import net.torvald.terrarum.blockproperties.Block
* Created by minjaesong on 2016-03-12.
*/
object DefaultConfig {
- fun fetch(): JsonObject {
- val jsonObject = JsonObject()
- jsonObject.addProperty("displayfps", 0) // 0: no limit, non-zero: limit
- jsonObject.addProperty("usevsync", false)
- jsonObject.addProperty("screenwidth", TerrarumScreenSize.defaultW)
- jsonObject.addProperty("screenheight", TerrarumScreenSize.defaultH)
- jsonObject.addProperty("atlastexsize", 2048)
+ val hashMap = hashMapOf(
+ "displayfps" to 0, // 0: no limit, non-zero: limit
+ "usevsync" to false,
+ "screenwidth" to TerrarumScreenSize.defaultW,
+ "screenheight" to TerrarumScreenSize.defaultH,
+ "atlastexsize" to 2048,
+
+ "language" to AppLoader.getSysLang(),
+ "notificationshowuptime" to 4000,
+ "multithread" to true,
+ "multithreadedlight" to false,
+
+ "showhealthmessageonstartup" to true,
+
+ "usexinput" to true, // when FALSE, LT+RT input on xbox controller is impossible
+
+ "config_gamepadkeyn" to 3,
+ "config_gamepadkeyw" to 2,
+ "config_gamepadkeys" to 0,
+ "config_gamepadkeye" to 1, // xbox indices
+
+ "config_gamepadlup" to 4,
+ "config_gamepadrup" to 5,
+ "config_gamepadselect" to 6,
+ "config_gamepadstart" to 7,
+
+ "config_gamepadltrigger" to 8,
+ "config_gamepadrtrigger" to 9,
+ "config_gamepadlthumb" to 10,
+ "config_gamepadrthumb" to 11,
- //jsonObject.addProperty("imtooyoungtodie", false) // no perma-death
- jsonObject.addProperty("language", AppLoader.getSysLang())
- jsonObject.addProperty("notificationshowuptime", 4000)
- jsonObject.addProperty("multithread", true) // experimental!
- jsonObject.addProperty("multithreadedlight", false) // experimental!
+ "config_gamepadaxislx" to 1,
+ "config_gamepadaxisly" to 0,
+ "config_gamepadaxisrx" to 3,
+ "config_gamepadaxisry" to 2, // 0-1-2-3 but sometimes 3-2-1-0 ?! what the actual fuck?
+ "config_gamepadtriggeraxis" to 4, // positive: LT, negative: RT (xbox pad)
+ "config_gamepadtriggeraxis2" to 5, // just in case... (RT)
- jsonObject.addProperty("showhealthmessageonstartup", true)
+ // to accomodate shifted zero point of analog stick
+ "gamepadaxiszeropoints" to doubleArrayOf(-0.011, -0.022, -0.033, -0.044),
- // control-gamepad
+ "gamepadlabelstyle" to "msxbone", // "nwii", "logitech", "sonyps", "msxb360", "msxbone"
- // "config_key", "config_mouse", "config_gamepad" are keyword recognised by control setup UI
+ // control-keyboard (GDX key codes,
+ "config_keyup" to Input.Keys.E,
+ "config_keyleft" to Input.Keys.S,
+ "config_keydown" to Input.Keys.D,
+ "config_keyright" to Input.Keys.F, // ESDF Masterrace
- jsonObject.addProperty("usexinput", true) // when FALSE, LT+RT input on xbox controller is impossible
+ "config_keymovementaux" to Input.Keys.A, // movement-auxiliary, or hookshot
+ "config_keyinventory" to Input.Keys.Q,
+ "config_keyinteract" to Input.Keys.R,
+ "config_keyclose" to Input.Keys.C, // this or hard-coded ESC
+ "config_keyzoom" to Input.Keys.Z,
- jsonObject.addProperty("config_gamepadkeyn", 3)
- jsonObject.addProperty("config_gamepadkeyw", 2)
- jsonObject.addProperty("config_gamepadkeys", 0)
- jsonObject.addProperty("config_gamepadkeye", 1) // xbox indices
+ "config_keygamemenu" to Input.Keys.TAB,
+ "config_keyquicksel" to Input.Keys.SHIFT_LEFT, // pie menu is now LShift because GDX does not read CapsLock
+ // Colemak, Workman and some typers use CapsLock as Backspace, Apple-JIS and HHKB has Control in place of CapsLock and often re-assigned to Command
+ // so these keys are treated as the same.
+ // FOR ~~FUCKS~~ERGONOMICS' SAKE DON'T USE CTRL AND ALT AS A KEY!
+ "config_keyquickselalt" to intArrayOf(Input.Keys.BACKSPACE, Input.Keys.CONTROL_LEFT, Input.Keys.BACKSLASH),
+ "config_mousequicksel" to Input.Buttons.MIDDLE, // middle click to open pie menu
- jsonObject.addProperty("config_gamepadlup", 4)
- jsonObject.addProperty("config_gamepadrup", 5)
- jsonObject.addProperty("config_gamepadselect", 6)
- jsonObject.addProperty("config_gamepadstart", 7)
+ "config_keyjump" to Input.Keys.SPACE,
- jsonObject.addProperty("config_gamepadltrigger", 8)
- jsonObject.addProperty("config_gamepadrtrigger", 9)
- jsonObject.addProperty("config_gamepadlthumb", 10)
- jsonObject.addProperty("config_gamepadrthumb", 11)
+ "config_keyquickslots" to (Input.Keys.NUM_0..Input.Keys.NUM_9).toList(),
+
+ "config_mouseprimary" to Input.Buttons.LEFT, // left mouse
+ "config_mousesecondary" to Input.Buttons.RIGHT, // right mouse
- jsonObject.addProperty("config_gamepadaxislx", 1)
- jsonObject.addProperty("config_gamepadaxisly", 0)
- jsonObject.addProperty("config_gamepadaxisrx", 3)
- jsonObject.addProperty("config_gamepadaxisry", 2) // 0-1-2-3 but sometimes 3-2-1-0 ?! what the actual fuck?
- jsonObject.addProperty("config_gamepadtriggeraxis", 4) // positive: LT, negative: RT (xbox pad)
- jsonObject.addProperty("config_gamepadtriggeraxis2", 5) // just in case... (RT)
+ "pcgamepadenv" to "console",
- val axesZeroPoints = JsonArray(); axesZeroPoints.add(-0.011f); axesZeroPoints.add(-0.022f); axesZeroPoints.add(-0.033f); axesZeroPoints.add(-0.044f)
- jsonObject.add("gamepadaxiszeropoints", axesZeroPoints) // to accomodate shifted zero point of analog stick
-
- jsonObject.addProperty("gamepadlabelstyle", "msxbone") // "nwii", "logitech", "sonyps", "msxb360", "msxbone"
-
- // control-keyboard (GDX key codes)
- jsonObject.addProperty("config_keyup", Input.Keys.E)
- jsonObject.addProperty("config_keyleft", Input.Keys.S)
- jsonObject.addProperty("config_keydown", Input.Keys.D)
- jsonObject.addProperty("config_keyright", Input.Keys.F) // ESDF Masterrace
-
- jsonObject.addProperty("config_keymovementaux", Input.Keys.A) // movement-auxiliary, or hookshot
- jsonObject.addProperty("config_keyinventory", Input.Keys.Q)
- jsonObject.addProperty("config_keyinteract", Input.Keys.R)
- jsonObject.addProperty("config_keyclose", Input.Keys.C) // this or hard-coded ESC
- jsonObject.addProperty("config_keyzoom", Input.Keys.Z)
-
- jsonObject.addProperty("config_keygamemenu", Input.Keys.TAB)
- jsonObject.addProperty("config_keyquicksel", Input.Keys.SHIFT_LEFT) // pie menu is now LShift because GDX does not read CapsLock
- val keyquickselalt = JsonArray(); keyquickselalt.add(Input.Keys.BACKSPACE); keyquickselalt.add(Input.Keys.CONTROL_LEFT); keyquickselalt.add(Input.Keys.BACKSLASH)
- // Colemak, Workman and some typers use CapsLock as Backspace, Apple-JIS and HHKB has Control in place of CapsLock and often re-assigned to Command
- // so these keys are treated as the same.
- // FOR ~~FUCKS~~ERGONOMICS' SAKE DON'T USE CTRL AND ALT AS A KEY!
- jsonObject.add("config_keyquickselalt", keyquickselalt)
- jsonObject.addProperty("config_mousequicksel", Input.Buttons.MIDDLE) // middle click to open pie menu
-
- jsonObject.addProperty("config_keyjump", Input.Keys.SPACE)
-
- val keyquickslots = JsonArray(); for (i in Input.Keys.NUM_1..Input.Keys.NUM_9) keyquickslots.add(i); keyquickslots.add(Input.Keys.NUM_0) // NUM_1 to NUM_0
- jsonObject.add("config_keyquickslots", keyquickslots)
-
- jsonObject.addProperty("config_mouseprimary", Input.Buttons.LEFT) // left mouse
- jsonObject.addProperty("config_mousesecondary", Input.Buttons.RIGHT) // right mouse
+ //jsonObject.writeValue("safetywarning" to true,
- jsonObject.addProperty("pcgamepadenv", "console")
+ "maxparticles" to 768,
- //jsonObject.addProperty("safetywarning", true)
+ "temperatureunit" to 1, // -1: american, 0: kelvin, 1: celcius
- jsonObject.addProperty("maxparticles", 768)
-
- jsonObject.addProperty("temperatureunit", 1) // -1: american, 0: kelvin, 1: celcius
+ // "fancy" graphics settings
+ "fxdither" to true,
+ "fxretro" to false,
+ //"fx3dlut" to false,
- // "fancy" graphics settings
- jsonObject.addProperty("fxdither", true)
- jsonObject.addProperty("fxretro", false)
- //jsonObject.addProperty("fx3dlut", false)
+ // settings regarding debugger
+ /*"buildingmakerfavs" to arrayOf(
+ Block.GLASS_CRUDE,
+ Block.PLANK_NORMAL,
+ Block.PLANK_BIRCH,
+ Block.STONE_QUARRIED,
+ Block.STONE_BRICKS,
-
- // settings regarding debugger
- val buildingMakerFavs = JsonArray()
- arrayOf(
- Block.GLASS_CRUDE,
- Block.PLANK_NORMAL,
- Block.PLANK_BIRCH,
- Block.STONE_QUARRIED,
- Block.STONE_BRICKS,
-
- Block.STONE_TILE_WHITE,
- Block.TORCH,
- "wall@" + Block.PLANK_NORMAL,
- "wall@" + Block.PLANK_BIRCH,
- "wall@" + Block.GLASS_CRUDE
- ).forEach {
- buildingMakerFavs.add(it)
- }
- jsonObject.add("buildingmakerfavs", buildingMakerFavs)
-
-
- return jsonObject
- }
+ Block.STONE_TILE_WHITE,
+ Block.TORCH,
+ "wall@" + Block.PLANK_NORMAL,
+ "wall@" + Block.PLANK_BIRCH,
+ "wall@" + Block.GLASS_CRUDE
+ )*/
+ )
}
/*
diff --git a/src/net/torvald/terrarum/GsonSerialisable.kt b/src/net/torvald/terrarum/GsonSerialisable.kt
deleted file mode 100644
index f39a89eb5..000000000
--- a/src/net/torvald/terrarum/GsonSerialisable.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package net.torvald.terrarum
-
-import com.google.gson.JsonObject
-
-/**
- * Created by minjaesong on 2018-05-18.
- */
-interface GsonSerialisable {
-
- /**
- * Will modify itself according to the input gson. Not sure it's even necessary so please test.
- */
- fun read(gson: JsonObject)
-
-}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/IngameInstance.kt b/src/net/torvald/terrarum/IngameInstance.kt
index 789751926..45abd3305 100644
--- a/src/net/torvald/terrarum/IngameInstance.kt
+++ b/src/net/torvald/terrarum/IngameInstance.kt
@@ -45,7 +45,8 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
field = value
}
/** how many different planets/stages/etc. are thenre. Whole stages must be manually managed by YOU. */
- var gameworldCount = 0
+ var gameworldIndices = ArrayList()
+
/** The actor the game is currently allowing you to control.
*
* Most of the time it'd be the "player", but think about the case where you have possessed
diff --git a/src/net/torvald/terrarum/KVHashMap.kt b/src/net/torvald/terrarum/KVHashMap.kt
index f25e98a72..0900058ef 100644
--- a/src/net/torvald/terrarum/KVHashMap.kt
+++ b/src/net/torvald/terrarum/KVHashMap.kt
@@ -1,14 +1,11 @@
package net.torvald.terrarum
-import com.google.gson.JsonObject
-import com.google.gson.JsonPrimitive
-
typealias ItemValue = KVHashMap
/**
* Created by minjaesong on 2015-12-30.
*/
-open class KVHashMap : GsonSerialisable {
+open class KVHashMap {
constructor() {
hashMap = HashMap()
@@ -49,8 +46,7 @@ open class KVHashMap : GsonSerialisable {
if (value == null) return null
- if (value is JsonPrimitive)
- return value.asInt
+// if (value is JsonPrimitive) return value.asInt
return value as Int
}
@@ -62,8 +58,7 @@ open class KVHashMap : GsonSerialisable {
if (value is Int)
return value.toDouble()
- else if (value is JsonPrimitive)
- return value.asDouble
+// else if (value is JsonPrimitive) return value.asDouble
return value as Double
}
@@ -77,8 +72,7 @@ open class KVHashMap : GsonSerialisable {
if (value == null) return null
- if (value is JsonPrimitive)
- return value.asString
+// if (value is JsonPrimitive) return value.asString
return value as String
}
@@ -88,8 +82,7 @@ open class KVHashMap : GsonSerialisable {
if (value == null) return null
- if (value is JsonPrimitive)
- return value.asBoolean
+// if (value is JsonPrimitive) return value.asBoolean
return value as Boolean
}
@@ -109,9 +102,4 @@ open class KVHashMap : GsonSerialisable {
val cloneOfMap = hashMap.clone() as HashMap
return KVHashMap(cloneOfMap)
}
-
- override fun read(gson: JsonObject) {
- TODO()
- }
-
}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/ModMgr.kt b/src/net/torvald/terrarum/ModMgr.kt
index 0d9735af2..22131642d 100644
--- a/src/net/torvald/terrarum/ModMgr.kt
+++ b/src/net/torvald/terrarum/ModMgr.kt
@@ -62,6 +62,8 @@ object ModMgr {
val moduleInfo = HashMap()
val entryPointClasses = ArrayList()
+ val loadOrder = ArrayList()
+
init {
// load modules
val loadOrderCSVparser = CSVParser.parse(
@@ -75,6 +77,7 @@ object ModMgr {
loadOrder.forEachIndexed { index, it ->
val moduleName = it[0]
+ this.loadOrder.add(moduleName)
printmsg(this, "Loading module $moduleName")
try {
diff --git a/src/net/torvald/terrarum/blockproperties/BlockCodex.kt b/src/net/torvald/terrarum/blockproperties/BlockCodex.kt
index 20933ab61..3a340e69a 100644
--- a/src/net/torvald/terrarum/blockproperties/BlockCodex.kt
+++ b/src/net/torvald/terrarum/blockproperties/BlockCodex.kt
@@ -20,7 +20,7 @@ import java.io.IOException
*/
object BlockCodex {
- private var blockProps = HashMap()
+ val blockProps = HashMap()
val dynamicLights = SortedArrayList() // does not include virtual ones
diff --git a/src/net/torvald/terrarum/blockproperties/BlockProp.kt b/src/net/torvald/terrarum/blockproperties/BlockProp.kt
index 88e8b58fc..3af22f925 100644
--- a/src/net/torvald/terrarum/blockproperties/BlockProp.kt
+++ b/src/net/torvald/terrarum/blockproperties/BlockProp.kt
@@ -4,7 +4,6 @@ import net.torvald.gdx.graphics.Cvec
import net.torvald.random.XXHash32
import net.torvald.terrarum.gameitem.ItemID
import net.torvald.terrarum.gameworld.fmod
-import net.torvald.terrarum.serialise.toLittle
/**
* Created by minjaesong on 2016-02-16.
@@ -92,7 +91,7 @@ class BlockProp {
var material: String = ""
- var rngBase0 = Math.random().toFloat() // initial cycle phase (xxxxFuncX)
- var rngBase1 = Math.random().toFloat() // flicker P0, etc
- var rngBase2 = Math.random().toFloat() // flicker P1, etc
+ @Transient var rngBase0 = Math.random().toFloat() // initial cycle phase (xxxxFuncX)
+ @Transient var rngBase1 = Math.random().toFloat() // flicker P0, etc
+ @Transient var rngBase2 = Math.random().toFloat() // flicker P1, etc
}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/blockproperties/WireCodex.kt b/src/net/torvald/terrarum/blockproperties/WireCodex.kt
index 5a0ae7eb4..2a74a8f9b 100644
--- a/src/net/torvald/terrarum/blockproperties/WireCodex.kt
+++ b/src/net/torvald/terrarum/blockproperties/WireCodex.kt
@@ -17,7 +17,7 @@ import java.io.IOException
*/
object WireCodex {
- private var wireProps = HashMap()
+ val wireProps = HashMap()
private val nullProp = WireProp()
diff --git a/src/net/torvald/terrarum/console/CommandDict.kt b/src/net/torvald/terrarum/console/CommandDict.kt
index 7290d43d0..8a606ba27 100644
--- a/src/net/torvald/terrarum/console/CommandDict.kt
+++ b/src/net/torvald/terrarum/console/CommandDict.kt
@@ -48,7 +48,6 @@ object CommandDict {
// Test codes
"bulletintest" to SetBulletin,
- "gsontest" to GsonTest,
"tips" to PrintRandomTips,
"langtest" to LangTest,
"spawnball" to SpawnPhysTestBall,
diff --git a/src/net/torvald/terrarum/controller/TerrarumController.kt b/src/net/torvald/terrarum/controller/TerrarumController.kt
index aced53db5..3aee97ea7 100644
--- a/src/net/torvald/terrarum/controller/TerrarumController.kt
+++ b/src/net/torvald/terrarum/controller/TerrarumController.kt
@@ -1,7 +1,7 @@
package net.torvald.terrarum.controller
import net.torvald.terrarum.AppLoader.gamepadDeadzone
-import net.torvald.terrarum.AppLoader.getConfigFloatArray
+import net.torvald.terrarum.AppLoader.getConfigDoubleArray
/**
* Created by minjaesong on 2019-02-09.
@@ -49,7 +49,7 @@ interface TerrarumController {
*/
fun getAxis(index:Int): Float {
val raw = getAxisRaw(index)
- val zero = if (index < 4) getConfigFloatArray("gamepadaxiszeropoints")[index] else 0f
+ val zero = if (index < 4) getConfigDoubleArray("gamepadaxiszeropoints")[index] else 0.0
val compensatedRaw = raw - zero
val inDeadzone = Math.abs(compensatedRaw) < gamepadDeadzone
@@ -58,7 +58,7 @@ interface TerrarumController {
fun inDeadzone(axis: Int): Boolean {
val ax = getAxisRaw(axis)
- val zero = if (axis < 4) getConfigFloatArray("gamepadaxiszeropoints")[axis] else 0f
+ val zero = if (axis < 4) getConfigDoubleArray("gamepadaxiszeropoints")[axis] else 0.0
return Math.abs(ax - zero) < gamepadDeadzone
}
diff --git a/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt b/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt
index d3ed1fcee..4c5d56a45 100644
--- a/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt
+++ b/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt
@@ -16,12 +16,12 @@ object FactionFactory {
@Throws(IOException::class)
fun create(module: String, path: String): Faction {
val jsonObj = JsonFetcher(ModMgr.getFile(module, path))
- val factionObj = Faction(jsonObj.get("factionname").asString)
+ val factionObj = Faction(jsonObj.getString("factionname"))
- jsonObj.get("factionamicable").asJsonArray.forEach { factionObj.addFactionAmicable(it.asString) }
- jsonObj.get("factionneutral").asJsonArray.forEach { factionObj.addFactionNeutral(it.asString) }
- jsonObj.get("factionhostile").asJsonArray.forEach { factionObj.addFactionHostile(it.asString) }
- jsonObj.get("factionfearful").asJsonArray.forEach { factionObj.addFactionFearful(it.asString) }
+ jsonObj.get("factionamicable").asStringArray().forEach { factionObj.addFactionAmicable(it) }
+ jsonObj.get("factionneutral").asStringArray().forEach { factionObj.addFactionNeutral(it) }
+ jsonObj.get("factionhostile").asStringArray().forEach { factionObj.addFactionHostile(it) }
+ jsonObj.get("factionfearful").asStringArray().forEach { factionObj.addFactionFearful(it) }
return factionObj
}
diff --git a/src/net/torvald/terrarum/gamecontroller/KeyLayout.kt b/src/net/torvald/terrarum/gamecontroller/KeyLayout.kt
index 5119cd2a4..dffedf719 100644
--- a/src/net/torvald/terrarum/gamecontroller/KeyLayout.kt
+++ b/src/net/torvald/terrarum/gamecontroller/KeyLayout.kt
@@ -1,8 +1,12 @@
package net.torvald.terrarum.gamecontroller
+import com.badlogic.gdx.utils.JsonValue
import net.torvald.terrarum.utils.JsonFetcher
import java.util.*
+
+
+
/**
* Created by minjaesong on 2016-07-28.
*/
@@ -16,17 +20,18 @@ object KeyLayout {
init {
layouts = HashMap()
- val json = JsonFetcher("./res/keylayout.json")
- json.entrySet().forEach { it ->
+ val map = net.torvald.terrarum.utils.JsonFetcher("./res/keylayout.json")
+ JsonFetcher.forEach(map) { name, entry ->
layouts.put(
- it.key,
+ name,
KeyLayoutClass(
- it.value.asJsonObject.get("layout").asString,
- it.value.asJsonObject.get("name").asString,
- it.value.asJsonObject.get("capslock").asString
+ entry.getString("layout"),
+ entry.getString("name"),
+ entry.getString("capslock")
)
)
}
+
}
}
diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt
index 597d4c087..dd865fcde 100644
--- a/src/net/torvald/terrarum/gameworld/GameWorld.kt
+++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt
@@ -11,7 +11,6 @@ import net.torvald.terrarum.blockproperties.Fluid
import net.torvald.terrarum.gameactors.WireActor
import net.torvald.terrarum.gameitem.ItemID
import net.torvald.terrarum.realestate.LandUtil
-import net.torvald.terrarum.serialise.ReadLayerDataZip
import net.torvald.util.SortedArrayList
import org.dyn4j.geometry.Vector2
import kotlin.experimental.and
@@ -165,31 +164,10 @@ open class GameWorld : Disposable {
/**
* Load existing world
*/
- internal constructor(worldIndex: Int, layerData: ReadLayerDataZip.LayerData, creationTIME_T: Long, lastPlayTIME_T: Long, totalPlayTime: Int) {
+ /*internal constructor(worldIndex: Int, json: JsonObject) {
this.worldIndex = worldIndex
- layerTerrain = layerData.layerTerrain
- layerWall = layerData.layerWall
- //layerWire = layerData.layerWire
-
- wallDamages = layerData.wallDamages
- terrainDamages = layerData.terrainDamages
- fluidTypes = layerData.fluidTypes
- fluidFills = layerData.fluidFills
-
- //wiringBlocks = HashMap()
- wirings = HashMap()
-
- spawnX = layerData.spawnX
- spawnY = layerData.spawnY
-
- width = layerTerrain.width
- height = layerTerrain.height
-
-
- creationTime = creationTIME_T
- lastPlayTime = lastPlayTIME_T
- this.totalPlayTime = totalPlayTime
+ // TODO setup layerTerrain, layerWall, etc. from the json
// before the renaming, update the name maps
tileNumberToNameMap = HashMap()
@@ -200,7 +178,7 @@ open class GameWorld : Disposable {
}
// perform renaming of tile layers
- val oldTileNumberToNameMap = layerData.tileNumberToNameMap
+ val oldTileNumberToNameMap = /* todo */
for (y in 0 until layerTerrain.height) {
for (x in 0 until layerTerrain.width) {
layerTerrain.unsafeSetTile(x, y, tileNameToNumberMap[oldTileNumberToNameMap[layerTerrain.unsafeGetTile(x, y)]]!!)
@@ -212,7 +190,7 @@ open class GameWorld : Disposable {
// AN EXCEPTIONAL TERM: tilenum 0 is always redirected to Air tile, even if the tilenum for actual Air tile is not zero
tileNumberToNameMap[0] = Block.AIR
- }
+ }*/
/**
* Get 2d array data of wire
diff --git a/src/net/torvald/terrarum/itemproperties/ItemCodex.kt b/src/net/torvald/terrarum/itemproperties/ItemCodex.kt
index df0d7593e..df4147a7b 100644
--- a/src/net/torvald/terrarum/itemproperties/ItemCodex.kt
+++ b/src/net/torvald/terrarum/itemproperties/ItemCodex.kt
@@ -26,7 +26,7 @@ object ItemCodex {
*
* Will return corresponding Actor if ID >= ACTORID_MIN
*/
- private val itemCodex = HashMap()
+ val itemCodex = HashMap()
val dynamicItemDescription = HashMap()
val dynamicToStaticTable = HashMap()
@@ -119,5 +119,5 @@ object ItemCodex {
}
- fun hasItem(itemID: Int): Boolean = dynamicItemDescription.containsKey(itemID)
+ fun hasItem(itemID: ItemID): Boolean = dynamicItemDescription.containsKey(itemID)
}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/itemproperties/Material.kt b/src/net/torvald/terrarum/itemproperties/Material.kt
index 76526681e..47b15d8d1 100644
--- a/src/net/torvald/terrarum/itemproperties/Material.kt
+++ b/src/net/torvald/terrarum/itemproperties/Material.kt
@@ -28,7 +28,7 @@ class Material {
object MaterialCodex {
- private var materialProps = HashMap()
+ val materialProps = HashMap()
private val nullMaterial = Material()
operator fun invoke(module: String, path: String) {
diff --git a/src/net/torvald/terrarum/langpack/Lang.kt b/src/net/torvald/terrarum/langpack/Lang.kt
index 3aad4c796..a2b8b3a66 100644
--- a/src/net/torvald/terrarum/langpack/Lang.kt
+++ b/src/net/torvald/terrarum/langpack/Lang.kt
@@ -82,9 +82,10 @@ object Lang {
* "<>" = "<>"
*/
//println(json.entrySet())
- json.entrySet().forEach {
- langpack.put("${it.key}_$lang", it.value.asString)
+ JsonFetcher.forEach(json) { key, value ->
+ langpack.put("${key}_$lang", value.asString())
}
+
}
private fun processPolyglotLangFile(file: File, lang: String) {
@@ -106,12 +107,13 @@ object Lang {
* (the array continues)
*
*/
- json.getAsJsonObject("resources").getAsJsonArray("data").forEach {
+ JsonFetcher.forEach(json.get("resources").get("data")) { _, entry ->
langpack.put(
- "${it.asJsonObject["n"].asString}_$lang",
- it.asJsonObject["s"].asString
+ "${entry.getString("n")}_$lang",
+ entry.getString("s")
)
}
+
}
operator fun get(key: String): String {
diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt
index d9e781ed7..394ce0fce 100644
--- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt
+++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt
@@ -303,7 +303,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
// init map as chosen size
val timeNow = System.currentTimeMillis() / 1000
gameworld = GameWorldExtension(1, worldParams.width, worldParams.height, timeNow, timeNow, 0) // new game, so the creation time is right now
- gameworldCount++
+ gameworldIndices.add(gameworld.worldIndex)
world = gameworld
// generate terrain for the map
diff --git a/src/net/torvald/terrarum/modulebasegame/console/ExportAV.kt b/src/net/torvald/terrarum/modulebasegame/console/ExportAV.kt
index 49d2adde6..ed1de7c98 100644
--- a/src/net/torvald/terrarum/modulebasegame/console/ExportAV.kt
+++ b/src/net/torvald/terrarum/modulebasegame/console/ExportAV.kt
@@ -20,7 +20,7 @@ internal object ExportAV : ConsoleCommand {
if (player == null) return
JsonWriter.writeToFile(
- player.actorValue,
+ player,
AppLoader.defaultDir + "/Exports/" + args[1] + ".json")
Echo("ExportAV: exported to " + args[1] + ".json")
diff --git a/src/net/torvald/terrarum/modulebasegame/console/ExportLayerData.kt b/src/net/torvald/terrarum/modulebasegame/console/ExportLayerData.kt
index b1535d0f0..5767dcb50 100644
--- a/src/net/torvald/terrarum/modulebasegame/console/ExportLayerData.kt
+++ b/src/net/torvald/terrarum/modulebasegame/console/ExportLayerData.kt
@@ -1,22 +1,31 @@
package net.torvald.terrarum.modulebasegame.console
+import com.badlogic.gdx.utils.Json
+import net.torvald.terrarum.AppLoader
+import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.console.ConsoleCommand
import net.torvald.terrarum.console.Echo
+import net.torvald.terrarum.modulebasegame.TerrarumIngame
+import net.torvald.terrarum.serialise.WriteMeta
+import net.torvald.terrarum.utils.JsonWriter
+import java.io.IOException
/**
* Created by minjaesong on 2017-07-18.
*/
object ExportLayerData : ConsoleCommand {
override fun execute(args: Array) {
- /*try {
- val outfile = WriteLayerDataZip()
- WriteWorldInfo()
- Echo("Layer data exported to ${outfile!!.canonicalPath}")
+ try {
+ val str = WriteMeta(Terrarum.ingame!! as TerrarumIngame).invoke()
+ val writer = java.io.FileWriter(AppLoader.defaultDir + "/Exports/savegame.json", false)
+ writer.write(str)
+ writer.close()
+ Echo("Exportlayer: exported to savegame.json")
}
- catch (e: Exception) {
+ catch (e: IOException) {
+ Echo("Exportlayer: IOException raised.")
e.printStackTrace()
- EchoError("Layer data export failed; see console for error traces.")
- }*/
+ }
}
override fun printUsage() {
diff --git a/src/net/torvald/terrarum/modulebasegame/console/GsonTest.kt b/src/net/torvald/terrarum/modulebasegame/console/GsonTest.kt
index 04c1c10e9..8ad88d89e 100644
--- a/src/net/torvald/terrarum/modulebasegame/console/GsonTest.kt
+++ b/src/net/torvald/terrarum/modulebasegame/console/GsonTest.kt
@@ -13,7 +13,7 @@ import java.io.IOException
/**
* Created by minjaesong on 2016-02-10.
*/
-internal object GsonTest : ConsoleCommand {
+/*internal object GsonTest : ConsoleCommand {
override fun execute(args: Array) {
if (args.size == 2) {
@@ -51,4 +51,4 @@ internal object GsonTest : ConsoleCommand {
Echo("Usage: gsontest filename-without-extension")
}
-}
+}*/
diff --git a/src/net/torvald/terrarum/modulebasegame/console/ImportLayerData.kt b/src/net/torvald/terrarum/modulebasegame/console/ImportLayerData.kt
index 35cee4852..685273891 100644
--- a/src/net/torvald/terrarum/modulebasegame/console/ImportLayerData.kt
+++ b/src/net/torvald/terrarum/modulebasegame/console/ImportLayerData.kt
@@ -5,7 +5,6 @@ import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
import net.torvald.terrarum.console.ConsoleCommand
import net.torvald.terrarum.console.Echo
import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension
-import net.torvald.terrarum.serialise.ReadLayerDataZip
import java.io.File
/**
@@ -13,7 +12,7 @@ import java.io.File
*/
object ImportLayerData : ConsoleCommand {
override fun execute(args: Array) {
- if (args.size < 2) {
+ /*if (args.size < 2) {
ExportLayerData.printUsage()
return
}
@@ -28,7 +27,7 @@ object ImportLayerData : ConsoleCommand {
(Terrarum.ingame!!.world).spawnX * TILE_SIZED
)
- Echo("Successfully loaded ${args[1]}")
+ Echo("Successfully loaded ${args[1]}")*/
}
override fun printUsage() {
diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt
index f27d36271..173aff676 100644
--- a/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt
+++ b/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt
@@ -2,13 +2,12 @@ package net.torvald.terrarum.modulebasegame.gameactors
import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.random.Fudge3
-import net.torvald.terrarum.langpack.Lang
-import com.google.gson.JsonObject
import net.torvald.terrarum.AppLoader.printdbg
import net.torvald.terrarum.ModMgr
import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.gameactors.ActorValue
import java.security.SecureRandom
+import kotlin.collections.ArrayList
/**
* Created by minjaesong on 2016-03-25.
@@ -27,46 +26,44 @@ object InjectCreatureRaw {
operator fun invoke(actorValueRef: ActorValue, module: String, jsonFileName: String) {
val jsonObj = JsonFetcher(ModMgr.getPath(module, "creatures/$jsonFileName"))
- jsonObj.keySet().filter { !it.startsWith("_") }.forEach { key ->
+ JsonFetcher.forEach(jsonObj) { key, value -> if (!key.startsWith("_")) {
val diceRollers = ArrayList()
- jsonObj[key].let {
- if (it.isJsonPrimitive) {
- val raw = it.asString
- val lowraw = raw.toLowerCase()
- // can the value be cast to Boolean?
- if (lowraw == "true") actorValueRef[key] = true
- else if (lowraw == "false") actorValueRef[key] = false
- else {
- try {
- actorValueRef[key] =
- if (raw.contains('.')) it.asDouble
- else it.asInt
- }
- catch (e: NumberFormatException) {
- actorValueRef[key] = raw
- }
+ if (!value.isArray && !value.isObject) {
+ val raw = value.asString()
+ val lowraw = raw.lowercase()
+ // can the value be cast to Boolean?
+ if (lowraw == "true") actorValueRef[key] = true
+ else if (lowraw == "false") actorValueRef[key] = false
+ else {
+ try {
+ actorValueRef[key] =
+ if (raw.contains('.')) value.asDouble()
+ else value.asLong().toInt()
+ }
+ catch (e: NumberFormatException) {
+ actorValueRef[key] = raw
}
}
- else if (key.endsWith(JSONMULT) && it.isJsonArray) {
- diceRollers.add(key)
- }
- else {
- printdbg(this, "Unknown Creature Raw key: $key")
- }
+ }
+ else if (key.endsWith(JSONMULT) && value.isArray) {
+ diceRollers.add(key)
+ }
+ else {
+ printdbg(this, "Unknown Creature Raw key: $key")
}
diceRollers.forEach { keymult ->
val keybase = keymult.substring(0, keymult.length - 4)
- val baseValue = jsonObj[keybase].asDouble
+ val baseValue = jsonObj[keybase].asDouble()
val selected = Fudge3(SecureRandom()).rollForArray()
- val mult = jsonObj[keymult].asJsonArray.get(selected).asInt
+ val mult = jsonObj[keymult].asIntArray()[selected]
val realValue = baseValue * mult / 100.0
actorValueRef[keybase] = realValue
actorValueRef[keybase + BUFF] = 1.0
}
- }
+ } }
}
}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/modulebasegame/gameworld/GameWorldExtension.kt b/src/net/torvald/terrarum/modulebasegame/gameworld/GameWorldExtension.kt
index 5b45fe4ce..7b2280eb5 100644
--- a/src/net/torvald/terrarum/modulebasegame/gameworld/GameWorldExtension.kt
+++ b/src/net/torvald/terrarum/modulebasegame/gameworld/GameWorldExtension.kt
@@ -2,7 +2,6 @@ package net.torvald.terrarum.modulebasegame.gameworld
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.gameworld.WorldTime
-import net.torvald.terrarum.serialise.ReadLayerDataZip
/**
* Created by minjaesong on 2018-07-03.
@@ -10,7 +9,7 @@ import net.torvald.terrarum.serialise.ReadLayerDataZip
class GameWorldExtension : GameWorld {
constructor(worldIndex: Int, width: Int, height: Int, creationTIME_T: Long, lastPlayTIME_T: Long, totalPlayTime: Int) : super(worldIndex, width, height, creationTIME_T, lastPlayTIME_T, totalPlayTime)
- internal constructor(worldIndex: Int, layerData: ReadLayerDataZip.LayerData, creationTIME_T: Long, lastPlayTIME_T: Long, totalPlayTime: Int) : super(worldIndex, layerData, creationTIME_T, lastPlayTIME_T, totalPlayTime)
+ //internal constructor(worldIndex: Int, layerData: ReadLayerDataZip.LayerData, creationTIME_T: Long, lastPlayTIME_T: Long, totalPlayTime: Int) : super(worldIndex, layerData, creationTIME_T, lastPlayTIME_T, totalPlayTime)
val economy = GameEconomy()
diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIBuildingMakerPenMenu.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIBuildingMakerPenMenu.kt
index 639f47fee..09a4ef855 100644
--- a/src/net/torvald/terrarum/modulebasegame/ui/UIBuildingMakerPenMenu.kt
+++ b/src/net/torvald/terrarum/modulebasegame/ui/UIBuildingMakerPenMenu.kt
@@ -6,6 +6,7 @@ import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.*
+import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.modulebasegame.BuildingMaker
import net.torvald.terrarum.ui.UICanvas
@@ -153,7 +154,19 @@ class UIBuildingMakerPenMenu(val parent: BuildingMaker): UICanvas() {
// draw blocks slot
batch.color = blockCellCol
- val slotConfig = AppLoader.getConfigStringArray("buildingmakerfavs")
+ val slotConfig = arrayOf(
+ Block.GLASS_CRUDE,
+ Block.PLANK_NORMAL,
+ Block.PLANK_BIRCH,
+ Block.STONE_QUARRIED,
+ Block.STONE_BRICKS,
+
+ Block.STONE_TILE_WHITE,
+ Block.TORCH,
+ "wall@" + Block.PLANK_NORMAL,
+ "wall@" + Block.PLANK_BIRCH,
+ "wall@" + Block.GLASS_CRUDE
+ )//AppLoader.getConfigStringArray("buildingmakerfavs")
for (i in 0 until PALETTE_SIZE) {
val x = blockCellPos[i].x.roundToInt().toFloat()
val y = blockCellPos[i].y.roundToInt().toFloat()
diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIItemPlayerInfoCell.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIItemPlayerInfoCell.kt
index 0daf29dc7..d3518d181 100644
--- a/src/net/torvald/terrarum/modulebasegame/ui/UIItemPlayerInfoCell.kt
+++ b/src/net/torvald/terrarum/modulebasegame/ui/UIItemPlayerInfoCell.kt
@@ -2,10 +2,10 @@ package net.torvald.terrarum.modulebasegame.ui
import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.g2d.SpriteBatch
+import com.badlogic.gdx.utils.JsonValue
import net.torvald.terrarum.*
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
-import net.torvald.terrarum.serialise.ReadWorldInfo
import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.ui.UIItem
import java.util.*
@@ -17,7 +17,7 @@ import java.util.*
*/
class UIItemPlayerInfoCell(
parent: UICanvas,
- val saveInfo: ReadWorldInfo.SaveMetaData,
+ val saveInfo: JsonValue,
override val width: Int,
initialX: Int,
initialY: Int,
@@ -50,18 +50,18 @@ class UIItemPlayerInfoCell(
init {
val cal = Calendar.getInstance()
- cal.timeInMillis = saveInfo.creationTime * 1000
+ cal.timeInMillis = saveInfo.getLong("creation_t") * 1000
creationTimeStr = "${cal[Calendar.YEAR]}-" +
"${cal[Calendar.MONTH].toString().padStart(2,'0')}-" +
"${cal[Calendar.DATE].toString().padStart(2,'0')}"
- cal.timeInMillis = saveInfo.lastPlayTime * 1000
+ cal.timeInMillis = saveInfo.getLong("lastplay_t") * 1000
modificationTimeStr = "${cal[Calendar.YEAR]}-" +
"${cal[Calendar.MONTH].toString().padStart(2,'0')}-" +
"${cal[Calendar.DATE].toString().padStart(2,'0')}"
- worldCountStr = Lang["CONTEXT_WORLD_COUNT"] + saveInfo.worldCount
+ worldCountStr = Lang["CONTEXT_WORLD_COUNT"] + saveInfo.get("worlds").asIntArray().size
worldCountStrWidth = AppLoader.fontGame.getWidth(worldCountStr)
}
diff --git a/src/net/torvald/terrarum/serialise/PayloadUtil.kt b/src/net/torvald/terrarum/serialise/PayloadUtil.kt
deleted file mode 100644
index 523e7374e..000000000
--- a/src/net/torvald/terrarum/serialise/PayloadUtil.kt
+++ /dev/null
@@ -1,114 +0,0 @@
-package net.torvald.terrarum.serialise
-
-import net.torvald.terrarum.AppLoader
-import net.torvald.terrarum.serialise.WriteLayerDataZip.FILE_FOOTER
-import net.torvald.terrarum.serialise.WriteLayerDataZip.PAYLOAD_FOOTER
-import net.torvald.terrarum.toHex
-import java.nio.charset.Charset
-import java.util.*
-
-/**
- * Created by minjaesong on 2019-02-20.
- */
-
-object PayloadUtil {
- /**
- * InputStream must be located manually at the payload begin
- *
- * For the actual use case, take a look at the source of the [ReadLayerDataZip].
- */
- fun readAll(inputStream: MarkableFileInputStream, footer: ByteArray = FILE_FOOTER): HashMap {
- val pldBuffer4 = ByteArray(4)
- val pldBuffer6 = ByteArray(6)
- val pldBuffer8 = ByteArray(8)
-
- val payloads = HashMap()
-
- var pldCnt = 1
-
- while (true) {
- // read header and get payload's name
- inputStream.read(pldBuffer8)
-
- // check if end of payload reached
- if (pldBuffer8.contentEquals(footer)) {
- break
- }
-
- val payloadName = pldBuffer8.copyOfRange(4, 8).toString(Charset.forName("US-ASCII"))
-
- AppLoader.printdbg(this, "Payload $pldCnt name: $payloadName") // maybe maybe related with buffer things?
-
- // get uncompressed size
- inputStream.read(pldBuffer6)
- val uncompressedSize = pldBuffer6.toLittleInt48()
-
- // get deflated size
- inputStream.mark(2147483647) // FIXME deflated stream cannot be larger than 2 GB
- // creep forward until we hit the PAYLOAD_FOOTER
- var compressedSize: Int = 0 // FIXME deflated stream cannot be larger than 2 GB
- // loop init
- inputStream.read(pldBuffer8)
- // loop main
- while (!pldBuffer8.contentEquals(PAYLOAD_FOOTER)) {
- val aByte = inputStream.read(); compressedSize += 1
- if (aByte == -1) throw InternalError("Unexpected end-of-file at payload $pldCnt")
- pldBuffer8.shiftLeftBy(1, aByte.toByte())
- }
-
- // at this point, we should have correct size of deflated bytestream
-
- AppLoader.printdbg(this, "Payload $pldCnt compressed size: $compressedSize")
-
- val compressedBytes = ByteArray(compressedSize) // FIXME deflated stream cannot be larger than 2 GB
- inputStream.reset() // go back to marked spot
- inputStream.read(compressedBytes)
-
- // PRO Debug tip: every deflated bytes must begin with 0x789C or 0x78DA
- // Thus, \0pLd + [10] must be either of these.
-
- // put constructed payload into a container
- payloads.put(payloadName, TEMzPayload(uncompressedSize, compressedBytes))
-
- // skip over to be aligned with the next payload
- inputStream.skip(8)
-
- pldCnt += 1
- }
-
- return payloads
- }
-
- private fun ByteArray.shiftLeftBy(size: Int, fill: Byte = 0.toByte()) {
- if (size == 0) {
- return
- }
- else if (size < 0) {
- throw IllegalArgumentException("This won't shift to right (size = $size)")
- }
- else if (size >= this.size) {
- Arrays.fill(this, 0.toByte())
- }
- else {
- for (c in size..this.lastIndex) {
- this[c - size] = this[c]
- }
- for (c in (this.size - size)..this.lastIndex) {
- this[c] = fill
- }
- }
- }
-
- private fun ByteArray.toByteString(): String {
- val sb = StringBuilder()
- this.forEach {
- sb.append(it.toUint().toHex().takeLast(2))
- sb.append(' ')
- }
- sb.deleteCharAt(sb.lastIndex)
- return sb.toString()
- }
-
- data class TEMzPayload(val uncompressedSize: Long, val bytes: ByteArray) // FIXME deflated stream cannot be larger than 2 GB
-
-}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/serialise/ReadLayerData.kt b/src/net/torvald/terrarum/serialise/ReadLayerData.kt
deleted file mode 100644
index fd475c2e4..000000000
--- a/src/net/torvald/terrarum/serialise/ReadLayerData.kt
+++ /dev/null
@@ -1,188 +0,0 @@
-package net.torvald.terrarum.serialise
-
-/**
- * Only being used by the title screen and the demoworld. This object may get deleted at any update
- *
- * Created by minjaesong on 2016-08-24.
- */
-// internal for everything: prevent malicious module from messing up the savedata
-@Deprecated("TEMD is deprecated format; use TEMz which does compression")
-internal object ReadLayerData {
-
- init {
- throw Error("TEMD is old and removed format; use TEMz which does compression")
- }
-
- /*internal operator fun invoke(inputStream: InputStream, inWorld: GameWorldExtension? = null): GameWorldExtension {
- val magicBytes = ByteArray(4)
- val layerSizeBytes = ByteArray(1)
- val layerCountBytes = ByteArray(1)
- val worldWidthBytes = ByteArray(4)
- val worldHeightBytes = ByteArray(4)
- val spawnCoordXBytes = ByteArray(4)
- val spawnCoordYBytes = ByteArray(4)
-
- // read header first
- inputStream.read(magicBytes)
- if (!Arrays.equals(magicBytes, WriteLayerData.MAGIC)) {
- throw IllegalArgumentException("File not a Layer Data")
- }
-
- inputStream.read(layerSizeBytes)
- inputStream.read(layerCountBytes)
- inputStream.skip(2) // reserved bytes
- inputStream.read(worldWidthBytes)
- inputStream.read(worldHeightBytes)
- inputStream.read(spawnCoordXBytes)
- inputStream.read(spawnCoordYBytes)
-
- val worldWidth = worldWidthBytes.toLittleInt()
- val worldHeight = worldHeightBytes.toLittleInt()
- val bytesPerTile = layerSizeBytes[0].toUint()
- val layerCount = layerCountBytes[0].toUint()
- val layerSize = worldWidth * worldHeight * bytesPerTile
-
- val terrainLayerMSB = ByteArray(layerSize)
- val wallLayerMSB = ByteArray(layerSize)
- val terrainLayerLSB = ByteArray(layerSize / 2)
- val wallLayerLSB = ByteArray(layerSize / 2)
- var wireLayer: ByteArray? = null
-
- inputStream.read(terrainLayerMSB)
- inputStream.read(wallLayerMSB)
- inputStream.read(terrainLayerLSB)
- inputStream.read(wallLayerLSB)
-
- if (layerCount == 4) {
- wireLayer = ByteArray(layerSize)
- inputStream.read(wireLayer)
- }
-
-
-
- // create world out of tiles data
-
- val retWorld = inWorld ?: GameWorldExtension(1, worldWidth, worldHeight, 0, 0, 0) // FIXME null TIME_T for the (partial) test to pass
-
- retWorld.layerTerrain.data = terrainLayerMSB
- retWorld.layerWall.data = wallLayerMSB
- retWorld.layerTerrainLowBits.data = terrainLayerLSB
- retWorld.layerWallLowBits.data = wallLayerLSB
-
-
- retWorld.spawnX = spawnCoordXBytes.toLittleInt()
- retWorld.spawnY = spawnCoordYBytes.toLittleInt()
-
-
- return retWorld
- }
-
-
- internal fun InputStream.readRelative(b: ByteArray, off: Int, len: Int): Int {
- if (b == null) {
- throw NullPointerException()
- } else if (off < 0 || len < 0 || len > b.size) {
- throw IndexOutOfBoundsException()
- } else if (len == 0) {
- return 0
- }
-
- var c = read()
- if (c == -1) {
- return -1
- }
- b[0] = c.toByte()
-
- var i = 1
- try {
- while (i < len) {
- c = read()
- if (c == -1) {
- break
- }
- b[i] = c.toByte()
- i++
- }
- } catch (ee: IOException) {
- }
-
- return i
- }*/
-}
-
-fun Int.toLittle() = byteArrayOf(
- this.and(0xFF).toByte(),
- this.ushr(8).and(0xFF).toByte(),
- this.ushr(16).and(0xFF).toByte(),
- this.ushr(24).and(0xFF).toByte()
-)
-/** Converts int as 2-byte array, discarding the sign.*/
-fun Int.toULittleShort() = byteArrayOf(
- this.and(0xFF).toByte(),
- this.ushr(8).and(0xFF).toByte()
-)
-/** Converts int as 2-byte array, preserving the sign. In other words, it converts int to short. */
-fun Int.toLittleShort() = byteArrayOf(
- this.and(0xFF).toByte(),
- this.shr(8).and(0xFF).toByte()
-)
-fun Long.toLittle() = byteArrayOf(
- this.and(0xFF).toByte(),
- this.ushr(8).and(0xFF).toByte(),
- this.ushr(16).and(0xFF).toByte(),
- this.ushr(24).and(0xFF).toByte(),
- this.ushr(32).and(0xFF).toByte(),
- this.ushr(40).and(0xFF).toByte(),
- this.ushr(48).and(0xFF).toByte(),
- this.ushr(56).and(0xFF).toByte()
-)
-/** Converts long as 6-byte array, discarding the sign. */
-fun Long.toULittle48() = byteArrayOf(
- this.and(0xFF).toByte(),
- this.ushr(8).and(0xFF).toByte(),
- this.ushr(16).and(0xFF).toByte(),
- this.ushr(24).and(0xFF).toByte(),
- this.ushr(32).and(0xFF).toByte(),
- this.ushr(40).and(0xFF).toByte()
-)
-fun Double.toLittle() = java.lang.Double.doubleToRawLongBits(this).toLittle()
-fun Boolean.toLittle() = byteArrayOf(if (this) 0xFF.toByte() else 0.toByte())
-
-fun ByteArray.toLittleInt() =
- if (this.size != 4) throw Error("Array not in size of 4")
- else this[0].toUint() or
- this[1].toUint().shl(8) or
- this[2].toUint().shl(16) or
- this[3].toUint().shl(24)
-fun ByteArray.toULittleShort() =
- if (this.size != 4) throw Error("Array not in size of 2")
- else this[0].toUint() or
- this[1].toUint().shl(8)
-fun ByteArray.toLittleShort() =
- if (this.size != 4) throw Error("Array not in size of 2")
- else this[0].toUint() or
- this[1].toInt().shl(8)
-fun ByteArray.toLittleLong() =
- if (this.size != 8) throw Error("Array not in size of 8")
- else this[0].toUlong() or
- this[1].toUlong().shl(8) or
- this[2].toUlong().shl(16) or
- this[3].toUlong().shl(24) or
- this[4].toUlong().shl(32) or
- this[5].toUlong().shl(40) or
- this[6].toUlong().shl(48) or
- this[7].toUlong().shl(56)
-fun ByteArray.toLittleInt48() =
- if (this.size != 6) throw Error("Array not in size of 6")
- else this[0].toUlong() or
- this[1].toUlong().shl(8) or
- this[2].toUlong().shl(16) or
- this[3].toUlong().shl(24) or
- this[4].toUlong().shl(32) or
- this[5].toUlong().shl(40)
-fun ByteArray.toLittleFloat() = java.lang.Float.intBitsToFloat(this.toLittleInt())
-
-fun Byte.toUlong() = java.lang.Byte.toUnsignedLong(this)
-fun Byte.toUint() = java.lang.Byte.toUnsignedInt(this)
-
-const val WORLD_GENERATOR_VERSION = 1
diff --git a/src/net/torvald/terrarum/serialise/ReadLayerDataLzma.kt b/src/net/torvald/terrarum/serialise/ReadLayerDataLzma.kt
deleted file mode 100644
index d5cd4a57e..000000000
--- a/src/net/torvald/terrarum/serialise/ReadLayerDataLzma.kt
+++ /dev/null
@@ -1,224 +0,0 @@
-package net.torvald.terrarum.serialise
-
-import com.badlogic.gdx.utils.compression.Lzma
-import net.torvald.terrarum.AppLoader.printdbg
-import net.torvald.terrarum.gameitem.ItemID
-import net.torvald.terrarum.gameworld.BlockAddress
-import net.torvald.terrarum.gameworld.BlockLayer
-import net.torvald.terrarum.gameworld.FluidType
-import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.DiskSkimmer.Companion.read
-import net.torvald.terrarum.realestate.LandUtil
-import java.io.*
-import java.util.*
-import kotlin.collections.HashMap
-
-/**
- * Created by minjaesong on 2016-08-24.
- */
-// internal for everything: prevent malicious module from messing up the savedata
-internal object ReadLayerDataLzma {
-
- // FIXME TERRAIN DAMAGE UNTESTED
-
- internal operator fun invoke(file: File): ReadLayerDataZip.LayerData {
- val inputStream = MarkableFileInputStream(FileInputStream(file))
-
-
- val magicBytes = ByteArray(4)
-
-
- //////////////////
- // FILE READING //
- //////////////////
-
-
- // read header first
- inputStream.read(magicBytes)
- if (!Arrays.equals(magicBytes, WriteLayerDataZip.MAGIC)) {
- throw IllegalArgumentException("File not a Layer Data")
- }
-
- 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 generatorVer = inputStream.read(2).toULittleShort()
- val width = inputStream.read(4).toLittleInt()
- val height = inputStream.read(4).toLittleInt()
- val spawnAddress = inputStream.read(6).toLittleInt48()
-
- if (compression != 2) throw IllegalArgumentException("Input file is not compressed as LZMA; it's using algorithm $compression")
-
- printdbg(this, "Version number: $versionNumber")
- printdbg(this, "Layers count: $layerCount")
- printdbg(this, "Payloads count: $payloadCount")
- printdbg(this, "Compression: $compression")
- printdbg(this, "World generator version: $generatorVer")
- printdbg(this, "Dimension: ${width}x$height")
-
- // read payloads
-
- val payloads = PayloadUtil.readAll(inputStream)
- /*val pldBuffer4 = ByteArray(4)
- val pldBuffer6 = ByteArray(6)
- val pldBuffer8 = ByteArray(8)
-
- val payloads = HashMap()
-
-
- // TODO please test the read; write has been fixed up
-
- for (pldCnt in 0 until payloadCount) {
- inputStream.read(pldBuffer4)
-
- // check payload header
- if (!pldBuffer4.contentEquals(WriteLayerDataZip.PAYLOAD_HEADER))
- throw InternalError("Payload $pldCnt not found -- expected ${WriteLayerDataZip.PAYLOAD_HEADER.toByteString()}, got ${pldBuffer4.toByteString()}")
-
- // get payload's name
- inputStream.read(pldBuffer4)
- val payloadName = pldBuffer4.toString(Charset.forName("US-ASCII"))
-
- printdbg(this, "Payload $pldCnt name: $payloadName") // maybe maybe related with buffer things?
-
- // get uncompressed size
- inputStream.read(pldBuffer6)
- val uncompressedSize = pldBuffer6.toLittleInt48()
-
- // get deflated size
- inputStream.mark(2147483647) // FIXME deflated stream cannot be larger than 2 GB
- // creep forward until we hit the PAYLOAD_FOOTER
- var deflatedSize: Int = 0 // FIXME deflated stream cannot be larger than 2 GB
- // loop init
- inputStream.read(pldBuffer8)
- // loop main
- while (!pldBuffer8.contentEquals(WriteLayerDataZip.PAYLOAD_FOOTER)) {
- val aByte = inputStream.read(); deflatedSize += 1
- if (aByte == -1) throw InternalError("Unexpected end-of-file at payload $pldCnt")
- pldBuffer8.shiftLeftBy(1, aByte.toByte())
- }
-
- // at this point, we should have correct size of deflated bytestream
-
- printdbg(this, "Payload $pldCnt compressed size: $deflatedSize")
-
- val deflatedBytes = ByteArray(deflatedSize) // FIXME deflated stream cannot be larger than 2 GB
- inputStream.reset() // go back to marked spot
- inputStream.read(deflatedBytes)
-
- // PRO Debug tip: every deflated bytes must begin with 0x789C or 0x78DA
- // Thus, \0pLd + [10] must be either of these.
-
- // put constructed payload into a container
- payloads.put(payloadName, TEMzPayload(uncompressedSize, deflatedBytes))
-
- // skip over to be aligned with the next payload
- inputStream.skip(8)
- }
-
-
- // test for EOF
- inputStream.read(pldBuffer8)
- if (!pldBuffer8.contentEquals(WriteLayerDataZip.FILE_FOOTER))
- throw InternalError("Expected end-of-file, got not-so-end-of-file")*/
-
-
- //////////////////////
- // END OF FILE READ //
- //////////////////////
-
- val worldSize = width.toLong() * height
-
- val payloadBytes = HashMap()
-
- payloads.forEach { t, u ->
- val inflatedOS = ByteArrayOutputStream(u.uncompressedSize.toInt()) // FIXME deflated stream cannot be larger than 2 GB
-
- try {
- Lzma.decompress(ByteArrayInputStream(u.bytes), inflatedOS)
- }
- catch (e: RuntimeException) {
- // keep it empty (zero-sized file was compressed)
- }
-
- val inflatedFile = inflatedOS.toByteArray()
-
- payloadBytes[t] = inflatedFile
- }
-
- val spawnPoint = LandUtil.resolveBlockAddr(width, spawnAddress)
-
- val terrainDamages = HashMap()
- val wallDamages = HashMap()
- val fluidTypes = HashMap()
- val fluidFills = HashMap()
- val tileNumToName = HashMap()
-
- // parse terrain damages
- for (c in payloadBytes["TdMG"]!!.indices step 10) {
- val bytes = payloadBytes["TdMG"]!!
-
- val tileAddr = bytes.sliceArray(c..c+5)
- val value = bytes.sliceArray(c+6..c+9)
-
- terrainDamages[tileAddr.toLittleInt48()] = value.toLittleFloat()
- }
-
-
- // parse wall damages
- for (c in payloadBytes["WdMG"]!!.indices step 10) {
- val bytes = payloadBytes["WdMG"]!!
-
- val tileAddr = bytes.sliceArray(c..c+5)
- val value = bytes.sliceArray(c+6..c+9)
-
- wallDamages[tileAddr.toLittleInt48()] = value.toLittleFloat()
- }
-
-
- // TODO parse fluid(Types|Fills)
-
- // TODO parse tileNumToName
-
-
- return ReadLayerDataZip.LayerData(
- BlockLayer(width, height, payloadBytes["WALL"]!!),
- BlockLayer(width, height, payloadBytes["TERR"]!!),
-
- spawnPoint.first, spawnPoint.second,
-
- wallDamages, terrainDamages, fluidTypes, fluidFills, tileNumToName
- )
- }
-
- internal fun InputStream.readRelative(b: ByteArray, off: Int, len: Int): Int {
- if (b == null) {
- throw NullPointerException()
- } else if (off < 0 || len < 0 || len > b.size) {
- throw IndexOutOfBoundsException()
- } else if (len == 0) {
- return 0
- }
-
- var c = read()
- if (c == -1) {
- return -1
- }
- b[0] = c.toByte()
-
- var i = 1
- try {
- while (i < len) {
- c = read()
- if (c == -1) {
- break
- }
- b[i] = c.toByte()
- i++
- }
- } catch (ee: IOException) {
- }
-
- return i
- }
-}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/serialise/ReadLayerDataZip.kt b/src/net/torvald/terrarum/serialise/ReadLayerDataZip.kt
deleted file mode 100644
index b145aa682..000000000
--- a/src/net/torvald/terrarum/serialise/ReadLayerDataZip.kt
+++ /dev/null
@@ -1,243 +0,0 @@
-package net.torvald.terrarum.serialise
-
-import net.torvald.terrarum.AppLoader.printdbg
-import net.torvald.terrarum.gameitem.ItemID
-import net.torvald.terrarum.gameworld.BlockAddress
-import net.torvald.terrarum.gameworld.BlockLayer
-import net.torvald.terrarum.gameworld.FluidType
-import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.DiskSkimmer.Companion.read
-import net.torvald.terrarum.realestate.LandUtil
-import java.io.File
-import java.io.FileInputStream
-import java.io.IOException
-import java.io.InputStream
-import java.util.*
-import java.util.zip.Inflater
-import kotlin.collections.HashMap
-
-/**
- * Created by minjaesong on 2016-08-24.
- */
-// internal for everything: prevent malicious module from messing up the savedata
-internal object ReadLayerDataZip {
-
- // FIXME TERRAIN DAMAGE UNTESTED
-
- internal operator fun invoke(file: File): LayerData {
- val inputStream = MarkableFileInputStream(FileInputStream(file))
-
-
- val magicBytes = ByteArray(4)
-
-
- //////////////////
- // FILE READING //
- //////////////////
-
-
- // read header first
- inputStream.read(magicBytes)
- if (!Arrays.equals(magicBytes, WriteLayerDataZip.MAGIC)) {
- throw IllegalArgumentException("File not a Layer Data")
- }
-
- 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 generatorVer = inputStream.read(2).toULittleShort()
- val width = inputStream.read(4).toLittleInt()
- val height = inputStream.read(4).toLittleInt()
- val spawnAddress = inputStream.read(6).toLittleInt48()
-
- if (compression != 1) throw IllegalArgumentException("Input file is not compressed as DEFLATE; it's using algorithm $compression")
-
- printdbg(this, "Version number: $versionNumber")
- printdbg(this, "Layers count: $layerCount")
- printdbg(this, "Payloads count: $payloadCount")
- printdbg(this, "Compression: $compression")
- printdbg(this, "World generator version: $generatorVer")
- printdbg(this, "Dimension: ${width}x$height")
-
- // read payloads
-
- val payloads = PayloadUtil.readAll(inputStream)
- /*val pldBuffer4 = ByteArray(4)
- val pldBuffer6 = ByteArray(6)
- val pldBuffer8 = ByteArray(8)
-
- val payloads = HashMap()
-
-
- // TODO please test the read; write has been fixed up
-
- for (pldCnt in 0 until payloadCount) {
- inputStream.read(pldBuffer4)
-
- // check payload header
- if (!pldBuffer4.contentEquals(WriteLayerDataZip.PAYLOAD_HEADER))
- throw InternalError("Payload $pldCnt not found -- expected ${WriteLayerDataZip.PAYLOAD_HEADER.toByteString()}, got ${pldBuffer4.toByteString()}")
-
- // get payload's name
- inputStream.read(pldBuffer4)
- val payloadName = pldBuffer4.toString(Charset.forName("US-ASCII"))
-
- printdbg(this, "Payload $pldCnt name: $payloadName") // maybe maybe related with buffer things?
-
- // get uncompressed size
- inputStream.read(pldBuffer6)
- val uncompressedSize = pldBuffer6.toLittleInt48()
-
- // get deflated size
- inputStream.mark(2147483647) // FIXME deflated stream cannot be larger than 2 GB
- // creep forward until we hit the PAYLOAD_FOOTER
- var deflatedSize: Int = 0 // FIXME deflated stream cannot be larger than 2 GB
- // loop init
- inputStream.read(pldBuffer8)
- // loop main
- while (!pldBuffer8.contentEquals(WriteLayerDataZip.PAYLOAD_FOOTER)) {
- val aByte = inputStream.read(); deflatedSize += 1
- if (aByte == -1) throw InternalError("Unexpected end-of-file at payload $pldCnt")
- pldBuffer8.shiftLeftBy(1, aByte.toByte())
- }
-
- // at this point, we should have correct size of deflated bytestream
-
- printdbg(this, "Payload $pldCnt compressed size: $deflatedSize")
-
- val deflatedBytes = ByteArray(deflatedSize) // FIXME deflated stream cannot be larger than 2 GB
- inputStream.reset() // go back to marked spot
- inputStream.read(deflatedBytes)
-
- // PRO Debug tip: every deflated bytes must begin with 0x789C or 0x78DA
- // Thus, \0pLd + [10] must be either of these.
-
- // put constructed payload into a container
- payloads.put(payloadName, TEMzPayload(uncompressedSize, deflatedBytes))
-
- // skip over to be aligned with the next payload
- inputStream.skip(8)
- }
-
-
- // test for EOF
- inputStream.read(pldBuffer8)
- if (!pldBuffer8.contentEquals(WriteLayerDataZip.FILE_FOOTER))
- throw InternalError("Expected end-of-file, got not-so-end-of-file")*/
-
-
- //////////////////////
- // END OF FILE READ //
- //////////////////////
-
- val worldSize = width.toLong() * height
-
- val payloadBytes = HashMap()
-
- payloads.forEach { t, u ->
- val inflatedFile = ByteArray(u.uncompressedSize.toInt()) // FIXME deflated stream cannot be larger than 2 GB
- val inflater = Inflater()
- inflater.setInput(u.bytes, 0, u.bytes.size)
- val uncompLen = inflater.inflate(inflatedFile)
-
- // just in case
- if (uncompLen.toLong() != u.uncompressedSize)
- throw InternalError("Payload $t DEFLATE size mismatch -- expected ${u.uncompressedSize}, got $uncompLen")
-
- payloadBytes[t] = inflatedFile
- }
-
- val spawnPoint = LandUtil.resolveBlockAddr(width, spawnAddress)
-
- val terrainDamages = HashMap()
- val wallDamages = HashMap()
- val fluidTypes = HashMap()
- val fluidFills = HashMap()
- val tileNumberToNameMap = HashMap()
-
- // parse terrain damages
- for (c in payloadBytes["TdMG"]!!.indices step 10) {
- val bytes = payloadBytes["TdMG"]!!
-
- val tileAddr = bytes.sliceArray(c..c+5)
- val value = bytes.sliceArray(c+6..c+9)
-
- terrainDamages[tileAddr.toLittleInt48()] = value.toLittleFloat()
- }
-
-
- // parse wall damages
- for (c in payloadBytes["WdMG"]!!.indices step 10) {
- val bytes = payloadBytes["WdMG"]!!
-
- val tileAddr = bytes.sliceArray(c..c+5)
- val value = bytes.sliceArray(c+6..c+9)
-
- wallDamages[tileAddr.toLittleInt48()] = value.toLittleFloat()
- }
-
-
- // TODO parse fluid(Types|Fills)
-
-
- return LayerData(
- BlockLayer(width, height, payloadBytes["WALL"]!!),
- BlockLayer(width, height, payloadBytes["TERR"]!!),
-
- spawnPoint.first, spawnPoint.second,
-
- wallDamages, terrainDamages, fluidTypes, fluidFills, tileNumberToNameMap
- )
- }
-
- /**
- * Immediately deployable, a part of the gameworld
- */
- internal data class LayerData(
- val layerWall: BlockLayer,
- val layerTerrain: BlockLayer,
- //val layerThermal: MapLayerHalfFloat, // in Kelvins
- //val layerAirPressure: MapLayerHalfFloat, // (milibar - 1000)
-
- val spawnX: Int,
- val spawnY: Int,
-
- //val wirings: HashMap>,
- val wallDamages: HashMap,
- val terrainDamages: HashMap,
- val fluidTypes: HashMap,
- val fluidFills: HashMap,
- val tileNumberToNameMap: HashMap
- )
-
- internal fun InputStream.readRelative(b: ByteArray, off: Int, len: Int): Int {
- if (b == null) {
- throw NullPointerException()
- } else if (off < 0 || len < 0 || len > b.size) {
- throw IndexOutOfBoundsException()
- } else if (len == 0) {
- return 0
- }
-
- var c = read()
- if (c == -1) {
- return -1
- }
- b[0] = c.toByte()
-
- var i = 1
- try {
- while (i < len) {
- c = read()
- if (c == -1) {
- break
- }
- b[i] = c.toByte()
- i++
- }
- } catch (ee: IOException) {
- }
-
- return i
- }
-}
diff --git a/src/net/torvald/terrarum/serialise/ReadWorldInfo.kt b/src/net/torvald/terrarum/serialise/ReadWorldInfo.kt
deleted file mode 100644
index 0614a4445..000000000
--- a/src/net/torvald/terrarum/serialise/ReadWorldInfo.kt
+++ /dev/null
@@ -1,84 +0,0 @@
-package net.torvald.terrarum.serialise
-
-import com.badlogic.gdx.graphics.Pixmap
-import com.badlogic.gdx.graphics.Texture
-import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.DiskSkimmer.Companion.read
-import java.io.File
-import java.io.FileInputStream
-import java.util.*
-
-
-object ReadWorldInfo {
-
- // FIXME UNTESTED
-
- internal operator fun invoke(file: File): SaveMetaData {
-
- val magic = ByteArray(4)
- val worldNameUTF8 = ArrayList()
-
- val fis = FileInputStream(file)
-
- fis.read(magic)
- if (!Arrays.equals(magic, WriteWorldInfo.META_MAGIC)) {
- throw IllegalArgumentException("File not a Save Meta")
- }
-
-
- val descVersion = fis.read(1) // 0-127
- val numberOfHashes = fis.read() // 0-127
-
-
- var byteRead = fis.read()
- while (byteRead != 0) {
- if (byteRead == -1)
- throw InternalError("Unexpected EOF")
-
- worldNameUTF8.add(byteRead.toByte())
- byteRead = fis.read()
- }
-
- return SaveMetaData(
- String(worldNameUTF8.toByteArray(), Charsets.UTF_8),
- fis.read(8).toLittleLong(), // terrain seed
- fis.read(8).toLittleLong(), // rng s0
- fis.read(8).toLittleLong(), // rng s1
- fis.read(8).toLittleLong(), // weather s0
- fis.read(8).toLittleLong(), // weather s1
- fis.read(4).toLittleInt(), // player id
- fis.read(8).toLittleLong(), // world TIME_T
- fis.read(6).toLittleLong(), // creation time
- fis.read(6).toLittleLong(), // last play time
- fis.read(4).toLittleInt(), // total time wasted
- fis.read(32), // sha256sum worldinfo1
- fis.read(32), // sha256sum worldinfo2
- fis.read(32) // sha256sum worldinfo3
- )
- }
-
-
- data class SaveMetaData(
- val worldName: String,
- val terrainSeed: Long,
- val rngS0: Long,
- val rngS1: Long,
- val weatherS0: Long,
- val weatherS1: Long,
- val playerID: Int,
- val timeNow: Long,
- val creationTime: Long,
- val lastPlayTime: Long,
- val totalPlayTime: Int,
- val worldinfo1Hash: ByteArray,
- val worldInfo2Hash: ByteArray,
- val worldInfo3Hash: ByteArray,
-
- // gzipped TGA in meta
- val thumbnail: Texture = Texture(2, 2, Pixmap.Format.RGBA8888),
- // skim through the virtualdisk entries
- val worldCount: Int = 1,
- // read from the entry file
- val playerName: String = "Savegame",
- val playerWallet: Int = 0
- )
-}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/serialise/SavegameLoader.kt b/src/net/torvald/terrarum/serialise/SavegameReader.kt
similarity index 84%
rename from src/net/torvald/terrarum/serialise/SavegameLoader.kt
rename to src/net/torvald/terrarum/serialise/SavegameReader.kt
index 857766afd..39753f169 100644
--- a/src/net/torvald/terrarum/serialise/SavegameLoader.kt
+++ b/src/net/torvald/terrarum/serialise/SavegameReader.kt
@@ -3,7 +3,7 @@ package net.torvald.terrarum.serialise
/**
* Created by minjaesong on 2018-10-03.
*/
-object SavegameLoader {
+object SavegameReader {
// TODO read TEVd, load necessary shits
diff --git a/src/net/torvald/terrarum/serialise/SavegameWriter.kt b/src/net/torvald/terrarum/serialise/SavegameWriter.kt
index 58776daf4..122a06533 100644
--- a/src/net/torvald/terrarum/serialise/SavegameWriter.kt
+++ b/src/net/torvald/terrarum/serialise/SavegameWriter.kt
@@ -9,7 +9,6 @@ import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameitem.GameItem
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.*
-import net.torvald.terrarum.utils.JsonWriter.getJsonBuilder
import net.torvald.util.SortedArrayList
import java.io.File
import java.nio.charset.Charset
@@ -77,76 +76,17 @@ object SavegameWriter {
// serialise current world (stage)
- val worldBytes = WriteLayerDataZip(gameworld) // filename can be anything that is "world[n]" where [n] is any number
- if (worldBytes == null) {
- throw Error("Serialising world failed")
- }
- if (!worldBytes.sliceArray(0..3).contentEquals(WriteLayerDataZip.MAGIC)) {
- worldBytes.forEach {
- print(it.toUInt().and(255u).toString(16).toUpperCase().padStart(2, '0'))
- print(' ')
- }; println()
- throw Error()
- }
-
- // add current world (stage) to the disk
- VDUtil.registerFile(disk, DiskEntry(
- gameworld.worldIndex, ROOT,
- "world${gameworld.worldIndex}".toByteArray(charset),
- creationDate, creationDate,
- EntryFile(worldBytes)
- ))
-
-
-
- // TODO world[n] is done, needs whole other things
-
-
- // worldinfo0..3
- val worldinfoBytes = WriteWorldInfo(ingame)
- worldinfoBytes?.forEachIndexed { index, bytes ->
- VDUtil.registerFile(disk, DiskEntry(
- 32766 - index, ROOT, "worldinfo$index".toByteArray(charset),
- creationDate, creationDate,
- EntryFile(bytes)
- ))
- } ?: throw Error("Serialising worldinfo failed")
-
- // loadorder.txt
- VDUtil.registerFile(disk, DiskEntry(
- 32767, ROOT, "load_order.txt".toByteArray(charset),
- creationDate, creationDate,
- EntryFile(ByteArray64.fromByteArray(Gdx.files.internal("./assets/mods/LoadOrder.csv").readBytes()))
- ))
-
- // actors
- ingame.actorContainerActive.forEach {
- VDUtil.registerFile(disk, DiskEntry(
- rngPool.next(), ROOT,
- it.referenceID.toString(16).toUpperCase().toByteArray(charset),
- creationDate, creationDate,
- EntryFile(serialiseActor(it))
- ))
- }
- ingame.actorContainerInactive.forEach {
- VDUtil.registerFile(disk, DiskEntry(
- rngPool.next(), ROOT,
- it.referenceID.toString(16).toUpperCase().toByteArray(charset),
- creationDate, creationDate,
- EntryFile(serialiseActor(it))
- ))
- }
// items
- ItemCodex.dynamicItemDescription.forEach { dynamicID, item ->
+ /*ItemCodex.dynamicItemDescription.forEach { dynamicID, item ->
VDUtil.registerFile(disk, DiskEntry(
rngPool.next(), ROOT,
dynamicID.toByteArray(charset),
creationDate, creationDate,
EntryFile(serialiseItem(item))
))
- }
+ }*/
System.gc()
@@ -156,14 +96,79 @@ object SavegameWriter {
fun modifyExistingSave(savefile: File): VirtualDisk {
TODO()
}
+}
- private fun serialiseActor(a: Actor): ByteArray64 {
- val gson = getJsonBuilder().toJson(a).toByteArray(charset)
- return ByteArray64.fromByteArray(gson)
- }
+fun Int.toLittle() = byteArrayOf(
+ this.and(0xFF).toByte(),
+ this.ushr(8).and(0xFF).toByte(),
+ this.ushr(16).and(0xFF).toByte(),
+ this.ushr(24).and(0xFF).toByte()
+)
+/** Converts int as 2-byte array, discarding the sign.*/
+fun Int.toULittleShort() = byteArrayOf(
+ this.and(0xFF).toByte(),
+ this.ushr(8).and(0xFF).toByte()
+)
+/** Converts int as 2-byte array, preserving the sign. In other words, it converts int to short. */
+fun Int.toLittleShort() = byteArrayOf(
+ this.and(0xFF).toByte(),
+ this.shr(8).and(0xFF).toByte()
+)
+fun Long.toLittle() = byteArrayOf(
+ this.and(0xFF).toByte(),
+ this.ushr(8).and(0xFF).toByte(),
+ this.ushr(16).and(0xFF).toByte(),
+ this.ushr(24).and(0xFF).toByte(),
+ this.ushr(32).and(0xFF).toByte(),
+ this.ushr(40).and(0xFF).toByte(),
+ this.ushr(48).and(0xFF).toByte(),
+ this.ushr(56).and(0xFF).toByte()
+)
+/** Converts long as 6-byte array, discarding the sign. */
+fun Long.toULittle48() = byteArrayOf(
+ this.and(0xFF).toByte(),
+ this.ushr(8).and(0xFF).toByte(),
+ this.ushr(16).and(0xFF).toByte(),
+ this.ushr(24).and(0xFF).toByte(),
+ this.ushr(32).and(0xFF).toByte(),
+ this.ushr(40).and(0xFF).toByte()
+)
+fun Double.toLittle() = java.lang.Double.doubleToRawLongBits(this).toLittle()
+fun Boolean.toLittle() = byteArrayOf(if (this) 0xFF.toByte() else 0.toByte())
- private fun serialiseItem(i: GameItem): ByteArray64 {
- val gson = getJsonBuilder().toJson(i).toByteArray(charset)
- return ByteArray64.fromByteArray(gson)
- }
-}
\ No newline at end of file
+fun ByteArray.toLittleInt() =
+ if (this.size != 4) throw Error("Array not in size of 4")
+ else this[0].toUint() or
+ this[1].toUint().shl(8) or
+ this[2].toUint().shl(16) or
+ this[3].toUint().shl(24)
+fun ByteArray.toULittleShort() =
+ if (this.size != 4) throw Error("Array not in size of 2")
+ else this[0].toUint() or
+ this[1].toUint().shl(8)
+fun ByteArray.toLittleShort() =
+ if (this.size != 4) throw Error("Array not in size of 2")
+ else this[0].toUint() or
+ this[1].toInt().shl(8)
+fun ByteArray.toLittleLong() =
+ if (this.size != 8) throw Error("Array not in size of 8")
+ else this[0].toUlong() or
+ this[1].toUlong().shl(8) or
+ this[2].toUlong().shl(16) or
+ this[3].toUlong().shl(24) or
+ this[4].toUlong().shl(32) or
+ this[5].toUlong().shl(40) or
+ this[6].toUlong().shl(48) or
+ this[7].toUlong().shl(56)
+fun ByteArray.toLittleInt48() =
+ if (this.size != 6) throw Error("Array not in size of 6")
+ else this[0].toUlong() or
+ this[1].toUlong().shl(8) or
+ this[2].toUlong().shl(16) or
+ this[3].toUlong().shl(24) or
+ this[4].toUlong().shl(32) or
+ this[5].toUlong().shl(40)
+fun ByteArray.toLittleFloat() = java.lang.Float.intBitsToFloat(this.toLittleInt())
+
+fun Byte.toUlong() = java.lang.Byte.toUnsignedLong(this)
+fun Byte.toUint() = java.lang.Byte.toUnsignedInt(this)
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/serialise/WriteCSV.kt b/src/net/torvald/terrarum/serialise/WriteCSV.kt
deleted file mode 100644
index f88c7d30e..000000000
--- a/src/net/torvald/terrarum/serialise/WriteCSV.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-package net.torvald.terrarum.serialise
-
-import net.torvald.terrarum.AppLoader
-import java.io.IOException
-import java.nio.file.Files
-import java.nio.file.Paths
-import java.nio.file.StandardCopyOption
-
-/**
- * Created by minjaesong on 2016-03-18.
- */
-// internal for everything: prevent malicious module from messing up the savedata
-internal object WriteCSV {
- val META_FILENAME_TILE = "worldinfo2"
- val META_FILENAME_ITEM = "worldinfo3"
- val META_FILENAME_MAT = "worldinfo4"
-
- internal fun write(saveDirectoryName: String): Boolean {
- //val tileCSV = CSVFetcher.readCSVasString(BlockCodex.CSV_PATH)
- //val itemCSV = CSVFetcher.readCSVasString(ItemCodex.CSV_PATH)
- //val matCSV = CSVFetcher.readCSVasString(MaterialCodex.CSV_PATH)
-
- val pathTile = Paths.get("${AppLoader.defaultSaveDir}" +
- "/$saveDirectoryName/${META_FILENAME_TILE}")
- val pathItem = Paths.get("${AppLoader.defaultSaveDir}" +
- "/$saveDirectoryName/${META_FILENAME_ITEM}")
- val pathMat = Paths.get("${AppLoader.defaultSaveDir}" +
- "/$saveDirectoryName/${META_FILENAME_MAT}")
- val tempPathTile = Files.createTempFile(pathTile.toString(), "_temp")
- val tempPathItem = Files.createTempFile(pathItem.toString(), "_temp")
- val tempPathMat = Files.createTempFile(pathMat.toString(), "_temp")
-
- // TODO gzip
-
- // write CSV to path
- //Files.write(tempPathTile, tileCSV.toByteArray(Charsets.UTF_8))
- //Files.write(tempPathItem, itemCSV.toByteArray(Charsets.UTF_8))
- //Files.write(tempPathMat, matCSV.toByteArray(Charsets.UTF_8))
-
- // replace savemeta with tempfile
- try {
- Files.copy(tempPathTile, pathTile, StandardCopyOption.REPLACE_EXISTING)
- Files.deleteIfExists(tempPathTile)
-
- Files.copy(tempPathItem, pathItem, StandardCopyOption.REPLACE_EXISTING)
- Files.deleteIfExists(tempPathItem)
-
- Files.copy(tempPathMat, pathMat, StandardCopyOption.REPLACE_EXISTING)
- Files.deleteIfExists(tempPathMat)
-
- println("Saved map data '${WriteLayerData.LAYERS_FILENAME}' to $saveDirectoryName.")
-
- return true
- }
- catch (e: IOException) {
- e.printStackTrace()
- }
- return false
- }
-
-}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/serialise/WriteLayerData.kt b/src/net/torvald/terrarum/serialise/WriteLayerData.kt
deleted file mode 100644
index 5bbfd8863..000000000
--- a/src/net/torvald/terrarum/serialise/WriteLayerData.kt
+++ /dev/null
@@ -1,85 +0,0 @@
-package net.torvald.terrarum.serialise
-
-/**
- * TODO this one does not use TerranVirtualDisk
- *
- * Created by minjaesong on 2016-03-18.
- */
-// internal for everything: prevent malicious module from messing up the savedata
-@Deprecated("TEMD is old and removed format; use TEMz which does compression")
-internal object WriteLayerData {
-
- init {
- throw Error("TEMD is old and removed format; use TEMz which does compression")
- }
-
- val LAYERS_FILENAME = "worldinfo1"
-
- /*val MAGIC = "TEMD".toByteArray(charset = Charset.forName("US-ASCII"))
-
- val BYTE_NULL: Byte = 0
-
-
- internal operator fun invoke(saveDirectoryName: String): Boolean {
- val path = "${AppLoader.defaultSaveDir}/$saveDirectoryName/${LAYERS_FILENAME}"
- val tempPath = "${path}_bak"
- val map = (Terrarum.ingame!!.world)
-
- val parentDir = File("${AppLoader.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()
-
- val outputStream = GZIPOutputStream(FileOutputStream(tempFile))
-
-
- // write binary
- outputStream.write(MAGIC)
- outputStream.write(byteArrayOf(GameWorld.SIZEOF))
- outputStream.write(byteArrayOf(GameWorld.LAYERS))
- outputStream.write(byteArrayOf(BYTE_NULL))
- outputStream.write(byteArrayOf(BYTE_NULL))
- outputStream.write(map.width.toLittle())
- outputStream.write(map.height.toLittle())
- outputStream.write(map.spawnX.toLittle())
- outputStream.write(map.spawnY.toLittle())
- // write one row (byteArray) at a time
- outputStream.write(map.layerTerrain.data)
- outputStream.write(map.layerWall.data)
- outputStream.write(map.layerTerrainLowBits.data)
- outputStream.write(map.layerWallLowBits.data)
-
- // replace savemeta with tempfile
- try {
- outputStream.flush()
- outputStream.close()
-
- outFile.delete()
- tempFile.copyTo(outFile, overwrite = true)
- tempFile.delete()
- println("Saved map data '$LAYERS_FILENAME' to $saveDirectoryName.")
-
- return true
- }
- catch (e: IOException) {
- e.printStackTrace()
- }
- finally {
- outputStream.close()
- }
-
- return false
- }*/
-
-
-}
-
-const val WORLD_WRITER_FORMAT_VERSION = 3
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/serialise/WriteLayerDataLzma.kt b/src/net/torvald/terrarum/serialise/WriteLayerDataLzma.kt
deleted file mode 100644
index 3f99b9b63..000000000
--- a/src/net/torvald/terrarum/serialise/WriteLayerDataLzma.kt
+++ /dev/null
@@ -1,208 +0,0 @@
-package net.torvald.terrarum.serialise
-
-import com.badlogic.gdx.utils.compression.Lzma
-import net.torvald.terrarum.AppLoader
-import net.torvald.terrarum.Terrarum
-import net.torvald.terrarum.realestate.LandUtil
-import net.torvald.terrarum.serialise.WriteLayerDataZip.FILE_FOOTER
-import net.torvald.terrarum.serialise.WriteLayerDataZip.PAYLOAD_FOOTER
-import net.torvald.terrarum.serialise.WriteLayerDataZip.PAYLOAD_HEADER
-import java.io.*
-import java.util.zip.DeflaterOutputStream
-
-/**
- * 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.
- */
-// internal for everything: prevent malicious module from messing up the savedata
-internal object WriteLayerDataLzma {
-
- // FIXME TERRAIN DAMAGE UNTESTED
-
-
- // 2400x800 world size: about .. kB
- // 8192x2048 world size: about 470 kB but writes much slower than DEFLATE
-
-
- val LAYERS_FILENAME = "world"
-
- val MAGIC = byteArrayOf(0x54, 0x45, 0x4D, 0x7A)
- val VERSION_NUMBER = WORLD_WRITER_FORMAT_VERSION.toByte()
- val NUMBER_OF_LAYERS = 3.toByte()
- val NUMBER_OF_PAYLOADS = 5.toByte()
- val COMPRESSION_ALGORITHM = 2.toByte()
- val GENERATOR_VERSION = WORLD_GENERATOR_VERSION.toULittleShort()
-
- //val NULL: Byte = 0
-
-
- /**
- * 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 path = "${AppLoader.defaultSaveDir}/tmp_$LAYERS_FILENAME${world.worldIndex}"
-
- // TODO let's try dump-on-the-disk-then-pack method...
-
- /*val parentDir = File("${AppLoader.defaultSaveDir}/$saveDirectoryName")
- if (!parentDir.exists()) {
- parentDir.mkdir()
- }
- else if (!parentDir.isDirectory) {
- EchoError("Savegame directory is not actually a directory, aborting...")
- return false
- }*/
-
-
- val outFile = File(path)
- if (outFile.exists()) outFile.delete()
- outFile.createNewFile()
-
- val outputStream = BufferedOutputStream(FileOutputStream(outFile), 8192)
- var deflater: DeflaterOutputStream // couldn't really use one outputstream for all the files.
-
- fun wb(byteArray: ByteArray) { outputStream.write(byteArray) }
- fun wb(byte: Byte) { outputStream.write(byte.toInt()) }
- //fun wb(byte: Int) { outputStream.write(byte) }
- fun wi32(int: Int) { wb(int.toLittle()) }
- fun wi48(long: Long) { wb(long.toULittle48()) }
- fun wi64(long: Long) { wb(long.toLittle()) }
- fun wf32(float: Float) { wi32(float.toRawBits()) }
-
-
- ////////////////////
- // WRITE BINARIES //
- ////////////////////
-
-
- // all the necessary headers
- wb(MAGIC); wb(VERSION_NUMBER); wb(NUMBER_OF_LAYERS); wb(NUMBER_OF_PAYLOADS); wb(COMPRESSION_ALGORITHM); wb(GENERATOR_VERSION)
-
- // world width, height, and spawn point
- wi32(world.width); wi32(world.height)
- wi48(LandUtil.getBlockAddr(world, world.spawnX, world.spawnY))
-
- // write payloads //
- outputStream.flush()
-
- // TERR payload
- // PRO Debug tip: every deflated bytes must begin with 0x789C or 0x78DA
- // Thus, \0pLd + [10] must be either of these.
-
- wb(PAYLOAD_HEADER); wb("TERR".toByteArray())
- wi48(world.width * world.height * 3L / 2)
- world.layerTerrain.bytesIterator().forEach {
- val tempByteArray = ByteArray(1)
- tempByteArray[0] = it
- val tempByteArrayStream = ByteArrayInputStream(tempByteArray)
- Lzma.compress(tempByteArrayStream, outputStream)
- }
- wb(PAYLOAD_FOOTER)
-
- // WALL payload
- wb(PAYLOAD_HEADER); wb("WALL".toByteArray())
- wi48(world.width * world.height * 3L / 2)
- world.layerWall.bytesIterator().forEach {
- val tempByteArray = ByteArray(1)
- tempByteArray[0] = it
- val tempByteArrayStream = ByteArrayInputStream(tempByteArray)
- Lzma.compress(tempByteArrayStream, outputStream)
- }
- wb(PAYLOAD_FOOTER)
-
- // WIRE payload
- /*wb(PAYLOAD_HEADER); wb("WIRE".toByteArray())
- wi48(world.width * world.height.toLong())
- Lzma.compress(ByteArrayInputStream(world.wireArray), outputStream)
- wb(PAYLOAD_FOOTER)*/
-
- // TdMG payload
- wb(PAYLOAD_HEADER); wb("TdMG".toByteArray())
- wi48(world.terrainDamages.size * 10L)
-
-
- world.terrainDamages.forEach { t, u ->
- Lzma.compress(ByteArrayInputStream(t.toULittle48()), outputStream)
- Lzma.compress(ByteArrayInputStream(u.toRawBits().toLittle()), outputStream)
- }
-
- wb(PAYLOAD_FOOTER)
-
- // WdMG payload
- wb(PAYLOAD_HEADER); wb("WdMG".toByteArray())
- wi48(world.wallDamages.size * 10L)
-
-
- world.wallDamages.forEach { t, u ->
- Lzma.compress(ByteArrayInputStream(t.toULittle48()), outputStream)
- Lzma.compress(ByteArrayInputStream(u.toRawBits().toLittle()), outputStream)
- }
-
- wb(PAYLOAD_FOOTER)
-
- // FlTP payload
- wb(PAYLOAD_HEADER); wb("FlTP".toByteArray())
- wi48(world.fluidTypes.size * 8L)
-
-
- world.fluidTypes.forEach { t, u ->
- Lzma.compress(ByteArrayInputStream(t.toULittle48()), outputStream)
- Lzma.compress(ByteArrayInputStream(u.value.toLittleShort()), outputStream)
- }
-
- wb(PAYLOAD_FOOTER)
-
- // FlFL payload
- wb(PAYLOAD_HEADER); wb("FlFL".toByteArray())
- wi48(world.fluidFills.size * 10L)
-
-
- world.fluidFills.forEach { t, u ->
- Lzma.compress(ByteArrayInputStream(t.toULittle48()), outputStream)
- Lzma.compress(ByteArrayInputStream(u.toRawBits().toLittle()), outputStream)
- }
-
- wb(PAYLOAD_FOOTER)
-
-
-
- // write footer
- wb(FILE_FOOTER)
-
-
- //////////////////
- // END OF WRITE //
- //////////////////
-
-
-
- // replace savemeta with tempfile
- try {
- outputStream.flush()
- outputStream.close()
-
-
- return outFile
- }
- catch (e: IOException) {
- e.printStackTrace()
- }
- finally {
- outputStream.close()
- }
-
- return null
- }
-
-
-}
diff --git a/src/net/torvald/terrarum/serialise/WriteLayerDataZip.kt b/src/net/torvald/terrarum/serialise/WriteLayerDataZip.kt
deleted file mode 100644
index 04e57a2a9..000000000
--- a/src/net/torvald/terrarum/serialise/WriteLayerDataZip.kt
+++ /dev/null
@@ -1,208 +0,0 @@
-package net.torvald.terrarum.serialise
-
-import net.torvald.terrarum.AppLoader.printdbg
-import net.torvald.terrarum.gameworld.GameWorld
-import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64
-import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64GrowableOutputStream
-import net.torvald.terrarum.realestate.LandUtil
-import java.util.zip.Deflater
-import java.util.zip.DeflaterOutputStream
-
-/**
- * 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.
- */
-// internal for everything: prevent malicious module from messing up the savedata
-internal object WriteLayerDataZip {
-
- // FIXME TERRAIN DAMAGE UNTESTED
-
-
- // 2400x800 world size, default comp level: about 90 kB
- // 8192x2048 world size, default comp level: about 670 kB
-
- // 2400x800 world size, best comp level: about 75 kB
- // 8192x2048 world size, best comp level: about 555 kB
-
- val LAYERS_FILENAME = "world"
-
- val MAGIC = byteArrayOf(0x54, 0x45, 0x4D, 0x7A)
- val VERSION_NUMBER = WORLD_WRITER_FORMAT_VERSION.toByte()
- val NUMBER_OF_LAYERS = 3.toByte()
- val NUMBER_OF_PAYLOADS = 5.toByte()
- val COMPRESSION_ALGORITHM = 1.toByte()
- val GENERATOR_VERSION = WORLD_GENERATOR_VERSION.toULittleShort()
- val PAYLOAD_HEADER = byteArrayOf(0, 0x70, 0x4C, 0x64) // \0pLd
- val PAYLOAD_FOOTER = byteArrayOf(0x45, 0x6E, 0x64, 0x50, 0x59, 0x4C, 0x64, -1) // EndPYLd\xFF
- val FILE_FOOTER = byteArrayOf(0x45, 0x6E, 0x64, 0x54, 0x45, 0x4D, -1, -2) // EndTEM with BOM
-
- //val NULL: Byte = 0
-
-
- /**
- * @param world The world to serialise
- * @param path The directory where the temporary file goes, in relative to the AppLoader.defaultSaveDir. Should NOT start with slashed
- *
- * @return File on success; `null` on failure
- */
- internal operator fun invoke(world: GameWorld): ByteArray64? {
- //val sanitisedPath = path.replace('\\', '/').removePrefix("/").replace("../", "")
-
- //val path = "${AppLoader.defaultSaveDir}/$sanitisedPath/tmp_$LAYERS_FILENAME${world.worldIndex}"
- //val path = "${AppLoader.defaultSaveDir}/tmp_$LAYERS_FILENAME${world.worldIndex}"
-
- // TODO let's try dump-on-the-disk-then-pack method...
-
- /*val parentDir = File("${AppLoader.defaultSaveDir}/$saveDirectoryName")
- if (!parentDir.exists()) {
- parentDir.mkdir()
- }
- else if (!parentDir.isDirectory) {
- EchoError("Savegame directory is not actually a directory, aborting...")
- return false
- }*/
-
-
- //val outFile = File(path)
- //if (outFile.exists()) outFile.delete()
- //outFile.createNewFile()
-
- //val outputStream = BufferedOutputStream(FileOutputStream(outFile), 8192)
- val outputStream = ByteArray64GrowableOutputStream()
- var deflater: DeflaterOutputStream // couldn't really use one outputstream for all the files.
-
- fun wb(byteArray: ByteArray) { outputStream.write(byteArray) }
- fun wb(byte: Byte) { outputStream.write(byte.toInt()) }
- //fun wb(byte: Int) { outputStream.write(byte) }
- fun wi32(int: Int) { wb(int.toLittle()) }
- fun wi48(long: Long) { wb(long.toULittle48()) }
- fun wi64(long: Long) { wb(long.toLittle()) }
- fun wf32(float: Float) { wi32(float.toRawBits()) }
-
-
- ////////////////////
- // WRITE BINARIES //
- ////////////////////
-
-
- // all the necessary headers
- wb(MAGIC); wb(VERSION_NUMBER); wb(NUMBER_OF_LAYERS); wb(NUMBER_OF_PAYLOADS); wb(COMPRESSION_ALGORITHM); wb(GENERATOR_VERSION)
-
- // world width, height, and spawn point
- wi32(world.width); wi32(world.height)
- wi48(LandUtil.getBlockAddr(world, world.spawnX, world.spawnY))
-
- // write payloads //
-
- // TERR payload
- // PRO Debug tip: every deflated bytes must begin with 0x789C or 0x78DA
- // Thus, \0pLd + [10] must be either of these.
-
- // TODO serialised payloads have bit too much zeros, should I be worried?
-
- val savePayloads = world.javaClass.superclass.declaredFields//.filter { it.isAnnotationPresent(TEMzPayload::class.java) }
- printdbg(this, "")
- savePayloads.forEach { printdbg(this, "${it.name}: ${it.type} @${it.declaredAnnotations.size}") }
-
- wb(PAYLOAD_HEADER); wb("TERR".toByteArray())
- wi48(world.width * world.height * 3L / 2)
- deflater = DeflaterOutputStream(outputStream, Deflater(Deflater.BEST_COMPRESSION, true), false)
- world.layerTerrain.bytesIterator().forEach { deflater.write(it.toInt()) }
- deflater.flush(); deflater.finish()
- wb(PAYLOAD_FOOTER)
-
- // WALL payload
- wb(PAYLOAD_HEADER); wb("WALL".toByteArray())
- wi48(world.width * world.height * 3L / 2)
- deflater = DeflaterOutputStream(outputStream, Deflater(Deflater.BEST_COMPRESSION, true), false)
- world.layerWall.bytesIterator().forEach { deflater.write(it.toInt()) }
- deflater.flush(); deflater.finish()
- wb(PAYLOAD_FOOTER)
-
- // WIRE payload
- /*wb(PAYLOAD_HEADER); wb("WIRE".toByteArray())
- wi48(world.width * world.height.toLong())
- deflater = DeflaterOutputStream(outputStream, Deflater(Deflater.BEST_COMPRESSION, true), false)
- deflater.write(world.wireArray)
- deflater.flush(); deflater.finish()
- wb(PAYLOAD_FOOTER)*/
-
- // TdMG payload
- wb(PAYLOAD_HEADER); wb("TdMG".toByteArray())
- wi48(world.terrainDamages.size * 10L)
-
- deflater = DeflaterOutputStream(outputStream, Deflater(Deflater.BEST_COMPRESSION, true), false)
-
- world.terrainDamages.forEach { t, u ->
- deflater.write(t.toULittle48())
- deflater.write(u.toRawBits().toLittle())
- }
-
- deflater.flush(); deflater.finish()
- wb(PAYLOAD_FOOTER)
-
- // WdMG payload
- wb(PAYLOAD_HEADER); wb("WdMG".toByteArray())
- wi48(world.wallDamages.size * 10L)
-
- deflater = DeflaterOutputStream(outputStream, Deflater(Deflater.BEST_COMPRESSION, true), false)
-
- world.wallDamages.forEach { t, u ->
- deflater.write(t.toULittle48())
- deflater.write(u.toRawBits().toLittle())
- }
-
- deflater.flush(); deflater.finish()
- wb(PAYLOAD_FOOTER)
-
- // FlTP payload
- wb(PAYLOAD_HEADER); wb("FlTP".toByteArray())
- wi48(world.fluidTypes.size * 8L)
-
- deflater = DeflaterOutputStream(outputStream, Deflater(Deflater.BEST_COMPRESSION, true), false)
-
- world.fluidTypes.forEach { t, u ->
- deflater.write(t.toULittle48())
- deflater.write(u.value.toLittleShort())
- }
-
- deflater.flush(); deflater.finish()
- wb(PAYLOAD_FOOTER)
-
- // FlFL payload
- wb(PAYLOAD_HEADER); wb("FlFL".toByteArray())
- wi48(world.fluidFills.size * 10L)
-
- deflater = DeflaterOutputStream(outputStream, Deflater(Deflater.BEST_COMPRESSION, true), false)
-
- world.fluidFills.forEach { t, u ->
- deflater.write(t.toULittle48())
- deflater.write(u.toRawBits().toLittle())
- }
-
- deflater.flush(); deflater.finish()
- wb(PAYLOAD_FOOTER)
-
-
- // write footer
- wb(FILE_FOOTER)
-
-
- //////////////////
- // END OF WRITE //
- //////////////////
-
- outputStream.flush()
- outputStream.close()
-
- return outputStream.toByteArray64()
- }
-
-
-}
diff --git a/src/net/torvald/terrarum/serialise/WriteMeta.kt b/src/net/torvald/terrarum/serialise/WriteMeta.kt
index ba0c61191..7dedfb506 100644
--- a/src/net/torvald/terrarum/serialise/WriteMeta.kt
+++ b/src/net/torvald/terrarum/serialise/WriteMeta.kt
@@ -1,70 +1,73 @@
package net.torvald.terrarum.serialise
-import net.torvald.terrarum.modulebasegame.worldgenerator.Worldgen
-import java.nio.charset.Charset
+import com.badlogic.gdx.utils.Json
+import com.badlogic.gdx.utils.JsonWriter
+import net.torvald.terrarum.ModMgr
+import net.torvald.terrarum.blockproperties.BlockCodex
+import net.torvald.terrarum.blockproperties.WireCodex
+import net.torvald.terrarum.itemproperties.ItemCodex
+import net.torvald.terrarum.itemproperties.MaterialCodex
+import net.torvald.terrarum.modulebasegame.TerrarumIngame
+import net.torvald.terrarum.modulebasegame.worldgenerator.RoguelikeRandomiser
+import net.torvald.terrarum.weather.WeatherMixer
-/**
- * Created by minjaesong on 2016-03-15.
- */
-// internal for everything: prevent malicious module from messing up the savedata
-internal object WriteMeta {
+open class WriteMeta(val ingame: TerrarumIngame) {
- val META_FILENAME = "worldinfo0"
+ open fun invoke(): String {
+ val world = ingame.world
+
+ val props = hashMapOf(
+ "genver" to 4,
+ "savename" to world.worldName,
+ "terrseed" to world.generatorSeed,
+ "randseed0" to RoguelikeRandomiser.RNG.state0,
+ "randseed1" to RoguelikeRandomiser.RNG.state1,
+ "weatseed0" to WeatherMixer.RNG.state0,
+ "weatseed1" to WeatherMixer.RNG.state1,
+ "playerid" to ingame.theRealGamer.referenceID,
+ "creation_t" to world.creationTime,
+ "lastplay_t" to world.lastPlayTime,
+ "playtime_t" to world.totalPlayTime,
- val MAGIC = "TESV".toByteArray(charset = Charset.forName("US-ASCII"))
+ // CSVs
+ "blocks" to StringBuilder().let {
+ ModMgr.getFilesFromEveryMod("blocks/blocks.csv").forEach { (modname, file) ->
+ it.append("\n\n## module: $modname ##\n\n")
+ it.append(file.readText())
+ }
+ it.toString()
+ },
+ "items" to StringBuilder().let {
+ ModMgr.getFilesFromEveryMod("items/itemid.csv").forEach { (modname, file) ->
+ it.append("\n\n## module: $modname ##\n\n")
+ it.append(file.readText())
+ }
+ it.toString()
+ },
- val BYTE_NULL: Byte = 0
+ "wires" to StringBuilder().let {
+ ModMgr.getFilesFromEveryMod("wires/wires.csv").forEach { (modname, file) ->
+ it.append("\n\n## module: $modname ##\n\n")
+ it.append(file.readText())
+ }
+ it.toString()
+ },
- val terraseed: Long = Worldgen.params.seed
+ // TODO fluids
+ "materials" to StringBuilder().let {
+ ModMgr.getFilesFromEveryMod("materials/materials.csv").forEach { (modname, file) ->
+ it.append("\n\n## module: $modname ##\n\n")
+ it.append(file.readText())
+ }
+ it.toString()
+ },
-
- /**
- * Write save meta to specified directory. Returns false if something went wrong.
- * @param saveDirectoryName
- * @param savegameName -- Nullable. If the value is not specified, saveDirectoryName will be used instead.
- */
- internal fun write(saveDirectoryName: String, savegameName: String?): Boolean {
- /*val hashArray: ArrayList = ArrayList()
- val savenameAsByteArray: ByteArray =
- (savegameName ?: saveDirectoryName).toByteArray(Charsets.UTF_8)
-
- // define Strings to be hashed
- val props = arrayOf(
- TilePropCSV()
- //, (item, mat, ...)
+ "loadorder" to ModMgr.loadOrder,
+ "worlds" to ingame.gameworldIndices
)
-
- // get and store hash from the list
- props.map { hashArray.add(DigestUtils.sha256(it)) }
-
- // open file and delete it
- val metaPath = Paths.get("$AppLoader.defaultSaveDir" +
- "/$saveDirectoryName/$META_FILENAME")
- val metaTempPath = Files.createTempFile(metaPath.toString(), "_temp")
-
- // TODO gzip
-
- // write bytes in tempfile
- Files.write(metaTempPath, MAGIC)
- Files.write(metaTempPath, savenameAsByteArray)
- Files.write(metaTempPath, byteArrayOf(BYTE_NULL))
- Files.write(metaTempPath, toByteArray(terraseed))
- Files.write(metaTempPath, toByteArray(rogueseed))
- for (hash in hashArray)
- Files.write(metaTempPath, hash)
-
- // replace savemeta with tempfile
- try {
- Files.copy(metaTempPath, metaPath, StandardCopyOption.REPLACE_EXISTING)
- Files.deleteIfExists(metaTempPath)
- println("Saved metadata to $saveDirectoryName.")
-
- return true
- }
- catch (e: IOException) {
- e.printStackTrace()
- }*/
- return false
+
+ return Json(JsonWriter.OutputType.json).toJson(props)
}
+
}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/serialise/WriteWorldInfo.kt b/src/net/torvald/terrarum/serialise/WriteWorldInfo.kt
deleted file mode 100644
index d2925c876..000000000
--- a/src/net/torvald/terrarum/serialise/WriteWorldInfo.kt
+++ /dev/null
@@ -1,185 +0,0 @@
-package net.torvald.terrarum.serialise
-
-import com.badlogic.gdx.Gdx
-import com.badlogic.gdx.graphics.GL30
-import com.badlogic.gdx.graphics.OrthographicCamera
-import com.badlogic.gdx.graphics.Pixmap
-import com.badlogic.gdx.graphics.g2d.SpriteBatch
-import com.badlogic.gdx.graphics.glutils.FrameBuffer
-import com.badlogic.gdx.utils.ScreenUtils
-import net.torvald.gdx.graphics.PixmapIO2
-import net.torvald.terrarum.*
-import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension
-import net.torvald.terrarum.weather.WeatherMixer
-import net.torvald.terrarum.modulebasegame.worldgenerator.RoguelikeRandomiser
-import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64
-import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64GrowableOutputStream
-import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64InputStream
-import org.apache.commons.codec.digest.DigestUtils
-import java.io.ByteArrayOutputStream
-import java.util.zip.Deflater
-import java.util.zip.DeflaterOutputStream
-
-object WriteWorldInfo {
-
- val META_MAGIC = "TESV".toByteArray(Charsets.UTF_8)
- val NULL = 0.toByte()
-
- val VERSION = 1
- val HASHED_FILES_COUNT = 3
-
- /**
- * TODO currently it'll dump the temporary file (tmp_worldinfo1) onto the disk and will return the temp file.
- *
- * @return List of ByteArray64, worldinfo0..worldinfo3; `null` on failure
- */
- internal operator fun invoke(ingame: IngameInstance): List? {
-
- //val path = "${AppLoader.defaultSaveDir}/tmp_worldinfo"
-
- val infileList = arrayOf(
- ModMgr.getGdxFilesFromEveryMod("blocks/blocks.csv"),
- ModMgr.getGdxFilesFromEveryMod("items/items.csv"),
- ModMgr.getGdxFilesFromEveryMod("materials/materials.csv")
- )
-
- val outFiles = ArrayList() // for worldinfo1-3 only
- val worldInfoHash = ArrayList() // hash of worldinfo1-3
- // try to write worldinfo1-3
-
- for (filenum in 1..HASHED_FILES_COUNT) {
- val outputStream = ByteArray64GrowableOutputStream()
- val infile = infileList[filenum - 1]
-
- infile.forEach {
- outputStream.write("## from file: ${it.second.nameWithoutExtension()} ##############################\n".toByteArray())
- val readBytes = it.second.readBytes()
- outputStream.write(readBytes)
- outputStream.write("\n".toByteArray())
- }
-
- outputStream.flush()
- outputStream.close()
-
-
- outFiles.add(outputStream.toByteArray64())
-
-
- worldInfoHash.add(DigestUtils.sha256(ByteArray64InputStream(outputStream.toByteArray64())))
- }
-
-
- // compose save meta (actual writing part)
- val metaOut = ByteArray64GrowableOutputStream()
-
-
- metaOut.write(META_MAGIC)
- metaOut.write(VERSION)
- metaOut.write(HASHED_FILES_COUNT)
-
- // world name
- val world = ingame.world
- val worldNameBytes = world.worldName.toByteArray(Charsets.UTF_8)
- //metaOut.write(worldNameBytes)
- worldNameBytes.forEach {
- if (it != 0.toByte()) metaOut.write(it.toInt())
- }
- metaOut.write(NULL.toInt())
-
- // terrain seed
- metaOut.write(world.generatorSeed.toLittle())
-
- // randomiser seed
- metaOut.write(RoguelikeRandomiser.RNG.state0.toLittle())
- metaOut.write(RoguelikeRandomiser.RNG.state1.toLittle())
-
- // weather seed
- metaOut.write(WeatherMixer.RNG.state0.toLittle())
- metaOut.write(WeatherMixer.RNG.state1.toLittle())
-
- // reference ID of the player
- metaOut.write(Terrarum.PLAYER_REF_ID.toLittle())
-
- // ingame time_t
- metaOut.write((world as GameWorldExtension).worldTime.TIME_T.toLittle())
-
- // creation time (real world time)
- metaOut.write(world.creationTime.toULittle48())
-
- // time at save (real world time)
- val timeNow = System.currentTimeMillis() / 1000L
- metaOut.write(timeNow.toULittle48())
-
- // get playtime and save it
- val timeToAdd = (timeNow - world.loadTime).toInt()
- metaOut.write((world.totalPlayTime + timeToAdd).toLittle())
- world.lastPlayTime = timeNow
- world.totalPlayTime += timeToAdd
-
- // SHA256SUM of worldinfo1-3
- worldInfoHash.forEach {
- metaOut.write(it)
- }
-
- // thumbnail
- val texreg = ingame.actorGamer.sprite?.textureRegion
- if (texreg != null) {
- val batch = SpriteBatch()
- val camera = OrthographicCamera(texreg.tileW.toFloat(), texreg.tileH.toFloat())
- val fbo = FrameBuffer(Pixmap.Format.RGBA8888, texreg.tileW, texreg.tileH, false)
-
- fbo.inAction(camera, batch) {
- batch.inUse {
- batch.draw(texreg.get(0, 0), 0f, 0f)
- }
- }
-
- // bind and unbind the fbo so that I can get the damned Pixmap using ScreenUtils
- // NullPointerException if not appconfig.useGL30
- Gdx.gl30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, fbo.framebufferHandle)
- Gdx.gl30.glReadBuffer(GL30.GL_COLOR_ATTACHMENT0)
-
- val outpixmap = ScreenUtils.getFrameBufferPixmap(0, 0, fbo.width, fbo.height)
-
- Gdx.gl30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, 0)
- Gdx.gl30.glReadBuffer(GL30.GL_BACK)
-
-
- val tgaSize = PixmapIO2.HEADER_FOOTER_SIZE + outpixmap.width * outpixmap.height * 4
- val byteArrayOS = ByteArrayOutputStream(tgaSize)
- PixmapIO2._writeTGA(byteArrayOS, outpixmap, true, true)
- byteArrayOS.flush()
- byteArrayOS.close()
-
-
- //PixmapIO2.writeTGA(Gdx.files.absolute(AppLoader.defaultDir+"/tmp_writeworldinfo+outpixmap.tga"), outpixmap, true)
-
-
- outpixmap.dispose()
- batch.dispose()
- fbo.dispose()
-
-
-
- // write uncompressed size
- metaOut.write(tgaSize.toULittleShort())
- // write compressed tga
- val deflater = DeflaterOutputStream(metaOut, Deflater(Deflater.BEST_COMPRESSION, true), false)
- deflater.write(byteArrayOS.toByteArray())
- deflater.flush(); deflater.finish()
- // write footer
- metaOut.write(-1); metaOut.write(-2)
- }
-
- // more data goes here //
-
-
- metaOut.flush()
- metaOut.close()
-
-
-
- return listOf(metaOut.toByteArray64()) + outFiles.toList()
- }
-
-}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/tests/Addnewcolumn.kt b/src/net/torvald/terrarum/tests/Addnewcolumn.kt
index 4e5a90737..fc5ba00da 100644
--- a/src/net/torvald/terrarum/tests/Addnewcolumn.kt
+++ b/src/net/torvald/terrarum/tests/Addnewcolumn.kt
@@ -1,5 +1,6 @@
package net.torvald.terrarum.tests
+import com.badlogic.gdx.utils.JsonValue
import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.terrarum.utils.JsonWriter
import java.io.File
@@ -63,7 +64,7 @@ fun main() {
val key = record[0]
val value = record[index + 2]
if (value.isNotBlank()) {
- jsonObject.addProperty(key, value)
+ jsonObject.addChild(key, JsonValue(value))
}
}
diff --git a/src/net/torvald/terrarum/tests/ByteArray64Test.kt b/src/net/torvald/terrarum/tests/ByteArray64Test.kt
index cac49f47d..d84f3525b 100644
--- a/src/net/torvald/terrarum/tests/ByteArray64Test.kt
+++ b/src/net/torvald/terrarum/tests/ByteArray64Test.kt
@@ -1,7 +1,6 @@
package net.torvald.terrarum.tests
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64GrowableOutputStream
-import net.torvald.terrarum.serialise.WriteLayerDataZip
import net.torvald.terrarum.serialise.toLittle
import net.torvald.terrarum.serialise.toULittle48
import java.util.zip.Deflater
@@ -33,7 +32,7 @@ Ooh, black and yellow! Let's shake it up a little.""".trimIndent().toByteArray()
- wb(WriteLayerDataZip.MAGIC); wb(WriteLayerDataZip.VERSION_NUMBER); wb(WriteLayerDataZip.NUMBER_OF_LAYERS); wb(WriteLayerDataZip.NUMBER_OF_PAYLOADS); wb(WriteLayerDataZip.COMPRESSION_ALGORITHM); wb(WriteLayerDataZip.GENERATOR_VERSION)
+ //wb(WriteLayerDataZip.MAGIC); wb(WriteLayerDataZip.VERSION_NUMBER); wb(WriteLayerDataZip.NUMBER_OF_LAYERS); wb(WriteLayerDataZip.NUMBER_OF_PAYLOADS); wb(WriteLayerDataZip.COMPRESSION_ALGORITHM); wb(WriteLayerDataZip.GENERATOR_VERSION)
val deflater = DeflaterOutputStream(outputStream, Deflater(Deflater.BEST_COMPRESSION), true)
repeat(20001) {
deflater.write(Math.random().times(256).toInt().and(255))
diff --git a/src/net/torvald/terrarum/tests/GsonTest.kt b/src/net/torvald/terrarum/tests/GsonTest.kt
index d48684087..075e5303a 100644
--- a/src/net/torvald/terrarum/tests/GsonTest.kt
+++ b/src/net/torvald/terrarum/tests/GsonTest.kt
@@ -1,5 +1,6 @@
package net.torvald.terrarum.tests
+import com.badlogic.gdx.utils.Json
import net.torvald.terrarum.utils.JsonWriter
import org.dyn4j.geometry.Vector2
@@ -22,13 +23,12 @@ object GsonTest {
operator fun invoke() {
- val gson = JsonWriter.getJsonBuilder()
- val jsonString = gson.toJson(testClass)
+ val jsonString = Json(com.badlogic.gdx.utils.JsonWriter.OutputType.json).toJson(testClass)
println(jsonString)
+ val deserialised = Json().fromJson(GsonTestSuper::class.java, jsonString)
- val deserialised = gson.fromJson(jsonString, GsonTestSuper::class.java)
println(deserialised)
println(deserialised as GsonTestClass) // ClassCastException
}
diff --git a/src/net/torvald/terrarum/ui/UINSMenu.kt b/src/net/torvald/terrarum/ui/UINSMenu.kt
index 302031315..6d74a309d 100644
--- a/src/net/torvald/terrarum/ui/UINSMenu.kt
+++ b/src/net/torvald/terrarum/ui/UINSMenu.kt
@@ -92,7 +92,7 @@ class UINSMenu(
val listWidth = maxOf(
AppLoader.fontGame.getWidth(menuTitle), minimumWidth,
- stringsFromTree.map { AppLoader.fontGame.getWidth(it) }.max() ?: 0
+ stringsFromTree.map { AppLoader.fontGame.getWidth(it) }.maxOrNull() ?: 0
)
val uiWidth = listWidth + (2 * TEXT_OFFSETX.toInt())
val listHeight = stringsFromTree.size * LINE_HEIGHT
diff --git a/src/net/torvald/terrarum/utils/JsonFetcher.kt b/src/net/torvald/terrarum/utils/JsonFetcher.kt
index 395b38c73..1f39b00d9 100644
--- a/src/net/torvald/terrarum/utils/JsonFetcher.kt
+++ b/src/net/torvald/terrarum/utils/JsonFetcher.kt
@@ -1,5 +1,7 @@
package net.torvald.terrarum.utils
+import com.badlogic.gdx.utils.JsonReader
+import com.badlogic.gdx.utils.JsonValue
import net.torvald.terrarum.AppLoader.printdbg
/**
@@ -10,7 +12,7 @@ object JsonFetcher {
private var jsonString: StringBuffer? = null
@Throws(java.nio.file.NoSuchFileException::class)
- operator fun invoke(jsonFilePath: String): com.google.gson.JsonObject {
+ operator fun invoke(jsonFilePath: String): JsonValue {
jsonString = StringBuffer() // reset buffer every time it called
readJsonFileAsString(jsonFilePath)
@@ -20,14 +22,11 @@ object JsonFetcher {
throw Error("[JsonFetcher] jsonString is null!")
}
- val jsonParser = com.google.gson.JsonParser()
- val jsonObj = jsonParser.parse(jsonString.toString()).asJsonObject
-
- return jsonObj
+ return JsonReader().parse(jsonString.toString())
}
@Throws(java.nio.file.NoSuchFileException::class)
- operator fun invoke(jsonFile: java.io.File): com.google.gson.JsonObject {
+ operator fun invoke(jsonFile: java.io.File): JsonValue {
jsonString = StringBuffer() // reset buffer every time it called
readJsonFileAsString(jsonFile.canonicalPath)
@@ -37,10 +36,7 @@ object JsonFetcher {
throw Error("[JsonFetcher] jsonString is null!")
}
- val jsonParser = com.google.gson.JsonParser()
- val jsonObj = jsonParser.parse(jsonString.toString()).asJsonObject
-
- return jsonObj
+ return JsonReader().parse(jsonString.toString())
}
@Throws(java.nio.file.NoSuchFileException::class)
@@ -50,4 +46,14 @@ object JsonFetcher {
) // JSON does not require line break
}
+
+ fun forEach(map: JsonValue, action: (String, JsonValue) -> Unit) {
+ var counter = 0
+ var entry = map.child
+ while (entry != null) {
+ action(entry.name ?: "(arrayindex $counter)", entry)
+ entry = entry.next
+ counter += 1
+ }
+ }
}
diff --git a/src/net/torvald/terrarum/utils/JsonWriter.kt b/src/net/torvald/terrarum/utils/JsonWriter.kt
index 21e26de0b..48f78a7f4 100644
--- a/src/net/torvald/terrarum/utils/JsonWriter.kt
+++ b/src/net/torvald/terrarum/utils/JsonWriter.kt
@@ -1,7 +1,7 @@
package net.torvald.terrarum.utils
-import com.google.gson.GsonBuilder
-import net.torvald.terrarum.AppLoader
+import com.badlogic.gdx.utils.Json
+import com.badlogic.gdx.utils.JsonWriter
/**
* Created by minjaesong on 2016-03-04.
@@ -10,25 +10,6 @@ object JsonWriter {
private val formattingRegex = Regex("""(?<=[\{,\[])|(?=[\]}])""")
- fun getJsonBuilder() = if (AppLoader.IS_DEVELOPMENT_BUILD) {
- getPrettyBuilder()
- }
- else {
- GsonBuilder()
- .serializeNulls()
- .disableHtmlEscaping()
- .enableComplexMapKeySerialization()
- .create()
- }
-
- fun getPrettyBuilder() = GsonBuilder()
- .setPrettyPrinting()
-
- .serializeNulls()
- .disableHtmlEscaping()
- .enableComplexMapKeySerialization()
- .create()
-
/**
* serialise a class to the file as JSON, using Google GSON.
*
@@ -37,10 +18,8 @@ object JsonWriter {
*/
@Throws(java.io.IOException::class)
fun writeToFile(c: Any, path: String) {
- val jsonString = getJsonBuilder().toJson(c)
-
val writer = java.io.FileWriter(path, false)
- writer.write(jsonString.replace(formattingRegex, "\n"))
+ writer.write(Json(JsonWriter.OutputType.json).toJson(c).replace(formattingRegex, "\n"))
writer.close()
}
@@ -50,13 +29,13 @@ object JsonWriter {
* @param jsonObject
* @param path: path to write a file
*/
- @Throws(java.io.IOException::class)
- fun writeToFile(jsonObject: com.google.gson.JsonObject, path: String) {
+ /*@Throws(java.io.IOException::class)
+ fun writeToFile(jsonObject: Json, path: String) {
val writer = java.io.FileWriter(path, false)
- writer.write(getPrettyBuilder().toJson(jsonObject))
+ writer.write(jsonObject.)
//writer.write(jsonObject.toString().replace(formattingRegex, "\n"))
writer.close()
- }
+ }*/
}
diff --git a/src/net/torvald/terrarum/weather/WeatherMixer.kt b/src/net/torvald/terrarum/weather/WeatherMixer.kt
index 416bd4970..b4f33a550 100644
--- a/src/net/torvald/terrarum/weather/WeatherMixer.kt
+++ b/src/net/torvald/terrarum/weather/WeatherMixer.kt
@@ -275,37 +275,31 @@ internal object WeatherMixer : RNGConsumer {
val JSON = JsonFetcher(path)
- val skyboxInJson = JSON.get("skyboxGradColourMap").asJsonPrimitive
- val extraImagesPath = JSON.getAsJsonArray("extraImages")
+ val skyboxInJson = JSON.getString("skyboxGradColourMap")
+ val extraImagesPath = JSON.get("extraImages").asStringArray()
-
-
- val skybox = if (skyboxInJson.isString)
- GdxColorMap(ModMgr.getGdxFile("basegame", "$pathToImage/${skyboxInJson.asString}"))
- else
- throw IllegalStateException("In weather descriptor $path -- skyboxGradColourMap seems malformed.")
+ val skybox = GdxColorMap(ModMgr.getGdxFile("basegame", "$pathToImage/${skyboxInJson}"))
val extraImages = ArrayList()
for (i in extraImagesPath)
- extraImages.add(Texture(ModMgr.getGdxFile("basegame", "$pathToImage/${i.asString}")))
+ extraImages.add(Texture(ModMgr.getGdxFile("basegame", "$pathToImage/${i}")))
-
- val classification = JSON.get("classification").asJsonPrimitive.asString
+ val classification = JSON.getString("classification")
var mixFrom: String?
- try { mixFrom = JSON.get("mixFrom").asJsonPrimitive.asString }
- catch (e: NullPointerException) { mixFrom = null }
+ try { mixFrom = JSON.getString("mixFrom") }
+ catch (e: IllegalArgumentException) { mixFrom = null }
var mixPercentage: Double?
- try { mixPercentage = JSON.get("mixPercentage").asJsonPrimitive.asDouble }
- catch (e: NullPointerException) { mixPercentage = null }
+ try { mixPercentage = JSON.getDouble("mixPercentage") }
+ catch (e: IllegalArgumentException) { mixPercentage = null }
diff --git a/terrarum.terrarum.iml b/terrarum.terrarum.iml
index b34d17a36..1b2112522 100644
--- a/terrarum.terrarum.iml
+++ b/terrarum.terrarum.iml
@@ -12,7 +12,6 @@
-
@@ -22,7 +21,6 @@
-
diff --git a/work_files/DataFormats/just-json-it-saveformat.md b/work_files/DataFormats/just-json-it-saveformat.md
index db1be0c5c..87133ea0a 100644
--- a/work_files/DataFormats/just-json-it-saveformat.md
+++ b/work_files/DataFormats/just-json-it-saveformat.md
@@ -10,8 +10,8 @@ Following code is an example savegame JSON files.
weatseed: "e5e72beb4e3c6926d3dc9e3e2ef7833b",
playerid: 9545698,
creation_t: ,
- lastplay_t: ,
- creation_t: ,
+ lastplay_t: ,
+ playtime_t: ,
thumb: ,
blocks: ,