WIP custom commands and permissions loading from json

This commit is contained in:
DaMachinator 2018-02-18 20:22:27 +01:00
parent 4d51894628
commit 968ff1aacc
28 changed files with 211 additions and 136 deletions

View File

@ -58,10 +58,9 @@ object EventHandler {
@JvmStatic @JvmStatic
fun commandEvent(e: CommandEvent) { fun commandEvent(e: CommandEvent) {
val sender = when { val sender = when {
e.sender is EntityPlayer -> e.sender.name
e.sender is DedicatedServer -> cfg.relay.systemUser e.sender is DedicatedServer -> cfg.relay.systemUser
e.sender is TileEntityCommandBlock -> "CommandBlock" e.sender is TileEntityCommandBlock -> "CommandBlock"
else -> return else -> e.sender.name
} }
val args = e.parameters.joinToString(" ") val args = e.parameters.joinToString(" ")
val type = when { val type = when {

View File

@ -1,17 +1,15 @@
package matterlink package matterlink
import matterlink.command.CommandMatterlink import matterlink.command.CommandMatterlink
import matterlink.command.IMinecraftCommandSender import matterlink.bridge.command.IMinecraftCommandSender
import matterlink.command.MatterlinkCommandSender import matterlink.command.MatterlinkCommandSender
import matterlink.config.cfg import matterlink.config.cfg
import matterlink.update.UpdateChecker
import net.minecraft.util.text.TextComponentString import net.minecraft.util.text.TextComponentString
import net.minecraftforge.fml.common.FMLCommonHandler import net.minecraftforge.fml.common.FMLCommonHandler
import net.minecraftforge.fml.common.Mod import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.common.event.* import net.minecraftforge.fml.common.event.*
import org.apache.logging.log4j.Level import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Logger import org.apache.logging.log4j.Logger
import java.io.File
lateinit var logger: Logger lateinit var logger: Logger

View File

@ -2,6 +2,7 @@ package matterlink.command
import matterlink.bridge.ApiMessage import matterlink.bridge.ApiMessage
import matterlink.bridge.MessageHandler import matterlink.bridge.MessageHandler
import matterlink.bridge.command.IMinecraftCommandSender
import matterlink.config.cfg import matterlink.config.cfg
import net.minecraft.command.CommandResultStats import net.minecraft.command.CommandResultStats
import net.minecraft.command.ICommandSender import net.minecraft.command.ICommandSender
@ -18,7 +19,7 @@ import javax.annotation.Nonnull
object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender { object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender {
private var level: Int = 0 private var level: Int = 0
override fun execute(cmdString: String, level: Int): Boolean { override fun execute(cmdString: String): Boolean {
return 0 < FMLCommonHandler.instance().minecraftServerInstance.commandManager.executeCommand( return 0 < FMLCommonHandler.instance().minecraftServerInstance.commandManager.executeCommand(
this, this,
cmdString cmdString
@ -38,7 +39,7 @@ object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender {
} }
override fun canUseCommand(permLevel: Int, commandName: String?): Boolean { override fun canUseCommand(permLevel: Int, commandName: String?): Boolean {
//TODO: Implement actual permissions checking //we check user on our end
return true return true
} }

View File

@ -4,5 +4,4 @@ const val MODID = "matterlink"
const val NAME = "MatterLink" const val NAME = "MatterLink"
const val MODVERSION = "@MODVERSION@" const val MODVERSION = "@MODVERSION@"
const val MCVERSION = "@MCVERSION@" const val MCVERSION = "@MCVERSION@"
//const val DEPENDENCIES = "required-after:forgelin@[@FORGELIN-VERSION@,);required-after:forge@[@FORGE-VERSION@,);"
const val DEPENDENCIES = "required-after:forgelin@[@FORGELIN-VERSION@,);" const val DEPENDENCIES = "required-after:forgelin@[@FORGELIN-VERSION@,);"

View File

@ -59,10 +59,9 @@ object EventHandler {
@JvmStatic @JvmStatic
fun commandEvent(e: CommandEvent) { fun commandEvent(e: CommandEvent) {
val sender = when { val sender = when {
e.sender is EntityPlayer -> e.sender.name
e.sender is DedicatedServer -> cfg.relay.systemUser e.sender is DedicatedServer -> cfg.relay.systemUser
e.sender is TileEntityCommandBlock -> "CommandBlock" e.sender is TileEntityCommandBlock -> "CommandBlock"
else -> return else -> e.sender.name
} }
val args = e.parameters.joinToString(" ") val args = e.parameters.joinToString(" ")
val type = when { val type = when {

View File

@ -1,17 +1,15 @@
package matterlink package matterlink
import matterlink.command.CommandMatterlink import matterlink.command.CommandMatterlink
import matterlink.command.IMinecraftCommandSender import matterlink.bridge.command.IMinecraftCommandSender
import matterlink.command.MatterlinkCommandSender import matterlink.command.MatterlinkCommandSender
import matterlink.config.cfg import matterlink.config.cfg
import matterlink.update.UpdateChecker
import net.minecraft.util.text.TextComponentString import net.minecraft.util.text.TextComponentString
import net.minecraftforge.fml.common.FMLCommonHandler import net.minecraftforge.fml.common.FMLCommonHandler
import net.minecraftforge.fml.common.Mod import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.common.event.* import net.minecraftforge.fml.common.event.*
import org.apache.logging.log4j.Level import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Logger import org.apache.logging.log4j.Logger
import java.io.File
lateinit var logger: Logger lateinit var logger: Logger

View File

@ -2,6 +2,7 @@ package matterlink.command
import matterlink.bridge.ApiMessage import matterlink.bridge.ApiMessage
import matterlink.bridge.MessageHandler import matterlink.bridge.MessageHandler
import matterlink.bridge.command.IMinecraftCommandSender
import matterlink.config.cfg import matterlink.config.cfg
import net.minecraft.command.CommandResultStats import net.minecraft.command.CommandResultStats
import net.minecraft.command.ICommandSender import net.minecraft.command.ICommandSender
@ -16,9 +17,8 @@ import net.minecraftforge.fml.common.FMLCommonHandler
import javax.annotation.Nonnull import javax.annotation.Nonnull
object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender { object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender {
private var level: Int = 0
override fun execute(cmdString: String, level: Int): Boolean { override fun execute(cmdString: String): Boolean {
return 0 < FMLCommonHandler.instance().minecraftServerInstance.commandManager.executeCommand( return 0 < FMLCommonHandler.instance().minecraftServerInstance.commandManager.executeCommand(
this, this,
cmdString cmdString
@ -38,7 +38,7 @@ object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender {
} }
override fun canUseCommand(permLevel: Int, commandName: String?): Boolean { override fun canUseCommand(permLevel: Int, commandName: String?): Boolean {
//TODO: Implement actual permissions checking //we now do permissions checking on our end
return true return true
} }

View File

@ -51,10 +51,9 @@ object EventHandler {
@JvmStatic @JvmStatic
fun commandEvent(e: CommandEvent) { fun commandEvent(e: CommandEvent) {
val sender = when { val sender = when {
e.sender is EntityPlayer -> e.sender.name
e.sender is DedicatedServer -> cfg.relay.systemUser e.sender is DedicatedServer -> cfg.relay.systemUser
e.sender is TileEntityCommandBlock -> "CommandBlock" e.sender is TileEntityCommandBlock -> "CommandBlock"
else -> return else -> e.sender.name
} }
val args = e.parameters.joinToString(" ") val args = e.parameters.joinToString(" ")
val type = when { val type = when {

View File

@ -1,17 +1,15 @@
package matterlink package matterlink
import matterlink.command.CommandMatterlink import matterlink.command.CommandMatterlink
import matterlink.command.IMinecraftCommandSender import matterlink.bridge.command.IMinecraftCommandSender
import matterlink.command.MatterlinkCommandSender import matterlink.command.MatterlinkCommandSender
import matterlink.config.cfg import matterlink.config.cfg
import matterlink.update.UpdateChecker
import net.minecraft.util.text.TextComponentString import net.minecraft.util.text.TextComponentString
import net.minecraftforge.fml.common.FMLCommonHandler import net.minecraftforge.fml.common.FMLCommonHandler
import net.minecraftforge.fml.common.Mod import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.common.event.* import net.minecraftforge.fml.common.event.*
import org.apache.logging.log4j.Level import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Logger import org.apache.logging.log4j.Logger
import java.io.File
lateinit var logger: Logger lateinit var logger: Logger

View File

@ -2,6 +2,7 @@ package matterlink.command
import matterlink.bridge.ApiMessage import matterlink.bridge.ApiMessage
import matterlink.bridge.MessageHandler import matterlink.bridge.MessageHandler
import matterlink.bridge.command.IMinecraftCommandSender
import matterlink.config.cfg import matterlink.config.cfg
import net.minecraft.command.ICommandSender import net.minecraft.command.ICommandSender
import net.minecraft.server.MinecraftServer import net.minecraft.server.MinecraftServer
@ -11,9 +12,8 @@ import net.minecraftforge.fml.common.FMLCommonHandler
import javax.annotation.Nonnull import javax.annotation.Nonnull
object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender { object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender {
private var level: Int = 0
override fun execute(cmdString: String, level: Int): Boolean { override fun execute(cmdString: String): Boolean {
return 0 < FMLCommonHandler.instance().minecraftServerInstance.commandManager.executeCommand( return 0 < FMLCommonHandler.instance().minecraftServerInstance.commandManager.executeCommand(
this, this,
cmdString cmdString
@ -29,7 +29,7 @@ object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender {
} }
override fun canUseCommand(permLevel: Int, commandName: String?): Boolean { override fun canUseCommand(permLevel: Int, commandName: String?): Boolean {
//TODO: Implement actual permissions checking //permissions are checked on our end
return true return true
} }

View File

@ -54,10 +54,9 @@ object EventHandler {
@SubscribeEvent @SubscribeEvent
fun commandEvent(e: CommandEvent) { fun commandEvent(e: CommandEvent) {
val sender = when { val sender = when {
e.sender is EntityPlayer -> e.sender.commandSenderName
e.sender is DedicatedServer -> cfg.relay.systemUser e.sender is DedicatedServer -> cfg.relay.systemUser
e.sender is TileEntityCommandBlock -> "CommandBlock" e.sender is TileEntityCommandBlock -> "CommandBlock"
else -> return else -> e.sender.commandSenderName
} }
val args = e.parameters.joinToString(" ") val args = e.parameters.joinToString(" ")
val type = when { val type = when {

View File

@ -4,7 +4,7 @@ import cpw.mods.fml.common.FMLCommonHandler
import cpw.mods.fml.common.Mod import cpw.mods.fml.common.Mod
import cpw.mods.fml.common.event.* import cpw.mods.fml.common.event.*
import matterlink.command.CommandMatterlink import matterlink.command.CommandMatterlink
import matterlink.command.IMinecraftCommandSender import matterlink.bridge.command.IMinecraftCommandSender
import matterlink.command.MatterlinkCommandSender import matterlink.command.MatterlinkCommandSender
import matterlink.config.cfg import matterlink.config.cfg
import net.minecraft.server.MinecraftServer import net.minecraft.server.MinecraftServer

View File

@ -2,9 +2,9 @@ package matterlink.command
import matterlink.bridge.ApiMessage import matterlink.bridge.ApiMessage
import matterlink.bridge.MessageHandler import matterlink.bridge.MessageHandler
import matterlink.bridge.command.IMinecraftCommandSender
import matterlink.config.cfg import matterlink.config.cfg
import net.minecraft.command.ICommandSender import net.minecraft.command.ICommandSender
import net.minecraft.entity.Entity
import net.minecraft.server.MinecraftServer import net.minecraft.server.MinecraftServer
import net.minecraft.util.ChatComponentText import net.minecraft.util.ChatComponentText
import net.minecraft.util.ChunkCoordinates import net.minecraft.util.ChunkCoordinates
@ -15,7 +15,7 @@ object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender {
private var level: Int = 0 private var level: Int = 0
override fun execute(cmdString: String, level: Int): Boolean { override fun execute(cmdString: String): Boolean {
return 0 < MinecraftServer.getServer().commandManager.executeCommand( return 0 < MinecraftServer.getServer().commandManager.executeCommand(
this, this,
cmdString cmdString
@ -35,7 +35,7 @@ object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender {
} }
override fun canCommandSenderUseCommand(permLevel: Int, commandName: String?): Boolean { override fun canCommandSenderUseCommand(permLevel: Int, commandName: String?): Boolean {
//TODO: Implement actual permissions checking //we do permission
return true return true
} }

View File

@ -4,5 +4,4 @@ const val MODID = "matterlink"
const val NAME = "MatterLink" const val NAME = "MatterLink"
const val MODVERSION = "@MODVERSION@" const val MODVERSION = "@MODVERSION@"
const val MCVERSION = "@MCVERSION@" const val MCVERSION = "@MCVERSION@"
const val DEPENDENCIES = ""

View File

@ -2,7 +2,7 @@ package matterlink
import matterlink.bridge.MessageHandler import matterlink.bridge.MessageHandler
import matterlink.bridge.command.BridgeCommandRegistry import matterlink.bridge.command.BridgeCommandRegistry
import matterlink.command.IMinecraftCommandSender import matterlink.bridge.command.IMinecraftCommandSender
import matterlink.config.cfg import matterlink.config.cfg
import matterlink.update.UpdateChecker import matterlink.update.UpdateChecker
import java.io.File import java.io.File

View File

@ -20,7 +20,8 @@ object ServerChatHandler {
val message = when (nextMessage.event) { val message = when (nextMessage.event) {
"user_action" -> nextMessage.format(cfg.formatting.action) "user_action" -> nextMessage.format(cfg.formatting.action)
"" -> { "" -> {
if (BridgeCommandRegistry.handleCommand(nextMessage.text)) return // try to handle command and do not handle as a chat message
if (BridgeCommandRegistry.handleCommand(nextMessage)) return
nextMessage.format(cfg.formatting.chat) nextMessage.format(cfg.formatting.chat)
} }
"join_leave" -> nextMessage.format(cfg.formatting.joinLeave) "join_leave" -> nextMessage.format(cfg.formatting.joinLeave)

View File

@ -1,5 +1,8 @@
package matterlink.bridge.command package matterlink.bridge.command
import matterlink.bridge.ApiMessage
import matterlink.config.CommandConfig
import matterlink.config.PermissionConfig
import matterlink.config.cfg import matterlink.config.cfg
import matterlink.instance import matterlink.instance
import java.util.* import java.util.*
@ -8,25 +11,28 @@ object BridgeCommandRegistry {
private val commandMap: HashMap<String, IBridgeCommand> = HashMap() private val commandMap: HashMap<String, IBridgeCommand> = HashMap()
fun handleCommand(input: String): Boolean { fun handleCommand(input: ApiMessage): Boolean {
if (!cfg.command.enable) return false if (!cfg.command.enable) return false
if (input[0] != cfg.command.prefix[0] || input.length < 2) return false if (input.text[0] != cfg.command.prefix[0] || input.text.length < 2) return false
val cmd = input.substring(1).split(' ', ignoreCase = false, limit = 2) val cmd = input.text.substring(1).split(' ', ignoreCase = false, limit = 2)
val args = if (cmd.size == 2) val args = if (cmd.size == 2) cmd[1] else ""
cmd[1]
else
""
return if (commandMap.containsKey(cmd[0])) (commandMap[cmd[0]]!!.call(args)) else false return if (commandMap.containsKey(cmd[0]))
(commandMap[cmd[0]]!!.execute(input.username, input.userid, input.account, args))
else false
} }
fun register(cmd: IBridgeCommand): Boolean { fun register(cmd: IBridgeCommand): Boolean {
if (cmd.name.isBlank() || commandMap.containsKey(cmd.name)) { if (cmd.alias.isBlank() || commandMap.containsKey(cmd.alias)) {
instance.info("Failed to register command: '${cmd.name}'") instance.error("Failed to register command: '${cmd.alias}'")
return false return false
} }
commandMap[cmd.name] = cmd if(!cmd.validate()) {
instance.error("Failed to validate command: '${cmd.alias}'")
return false
}
commandMap[cmd.alias] = cmd
return true return true
} }
@ -42,14 +48,16 @@ object BridgeCommandRegistry {
return if (help.isNotBlank()) help else "No help for '$cmd'" return if (help.isNotBlank()) help else "No help for '$cmd'"
} }
val commandList: String fun getCommandList (permLvl : Int) : String {
get() = commandMap.keys.joinToString(separator = ", ") return commandMap.filter { (key, value) ->
value.permLevel <= permLvl
}.map {it.key}.joinToString(" ")
}
fun reloadCommands() { fun reloadCommands() {
commandMap.clear() commandMap.clear()
registerAll(HelpCommand,PlayerListCommand,UptimeCommand) PermissionConfig.loadPermFile()
for ((key, value) in cfg.command.commandMapping) { register(HelpCommand)
register(PassthroughCommand(key, value)) registerAll(*CommandConfig.readConfig())
}
} }
} }

View File

@ -0,0 +1,48 @@
package matterlink.bridge.command
import matterlink.bridge.ApiMessage
import matterlink.bridge.MessageHandler
import matterlink.instance
data class CustomCommand(
override val alias: String,
val type: CommandType = CommandType.RESPONSE,
val execute: String = "",
val response: String = "",
override val permLevel: Int = 0,
override val help: String = "",
val allowArgs : Boolean = true
) : IBridgeCommand {
override fun execute(user: String, userId: String, server: String, args: String): Boolean {
if (!allowArgs && args.isNotBlank()) return false
if (IBridgeCommand.getPermLevel(userId,server) < permLevel) {
MessageHandler.transmit(ApiMessage(text = "$user is not permitted to perform command: $alias"))
return false
}
return when (type) {
CommandType.PASSTHROUGH -> {
//TODO: use a new commandSender for each user
instance.commandSender.execute("$execute $args")
}
CommandType.RESPONSE -> {
//TODO: replace format variables, use arguments
MessageHandler.transmit(ApiMessage(text = response))
true
}
}
}
/**
*
*/
override fun validate(): Boolean {
return true
}
}
enum class CommandType {
PASSTHROUGH, RESPONSE
}

View File

@ -5,19 +5,19 @@ import matterlink.bridge.MessageHandler
import matterlink.config.cfg import matterlink.config.cfg
object HelpCommand : IBridgeCommand { object HelpCommand : IBridgeCommand {
override val name: String = "help" override val alias: String = "help"
override val help: String = "Returns the help string for the given command. Syntax: help <command>" override val help: String = "Returns the help string for the given command. Syntax: help <command>"
override fun call(args: String): Boolean { override val permLevel = 0
val msg: String = if (args.isEmpty()) { override fun execute(user:String, userId:String, server:String, args:String) : Boolean {
"Available commands: ${ BridgeCommandRegistry.commandList}" val msg: String = when {
} else { args.isEmpty() ->
args.split(" ", ignoreCase = false) "Available commands: ${BridgeCommandRegistry.getCommandList(IBridgeCommand.getPermLevel(userId, server))}"
.joinToString(separator = "\n") { "$it: ${ BridgeCommandRegistry.getHelpString(it) }" } else -> args.split(" ", ignoreCase = false)
.joinToString(separator = "\n") {
"$it: ${ BridgeCommandRegistry.getHelpString(it) }"
}
} }
MessageHandler.transmit(ApiMessage( MessageHandler.transmit(ApiMessage(text = msg))
username = cfg.relay.systemUser,
text = msg
))
return true return true
} }

View File

@ -1,7 +1,22 @@
package matterlink.bridge.command package matterlink.bridge.command
import matterlink.config.PermissionConfig
interface IBridgeCommand { interface IBridgeCommand {
val name: String val alias : String
fun call(args: String): Boolean val help : String
val help: String val permLevel : Int
fun execute(user:String, userId:String, server:String, args:String) : Boolean
fun validate() = true
companion object {
fun getPermLevel(userId: String, server: String): Int {
if (PermissionConfig.perms[server] == null) return 0
return PermissionConfig.perms[server]?.get(userId) ?: 0
}
}
} }

View File

@ -0,0 +1,10 @@
package matterlink.bridge.command
interface IMinecraftCommandSender {
/**
* @param cmdString The command to execute with its arguments
*
* @return True for success, or false for failure
*/
fun execute(cmdString: String) : Boolean
}

View File

@ -1,13 +0,0 @@
package matterlink.bridge.command
import matterlink.instance
class PassthroughCommand(override val name: String, val cmd: String) : IBridgeCommand {
override fun call(args: String): Boolean {
return instance.commandSender.execute("$cmd $args",100)
}
override val help: String = "No help available for this command."
}

View File

@ -1,26 +0,0 @@
package matterlink.bridge.command
import matterlink.instance
import matterlink.antiping
import matterlink.bridge.ApiMessage
import matterlink.bridge.MessageHandler
import matterlink.config.cfg
object PlayerListCommand : IBridgeCommand {
override val name: String = "players"
override val help: String = "Lists online players."
override fun call(args: String): Boolean {
if (args.isNotBlank()) return false
val playerList = instance.wrappedPlayerList()
MessageHandler.transmit(ApiMessage(
username = cfg.relay.systemUser,
text = when {
playerList.isNotEmpty() -> "players: " + playerList.joinToString(" ") { it.antiping }
else -> "No Players online"
}
))
return true
}
}

View File

@ -1,21 +0,0 @@
package matterlink.bridge.command
import matterlink.bridge.ApiMessage
import matterlink.bridge.MessageHandler
import matterlink.config.cfg
import matterlink.instance
object UptimeCommand : IBridgeCommand {
override val name: String = "uptime"
override val help: String = "Get server uptime."
override fun call(args: String): Boolean {
if (args.isNotBlank()) return false
MessageHandler.transmit(ApiMessage(
username = cfg.relay.systemUser,
text = instance.getUptimeAsString()
))
return true
}
}

View File

@ -1,11 +0,0 @@
package matterlink.command
interface IMinecraftCommandSender {
/**
* @param cmdString The command to execute with its arguments
* @param level Privilege level to execute this command at, currently unused
*
* @return Any output of the command
*/
fun execute(cmdString: String, level: Int) : Boolean
}

View File

@ -0,0 +1,48 @@
package matterlink.config
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import matterlink.bridge.command.CommandType
import matterlink.bridge.command.CustomCommand
import java.io.File
object CommandConfig {
private val gson: Gson = GsonBuilder().setPrettyPrinting().create()
private val configFile: File = cfg.cfgDirectory.resolve("commands.json")
private val default = arrayOf(
CustomCommand(
alias = "tps",
type = CommandType.PASSTHROUGH,
execute = "forge tps",
help = "Print server tps",
allowArgs = false
),
CustomCommand(
alias = "list",
type = CommandType.PASSTHROUGH,
execute = "list",
help = "List online players",
allowArgs = false
),
CustomCommand(
alias = "seed",
type = CommandType.PASSTHROUGH,
execute = "seed",
help = "Print server world seed",
allowArgs = false
)
)
fun readConfig() : Array<CustomCommand> {
if(!configFile.exists()) {
configFile.createNewFile()
configFile.writeText(gson.toJson(default))
return default
}
val text = configFile.readText()
return gson.fromJson(text, Array<CustomCommand>::class.java)
}
}

View File

@ -0,0 +1,27 @@
package matterlink.config
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import java.io.File
object PermissionConfig {
private val gson: Gson = GsonBuilder().setPrettyPrinting().create()
private val configFile: File = cfg.cfgDirectory.resolve("permissions.json")
private val default = hashMapOf<String,HashMap<String,Int>>()
var perms : HashMap<String,HashMap<String,Int>> = default
fun loadPermFile() {
if(!configFile.exists()) {
configFile.createNewFile()
perms = default
configFile.writeText(gson.toJson(default))
return
}
val text = configFile.readText()
perms = gson.fromJson(text, object : TypeToken <HashMap<String,HashMap<String,Int>>>(){}.type)
}
}

View File

@ -244,7 +244,7 @@ enable=true
#[[gateway.in]] specifies the account and channels we will receive messages from. #[[gateway.in]] specifies the account and channels we will receive messages from.
#The following example bridges between mattermost and irc #The following example bridges between mattermost and irc
[[gateway.in]] [[gateway.inout]]
account="irc.freenode" account="irc.freenode"
channel="#matterlink" channel="#matterlink"