some organisation, Base32 password generator

This commit is contained in:
minjaesong
2017-05-03 02:37:03 +09:00
parent f8435711dd
commit c1ef44c2f2
29 changed files with 367 additions and 217 deletions

View File

@@ -21,24 +21,7 @@ Any contribution in this project must be made sorely in English, Korean part is
## The Engine ## ## The Engine ##
The Engine is custom built to suit the needs most. Following list is our aims: Please refer to [```THE_ENGINE.md```](THE_ENGINE.md).
* Reasonable performance on vast world, on JVM
- At least better than Notch's codes...
* Thread scalability
- Multithreaded environments are commonplace in this era; even in the Intel Pentium G. We aim to introduce performance boost by supporting multithreads, without the limitation of threads count (hopefully).
* Lightweight physics solver, as light as we need
- This game is not exactly a physics toy, albeit some could add the fun.
- Currently implemented: gravity (NOT artificial), friction, buoyancy (WIP), air/fluid density and termination velocity
- Planned: artificial gravitation, wind, joints
* Cellular Automata fluid simulation
- It should be enough — period.
Because of this, we just couldn't use solutions out there. For example, Tiled is too slow<sup>[citation needed]</sup> and has large memory footprint<sup>[citation needed]</sup> for our vast world; we can't use JBox2d nor Dyn4j as we don't need any sophisticated physics simulation, and can't use them anyway as we have literally _millions_ of rigid bodies (tiles) and actors. (Trivia: we _do_ use Dyn4j's Vector2 class)
## Contribution guidelines ## ## Contribution guidelines ##

58
THE_ENGINE.md Normal file
View File

@@ -0,0 +1,58 @@
DISCLAIMER: this is marketing-team stuffs. Features are still in-development and may not be available.
### TODO: cleanup
The Engine is custom built to suit the needs most. Following list is our aims:
* Reasonable performance on vast world, on JVM
- At least better than Notch's codes...
* Thread scalability
- Multithreaded environments are commonplace in this era; even in the Intel Pentium G. We aim to introduce performance boost by supporting multithreads, without the limitation of threads count (hopefully).
* Lightweight physics solver, as light as we need
- This game is not exactly a physics toy, albeit some could add the fun.
- Currently implemented: gravity (NOT artificial), friction, buoyancy (WIP), air/fluid density and termination velocity
- Planned: artificial gravitation, wind, joints
* Cellular Automata fluid simulation
- It should be enough — period.
Because of this, we just couldn't use solutions out there. For example, Tiled is too slow<sup>[citation needed]</sup> and has large memory footprint<sup>[citation needed]</sup> for our vast world; we can't use JBox2d nor Dyn4j as we don't need any sophisticated physics simulation, and can't use them anyway as we have literally _millions_ of rigid bodies (tiles) and actors. (Trivia: we _do_ use Dyn4j's Vector2 class)
## General-Purpose Side-Scroller Game Maker
The Engines is specialised in side-scrolling platformers with controls specific to
The Engine is designed with modularity in mind — every game runs upon the Engine is individual module(s), and you can write your own module to alter the original game (module), essentially a game "mod" (put intended).
### Actors
The Engine allows Actors (NPCs) to have AIs
### Sprites
The Engine allows up to 64 sprite layers that are either software- or hardware-blended
### Multilingual Support
The Engine can support any arbitrary language, as long as there is fonts for them. A default font is shipped with the Engine, and it already supports 20+ languages.
### Utilities
The Engine also comes with various utilities to help the game making bit easier. They include:
- Savegame generator/loader
- Password system (old games used password system to load/save the gameplay)
- CSV loader (e.g. Item properties)
- Json loader/saver
- Text cipher

View File

@@ -1,21 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4"> <module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Lua" name="Lua">
<configuration SdkName="LuaJ" />
</facet>
<facet type="kotlin-language" name="Kotlin">
<configuration version="2" platform="JVM 1.6" useProjectSettings="false">
<compilerSettings />
<compilerArguments>
<option name="jvmTarget" value="1.6" />
<option name="languageVersion" value="1.1" />
<option name="apiVersion" value="1.1" />
<option name="coroutinesEnable" value="true" />
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">

View File

@@ -1,52 +0,0 @@
package net.torvald
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import java.io.File
import java.io.IOException
import java.nio.file.FileSystems
import java.nio.file.Files
import java.util.ArrayList
import java.util.function.Consumer
/**
* Created by minjaesong on 16-02-15.
*/
object JsonFetcher {
private var jsonString: StringBuffer? = null
@Throws(IOException::class)
operator fun invoke(jsonFilePath: String): JsonObject {
jsonString = StringBuffer() // reset buffer every time it called
readJsonFileAsString(jsonFilePath)
println("[JsonFetcher] Reading JSON $jsonFilePath")
val jsonParser = JsonParser()
val jsonObj = jsonParser.parse(jsonString!!.toString()).asJsonObject
return jsonObj
}
@Throws(IOException::class)
operator fun invoke(jsonFile: File): JsonObject {
jsonString = StringBuffer() // reset buffer every time it called
readJsonFileAsString(jsonFile.canonicalPath)
println("[JsonFetcher] Reading JSON ${jsonFile.path}")
val jsonParser = JsonParser()
val jsonObj = jsonParser.parse(jsonString!!.toString()).asJsonObject
return jsonObj
}
@Throws(IOException::class)
private fun readJsonFileAsString(path: String) {
Files.lines(FileSystems.getDefault().getPath(path)).forEach(
{ jsonString!!.append(it) }
) // JSON does not require line break
}
}

View File

@@ -1,49 +0,0 @@
package net.torvald
import javax.imageio.ImageIO
import java.awt.*
import java.awt.color.ColorSpace
import java.awt.image.*
import java.io.File
import java.io.IOException
/**
* Created by minjaesong on 16-03-04.
*/
object RasterWriter {
val BANDOFFSET_RGB = intArrayOf(0, 1, 2)
val BANDOFFSET_RGBA = intArrayOf(0, 1, 2, 3)
val BANDOFFSET_ARGB = intArrayOf(3, 0, 1, 2)
val BANDOFFSET_MONO = intArrayOf(0)
val COLORSPACE_SRGB = ColorSpace.CS_sRGB
val COLORSPACE_GRAY = ColorSpace.CS_GRAY
val COLORSPACE_GREY = COLORSPACE_GRAY
val COLORSPACE_CIEXYZ = ColorSpace.CS_CIEXYZ
val COLORSPACE_RGB_LINEAR_GAMMA = ColorSpace.CS_LINEAR_RGB
@Throws(IOException::class)
fun writePNG_RGB(w: Int, h: Int, rasterData: ByteArray, path: String) {
writePNG(w, h, rasterData, BANDOFFSET_RGB, COLORSPACE_SRGB, path)
}
@Throws(IOException::class)
fun writePNG_Mono(w: Int, h: Int, rasterData: ByteArray, path: String) {
writePNG(w, h, rasterData, BANDOFFSET_MONO, COLORSPACE_GREY, path)
}
@Throws(IOException::class)
fun writePNG(w: Int, h: Int, rasterData: ByteArray, bandOffsets: IntArray, awt_colorspace: Int, path: String) {
val buffer = DataBufferByte(rasterData, rasterData.size)
val raster = Raster.createInterleavedRaster(
buffer, w, h, bandOffsets.size * w, bandOffsets.size, bandOffsets, null)
val colorModel = ComponentColorModel(ColorSpace.getInstance(awt_colorspace), false, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE)
val image = BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied, null)
ImageIO.write(image, "PNG", File(path))
}
}

View File

@@ -1,6 +1,6 @@
package net.torvald.terrarum package net.torvald.terrarum
import net.torvald.CSVFetcher import net.torvald.terrarum.utils.CSVFetcher
import net.torvald.terrarum.itemproperties.GameItem import net.torvald.terrarum.itemproperties.GameItem
import net.torvald.terrarum.itemproperties.ItemCodex import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.blockproperties.BlockCodex import net.torvald.terrarum.blockproperties.BlockCodex
@@ -99,12 +99,6 @@ object ModMgr {
println("extension:" + f.extensions) println("extension:" + f.extensions)
println("-----------------------------------------------") println("-----------------------------------------------")
}*/ }*/
/*val engine = ScriptEngineManager().getEngineByExtension("groovy")!!
engine.eval(FileReader(getFile("basegame", "/items/testpick.groovy")))
val newPick = (engine as Invocable).invokeFunction("invoke", 8449) as GameItem
ItemCodex[8449] = newPick*/
} }
private fun checkExistence(module: String) { private fun checkExistence(module: String) {

View File

@@ -27,7 +27,7 @@ class StateUITest : BasicGameState() {
TODO("not implemented") TODO("not implemented")
} }
override fun actorValueChanged(key: String, value: Any?) { override fun onActorValueChange(key: String, value: Any?) {
} }
override var inventory: ActorInventory = ActorInventory(this, 100, ActorInventory.CAPACITY_MODE_WEIGHT) override var inventory: ActorInventory = ActorInventory(this, 100, ActorInventory.CAPACITY_MODE_WEIGHT)

View File

@@ -1,11 +1,10 @@
package net.torvald.terrarum package net.torvald.terrarum
import com.google.gson.JsonArray import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive import com.google.gson.JsonPrimitive
import net.torvald.imagefont.GameFontImpl import net.torvald.imagefont.GameFontImpl
import net.torvald.JsonFetcher import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.JsonWriter import net.torvald.terrarum.utils.JsonWriter
import net.torvald.imagefont.TinyAlphNum import net.torvald.imagefont.TinyAlphNum
import net.torvald.terrarum.gamecontroller.mouseTileX import net.torvald.terrarum.gamecontroller.mouseTileX
import net.torvald.terrarum.gamecontroller.mouseTileY import net.torvald.terrarum.gamecontroller.mouseTileY
@@ -18,7 +17,6 @@ import org.newdawn.slick.opengl.Texture
import org.newdawn.slick.state.StateBasedGame import org.newdawn.slick.state.StateBasedGame
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.lang.management.ManagementFactory
import java.nio.ByteOrder import java.nio.ByteOrder
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@@ -351,23 +349,23 @@ object Terrarum : StateBasedGame(GAME_NAME) {
val OS = System.getProperty("os.name").toUpperCase() val OS = System.getProperty("os.name").toUpperCase()
if (OS.contains("WIN")) { if (OS.contains("WIN")) {
OperationSystem = "WINDOWS" OperationSystem = "WINDOWS"
defaultDir = System.getenv("APPDATA") + "/terrarum" defaultDir = System.getenv("APPDATA") + "/Terrarum"
} }
else if (OS.contains("OS X")) { else if (OS.contains("OS X")) {
OperationSystem = "OSX" OperationSystem = "OSX"
defaultDir = System.getProperty("user.home") + "/Library/Application Support/terrarum" defaultDir = System.getProperty("user.home") + "/Library/Application Support/Terrarum"
} }
else if (OS.contains("NUX") || OS.contains("NIX")) { else if (OS.contains("NUX") || OS.contains("NIX")) {
OperationSystem = "LINUX" OperationSystem = "LINUX"
defaultDir = System.getProperty("user.home") + "/.terrarum" defaultDir = System.getProperty("user.home") + "/.Terrarum"
} }
else if (OS.contains("SUNOS")) { else if (OS.contains("SUNOS")) {
OperationSystem = "SOLARIS" OperationSystem = "SOLARIS"
defaultDir = System.getProperty("user.home") + "/.terrarum" defaultDir = System.getProperty("user.home") + "/.Terrarum"
} }
else { else {
OperationSystem = "UNKNOWN" OperationSystem = "UNKNOWN"
defaultDir = System.getProperty("user.home") + "/.terrarum" defaultDir = System.getProperty("user.home") + "/.Terrarum"
} }
defaultSaveDir = defaultDir + "/Saves" defaultSaveDir = defaultDir + "/Saves"

View File

@@ -1,6 +1,6 @@
package net.torvald.terrarum.blockproperties package net.torvald.terrarum.blockproperties
import net.torvald.CSVFetcher import net.torvald.terrarum.utils.CSVFetcher
import net.torvald.terrarum.gameworld.MapLayer import net.torvald.terrarum.gameworld.MapLayer
import net.torvald.terrarum.gameworld.PairedMapLayer import net.torvald.terrarum.gameworld.PairedMapLayer
import org.apache.commons.csv.CSVRecord import org.apache.commons.csv.CSVRecord

View File

@@ -1,6 +1,6 @@
package net.torvald.terrarum.console package net.torvald.terrarum.console
import net.torvald.JsonWriter import net.torvald.terrarum.utils.JsonWriter
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import java.io.IOException import java.io.IOException

View File

@@ -1,7 +1,7 @@
package net.torvald.terrarum.console package net.torvald.terrarum.console
import net.torvald.colourutil.Col4096 import net.torvald.colourutil.Col4096
import net.torvald.RasterWriter import net.torvald.terrarum.utils.RasterWriter
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.blockproperties.Block

View File

@@ -84,5 +84,7 @@ abstract class Actor(val renderOrder: RenderOrder) : Comparable<Actor>, Runnable
* *
* @param value null if the key is deleted * @param value null if the key is deleted
*/ */
abstract fun actorValueChanged(key: String, value: Any?) abstract @Event fun onActorValueChange(key: String, value: Any?)
} }
annotation class Event

