summaryrefslogtreecommitdiff
path: root/src/main/kotlin
diff options
context:
space:
mode:
authornea <romangraef@loves.dicksinhisan.us>2021-12-09 02:56:50 +0100
committernea <romangraef@loves.dicksinhisan.us>2021-12-09 02:56:50 +0100
commitf8c6246a262b1d15e42ce812363f7d4e4eb16b8a (patch)
tree373746da7e8b20a51e65d0a3761ddfc6691df043 /src/main/kotlin
parent06e71e5aa081a561498f00f963a393367b917a78 (diff)
downloadneamoe-f8c6246a262b1d15e42ce812363f7d4e4eb16b8a.tar.gz
neamoe-f8c6246a262b1d15e42ce812363f7d4e4eb16b8a.tar.bz2
neamoe-f8c6246a262b1d15e42ce812363f7d4e4eb16b8a.zip
suspend shell executor
Diffstat (limited to 'src/main/kotlin')
-rw-r--r--src/main/kotlin/moe/nea89/website/Command.kt19
-rw-r--r--src/main/kotlin/moe/nea89/website/KConsole.kt14
-rw-r--r--src/main/kotlin/moe/nea89/website/KFiles.kt9
-rw-r--r--src/main/kotlin/moe/nea89/website/ShellExecutionContext.kt48
-rw-r--r--src/main/kotlin/moe/nea89/website/index.kt61
5 files changed, 97 insertions, 54 deletions
diff --git a/src/main/kotlin/moe/nea89/website/Command.kt b/src/main/kotlin/moe/nea89/website/Command.kt
index cb59d0a..b8e4675 100644
--- a/src/main/kotlin/moe/nea89/website/Command.kt
+++ b/src/main/kotlin/moe/nea89/website/Command.kt
@@ -1,16 +1,11 @@
package moe.nea89.website
-interface Command {
- val name: String
- val aliases: Set<String>
- fun run(console: KConsole, name: String, args: List<String>)
-}
+data class Command(
+ val name: String,
+ val aliases: Set<String>,
+ val runner: suspend ShellExecutionContext.() -> Unit,
+)
-data class CommandContext(val console: KConsole, val name: String, val args: List<String>)
-fun command(name: String, vararg aliases: String, block: CommandContext. () -> Unit) = object : Command {
- override val name: String = name
- override val aliases: Set<String> = aliases.toSet()
-
- override fun run(console: KConsole, name: String, args: List<String>) = block(CommandContext(console, name, args))
-} \ No newline at end of file
+fun command(name: String, vararg aliases: String, block: suspend ShellExecutionContext. () -> Unit) =
+ Command(name, aliases.toSet(), block) \ No newline at end of file
diff --git a/src/main/kotlin/moe/nea89/website/KConsole.kt b/src/main/kotlin/moe/nea89/website/KConsole.kt
index 51a6734..29e2264 100644
--- a/src/main/kotlin/moe/nea89/website/KConsole.kt
+++ b/src/main/kotlin/moe/nea89/website/KConsole.kt
@@ -31,6 +31,13 @@ class KConsole(
}
}
+ enum class ConsoleState {
+ SHELLPROMPT,
+ IN_PROGRAM
+ }
+
+ var state = ConsoleState.SHELLPROMPT
+
val lines = mutableListOf<String>()
var input: String = ""
@@ -53,7 +60,9 @@ class KConsole(
}
fun rerender() {
- val view = lines.joinToString(separator = "\n") + "\n${'$'} $input"
+ var view = lines.joinToString(separator = "\n")
+ if (state == ConsoleState.SHELLPROMPT)
+ view += "\n${'$'} $input"
text.innerText = view
}
@@ -80,7 +89,7 @@ class KConsole(
addLine("Unknown command")
return
}
- commandThing.run(this, command, arguments)
+ ShellExecutionContext.run(this, commandThing, command, arguments)
}
@OptIn(ExperimentalStdlibApi::class)
@@ -105,6 +114,7 @@ class KConsole(
fun keydown(event: KeyboardEvent) {
if (event.altKey || event.ctrlKey || event.metaKey) return
if (event.isComposing || event.keyCode == 229) return
+ if (state != ConsoleState.SHELLPROMPT) return
when (event.key) {
"Enter" -> {
val toExecute = input
diff --git a/src/main/kotlin/moe/nea89/website/KFiles.kt b/src/main/kotlin/moe/nea89/website/KFiles.kt
index 91851bc..aad3036 100644
--- a/src/main/kotlin/moe/nea89/website/KFiles.kt
+++ b/src/main/kotlin/moe/nea89/website/KFiles.kt
@@ -150,3 +150,12 @@ class FileSystemBuilder {
files.values.forEach { file -> file.linkTo(dir) }
}
}
+
+suspend fun ShellExecutionContext.requireFileAccessor(): FileAccessor {
+ val fa = console.fileAccessor
+ if (fa == null) {
+ console.addLine("There is no file accessor present :(")
+ exit()
+ }
+ return fa
+}
diff --git a/src/main/kotlin/moe/nea89/website/ShellExecutionContext.kt b/src/main/kotlin/moe/nea89/website/ShellExecutionContext.kt
new file mode 100644
index 0000000..9040f95
--- /dev/null
+++ b/src/main/kotlin/moe/nea89/website/ShellExecutionContext.kt
@@ -0,0 +1,48 @@
+package moe.nea89.website
+
+import kotlinx.browser.window
+import kotlinx.coroutines.suspendCancellableCoroutine
+import kotlin.coroutines.*
+import kotlin.time.Duration
+import kotlin.time.DurationUnit
+
+class ShellExecutionContext(
+ val console: KConsole,
+ val name: String,
+ val args: List<String>,
+) {
+
+ suspend fun wait(duration: Duration) {
+ suspendCancellableCoroutine<Unit> {
+ window.setTimeout({
+ it.resume(Unit)
+ }, timeout = duration.toInt(DurationUnit.MILLISECONDS))
+ }
+ }
+
+ suspend fun exit(): Nothing {
+ suspendCancellableCoroutine<Unit> {
+ it.cancel()
+ console.state = KConsole.ConsoleState.SHELLPROMPT
+ console.rerender()
+ }
+ throw RuntimeException("THIs shOULDNT EXIST")
+ }
+
+ companion object {
+ fun run(
+ console: KConsole, command: Command, name: String, args: List<String>
+ ) {
+ val se = ShellExecutionContext(console, name, args)
+ command.runner.createCoroutine(se, object : Continuation<Unit> {
+ override val context: CoroutineContext
+ get() = EmptyCoroutineContext
+
+ override fun resumeWith(result: Result<Unit>) {
+ console.state = KConsole.ConsoleState.SHELLPROMPT
+ console.rerender()
+ }
+ }).resume(Unit)
+ }
+ }
+}
diff --git a/src/main/kotlin/moe/nea89/website/index.kt b/src/main/kotlin/moe/nea89/website/index.kt
index b122cec..a2577ad 100644
--- a/src/main/kotlin/moe/nea89/website/index.kt
+++ b/src/main/kotlin/moe/nea89/website/index.kt
@@ -6,37 +6,31 @@ import kotlinx.html.dom.append
import kotlinx.html.js.div
import styled.injectGlobal
-fun main() {
- require("@fontsource/comic-mono/index.css")
- injectGlobal(Styles.global)
- val root = document.body!!.append.div()
- val console = KConsole.createFor(root, fileSystem = fileSystem {
- "etc" {
- "passwd" text "hunter2"
- }
- "home/nea" {
- "todo" text """
+val defaultFileSystem = fileSystem {
+ "etc" {
+ "passwd" text "hunter2"
+ }
+ "home/nea" {
+ "todo" text """
| - git gud
| - finish this website
| - convince the general public that comic sans is a viable font
""".trimMargin()
- }
- "flag" text "CTF{12345abcdefghijklmonp3.1.4.1.5.9.2.8}"
- })
+ }
+ "flag" text "CTF{12345abcdefghijklmonp3.1.4.1.5.9.2.8}"
+}
+
+fun main() {
+ require("@fontsource/comic-mono/index.css")
+ injectGlobal(Styles.global)
+ val root = document.body!!.append.div()
+ val console = KConsole.createFor(root, fileSystem = defaultFileSystem)
console.registerCommand(command("cwd", "pwd") {
- val fa = console.fileAccessor
- if (fa == null) {
- console.addLine("There is no file accessor present :(")
- return@command
- }
+ val fa = requireFileAccessor()
console.addLine(fa.currentDir.joinToString(separator = "/", prefix = "/"))
})
console.registerCommand(command("cd") {
- val fa = console.fileAccessor
- if (fa == null) {
- console.addLine("There is no file accessor present :(")
- return@command
- }
+ val fa = requireFileAccessor()
val path = args.singleOrNull()
if (path == null) {
console.addLine("Usage: cd <directory>")
@@ -48,11 +42,7 @@ fun main() {
}
})
console.registerCommand(command("ls") {
- val fa = console.fileAccessor
- if (fa == null) {
- console.addLine("There is no file accessor present :(")
- return@command
- }
+ val fa = requireFileAccessor()
val path = when (args.size) {
0 -> "."
1 -> args[0]
@@ -79,13 +69,8 @@ fun main() {
}
})
console.registerCommand(command("cat") {
- val fa = console.fileAccessor
- if (fa == null) {
- console.addLine("There is no file accessor present :(")
- return@command
- }
+ val fa = requireFileAccessor()
val path = when (args.size) {
- 0 -> "."
1 -> args[0]
else -> {
console.addLine("Usage: cat [directory or file]")
@@ -107,11 +92,7 @@ fun main() {
console.registerCommand(command("dick", "cock") {
console.addMultilineText("Hehe")
})
- console.registerCommand(object : Command {
- override val name: String = "booob"
- override val aliases: Set<String> = setOf("boob")
- override fun run(console: KConsole, name: String, args: List<String>) {
- console.addMultilineText(boobs)
- }
+ console.registerCommand(command("boob", "booob") {
+ console.addMultilineText(boobs)
})
} \ No newline at end of file