changing allowArgs to regex check
This commit is contained in:
parent
6cab3c9838
commit
ff36de2446
2
api
2
api
|
@ -1 +1 @@
|
||||||
Subproject commit 041df81dfaf97bd000ee8a82f5fb7d52fb270000
|
Subproject commit 85568e243406fe959950b5918876be98bc9ebd89
|
|
@ -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()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -18,7 +18,7 @@ object HelpCommand : IBridgeCommand {
|
||||||
}
|
}
|
||||||
MessageHandlerInst.transmit(
|
MessageHandlerInst.transmit(
|
||||||
ApiMessage(
|
ApiMessage(
|
||||||
_text = msg.stripColorOut
|
text = msg.stripColorOut
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,14 +81,19 @@ object CommandConfig {
|
||||||
commands = gson.fromJson(configFile.readText(), object : TypeToken<CommandMap>() {}.type)
|
commands = gson.fromJson(configFile.readText(), object : TypeToken<CommandMap>() {}.type)
|
||||||
commands.filterValues { it.defaultCommand ?: false }.forEach { commands.remove(it.key) }
|
commands.filterValues { it.defaultCommand ?: false }.forEach { commands.remove(it.key) }
|
||||||
default.forEach { k, v ->
|
default.forEach { k, v ->
|
||||||
if(!commands.containsKey(k)){
|
if (!commands.containsKey(k)) {
|
||||||
commands[k] = v
|
commands[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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'")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue