Files
Terrarum/src/net/torvald/terrarum/console/CommandInterpreter.kt
2021-09-29 16:51:59 +09:00

143 lines
4.2 KiB
Kotlin

package net.torvald.terrarum.console
import net.torvald.terrarum.ccG
import net.torvald.terrarum.ccW
import net.torvald.terrarum.ccY
import net.torvald.terrarum.langpack.Lang
import java.time.ZonedDateTime
import java.util.*
import java.util.regex.Pattern
/**
* Created by minjaesong on 2016-01-15.
*/
internal object CommandInterpreter {
private val commandsNoAuth = arrayOf(
"auth",
"qqq",
"setlocale",
"getlocale",
"help",
"version",
"tips",
"screenshot",
"resize",
"echo",
"error",
"seed",
"quicksave"
)
internal fun execute(command: String) {
val cmd: Array<CommandInput?> = parse(command)
val error = Error()
for (single_command in cmd) {
if (single_command == null || single_command.argsCount == 0) continue
var commandObj: ConsoleCommand? = null
try {
if (single_command.name.toLowerCase().startsWith("qqq")) {
commandObj = CommandDict["QuitApp"]
}
else if (commandsNoAuth.contains(single_command.name.toLowerCase())) {
commandObj = CommandDict[single_command.name.toLowerCase()]
}
else {
if (Authenticator.b()) {
commandObj = CommandDict[single_command.name.toLowerCase()]
}
else {
// System.out.println("ee1");
throw NullPointerException() // if not authorised, say "Unknown command"
}
}
Echo("$ccW> $single_command") // prints out the input
println("${ZonedDateTime.now()} [CommandInterpreter] issuing command '$single_command'")
try {
commandObj.execute(single_command.toStringArray())
}
catch (e: Exception) {
System.err.print("[CommandInterpreter] ")
e.printStackTrace()
EchoError(Lang["ERROR_GENERIC_TEXT"])
}
}
catch (e: NullPointerException) {
echoUnknownCmd(single_command.name)
}
}
}
private fun parse(input: String): Array<CommandInput?> {
val patternCommands = Pattern.compile("[^;]+")
val patternTokensInCommand = Pattern.compile("[\"'][^;]+[\"']|[^ ]+")
val commands = ArrayList<String>()
// split multiple commands
var m = patternCommands.matcher(input)
while (m.find()) commands.add(m.group())
// split command tokens from a command
val parsedCommands = arrayOfNulls<CommandInput>(commands.size)
for (i in parsedCommands.indices) {
val tokens = ArrayList<String>()
m = patternTokensInCommand.matcher(commands[i])
while (m.find()) {
val regexGroup = m.group().replace("[\"\']".toRegex(), "")
tokens.add(regexGroup)
}
// create new command
parsedCommands[i] = CommandInput(tokens.toArray())
}
return parsedCommands
}
internal fun echoUnknownCmd(cmdname: String) {
val sb = StringBuilder()
val formatter = Formatter(sb)
EchoError(
formatter.format(Lang["DEV_MESSAGE_CONSOLE_COMMAND_UNKNOWN"], cmdname).toString())
}
private class CommandInput(o: Array<Any>) {
private val tokens: Array<String>
init {
tokens = Array<String>(o.size, { i -> o[i] as String })
}
fun toStringArray(): Array<String> {
return tokens
}
val name: String
get() = tokens[0]
val argsCount: Int
get() = tokens.size
override fun toString(): String {
val sb = StringBuilder()
tokens.forEachIndexed { i, s ->
if (i == 0)
sb.append("${ccY}$s${ccG}")
else
sb.append(" $s")
}
return sb.toString()
}
}
}