changing allowArgs to regex check

This commit is contained in:
nikky 2018-05-29 00:35:28 +02:00
parent 6cab3c9838
commit ff36de2446
12 changed files with 65 additions and 31 deletions

2
api

@ -1 +1 @@
Subproject commit 041df81dfaf97bd000ee8a82f5fb7d52fb270000 Subproject commit 85568e243406fe959950b5918876be98bc9ebd89

View File

@ -0,0 +1,15 @@
package matterlink
import com.google.gson.*
import java.lang.reflect.Type
object RegexDeSerializer: JsonSerializer<Regex>, JsonDeserializer<Regex> {
override fun serialize(src: Regex, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
return JsonPrimitive(src.pattern)
}
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Regex {
return json.asString.toRegex()
}
}

View File

@ -5,6 +5,7 @@ import matterlink.bridge.MessageHandlerInst
import matterlink.handlers.TickHandler import matterlink.handlers.TickHandler
import matterlink.instance import matterlink.instance
import matterlink.lazyFormat import matterlink.lazyFormat
import matterlink.stripColorIn
import matterlink.stripColorOut import matterlink.stripColorOut
data class CustomCommand( data class CustomCommand(
@ -13,10 +14,10 @@ data class CustomCommand(
val response: String? = null, val response: String? = null,
override val permLevel: Double = 0.0, override val permLevel: Double = 0.0,
override val help: String = "", override val help: String = "",
val allowArgs: Boolean = true,
val timeout: Int = 20, val timeout: Int = 20,
val defaultCommand: Boolean? = null, val defaultCommand: Boolean? = null,
val execOp: Boolean? = null val execOp: Boolean? = null,
val argumentsRegext: Regex? = null
) : IBridgeCommand { ) : IBridgeCommand {
val alias: String val alias: String
get() = BridgeCommandRegistry.getName(this)!! get() = BridgeCommandRegistry.getName(this)!!
@ -25,7 +26,17 @@ data class CustomCommand(
private var lastUsed: Int = 0 private var lastUsed: Int = 0
override fun execute(alias: String, user: String, userId: String, server: String, args: String): Boolean { override fun execute(alias: String, user: String, userId: String, server: String, args: String): Boolean {
if (!allowArgs && args.isNotBlank()) return false if(argumentsRegext != null) {
instance.debug("testing '$args' against '${argumentsRegext.pattern}'")
if(!argumentsRegext.matches(args)) {
MessageHandlerInst.transmit(
ApiMessage(
text = "$user sent invalid input to command $alias".stripColorOut
)
)
return false
}
}
if (TickHandler.tickCounter - lastUsed < timeout) { if (TickHandler.tickCounter - lastUsed < timeout) {
instance.debug("dropped command $alias") instance.debug("dropped command $alias")
@ -35,7 +46,7 @@ data class CustomCommand(
if (!canExecute(userId, server)) { if (!canExecute(userId, server)) {
MessageHandlerInst.transmit( MessageHandlerInst.transmit(
ApiMessage( ApiMessage(
_text = "$user is not permitted to perform command: $alias".stripColorOut text = "$user is not permitted to perform command: $alias".stripColorOut
) )
) )
return false return false
@ -43,17 +54,19 @@ data class CustomCommand(
lastUsed = TickHandler.tickCounter lastUsed = TickHandler.tickCounter
return when (type) { return when (type) {
CommandType.EXECUTE -> { CommandType.EXECUTE -> {
// uses a new commandsender for each use // uses a new commandsender for each use
val commandSender = instance.commandSenderFor(user, userId, server, execOp ?: false) val commandSender = instance.commandSenderFor(user, userId, server, execOp ?: false)
val cmd = "$execute $args" val cmd = execute?.lazyFormat(getReplacements(user, userId, server, args))?.stripColorIn ?: return false
commandSender.execute(cmd) || commandSender.reply.isNotBlank() commandSender.execute(cmd) || commandSender.reply.isNotBlank()
} }
CommandType.RESPONSE -> { CommandType.RESPONSE -> {
MessageHandlerInst.transmit( MessageHandlerInst.transmit(
ApiMessage( ApiMessage(
_text = (response?.lazyFormat(getReplacements(user, userId, server, args))?.stripColorOut ?: "") text = (response?.lazyFormat(getReplacements(user, userId, server, args))
?: "")
) )
) )
true true
@ -66,7 +79,7 @@ data class CustomCommand(
*/ */
override fun validate(): Boolean { override fun validate(): Boolean {
val typeCheck = when (type) { val typeCheck = when (type) {
CommandType.EXECUTE -> execute != null CommandType.EXECUTE -> execute?.isNotBlank() ?: false
CommandType.RESPONSE -> response?.isNotBlank() ?: false CommandType.RESPONSE -> response?.isNotBlank() ?: false
} }
if (!typeCheck) return false if (!typeCheck) return false

View File

@ -18,7 +18,7 @@ object HelpCommand : IBridgeCommand {
} }
MessageHandlerInst.transmit( MessageHandlerInst.transmit(
ApiMessage( ApiMessage(
_text = msg.stripColorOut text = msg.stripColorOut
) )
) )
return true return true

View File

@ -26,7 +26,7 @@ abstract class IMinecraftCommandSender(val user: String, val userId: String, val
reply = text reply = text
MessageHandlerInst.transmit( MessageHandlerInst.transmit(
ApiMessage( ApiMessage(
_text = text.stripColorOut text = text.stripColorOut
) )
) )
} }

View File

@ -4,16 +4,21 @@ import com.google.gson.Gson
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import com.google.gson.JsonSyntaxException import com.google.gson.JsonSyntaxException
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import matterlink.RegexDeSerializer
import matterlink.bridge.command.CommandType import matterlink.bridge.command.CommandType
import matterlink.bridge.command.CustomCommand import matterlink.bridge.command.CustomCommand
import matterlink.instance import matterlink.instance
import matterlink.stackTraceString import matterlink.stackTraceString
import java.io.File import java.io.File
import java.util.regex.PatternSyntaxException
typealias CommandMap = MutableMap<String, CustomCommand> typealias CommandMap = MutableMap<String, CustomCommand>
object CommandConfig { object CommandConfig {
private val gson: Gson = GsonBuilder().setPrettyPrinting().create() private val gson: Gson = GsonBuilder()
.registerTypeAdapter(Regex::class.java, RegexDeSerializer)
.setPrettyPrinting()
.create()
private val configFile: File = cfg.cfgDirectory.resolve("commands.json") private val configFile: File = cfg.cfgDirectory.resolve("commands.json")
private val default = hashMapOf( private val default = hashMapOf(
@ -21,7 +26,6 @@ object CommandConfig {
type = CommandType.EXECUTE, type = CommandType.EXECUTE,
execute = "forge tps", execute = "forge tps",
help = "Print server tps", help = "Print server tps",
allowArgs = false,
timeout = 200, timeout = 200,
defaultCommand = true defaultCommand = true
), ),
@ -29,14 +33,12 @@ object CommandConfig {
type = CommandType.EXECUTE, type = CommandType.EXECUTE,
execute = "list", execute = "list",
help = "List online players", help = "List online players",
allowArgs = false,
defaultCommand = true defaultCommand = true
), ),
"seed" to CustomCommand( "seed" to CustomCommand(
type = CommandType.EXECUTE, type = CommandType.EXECUTE,
execute = "seed", execute = "seed",
help = "Print server world seed", help = "Print server world seed",
allowArgs = false,
defaultCommand = true defaultCommand = true
), ),
"uptime" to CustomCommand( "uptime" to CustomCommand(
@ -44,23 +46,21 @@ object CommandConfig {
permLevel = 1.0, permLevel = 1.0,
response = "{uptime}", response = "{uptime}",
help = "Print server uptime", help = "Print server uptime",
allowArgs = false,
defaultCommand = true defaultCommand = true
), ),
"whoami" to CustomCommand( "whoami" to CustomCommand(
type = CommandType.RESPONSE, type = CommandType.RESPONSE,
response = "server: `{server}` userid: `{userid}` user: `{user}`", response = "server: `{server}` userid: `{userid}` user: `{user}`",
help = "Print debug user data", help = "Print debug user data",
allowArgs = false,
timeout = 200, timeout = 200,
defaultCommand = true defaultCommand = true
), ),
"exec" to CustomCommand( "exec" to CustomCommand(
type = CommandType.EXECUTE, type = CommandType.EXECUTE,
execute = "", execute = "{args}",
argumentsRegext = ".*".toRegex(),
permLevel = 1.0, permLevel = 1.0,
help = "Execute any command as OP, be careful with this one", help = "Execute any command as OP, be careful with this one",
allowArgs = true,
execOp = true, execOp = true,
defaultCommand = true defaultCommand = true
) )
@ -73,6 +73,7 @@ object CommandConfig {
if (!configFile.exists() || configFile.readText().isBlank()) { if (!configFile.exists() || configFile.readText().isBlank()) {
configFile.createNewFile() configFile.createNewFile()
configFile.writeText(gson.toJson(default)) configFile.writeText(gson.toJson(default))
commands = default
return true return true
} }
@ -87,7 +88,12 @@ object CommandConfig {
configFile.writeText(gson.toJson(commands)) configFile.writeText(gson.toJson(commands))
} catch (e: JsonSyntaxException) { } catch (e: JsonSyntaxException) {
instance.fatal(e.stackTraceString) instance.fatal(e.stackTraceString)
instance.fatal("failed to parse $configFile using last good values as fallback") instance.fatal("failed to parse $configFile, using last good values as fallback")
return false
} catch (e: PatternSyntaxException) {
instance.fatal(e.stackTraceString)
instance.fatal("failed to parse regex in $configFile, using last good values as fallback")
return false return false
} }

View File

@ -10,9 +10,9 @@ object ChatProcessor {
val message = msg.trim() val message = msg.trim()
when { when {
message.isNotBlank() -> MessageHandlerInst.transmit(ApiMessage( message.isNotBlank() -> MessageHandlerInst.transmit(ApiMessage(
_username = user.stripColorOut, username = user.stripColorOut,
_text = message.stripColorOut, text = message.stripColorOut,
_event = event) event = event)
) )
else -> instance.warn("WARN: dropped blank message by '$user'") else -> instance.warn("WARN: dropped blank message by '$user'")
} }

View File

@ -23,7 +23,7 @@ object DeathHandler {
val damageEmoji = emojis[random.nextInt(emojis.size)] val damageEmoji = emojis[random.nextInt(emojis.size)]
msg += " $damageEmoji" msg += " $damageEmoji"
} }
MessageHandlerInst.transmit(ApiMessage(_text = msg)) MessageHandlerInst.transmit(ApiMessage(text = msg))
} }
} }
} }

View File

@ -19,8 +19,8 @@ object JoinLeaveHandler {
) )
MessageHandlerInst.transmit( MessageHandlerInst.transmit(
ApiMessage( ApiMessage(
_text = msg, text = msg,
_event = JOIN_LEAVE event = JOIN_LEAVE
) )
) )
} }
@ -36,8 +36,8 @@ object JoinLeaveHandler {
) )
MessageHandlerInst.transmit( MessageHandlerInst.transmit(
ApiMessage( ApiMessage(
_text = msg, text = msg,
_event = JOIN_LEAVE event = JOIN_LEAVE
) )
) )
} }

View File

@ -13,7 +13,7 @@ object ProgressHandler {
val usr = name.stripColorOut.antiping val usr = name.stripColorOut.antiping
MessageHandlerInst.transmit( MessageHandlerInst.transmit(
ApiMessage( ApiMessage(
_text = "$usr $message $display".stripColorOut text = "$usr $message $display".stripColorOut
) )
) )
} }

View File

@ -110,7 +110,7 @@ class UpdateChecker : Thread() {
instance.warn("Mod out of date! New $version available at ${latest.downloadURL}") instance.warn("Mod out of date! New $version available at ${latest.downloadURL}")
MessageHandlerInst.transmit( MessageHandlerInst.transmit(
ApiMessage( ApiMessage(
_text = "MatterLink out of date! You are $count $version behind! Please download new version from ${latest.downloadURL}" text = "MatterLink out of date! You are $count $version behind! Please download new version from ${latest.downloadURL}"
) )
) )
} }

View File

@ -1,5 +1,5 @@
mod_name = MatterLink mod_name = MatterLink
mod_version = 1.6.0 mod_version = 1.6.1
forgelin_version = 1.6.0 forgelin_version = 1.6.0
curse_id = 287323 curse_id = 287323
curse_release_type = beta curse_release_type = beta