View File

@@ -335,8 +335,10 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
} }
override fun keyPressed(key: Int, c: Char) { override fun keyPressed(key: Int, c: Char) {
if (key in Key.NUM_1..Key.NUM_0) { // quickslot (quickbar)
actorValue[AVKey.__PLAYER_QUICKSLOTSEL] = key - Key.NUM_1 val quickbarKeys = Terrarum.getConfigIntArray("keyquickbars")
if (key in quickbarKeys) {
actorValue[AVKey.__PLAYER_QUICKSLOTSEL] = quickbarKeys.indexOf(key)
} }
} }
@@ -474,7 +476,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
} }
} }
override fun actorValueChanged(key: String, value: Any?) { override fun onActorValueChange(key: String, value: Any?) {
// quickslot implementation // quickslot implementation
if (key == AVKey.__PLAYER_QUICKSLOTSEL && value != null) { if (key == AVKey.__PLAYER_QUICKSLOTSEL && value != null) {
// ONLY FOR HAND_GRIPs!! // ONLY FOR HAND_GRIPs!!

View File

@@ -13,13 +13,13 @@ class ActorValue(val actor: Actor) : KVHashMap() {
override fun set(key: String, value: Any) { override fun set(key: String, value: Any) {
super.set(key, value) super.set(key, value)
actor.actorValueChanged(key, value) // fire the event handler actor.onActorValueChange(key, value) // fire the event handler
} }
override fun remove(key: String) { override fun remove(key: String) {
if (hashMap[key] != null) { if (hashMap[key] != null) {
hashMap.remove(key, hashMap[key]!!) hashMap.remove(key, hashMap[key]!!)
actor.actorValueChanged(key, null) actor.onActorValueChange(key, null)
} }
} }

View File

@@ -1135,7 +1135,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
} }
} }
override fun actorValueChanged(key: String, value: Any?) { override fun onActorValueChange(key: String, value: Any?) {
// do nothing // do nothing
} }

View File

@@ -1,10 +1,5 @@
package net.torvald.terrarum.gameactors package net.torvald.terrarum.gameactors
import net.torvald.JsonFetcher
import net.torvald.random.Fudge3
import net.torvald.random.HQRNG
import net.torvald.terrarum.langpack.Lang
import com.google.gson.JsonObject
import org.newdawn.slick.SlickException import org.newdawn.slick.SlickException
import java.io.IOException import java.io.IOException

View File

@@ -1,14 +1,10 @@
package net.torvald.terrarum.gameactors package net.torvald.terrarum.gameactors
import net.torvald.JsonFetcher import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.random.Fudge3 import net.torvald.random.Fudge3
import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.langpack.Lang
import com.google.gson.JsonObject import com.google.gson.JsonObject
import net.torvald.terrarum.gameactors.ActorValue
import net.torvald.terrarum.ModMgr import net.torvald.terrarum.ModMgr
import net.torvald.terrarum.gameactors.ActorHumanoid
import org.newdawn.slick.SlickException
import java.io.IOException
import java.security.SecureRandom import java.security.SecureRandom
/** /**

View File

@@ -1,7 +1,6 @@
package net.torvald.terrarum.gameactors.faction package net.torvald.terrarum.gameactors.faction
import net.torvald.JsonFetcher import net.torvald.terrarum.utils.JsonFetcher
import com.google.gson.JsonObject
import net.torvald.terrarum.ModMgr import net.torvald.terrarum.ModMgr
import java.io.IOException import java.io.IOException

View File

@@ -1,6 +1,6 @@
package net.torvald.terrarum.gamecontroller package net.torvald.terrarum.gamecontroller
import net.torvald.JsonFetcher import net.torvald.terrarum.utils.JsonFetcher
import java.util.* import java.util.*
/** /**

View File

@@ -1,6 +1,6 @@
package net.torvald.terrarum.langpack package net.torvald.terrarum.langpack
import net.torvald.JsonFetcher import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import java.io.* import java.io.*
import java.util.* import java.util.*

View File

@@ -1,4 +1,4 @@
package net.torvald package net.torvald.terrarum.utils
import net.torvald.terrarum.ModMgr import net.torvald.terrarum.ModMgr
import org.apache.commons.csv.CSVFormat import org.apache.commons.csv.CSVFormat
@@ -17,15 +17,15 @@ object CSVFetcher {
private var csvString: StringBuffer? = null private var csvString: StringBuffer? = null
fun readFromFile(csvFilePath: String): List<CSVRecord> { fun readFromFile(csvFilePath: String): List<org.apache.commons.csv.CSVRecord> {
csvString = StringBuffer() // reset buffer every time it called net.torvald.terrarum.utils.CSVFetcher.csvString = StringBuffer() // reset buffer every time it called
readCSVasString(csvFilePath) net.torvald.terrarum.utils.CSVFetcher.readCSVasString(csvFilePath)
println("[CSVFetcher] Reading CSV $csvFilePath") println("[CSVFetcher] Reading CSV $csvFilePath")
val csvParser = CSVParser.parse( val csvParser = org.apache.commons.csv.CSVParser.parse(
csvString!!.toString(), net.torvald.terrarum.utils.CSVFetcher.csvString!!.toString(),
CSVFormat.DEFAULT.withIgnoreSurroundingSpaces() org.apache.commons.csv.CSVFormat.DEFAULT.withIgnoreSurroundingSpaces()
.withHeader() .withHeader()
.withIgnoreEmptyLines() .withIgnoreEmptyLines()
.withDelimiter(';') .withDelimiter(';')
@@ -40,12 +40,12 @@ object CSVFetcher {
return csvRecordList return csvRecordList
} }
fun readFromModule(module: String, path: String) = readFromFile(ModMgr.getPath(module, path)) fun readFromModule(module: String, path: String) = net.torvald.terrarum.utils.CSVFetcher.readFromFile(ModMgr.getPath(module, path))
fun readFromString(csv: String): List<CSVRecord> { fun readFromString(csv: String): List<org.apache.commons.csv.CSVRecord> {
val csvParser = CSVParser.parse( val csvParser = org.apache.commons.csv.CSVParser.parse(
csv, csv,
CSVFormat.DEFAULT.withIgnoreSurroundingSpaces() org.apache.commons.csv.CSVFormat.DEFAULT.withIgnoreSurroundingSpaces()
.withHeader() .withHeader()
.withIgnoreEmptyLines() .withIgnoreEmptyLines()
.withDelimiter(';') .withDelimiter(';')
@@ -60,12 +60,12 @@ object CSVFetcher {
return csvRecordList return csvRecordList
} }
@Throws(IOException::class) @Throws(java.io.IOException::class)
fun readCSVasString(path: String): String { fun readCSVasString(path: String): String {
csvString = StringBuffer() net.torvald.terrarum.utils.CSVFetcher.csvString = StringBuffer()
Files.lines(FileSystems.getDefault().getPath(path)).forEach( java.nio.file.Files.lines(java.nio.file.FileSystems.getDefault().getPath(path)).forEach(
{ s -> csvString!!.append("$s\n") } { s -> net.torvald.terrarum.utils.CSVFetcher.csvString!!.append("$s\n") }
) )
return csvString!!.toString() return net.torvald.terrarum.utils.CSVFetcher.csvString!!.toString()
} }
} }

View File

@@ -1,9 +1,9 @@
package net.torvald.simplecipher package net.torvald.terrarum.utils
/** /**
* Created by minjaesong on 16-03-20. * Created by minjaesong on 16-03-20.
*/ */
object ROTUtil { object CipherROT {
const val CODE_CAP_A = 'A'.toInt() const val CODE_CAP_A = 'A'.toInt()
const val CODE_LOW_A = 'a'.toInt() const val CODE_LOW_A = 'a'.toInt()
@@ -14,18 +14,6 @@ object ROTUtil {
* * Latin alph: removes diacritics and do ROT13, string reverse, capitalised. * * Latin alph: removes diacritics and do ROT13, string reverse, capitalised.
* Ligatures are disassembled. Even if the target language does not have * Ligatures are disassembled. Even if the target language does not have
* certain alphabet (e.g. C in Icelandic), such alphabet will be printed anyway. * certain alphabet (e.g. C in Icelandic), such alphabet will be printed anyway.
*
* * Cyrillic: removes diacritics and do ROTnn, string reverse, capitalised.
*
* * Kana: raise Sutegana, ROT3 on vowels (a i u e o -> e o a i u), string reverse
* (Wa Wo -> Wo Wa), Nn will remain untouched, forced Katakana.
*
* * Hangul: ROT3 on initials\*, lower double initials to single
* ( -> ),
* string reverse
*
* * Chinese: NOT SUPPORTED
*
* * Numeric: no encrypt * * Numeric: no encrypt
*/ */
fun encrypt(plaintext: String): String { fun encrypt(plaintext: String): String {

View File

@@ -1,4 +1,4 @@
package net.torvald package net.torvald.terrarum.utils
import java.awt.Toolkit import java.awt.Toolkit
import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.DataFlavor

View File

@@ -0,0 +1,52 @@
package net.torvald.terrarum.utils
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import java.io.File
import java.io.IOException
import java.nio.file.FileSystems
import java.nio.file.Files
import java.util.ArrayList
import java.util.function.Consumer
/**
* Created by minjaesong on 16-02-15.
*/
object JsonFetcher {
private var jsonString: StringBuffer? = null
@Throws(java.io.IOException::class)
operator fun invoke(jsonFilePath: String): com.google.gson.JsonObject {
net.torvald.terrarum.utils.JsonFetcher.jsonString = StringBuffer() // reset buffer every time it called
net.torvald.terrarum.utils.JsonFetcher.readJsonFileAsString(jsonFilePath)
println("[JsonFetcher] Reading JSON $jsonFilePath")
val jsonParser = com.google.gson.JsonParser()
val jsonObj = jsonParser.parse(net.torvald.terrarum.utils.JsonFetcher.jsonString!!.toString()).asJsonObject
return jsonObj
}
@Throws(java.io.IOException::class)
operator fun invoke(jsonFile: java.io.File): com.google.gson.JsonObject {
net.torvald.terrarum.utils.JsonFetcher.jsonString = StringBuffer() // reset buffer every time it called
net.torvald.terrarum.utils.JsonFetcher.readJsonFileAsString(jsonFile.canonicalPath)
println("[JsonFetcher] Reading JSON ${jsonFile.path}")
val jsonParser = com.google.gson.JsonParser()
val jsonObj = jsonParser.parse(net.torvald.terrarum.utils.JsonFetcher.jsonString!!.toString()).asJsonObject
return jsonObj
}
@Throws(java.io.IOException::class)
private fun readJsonFileAsString(path: String) {
java.nio.file.Files.lines(java.nio.file.FileSystems.getDefault().getPath(path)).forEach(
{ net.torvald.terrarum.utils.JsonFetcher.jsonString!!.append(it) }
) // JSON does not require line break
}
}

View File

@@ -1,4 +1,4 @@
package net.torvald package net.torvald.terrarum.utils
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonElement import com.google.gson.JsonElement
@@ -18,11 +18,11 @@ object JsonWriter {
* @param c: a class * @param c: a class
* @param path: path to write a file * @param path: path to write a file
*/ */
@Throws(IOException::class) @Throws(java.io.IOException::class)
fun writeToFile(c: Any, path: String) { fun writeToFile(c: Any, path: String) {
val classElem = Gson().toJsonTree(c) val classElem = com.google.gson.Gson().toJsonTree(c)
val jsonString = classElem.toString() val jsonString = classElem.toString()
val writer = FileWriter(path) val writer = java.io.FileWriter(path)
writer.write(jsonString) writer.write(jsonString)
writer.close() writer.close()
} }
@@ -33,9 +33,9 @@ object JsonWriter {
* @param jsonObject * @param jsonObject
* @param path: path to write a file * @param path: path to write a file
*/ */
@Throws(IOException::class) @Throws(java.io.IOException::class)
fun writeToFile(jsonObject: JsonObject, path: String) { fun writeToFile(jsonObject: com.google.gson.JsonObject, path: String) {
val writer = FileWriter(path) val writer = java.io.FileWriter(path)
writer.write(jsonObject.toString()) writer.write(jsonObject.toString())
writer.close() writer.close()
} }

View File

@@ -0,0 +1,150 @@
package net.torvald.terrarum.utils
import kotlin.experimental.xor
/**
* Old-school passworld system using Base32
*
* Created by minjaesong on 2017-05-02.
*/
object PasswordBase32 {
private val stringSet = "YBNDRFG8EJKMCPQXOT+VWIS2A345H769="
private val substituteSet = hashMapOf(
Pair('0', 'O'),
Pair('1', 'I'),
Pair('Z', '2')
)
/*
0 x
1 6
2 4
3 3
4 1
*/
val padLen = arrayOf(0, 6, 4, 3, 1)
private val nullPw = byteArrayOf(0.toByte())
private fun encodeToLetters(byteArray: ByteArray, password: ByteArray): IntArray {
val out = ArrayList<Int>()
fun get(i: Int) = byteArray[i] xor (password[i % password.size])
/*
5 Bytes -> 8 Letters
0000 0000 | 1111 1111 | 2222 2222 | 3333 3333 | 4444 4444
AAAA ABBB | BBCC CCCD | DDDD EEEE | EFFF FFGG | GGGH HHHH
*/
// non-pads
(0..byteArray.lastIndex - 5 step 5).forEach {
/* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
/* B */ out.add(get(it).toInt().and(7).shl(2) or get(it+1).toInt().and(0xC0).ushr(6))
/* C */ out.add(get(it+1).toInt().and(0x3E).ushr(1))
/* D */ out.add(get(it+1).toInt().and(1).shl(4) or get(it+2).toInt().and(0xF0).ushr(4))
/* E */ out.add(get(it+2).toInt().and(0xF).shl(1) or get(it+3).toInt().and(0x80).ushr(7))
/* F */ out.add(get(it+3).toInt().and(0x7C).ushr(2))
/* G */ out.add(get(it+3).toInt().and(3).shl(3) or get(it+4).toInt().and(0xE0).ushr(5))
/* H */ out.add(get(it+4).toInt().and(0x1F))
}
// pads
val residue = byteArray.size % 5
if (residue != 0){
val it = (byteArray.size / 5) * 5 // dark magic of integer division, let's hope the compiler won't "optimise" this...
when (residue) {
1 -> {
/* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
/* B */ out.add(get(it).toInt().and(7).shl(2))
}
2 -> {
/* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
/* B */ out.add(get(it).toInt().and(7).shl(2) or get(it+1).toInt().and(0xC0).ushr(6))
/* C */ out.add(get(it+1).toInt().and(0x3E).ushr(1))
/* D */ out.add(get(it+1).toInt().and(1).shl(4))
}
3 -> {
/* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
/* B */ out.add(get(it).toInt().and(7).shl(2) or get(it+1).toInt().and(0xC0).ushr(6))
/* C */ out.add(get(it+1).toInt().and(0x3E).ushr(1))
/* D */ out.add(get(it+1).toInt().and(1).shl(4) or get(it+2).toInt().and(0xF0).ushr(4))
/* E */ out.add(get(it+2).toInt().and(0xF).shl(1))
}
4 -> {
/* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
/* B */ out.add(get(it).toInt().and(7).shl(2) or get(it+1).toInt().and(0xC0).ushr(6))
/* C */ out.add(get(it+1).toInt().and(0x3E).ushr(1))
/* D */ out.add(get(it+1).toInt().and(1).shl(4) or get(it+2).toInt().and(0xF0).ushr(4))
/* E */ out.add(get(it+2).toInt().and(0xF).shl(1) or get(it+3).toInt().and(0x80).ushr(7))
/* F */ out.add(get(it+3).toInt().and(0x7C).ushr(2))
/* G */ out.add(get(it+3).toInt().and(3).shl(3))
}
}
// append padding
kotlin.repeat(padLen[residue], { out.add(32) })
}
return out.toIntArray()
}
/**
*
* @param bytes size of multiple of five (5, 10, 15, 20, ...) is highly recommended to prevent
* lengthy padding
* @param password to encode resulting string using XOR Cipher to prevent unexperienced kids
* from doing naughty things. Longer, the better.
*/
fun encode(bytes: ByteArray, password: ByteArray = nullPw): String {
val plaintext = encodeToLetters(bytes, password)
val sb = StringBuilder()
plaintext.forEach { sb.append(stringSet[it]) }
return sb.toString()
}
/**
* @param outByteLength expected length of your decoded password. It is always a good idea to
* suspect user inputs and sanitise them.
*/
fun decode(input: String, outByteLength: Int, password: ByteArray = nullPw): ByteArray {
val buffer = ByteArray(outByteLength)
var appendCount = 0
var input = input.toUpperCase()
substituteSet.forEach { from, to ->
input = input.replace(from, to)
}
fun append(byte: Int) {
buffer[appendCount] = byte.toByte() xor (password[appendCount % password.size])
appendCount++
}
fun sbyteOf(i: Int) = stringSet.indexOf(input[i]).and(0x1F)
try {
/*
8 Letters -> 5 Bytes
0000 0000 | 1111 1111 | 2222 2222 | 3333 3333 | 4444 4444
AAAA ABBB | BBCC CCCD | DDDD EEEE | EFFF FFGG | GGGH HHHH
*/
(0..input.lastIndex.plus(8) step 8).forEach {
/* 0 */ append(sbyteOf(it+0).shl(3) or sbyteOf(it+1).ushr(2))
/* 1 */ append(sbyteOf(it+1).shl(6) or sbyteOf(it+2).shl(1) or sbyteOf(it+3).ushr(4))
/* 2 */ append(sbyteOf(it+3).shl(4) or sbyteOf(it+4).ushr(1))
/* 3 */ append(sbyteOf(it+4).shl(7) or sbyteOf(it+5).shl(2) or sbyteOf(it+6).ushr(3))
/* 4 */ append(sbyteOf(it+6).shl(5) or sbyteOf(it+7))
}
}
catch (endOfStream: ArrayIndexOutOfBoundsException) { }
return buffer
}
}

View File

@@ -0,0 +1,49 @@
package net.torvald.terrarum.utils
import javax.imageio.ImageIO
import java.awt.*
import java.awt.color.ColorSpace
import java.awt.image.*
import java.io.File
import java.io.IOException
/**
* Created by minjaesong on 16-03-04.
*/
object RasterWriter {
val BANDOFFSET_RGB = intArrayOf(0, 1, 2)
val BANDOFFSET_RGBA = intArrayOf(0, 1, 2, 3)
val BANDOFFSET_ARGB = intArrayOf(3, 0, 1, 2)
val BANDOFFSET_MONO = intArrayOf(0)
val COLORSPACE_SRGB = java.awt.color.ColorSpace.CS_sRGB
val COLORSPACE_GRAY = java.awt.color.ColorSpace.CS_GRAY
val COLORSPACE_GREY = net.torvald.terrarum.utils.RasterWriter.COLORSPACE_GRAY
val COLORSPACE_CIEXYZ = java.awt.color.ColorSpace.CS_CIEXYZ
val COLORSPACE_RGB_LINEAR_GAMMA = java.awt.color.ColorSpace.CS_LINEAR_RGB
@Throws(java.io.IOException::class)
fun writePNG_RGB(w: Int, h: Int, rasterData: ByteArray, path: String) {
net.torvald.terrarum.utils.RasterWriter.writePNG(w, h, rasterData, BANDOFFSET_RGB, COLORSPACE_SRGB, path)
}
@Throws(java.io.IOException::class)
fun writePNG_Mono(w: Int, h: Int, rasterData: ByteArray, path: String) {
net.torvald.terrarum.utils.RasterWriter.writePNG(w, h, rasterData, BANDOFFSET_MONO, COLORSPACE_GREY, path)
}
@Throws(java.io.IOException::class)
fun writePNG(w: Int, h: Int, rasterData: ByteArray, bandOffsets: IntArray, awt_colorspace: Int, path: String) {
val buffer = java.awt.image.DataBufferByte(rasterData, rasterData.size)
val raster = java.awt.image.Raster.createInterleavedRaster(
buffer, w, h, bandOffsets.size * w, bandOffsets.size, bandOffsets, null)
val colorModel = java.awt.image.ComponentColorModel(java.awt.color.ColorSpace.getInstance(awt_colorspace), false, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE)
val image = java.awt.image.BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied, null)
javax.imageio.ImageIO.write(image, "PNG", java.io.File(path))
}
}

View File

@@ -1,7 +1,6 @@
package net.torvald.terrarum.weather package net.torvald.terrarum.weather
import com.jme3.math.FastMath import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.JsonFetcher
import net.torvald.colourutil.* import net.torvald.colourutil.*
import net.torvald.random.HQRNG import net.torvald.random.HQRNG
import net.torvald.terrarum.* import net.torvald.terrarum.*

View File

@@ -1,3 +1,5 @@
The extension of [```THE_ENGINE.md```](THE_ENGINE.md)
The game has elements that are: The game has elements that are:
- Actors - Actors