mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-12 11:34:05 +09:00
Schrödinger's file: it's superposition between existent and nonexistent, file and directory. Tried java.nio.file but it seems it's just Java that is broken like vittupää
Former-commit-id: ec938b81d8c4a1385295846b7b3d5178652d93ad Former-commit-id: 0ff4806c81c94ec5a126894f8d41ca6891bcb1d2
This commit is contained in:
@@ -21,8 +21,8 @@ class StateVTTest : BasicGameState() {
|
|||||||
|
|
||||||
// HiRes: 100x64, LoRes: 80x25
|
// HiRes: 100x64, LoRes: 80x25
|
||||||
val computerInside = BaseTerrarumComputer(8)
|
val computerInside = BaseTerrarumComputer(8)
|
||||||
val vt = SimpleTextTerminal(SimpleTextTerminal.AMETHYST_NOVELTY, 80, 25,
|
val vt = SimpleTextTerminal(SimpleTextTerminal.AMETHYST_NOVELTY, 100, 64,
|
||||||
computerInside, colour = false, hires = false)
|
computerInside, colour = true, hires = true)
|
||||||
|
|
||||||
|
|
||||||
val vtUI = Image(vt.displayW, vt.displayH)
|
val vtUI = Image(vt.displayW, vt.displayH)
|
||||||
|
|||||||
@@ -91,12 +91,12 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
|||||||
computerValue["processor"] = -1 // do.
|
computerValue["processor"] = -1 // do.
|
||||||
|
|
||||||
// as in "dev/hda"; refers hard disk drive (and no partitioning)
|
// as in "dev/hda"; refers hard disk drive (and no partitioning)
|
||||||
computerValue["hda"] = "testhda" // 'UUID rendered as String' or "none"
|
computerValue["hda"] = "uuid_testhda" // 'UUID rendered as String' or "none"
|
||||||
computerValue["hdb"] = "none"
|
computerValue["hdb"] = "uuid_testhdb"
|
||||||
computerValue["hdc"] = "none"
|
computerValue["hdc"] = "none"
|
||||||
computerValue["hdd"] = "none"
|
computerValue["hdd"] = "none"
|
||||||
// as in "dev/fd1"; refers floppy disk drive
|
// as in "dev/fd1"; refers floppy disk drive
|
||||||
computerValue["fd1"] = "none"
|
computerValue["fd1"] = "uuid_testfd1"
|
||||||
computerValue["fd2"] = "none"
|
computerValue["fd2"] = "none"
|
||||||
computerValue["fd3"] = "none"
|
computerValue["fd3"] = "none"
|
||||||
computerValue["fd4"] = "none"
|
computerValue["fd4"] = "none"
|
||||||
@@ -159,7 +159,7 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
|||||||
|
|
||||||
|
|
||||||
// secure the sandbox
|
// secure the sandbox
|
||||||
luaJ_globals["io"] = LuaValue.NIL
|
//luaJ_globals["io"] = LuaValue.NIL
|
||||||
// dubug should be sandboxed in BOOT.lua (use OpenComputers code)
|
// dubug should be sandboxed in BOOT.lua (use OpenComputers code)
|
||||||
//val sethook = luaJ_globals["debug"]["sethook"]
|
//val sethook = luaJ_globals["debug"]["sethook"]
|
||||||
//luaJ_globals["debug"] = LuaValue.NIL
|
//luaJ_globals["debug"] = LuaValue.NIL
|
||||||
@@ -207,12 +207,13 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
|||||||
unsetThreadRun()
|
unsetThreadRun()
|
||||||
}
|
}
|
||||||
|
|
||||||
driveBeepQueueManager(delta)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!isHalted) {
|
||||||
if (isHalted) {
|
driveBeepQueueManager(delta)
|
||||||
|
}
|
||||||
|
else {
|
||||||
currentExecutionThread.interrupt()
|
currentExecutionThread.interrupt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -326,7 +327,6 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
|||||||
// complete emitTone queue
|
// complete emitTone queue
|
||||||
if (beepCursor >= beepQueue.size) {
|
if (beepCursor >= beepQueue.size) {
|
||||||
clearBeepQueue()
|
clearBeepQueue()
|
||||||
if (DEBUG) println("[BaseTerrarumComputer] !! Beep queue clear")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// actually play queue
|
// actually play queue
|
||||||
@@ -350,6 +350,8 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
|||||||
beepQueueLineExecTimer = 0
|
beepQueueLineExecTimer = 0
|
||||||
|
|
||||||
//AL.destroy()
|
//AL.destroy()
|
||||||
|
|
||||||
|
if (DEBUG) println("[BaseTerrarumComputer] !! Beep queue clear")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun enqueueBeep(duration: Int, freq: Double) {
|
fun enqueueBeep(duration: Int, freq: Double) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import net.torvald.terrarum.virtualcomputer.luaapi.Term.Companion.checkIBM437
|
|||||||
import java.io.*
|
import java.io.*
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.Paths
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,7 +21,9 @@ import java.util.*
|
|||||||
* Created by minjaesong on 16-09-17.
|
* Created by minjaesong on 16-09-17.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* NOTE: Don't convert '\' to '/'! Rev-slash is used for escape character in sh, and we're sh-compatible!
|
* NOTES:
|
||||||
|
* Don't convert '\' to '/'! Rev-slash is used for escape character in sh, and we're sh-compatible!
|
||||||
|
* Use .absoluteFile whenever possible; there's fuckin oddity! (http://bugs.java.com/bugdatabase/view_bug.do;:YfiG?bug_id=4483097)
|
||||||
*/
|
*/
|
||||||
internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
||||||
|
|
||||||
@@ -40,7 +43,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
globals["fs"]["concat"] = ConcatPath(computer) // OC compliant
|
globals["fs"]["concat"] = ConcatPath(computer) // OC compliant
|
||||||
globals["fs"]["open"] = OpenFile(computer) //CC compliant
|
globals["fs"]["open"] = OpenFile(computer) //CC compliant
|
||||||
globals["fs"]["parent"] = GetParentDir(computer)
|
globals["fs"]["parent"] = GetParentDir(computer)
|
||||||
// fs.dofile defined in ROMLIB
|
// fs.dofile defined in BOOT
|
||||||
// fs.fetchText defined in ROMLIB
|
// fs.fetchText defined in ROMLIB
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,29 +51,34 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
fun ensurePathSanity(path: LuaValue) {
|
fun ensurePathSanity(path: LuaValue) {
|
||||||
if (path.checkIBM437().contains(Regex("""\.\.""")))
|
if (path.checkIBM437().contains(Regex("""\.\.""")))
|
||||||
throw LuaError("'..' on path is not supported.")
|
throw LuaError("'..' on path is not supported.")
|
||||||
|
if (!isValidFilename(path.checkIBM437()))
|
||||||
|
throw IOException("path contains invalid characters")
|
||||||
}
|
}
|
||||||
|
|
||||||
val isCaseInsensitive: Boolean
|
val isCaseInsensitive: Boolean
|
||||||
get() {
|
|
||||||
// TODO add: force case insensitive in config
|
init {
|
||||||
try {
|
try {
|
||||||
val uuid = UUID.randomUUID().toString()
|
val uuid = UUID.randomUUID().toString()
|
||||||
val lowerCase = File(Terrarum.currentSaveDir, uuid + "oc_rox")
|
val lowerCase = File(Terrarum.currentSaveDir, uuid + "oc_rox")
|
||||||
val upperCase = File(Terrarum.currentSaveDir, uuid + "OC_ROX")
|
val upperCase = File(Terrarum.currentSaveDir, uuid + "OC_ROX")
|
||||||
// This should NEVER happen but could also lead to VERY weird bugs, so we
|
// This should NEVER happen but could also lead to VERY weird bugs, so we
|
||||||
// make sure the files don't exist.
|
// make sure the files don't exist.
|
||||||
lowerCase.exists() && lowerCase.delete()
|
if (lowerCase.exists()) lowerCase.delete()
|
||||||
upperCase.exists() && upperCase.delete()
|
if (upperCase.exists()) upperCase.delete()
|
||||||
lowerCase.createNewFile()
|
|
||||||
val insensitive = upperCase.exists()
|
lowerCase.createNewFile()
|
||||||
lowerCase.delete()
|
|
||||||
return insensitive
|
val insensitive = upperCase.exists()
|
||||||
}
|
lowerCase.delete()
|
||||||
catch (e: IOException) {
|
|
||||||
println("[Filesystem] Couldn't determine if file system is case sensitive, falling back to insensitive.")
|
isCaseInsensitive = insensitive
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch (e: IOException) {
|
||||||
|
println("[Filesystem] Couldn't determine if file system is case sensitive, falling back to insensitive.")
|
||||||
|
isCaseInsensitive = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Worst-case: we're on Windows or using a FAT32 partition mounted in *nix.
|
// Worst-case: we're on Windows or using a FAT32 partition mounted in *nix.
|
||||||
// Note: we allow / as the path separator and expect all \s to be converted
|
// Note: we allow / as the path separator and expect all \s to be converted
|
||||||
@@ -79,11 +87,11 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
|
|
||||||
fun isValidFilename(name: String) = !name.contains(invalidChars)
|
fun isValidFilename(name: String) = !name.contains(invalidChars)
|
||||||
|
|
||||||
fun validatePath(path: String) : String {
|
fun String.validatePath() : String {
|
||||||
if (!isValidFilename(path)) {
|
if (!isValidFilename(this)) {
|
||||||
throw IOException("path contains invalid characters")
|
throw IOException("path contains invalid characters")
|
||||||
}
|
}
|
||||||
return path
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
/** actual directory: <appdata>/Saves/<savename>/computers/<drivename>/
|
/** actual directory: <appdata>/Saves/<savename>/computers/<drivename>/
|
||||||
@@ -103,7 +111,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// remove first '/' in path
|
// remove first '/' in path
|
||||||
var path = luapath.checkIBM437()
|
var path = luapath.checkIBM437().validatePath()
|
||||||
if (path.startsWith('/')) path = path.substring(1)
|
if (path.startsWith('/')) path = path.substring(1)
|
||||||
|
|
||||||
if (path.startsWith("media/")) {
|
if (path.startsWith("media/")) {
|
||||||
@@ -131,7 +139,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
Filesystem.ensurePathSanity(path)
|
Filesystem.ensurePathSanity(path)
|
||||||
|
|
||||||
val table = LuaTable()
|
val table = LuaTable()
|
||||||
val file = File(computer.getRealPath(path))
|
val file = File(computer.getRealPath(path)).absoluteFile
|
||||||
file.list().forEachIndexed { i, s -> table.insert(i, LuaValue.valueOf(s)) }
|
file.list().forEachIndexed { i, s -> table.insert(i, LuaValue.valueOf(s)) }
|
||||||
return table
|
return table
|
||||||
}
|
}
|
||||||
@@ -141,7 +149,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
override fun call(path: LuaValue) : LuaValue {
|
override fun call(path: LuaValue) : LuaValue {
|
||||||
Filesystem.ensurePathSanity(path)
|
Filesystem.ensurePathSanity(path)
|
||||||
|
|
||||||
return LuaValue.valueOf(File(computer.getRealPath(path)).exists())
|
return LuaValue.valueOf(Files.exists(Paths.get(computer.getRealPath(path)).toAbsolutePath()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +157,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
override fun call(path: LuaValue) : LuaValue {
|
override fun call(path: LuaValue) : LuaValue {
|
||||||
Filesystem.ensurePathSanity(path)
|
Filesystem.ensurePathSanity(path)
|
||||||
|
|
||||||
return LuaValue.valueOf(File(computer.getRealPath(path)).isDirectory)
|
return LuaValue.valueOf(Files.isDirectory(Paths.get(computer.getRealPath(path)).toAbsolutePath()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +165,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
override fun call(path: LuaValue) : LuaValue {
|
override fun call(path: LuaValue) : LuaValue {
|
||||||
Filesystem.ensurePathSanity(path)
|
Filesystem.ensurePathSanity(path)
|
||||||
|
|
||||||
return LuaValue.valueOf(File(computer.getRealPath(path)).isFile)
|
return LuaValue.valueOf(!Files.isDirectory(Paths.get(computer.getRealPath(path)).toAbsolutePath()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +173,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
override fun call(path: LuaValue) : LuaValue {
|
override fun call(path: LuaValue) : LuaValue {
|
||||||
Filesystem.ensurePathSanity(path)
|
Filesystem.ensurePathSanity(path)
|
||||||
|
|
||||||
return LuaValue.valueOf(!File(computer.getRealPath(path)).canWrite())
|
return LuaValue.valueOf(!Files.isWritable(Paths.get(computer.getRealPath(path)).toAbsolutePath()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +182,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
override fun call(path: LuaValue) : LuaValue {
|
override fun call(path: LuaValue) : LuaValue {
|
||||||
Filesystem.ensurePathSanity(path)
|
Filesystem.ensurePathSanity(path)
|
||||||
|
|
||||||
return LuaValue.valueOf(File(computer.getRealPath(path)).length().toInt())
|
return LuaValue.valueOf(Files.size(Paths.get(computer.getRealPath(path)).toAbsolutePath()).toInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +195,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
override fun call(path: LuaValue) : LuaValue {
|
override fun call(path: LuaValue) : LuaValue {
|
||||||
Filesystem.ensurePathSanity(path)
|
Filesystem.ensurePathSanity(path)
|
||||||
|
|
||||||
return LuaValue.valueOf(File(computer.getRealPath(path)).mkdir())
|
return LuaValue.valueOf(File(computer.getRealPath(path)).absoluteFile.mkdir())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,11 +207,12 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
Filesystem.ensurePathSanity(from)
|
Filesystem.ensurePathSanity(from)
|
||||||
Filesystem.ensurePathSanity(to)
|
Filesystem.ensurePathSanity(to)
|
||||||
|
|
||||||
val fromFile = File(computer.getRealPath(from))
|
val fromFile = File(computer.getRealPath(from)).absoluteFile
|
||||||
var success = fromFile.copyRecursively(
|
var success = fromFile.copyRecursively(
|
||||||
File(computer.getRealPath(to)), overwrite = true
|
File(computer.getRealPath(to)).absoluteFile, overwrite = true
|
||||||
) // ignore IntelliJ's observation; it's opposite from redundant
|
)
|
||||||
success = fromFile.deleteRecursively()
|
if (success) success = fromFile.deleteRecursively()
|
||||||
|
else return LuaValue.valueOf(false)
|
||||||
return LuaValue.valueOf(success)
|
return LuaValue.valueOf(success)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,8 +227,8 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
Filesystem.ensurePathSanity(to)
|
Filesystem.ensurePathSanity(to)
|
||||||
|
|
||||||
return LuaValue.valueOf(
|
return LuaValue.valueOf(
|
||||||
File(computer.getRealPath(from)).copyRecursively(
|
File(computer.getRealPath(from)).absoluteFile.copyRecursively(
|
||||||
File(computer.getRealPath(to)), overwrite = true
|
File(computer.getRealPath(to)).absoluteFile, overwrite = true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -233,7 +242,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
Filesystem.ensurePathSanity(path)
|
Filesystem.ensurePathSanity(path)
|
||||||
|
|
||||||
return LuaValue.valueOf(
|
return LuaValue.valueOf(
|
||||||
File(computer.getRealPath(path)).deleteRecursively()
|
File(computer.getRealPath(path)).absoluteFile.deleteRecursively()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,7 +252,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
Filesystem.ensurePathSanity(base)
|
Filesystem.ensurePathSanity(base)
|
||||||
Filesystem.ensurePathSanity(local)
|
Filesystem.ensurePathSanity(local)
|
||||||
|
|
||||||
val combinedPath = combinePath(base.checkIBM437(), local.checkIBM437())
|
val combinedPath = combinePath(base.checkIBM437().validatePath(), local.checkIBM437().validatePath())
|
||||||
return LuaValue.valueOf(combinedPath)
|
return LuaValue.valueOf(combinedPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,9 +291,9 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
|
|
||||||
val mode = mode.checkIBM437().toLowerCase()
|
val mode = mode.checkIBM437().toLowerCase()
|
||||||
val luaClass = LuaTable()
|
val luaClass = LuaTable()
|
||||||
val file = File(computer.getRealPath(path))
|
val file = File(computer.getRealPath(path)).absoluteFile
|
||||||
|
|
||||||
if (mode.contains("[aw]") && !file.canWrite())
|
if (mode.contains(Regex("""[aw]""")) && !file.canWrite())
|
||||||
throw LuaError("Cannot open file for " +
|
throw LuaError("Cannot open file for " +
|
||||||
"${if (mode.startsWith('w')) "read" else "append"} mode" +
|
"${if (mode.startsWith('w')) "read" else "append"} mode" +
|
||||||
": is readonly.")
|
": is readonly.")
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class Input(globals: Globals, computer: BaseTerrarumComputer) {
|
|||||||
init {
|
init {
|
||||||
globals["input"] = LuaTable()
|
globals["input"] = LuaTable()
|
||||||
globals["input"]["isKeyDown"] = IsKeyDown(computer)
|
globals["input"]["isKeyDown"] = IsKeyDown(computer)
|
||||||
|
// input.readLine defined in ROMLIB
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ internal class Term(globals: Globals, term: Teletype) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// emitchar
|
||||||
class Emit(val term: Terminal) : ThreeArgFunction() {
|
class Emit(val term: Terminal) : ThreeArgFunction() {
|
||||||
override fun call(p0: LuaValue, x: LuaValue, y: LuaValue): LuaValue {
|
override fun call(p0: LuaValue, x: LuaValue, y: LuaValue): LuaValue {
|
||||||
term.emitChar(p0.checkint().toChar(), x.checkint() - 1, y.checkint() - 1)
|
term.emitChar(p0.checkint().toChar(), x.checkint() - 1, y.checkint() - 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user