mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +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
|
||||
val computerInside = BaseTerrarumComputer(8)
|
||||
val vt = SimpleTextTerminal(SimpleTextTerminal.AMETHYST_NOVELTY, 80, 25,
|
||||
computerInside, colour = false, hires = false)
|
||||
val vt = SimpleTextTerminal(SimpleTextTerminal.AMETHYST_NOVELTY, 100, 64,
|
||||
computerInside, colour = true, hires = true)
|
||||
|
||||
|
||||
val vtUI = Image(vt.displayW, vt.displayH)
|
||||
|
||||
@@ -91,12 +91,12 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
||||
computerValue["processor"] = -1 // do.
|
||||
|
||||
// as in "dev/hda"; refers hard disk drive (and no partitioning)
|
||||
computerValue["hda"] = "testhda" // 'UUID rendered as String' or "none"
|
||||
computerValue["hdb"] = "none"
|
||||
computerValue["hda"] = "uuid_testhda" // 'UUID rendered as String' or "none"
|
||||
computerValue["hdb"] = "uuid_testhdb"
|
||||
computerValue["hdc"] = "none"
|
||||
computerValue["hdd"] = "none"
|
||||
// as in "dev/fd1"; refers floppy disk drive
|
||||
computerValue["fd1"] = "none"
|
||||
computerValue["fd1"] = "uuid_testfd1"
|
||||
computerValue["fd2"] = "none"
|
||||
computerValue["fd3"] = "none"
|
||||
computerValue["fd4"] = "none"
|
||||
@@ -159,7 +159,7 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
||||
|
||||
|
||||
// secure the sandbox
|
||||
luaJ_globals["io"] = LuaValue.NIL
|
||||
//luaJ_globals["io"] = LuaValue.NIL
|
||||
// dubug should be sandboxed in BOOT.lua (use OpenComputers code)
|
||||
//val sethook = luaJ_globals["debug"]["sethook"]
|
||||
//luaJ_globals["debug"] = LuaValue.NIL
|
||||
@@ -207,12 +207,13 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
||||
unsetThreadRun()
|
||||
}
|
||||
|
||||
driveBeepQueueManager(delta)
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (isHalted) {
|
||||
if (!isHalted) {
|
||||
driveBeepQueueManager(delta)
|
||||
}
|
||||
else {
|
||||
currentExecutionThread.interrupt()
|
||||
}
|
||||
}
|
||||
@@ -326,7 +327,6 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
||||
// complete emitTone queue
|
||||
if (beepCursor >= beepQueue.size) {
|
||||
clearBeepQueue()
|
||||
if (DEBUG) println("[BaseTerrarumComputer] !! Beep queue clear")
|
||||
}
|
||||
|
||||
// actually play queue
|
||||
@@ -350,6 +350,8 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
|
||||
beepQueueLineExecTimer = 0
|
||||
|
||||
//AL.destroy()
|
||||
|
||||
if (DEBUG) println("[BaseTerrarumComputer] !! Beep queue clear")
|
||||
}
|
||||
|
||||
fun enqueueBeep(duration: Int, freq: Double) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import net.torvald.terrarum.virtualcomputer.luaapi.Term.Companion.checkIBM437
|
||||
import java.io.*
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
@@ -20,7 +21,9 @@ import java.util.*
|
||||
* 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) {
|
||||
|
||||
@@ -40,7 +43,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
||||
globals["fs"]["concat"] = ConcatPath(computer) // OC compliant
|
||||
globals["fs"]["open"] = OpenFile(computer) //CC compliant
|
||||
globals["fs"]["parent"] = GetParentDir(computer)
|
||||
// fs.dofile defined in ROMLIB
|
||||
// fs.dofile defined in BOOT
|
||||
// fs.fetchText defined in ROMLIB
|
||||
}
|
||||
|
||||
@@ -48,29 +51,34 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
||||
fun ensurePathSanity(path: LuaValue) {
|
||||
if (path.checkIBM437().contains(Regex("""\.\.""")))
|
||||
throw LuaError("'..' on path is not supported.")
|
||||
if (!isValidFilename(path.checkIBM437()))
|
||||
throw IOException("path contains invalid characters")
|
||||
}
|
||||
|
||||
val isCaseInsensitive: Boolean
|
||||
get() {
|
||||
// TODO add: force case insensitive in config
|
||||
try {
|
||||
val uuid = UUID.randomUUID().toString()
|
||||
val lowerCase = 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
|
||||
// make sure the files don't exist.
|
||||
lowerCase.exists() && lowerCase.delete()
|
||||
upperCase.exists() && upperCase.delete()
|
||||
lowerCase.createNewFile()
|
||||
val insensitive = upperCase.exists()
|
||||
lowerCase.delete()
|
||||
return insensitive
|
||||
}
|
||||
catch (e: IOException) {
|
||||
println("[Filesystem] Couldn't determine if file system is case sensitive, falling back to insensitive.")
|
||||
return true
|
||||
}
|
||||
|
||||
init {
|
||||
try {
|
||||
val uuid = UUID.randomUUID().toString()
|
||||
val lowerCase = 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
|
||||
// make sure the files don't exist.
|
||||
if (lowerCase.exists()) lowerCase.delete()
|
||||
if (upperCase.exists()) upperCase.delete()
|
||||
|
||||
lowerCase.createNewFile()
|
||||
|
||||
val insensitive = upperCase.exists()
|
||||
lowerCase.delete()
|
||||
|
||||
isCaseInsensitive = insensitive
|
||||
}
|
||||
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.
|
||||
// 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 validatePath(path: String) : String {
|
||||
if (!isValidFilename(path)) {
|
||||
fun String.validatePath() : String {
|
||||
if (!isValidFilename(this)) {
|
||||
throw IOException("path contains invalid characters")
|
||||
}
|
||||
return path
|
||||
return this
|
||||
}
|
||||
|
||||
/** actual directory: <appdata>/Saves/<savename>/computers/<drivename>/
|
||||
@@ -103,7 +111,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
||||
*/
|
||||
|
||||
// remove first '/' in path
|
||||
var path = luapath.checkIBM437()
|
||||
var path = luapath.checkIBM437().validatePath()
|
||||
if (path.startsWith('/')) path = path.substring(1)
|
||||
|
||||
if (path.startsWith("media/")) {
|
||||
@@ -131,7 +139,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
||||
Filesystem.ensurePathSanity(path)
|
||||
|
||||
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)) }
|
||||
return table
|
||||
}
|
||||
@@ -141,7 +149,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
||||
override fun call(path: LuaValue) : LuaValue {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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(to)
|
||||
|
||||
val fromFile = File(computer.getRealPath(from))
|
||||
val fromFile = File(computer.getRealPath(from)).absoluteFile
|
||||
var success = fromFile.copyRecursively(
|
||||
File(computer.getRealPath(to)), overwrite = true
|
||||
) // ignore IntelliJ's observation; it's opposite from redundant
|
||||
success = fromFile.deleteRecursively()
|
||||
File(computer.getRealPath(to)).absoluteFile, overwrite = true
|
||||
)
|
||||
if (success) success = fromFile.deleteRecursively()
|
||||
else return LuaValue.valueOf(false)
|
||||
return LuaValue.valueOf(success)
|
||||
}
|
||||
}
|
||||
@@ -218,8 +227,8 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
||||
Filesystem.ensurePathSanity(to)
|
||||
|
||||
return LuaValue.valueOf(
|
||||
File(computer.getRealPath(from)).copyRecursively(
|
||||
File(computer.getRealPath(to)), overwrite = true
|
||||
File(computer.getRealPath(from)).absoluteFile.copyRecursively(
|
||||
File(computer.getRealPath(to)).absoluteFile, overwrite = true
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -233,7 +242,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
||||
Filesystem.ensurePathSanity(path)
|
||||
|
||||
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(local)
|
||||
|
||||
val combinedPath = combinePath(base.checkIBM437(), local.checkIBM437())
|
||||
val combinedPath = combinePath(base.checkIBM437().validatePath(), local.checkIBM437().validatePath())
|
||||
return LuaValue.valueOf(combinedPath)
|
||||
}
|
||||
}
|
||||
@@ -282,9 +291,9 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
|
||||
|
||||
val mode = mode.checkIBM437().toLowerCase()
|
||||
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 " +
|
||||
"${if (mode.startsWith('w')) "read" else "append"} mode" +
|
||||
": is readonly.")
|
||||
|
||||
@@ -15,6 +15,7 @@ class Input(globals: Globals, computer: BaseTerrarumComputer) {
|
||||
init {
|
||||
globals["input"] = LuaTable()
|
||||
globals["input"]["isKeyDown"] = IsKeyDown(computer)
|
||||
// input.readLine defined in ROMLIB
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -118,6 +118,7 @@ internal class Term(globals: Globals, term: Teletype) {
|
||||
}
|
||||
}
|
||||
|
||||
// emitchar
|
||||
class Emit(val term: Terminal) : ThreeArgFunction() {
|
||||
override fun call(p0: LuaValue, x: LuaValue, y: LuaValue): LuaValue {
|
||||
term.emitChar(p0.checkint().toChar(), x.checkint() - 1, y.checkint() - 1)
|
||||
|
||||
Reference in New Issue
Block a user