package net.torvald.terrarum.console import net.torvald.terrarum.App.printdbg 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 = parse(command) for (single_command in cmd) { if (single_command == null || single_command.argsCount == 0) continue var commandObj: ConsoleCommand? = null try { 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 { val patternCommands = Pattern.compile("[^;]+") val patternTokensInCommand = Pattern.compile("[\"'][^;]+[\"']|[^ ]+") val commands = ArrayList() // split multiple commands var m = patternCommands.matcher(input) while (m.find()) commands.add(m.group()) // split command tokens from a command val parsedCommands = arrayOfNulls(commands.size) for (i in parsedCommands.indices) { val tokens = ArrayList() 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) { private val tokens: Array init { tokens = Array(o.size, { i -> o[i] as String }) } fun toStringArray(): Array { 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() } } }