implemented jankson loading for commands and permissions
This commit is contained in:
parent
240bff1677
commit
f24ba763ac
|
@ -88,6 +88,7 @@ data class CustomCommand(
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
val DEFAULT = CustomCommand()
|
||||||
|
|
||||||
fun getReplacements(user: String, userId: String, server: String, args: String): Map<String, () -> String> = mapOf(
|
fun getReplacements(user: String, userId: String, server: String, args: String): Map<String, () -> String> = mapOf(
|
||||||
"{uptime}" to instance::getUptimeAsString,
|
"{uptime}" to instance::getUptimeAsString,
|
||||||
|
|
|
@ -1,60 +1,64 @@
|
||||||
package matterlink.config
|
package matterlink.config
|
||||||
|
|
||||||
import com.google.gson.Gson
|
import blue.endless.jankson.Jankson
|
||||||
import com.google.gson.GsonBuilder
|
import blue.endless.jankson.JsonObject
|
||||||
import com.google.gson.JsonSyntaxException
|
import blue.endless.jankson.JsonPrimitive
|
||||||
import com.google.gson.reflect.TypeToken
|
import blue.endless.jankson.impl.Marshaller
|
||||||
import matterlink.RegexDeSerializer
|
import blue.endless.jankson.impl.SyntaxError
|
||||||
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 java.io.File
|
import java.io.File
|
||||||
import java.util.regex.PatternSyntaxException
|
import java.io.FileNotFoundException
|
||||||
|
|
||||||
typealias CommandMap = MutableMap<String, CustomCommand>
|
typealias CommandMap = MutableMap<String, CustomCommand>
|
||||||
|
typealias DefaultCommands = Map<String, Pair<String, CustomCommand>>
|
||||||
|
|
||||||
object CommandConfig {
|
object CommandConfig {
|
||||||
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: DefaultCommands = mapOf(
|
||||||
"tps" to CustomCommand(
|
"tps" to ("""Your run off the mill tps commands, change it to /sampler tps or /cofh tps if you like
|
||||||
|
|make sure to disable defaultCommand if you want your edits to have any effect
|
||||||
|
""".trimMargin()
|
||||||
|
to CustomCommand(
|
||||||
type = CommandType.EXECUTE,
|
type = CommandType.EXECUTE,
|
||||||
execute = "forge tps",
|
execute = "forge tps",
|
||||||
help = "Print server tps",
|
help = "Print server tps",
|
||||||
timeout = 200,
|
timeout = 200,
|
||||||
defaultCommand = true
|
defaultCommand = true
|
||||||
),
|
)),
|
||||||
"list" to CustomCommand(
|
"list" to ("lists all the players, this is just a straight pass-through"
|
||||||
|
to CustomCommand(
|
||||||
type = CommandType.EXECUTE,
|
type = CommandType.EXECUTE,
|
||||||
execute = "list",
|
execute = "list",
|
||||||
help = "List online players",
|
help = "List online players",
|
||||||
defaultCommand = true
|
defaultCommand = true
|
||||||
),
|
)),
|
||||||
"seed" to CustomCommand(
|
"seed" to ("another straight pass-through"
|
||||||
|
to CustomCommand(
|
||||||
type = CommandType.EXECUTE,
|
type = CommandType.EXECUTE,
|
||||||
execute = "seed",
|
execute = "seed",
|
||||||
help = "Print server world seed",
|
help = "Print server world seed",
|
||||||
defaultCommand = true
|
defaultCommand = true
|
||||||
),
|
)),
|
||||||
"uptime" to CustomCommand(
|
"uptime" to ("this is a reponse command, it uses the uptime function, time since the mod was first loaded"
|
||||||
|
to CustomCommand(
|
||||||
type = CommandType.RESPONSE,
|
type = CommandType.RESPONSE,
|
||||||
response = "{uptime}",
|
response = "{uptime}",
|
||||||
help = "Print server uptime",
|
help = "Print server uptime",
|
||||||
defaultCommand = true
|
defaultCommand = true
|
||||||
),
|
)),
|
||||||
"whoami" to CustomCommand(
|
"whoami" to ("this shows you some of the other response macros"
|
||||||
|
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",
|
||||||
timeout = 200,
|
timeout = 200,
|
||||||
defaultCommand = true
|
defaultCommand = true
|
||||||
),
|
)),
|
||||||
"exec" to CustomCommand(
|
"exec" to ("this uses arguments in a passed-through command, you could restrict the arguments with a regex"
|
||||||
|
to CustomCommand(
|
||||||
type = CommandType.EXECUTE,
|
type = CommandType.EXECUTE,
|
||||||
execute = "{args}",
|
execute = "{args}",
|
||||||
argumentsRegex = ".*".toRegex(),
|
argumentsRegex = ".*".toRegex(),
|
||||||
|
@ -62,40 +66,73 @@ object CommandConfig {
|
||||||
help = "Execute any command as OP, be careful with this one",
|
help = "Execute any command as OP, be careful with this one",
|
||||||
execOp = true,
|
execOp = true,
|
||||||
defaultCommand = true
|
defaultCommand = true
|
||||||
)
|
))
|
||||||
)
|
)
|
||||||
|
|
||||||
var commands: CommandMap = default
|
val commands: CommandMap = hashMapOf()
|
||||||
private set
|
|
||||||
|
|
||||||
fun readConfig(): Boolean {
|
fun readConfig(): Boolean {
|
||||||
if (!configFile.exists() || configFile.readText().isBlank()) {
|
val jankson = Jankson
|
||||||
configFile.createNewFile()
|
.builder()
|
||||||
configFile.writeText(gson.toJson(default))
|
.registerTypeAdapter(CustomCommand::class.java) { jsonObj ->
|
||||||
commands = default
|
with(CustomCommand.DEFAULT) {
|
||||||
return true
|
CustomCommand(
|
||||||
}
|
type = jsonObj.get(String::class.java, "type")?.let { CommandType.valueOf(it) }
|
||||||
|
?: type,
|
||||||
|
execute = jsonObj.get(String::class.java, "execute") ?: execute,
|
||||||
|
response = jsonObj.get(String::class.java, "response") ?: response,
|
||||||
|
permLevel = jsonObj.get(Double::class.java, "permLevel") ?: permLevel,
|
||||||
|
help = jsonObj.get(String::class.java, "help") ?: help,
|
||||||
|
timeout = jsonObj.get(Int::class.java, "timeout") ?: timeout,
|
||||||
|
defaultCommand = jsonObj.get(Boolean::class.java, "defaultCommand") ?: defaultCommand,
|
||||||
|
execOp = jsonObj.get(Boolean::class.java, "execOp") ?: execOp,
|
||||||
|
argumentsRegex = jsonObj.get(String::class.java, "argumentsRegex")?.toRegex()
|
||||||
|
?: argumentsRegex
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
commands = gson.fromJson(configFile.readText(), object : TypeToken<CommandMap>() {}.type)
|
|
||||||
commands.filterValues { it.defaultCommand ?: false }.forEach { commands.remove(it.key) }
|
|
||||||
default.forEach { k, v ->
|
|
||||||
if (!commands.containsKey(k)) {
|
|
||||||
commands[k] = v
|
|
||||||
}
|
}
|
||||||
}
|
.build()
|
||||||
configFile.writeText(gson.toJson(commands))
|
|
||||||
} catch (e: JsonSyntaxException) {
|
|
||||||
instance.fatal(e.stackTraceString)
|
|
||||||
instance.fatal("failed to parse $configFile, using last good values as fallback")
|
|
||||||
|
|
||||||
return false
|
Marshaller.getFallback().registerSerializer(Regex::class.java) {
|
||||||
} catch (e: PatternSyntaxException) {
|
JsonPrimitive(it.pattern)
|
||||||
instance.fatal(e.stackTraceString)
|
|
||||||
instance.fatal("failed to parse regex in $configFile, using last good values as fallback")
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
Marshaller.getFallback().registerSerializer(CommandType::class.java) {
|
||||||
|
JsonPrimitive(it.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
val jsonObject = try {
|
||||||
|
jankson.load(configFile)
|
||||||
|
} catch (e: SyntaxError) {
|
||||||
|
instance.error("error parsing config: ${e.completeMessage}")
|
||||||
|
JsonObject()
|
||||||
|
} catch (e: FileNotFoundException) {
|
||||||
|
configFile.createNewFile()
|
||||||
|
JsonObject()
|
||||||
|
}
|
||||||
|
// clear commands
|
||||||
|
commands.clear()
|
||||||
|
jsonObject.forEach { key, element ->
|
||||||
|
instance.trace("loading command '$key'")
|
||||||
|
val command = jankson.fromJson(element.toJson(), CustomCommand::class.java)
|
||||||
|
commands[key] = command
|
||||||
|
}
|
||||||
|
|
||||||
|
//apply defaults
|
||||||
|
default.forEach { k, (comment, defCommand) ->
|
||||||
|
val command = commands[k]
|
||||||
|
if (command == null || command.defaultCommand == true) {
|
||||||
|
commands[k] = defCommand
|
||||||
|
val element = Marshaller.getFallback().serialize(defCommand)
|
||||||
|
jsonObject.putDefault(k, element, comment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.debug("loaded jsonObj: $jsonObject")
|
||||||
|
instance.debug("loaded commandMap: $commands")
|
||||||
|
|
||||||
|
configFile.writeText(jsonObject.toJson(true, true))
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,46 +1,69 @@
|
||||||
package matterlink.config
|
package matterlink.config
|
||||||
|
|
||||||
import com.google.gson.Gson
|
import blue.endless.jankson.Jankson
|
||||||
import com.google.gson.GsonBuilder
|
import blue.endless.jankson.JsonObject
|
||||||
import com.google.gson.JsonSyntaxException
|
import blue.endless.jankson.impl.Marshaller
|
||||||
import com.google.gson.reflect.TypeToken
|
import blue.endless.jankson.impl.SyntaxError
|
||||||
import matterlink.instance
|
import matterlink.instance
|
||||||
import matterlink.stackTraceString
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.io.FileNotFoundException
|
||||||
|
|
||||||
typealias PermissionMap = Map<String, Map<String, Double>>
|
typealias PermissionMap = MutableMap<String, MutableMap<String, Double>>
|
||||||
|
|
||||||
object PermissionConfig {
|
object PermissionConfig {
|
||||||
private val gson: Gson = GsonBuilder().setPrettyPrinting().create()
|
private val jankson = Jankson
|
||||||
|
.builder()
|
||||||
|
.build()
|
||||||
|
|
||||||
private val configFile: File = cfg.cfgDirectory.resolve("permissions.json")
|
private val configFile: File = cfg.cfgDirectory.resolve("permissions.json")
|
||||||
|
|
||||||
private val default = mapOf(
|
private val default = mapOf(
|
||||||
"irc.esper" to mapOf(
|
"irc.esper" to mapOf(
|
||||||
"~nikky@nikky.moe" to 0.0,
|
"~nikky@nikky.moe" to (0.0 to "IRC users are identified by their username and hostmask"),
|
||||||
"user@example." to 0.0
|
"user@example.com" to (0.0 to "")
|
||||||
),
|
),
|
||||||
"discord.game" to mapOf(
|
"discord.game" to mapOf(
|
||||||
"112228624366575616" to 0.0
|
"112228624366575616" to (0.0 to "thats a discord user id")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
var perms: PermissionMap = default
|
var perms: PermissionMap = mutableMapOf()
|
||||||
|
private var jsonObject: JsonObject = JsonObject()
|
||||||
|
|
||||||
fun loadPermFile(): Boolean {
|
fun loadPermFile(): Boolean {
|
||||||
if (!configFile.exists() || configFile.readText().isBlank()) {
|
jsonObject = try {
|
||||||
|
jankson.load(configFile)
|
||||||
|
} catch (e: SyntaxError) {
|
||||||
|
instance.error("error parsing config: ${e.completeMessage}")
|
||||||
|
JsonObject()
|
||||||
|
} catch (e: FileNotFoundException) {
|
||||||
configFile.createNewFile()
|
configFile.createNewFile()
|
||||||
configFile.writeText(gson.toJson(default))
|
JsonObject()
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
default.forEach { platform, userMap ->
|
||||||
perms =gson.fromJson(configFile.readText(), object : TypeToken<PermissionMap>() {}.type)
|
val jsonUserMap = jsonObject.getOrDefault(platform, JsonObject()) as JsonObject
|
||||||
} catch (e: JsonSyntaxException) {
|
userMap.forEach { user, (powerlevel, comment) ->
|
||||||
instance.fatal(e.stackTraceString)
|
instance.trace("loading platform: $platform user: $user powwerlevel: $powerlevel")
|
||||||
instance.fatal("failed to parse $configFile using last good values as fallback")
|
val element = Marshaller.getFallback().serialize(powerlevel)
|
||||||
|
jsonUserMap.putDefault(user, element, comment.takeUnless { it.isBlank() })
|
||||||
return true
|
}
|
||||||
|
jsonObject[platform] = jsonUserMap
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
|
jsonObject.forEach { platform, jsonUserMap ->
|
||||||
|
val userMap = perms[platform] ?: mutableMapOf()
|
||||||
|
if (jsonUserMap is JsonObject) {
|
||||||
|
jsonUserMap.forEach { user, powerlevel ->
|
||||||
|
instance.info("$platform $user $powerlevel")
|
||||||
|
userMap[user] = jsonUserMap.get(Double::class.java, user) ?: 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
perms[platform] = userMap
|
||||||
|
}
|
||||||
|
|
||||||
|
configFile.writeText(jsonObject.toJson(true, true))
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue