diff options
author | nea <romangraef@loves.dicksinhisan.us> | 2021-12-09 02:56:50 +0100 |
---|---|---|
committer | nea <romangraef@loves.dicksinhisan.us> | 2021-12-09 02:56:50 +0100 |
commit | f8c6246a262b1d15e42ce812363f7d4e4eb16b8a (patch) | |
tree | 373746da7e8b20a51e65d0a3761ddfc6691df043 /src/main/kotlin | |
parent | 06e71e5aa081a561498f00f963a393367b917a78 (diff) | |
download | neamoe-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.kt | 19 | ||||
-rw-r--r-- | src/main/kotlin/moe/nea89/website/KConsole.kt | 14 | ||||
-rw-r--r-- | src/main/kotlin/moe/nea89/website/KFiles.kt | 9 | ||||
-rw-r--r-- | src/main/kotlin/moe/nea89/website/ShellExecutionContext.kt | 48 | ||||
-rw-r--r-- | src/main/kotlin/moe/nea89/website/index.kt | 61 |
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 |