restructure configuration, fix connection errors, register events properly on 1.7.10

This commit is contained in:
NikkyAI 2018-02-18 04:50:58 +01:00
parent 23c65bd4e1
commit 7fd8b31474
23 changed files with 160 additions and 122 deletions

View File

@ -11,6 +11,7 @@ import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.common.event.*
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Logger
import java.io.File
lateinit var logger: Logger
@ -33,7 +34,7 @@ object MatterLink : IMatterLink() {
logger = event.modLog
logger.info("Building bridge!")
cfg = MatterLinkConfig(event.suggestedConfigurationFile)
cfg = MatterLinkConfig(event.modConfigurationDirectory)
}
@Mod.EventHandler
@ -41,11 +42,6 @@ object MatterLink : IMatterLink() {
this.registerBridgeCommands()
}
@Mod.EventHandler
fun serverAboutToStart(event: FMLServerAboutToStartEvent) {
// MessageHandler.start(clear = true)
}
@Mod.EventHandler
fun serverStarting(event: FMLServerStartingEvent) {
logger.debug("Registering server commands")
@ -70,10 +66,10 @@ object MatterLink : IMatterLink() {
}
override fun log(level: String, formatString: String, vararg data: Any) =
logger.log(Level.toLevel(level, Level.INFO),formatString, *data)
logger.log(Level.toLevel(level, Level.INFO), formatString, *data)
override var commandSender: IMinecraftCommandSender = MatterlinkCommandSender
override val mcVersion: String = MCVERSION
override val mcVersion: String = MCVERSION
override val modVersion: String = MODVERSION
}

View File

@ -5,10 +5,10 @@ import matterlink.config.cfg
import net.minecraftforge.common.config.Configuration
import java.io.File
class MatterLinkConfig(val file: File) : BaseConfig() {
class MatterLinkConfig(val baseCfgDir: File) : BaseConfig(baseCfgDir) {
init {
logger.info("Reading bridge blueprints... from {}", file)
val config = Configuration(file)
logger.info("Reading bridge blueprints... from {}", cfgDirectory)
val config = Configuration(mainCfgFile)
load(
getBoolean = config::getBoolean,
@ -18,9 +18,8 @@ class MatterLinkConfig(val file: File) : BaseConfig() {
getStringList = config::getStringList,
addCustomCategoryComment = config::addCustomCategoryComment
)
if (config.hasChanged()) config.save()
}
override fun load() = MatterLinkConfig(file)
override fun load() = MatterLinkConfig(baseCfgDir)
}

View File

@ -48,7 +48,7 @@ object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender {
override fun sendMessage(@Nonnull component: ITextComponent?) {
MessageHandler.transmit(ApiMessage(
username = cfg!!.relay.systemUser,
username = cfg.relay.systemUser,
text = component!!.unformattedComponentText
))

View File

@ -11,6 +11,7 @@ import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.common.event.*
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Logger
import java.io.File
lateinit var logger: Logger
@ -33,17 +34,12 @@ object MatterLink : IMatterLink() {
logger = event.modLog
logger.info("Building bridge!")
cfg = MatterLinkConfig(event.suggestedConfigurationFile)
cfg = MatterLinkConfig(event.modConfigurationDirectory)
}
@Mod.EventHandler
fun init(event: FMLInitializationEvent) {
this.registerBridgeCommands()
}
@Mod.EventHandler
fun serverAboutToStart(event: FMLServerAboutToStartEvent) {
// MessageHandler.start(clear = true)
this.registerBridgeCommands()
}
@Mod.EventHandler
@ -70,7 +66,7 @@ object MatterLink : IMatterLink() {
}
override fun log(level: String, formatString: String, vararg data: Any) =
logger.log(Level.toLevel(level, Level.INFO),formatString, *data)
logger.log(Level.toLevel(level, Level.INFO), formatString, *data)
override var commandSender: IMinecraftCommandSender = MatterlinkCommandSender

View File

@ -5,10 +5,10 @@ import matterlink.config.cfg
import net.minecraftforge.common.config.Configuration
import java.io.File
class MatterLinkConfig(val file: File) : BaseConfig() {
class MatterLinkConfig(val baseCfgDir: File) : BaseConfig(baseCfgDir) {
init {
logger.info("Reading bridge blueprints... from {}", file)
val config = Configuration(file)
logger.info("Reading bridge blueprints... from {}", cfgDirectory)
val config = Configuration(mainCfgFile)
load(
getBoolean = config::getBoolean,
@ -18,9 +18,8 @@ class MatterLinkConfig(val file: File) : BaseConfig() {
getStringList = config::getStringList,
addCustomCategoryComment = config::addCustomCategoryComment
)
if (config.hasChanged()) config.save()
}
override fun load() = MatterLinkConfig(file)
override fun load() = MatterLinkConfig(baseCfgDir)
}

View File

@ -48,7 +48,7 @@ object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender {
override fun sendMessage(@Nonnull component: ITextComponent?) {
MessageHandler.transmit(ApiMessage(
username = cfg!!.relay.systemUser,
username = cfg.relay.systemUser,
text = component!!.unformattedComponentText
))

View File

@ -52,7 +52,7 @@ object EventHandler {
fun commandEvent(e: CommandEvent) {
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"
else -> return
}

View File

@ -11,6 +11,7 @@ import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.common.event.*
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Logger
import java.io.File
lateinit var logger: Logger
@ -33,7 +34,7 @@ object MatterLink : IMatterLink() {
logger = event.modLog
logger.info("Building bridge!")
cfg = MatterLinkConfig(event.suggestedConfigurationFile)
cfg = MatterLinkConfig(event.modConfigurationDirectory)
}
@Mod.EventHandler
@ -70,7 +71,7 @@ object MatterLink : IMatterLink() {
}
override fun log(level: String, formatString: String, vararg data: Any) =
logger.log(Level.toLevel(level, Level.INFO),formatString, *data)
logger.log(Level.toLevel(level, Level.INFO), formatString, *data)
override var commandSender: IMinecraftCommandSender = MatterlinkCommandSender
override val mcVersion: String = MCVERSION

View File

@ -5,10 +5,10 @@ import matterlink.config.cfg
import net.minecraftforge.common.config.Configuration
import java.io.File
class MatterLinkConfig(val file: File) : BaseConfig() {
class MatterLinkConfig(val baseCfgDir: File) : BaseConfig(baseCfgDir) {
init {
logger.info("Reading bridge blueprints... from {}", file)
val config = Configuration(file)
logger.info("Reading bridge blueprints... from {}", cfgDirectory)
val config = Configuration(mainCfgFile)
load(
getBoolean = config::getBoolean,
@ -21,5 +21,5 @@ class MatterLinkConfig(val file: File) : BaseConfig() {
if (config.hasChanged()) config.save()
}
override fun load() = MatterLinkConfig(file)
override fun load() = MatterLinkConfig(baseCfgDir)
}

View File

@ -39,7 +39,7 @@ object MatterlinkCommandSender : IMinecraftCommandSender, ICommandSender {
override fun sendMessage(@Nonnull component: ITextComponent?) {
MessageHandler.transmit(ApiMessage(
username = cfg!!.relay.systemUser,
username = cfg.relay.systemUser,
text = component!!.unformattedComponentText
))

View File

@ -1,5 +1,6 @@
package matterlink
import cpw.mods.fml.common.FMLCommonHandler
import cpw.mods.fml.common.Mod
import cpw.mods.fml.common.event.*
import matterlink.command.CommandMatterlink
@ -28,10 +29,12 @@ class MatterLink : IMatterLink() {
@Mod.EventHandler
fun preInit(event: FMLPreInitializationEvent) {
MinecraftForge.EVENT_BUS.register(EventHandler)
FMLCommonHandler.instance().bus().register(EventHandler)
logger = event.modLog
logger.info("Building bridge!")
cfg = MatterLinkConfig(event.suggestedConfigurationFile)
cfg = MatterLinkConfig(event.modConfigurationDirectory)
}
@Mod.EventHandler
@ -63,10 +66,10 @@ class MatterLink : IMatterLink() {
}
override fun log(level: String, formatString: String, vararg data: Any) =
logger.log(Level.toLevel(level, Level.INFO),formatString, *data)
logger.log(Level.toLevel(level, Level.INFO), formatString, *data)
override var commandSender: IMinecraftCommandSender = MatterlinkCommandSender
override val mcVersion: String = MCVERSION
override val mcVersion: String = MCVERSION
override val modVersion: String = MODVERSION
}

View File

@ -4,10 +4,10 @@ import matterlink.config.BaseConfig
import net.minecraftforge.common.config.Configuration
import java.io.File
class MatterLinkConfig(val file: File) : BaseConfig() {
class MatterLinkConfig(val baseCfgDir: File) : BaseConfig(baseCfgDir) {
init {
logger.info("Reading bridge blueprints... from {}", file)
val config = Configuration(file)
logger.info("Reading bridge blueprints... from {}", cfgDirectory)
val config = Configuration(mainCfgFile)
load(
getBoolean = config::getBoolean,
@ -17,9 +17,8 @@ class MatterLinkConfig(val file: File) : BaseConfig() {
getStringList = config::getStringList,
addCustomCategoryComment = config::addCustomCategoryComment
)
if (config.hasChanged()) config.save()
}
override fun load() = MatterLinkConfig(file)
override fun load() = MatterLinkConfig(baseCfgDir)
}

View File

@ -5,6 +5,7 @@ import matterlink.bridge.command.BridgeCommandRegistry
import matterlink.command.IMinecraftCommandSender
import matterlink.config.cfg
import matterlink.update.UpdateChecker
import java.io.File
lateinit var instance: IMatterLink
@ -12,21 +13,24 @@ abstract class IMatterLink {
abstract val mcVersion: String
abstract val modVersion: String
lateinit var cfgDir: File
abstract var commandSender: IMinecraftCommandSender
abstract fun wrappedSendToPlayers(msg: String)
abstract fun wrappedPlayerList(): Array<String>
private var updateChecked: Boolean = false
private var firstRun: Boolean = true
fun connect() {
MessageHandler.start(clear = true)
MessageHandler.start(clear = true, firstRun = firstRun)
if (!updateChecked && cfg.update.enable) {
if (firstRun && cfg.update.enable) {
Thread(UpdateChecker()).start()
updateChecked = true
}
firstRun = false
}
fun disconnect() {

View File

@ -1,12 +1,16 @@
package matterlink
import java.io.PrintWriter
import java.io.StringWriter
private const val ZWSP: Char = '\u200b'
//Inserts a zero-width space at index 1 in the string'
fun String.antiping(): String {
return this[0].toString() + ZWSP + this.substring(1)
}
val String.antiping: String
get() {
return this[0].toString() + ZWSP + this.substring(1)
}
fun String.mapFormat(env: Map<String, String>): String {
var result = this
@ -17,3 +21,10 @@ fun String.mapFormat(env: Map<String, String>): String {
}
return result
}
val Exception.stackTraceString: String
get() {
val sw = StringWriter()
this.printStackTrace(PrintWriter(sw))
return sw.toString()
}

View File

@ -44,7 +44,7 @@ data class ApiMessage(
"{gateway}" to gateway,
"{channel}" to channel,
"{protocol}" to protocol,
"{username:antiping}" to username.antiping()
"{username:antiping}" to username.antiping
)
)

View File

@ -2,11 +2,13 @@ package matterlink.bridge
import matterlink.config.cfg
import matterlink.instance
import matterlink.stackTraceString
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.methods.HttpRequestBase
import org.apache.http.impl.client.HttpClients
import java.io.InputStream
import java.net.SocketException
import java.net.UnknownHostException
import java.util.concurrent.ConcurrentLinkedQueue
const val BUFFER_SIZE = 1000
@ -20,12 +22,17 @@ fun HttpRequestBase.authorize() {
}
class HttpStreamConnection(private val rcvQueue: ConcurrentLinkedQueue<ApiMessage>,
private val clear: Boolean = true
private val clear: Boolean = true,
private val messageHandler: MessageHandler
) : Thread() {
var connected = false
private set
var connecting = false
var enabled = true
var connectErrors = 0
private set
var cancelled: Boolean = false
private set
init {
name = "MsgRcvThread"
@ -41,11 +48,12 @@ class HttpStreamConnection(private val rcvQueue: ConcurrentLinkedQueue<ApiMessag
connecting = false
if (success) {
instance.info("connected successfully")
connectErrors = 0
messageHandler.connectErrors = 0
connected = true
} else {
connectErrors++
messageHandler.connectErrors++
connected = false
instance.warn("connectErrors: ${messageHandler.connectErrors}")
}
}
@ -58,23 +66,32 @@ class HttpStreamConnection(private val rcvQueue: ConcurrentLinkedQueue<ApiMessag
private val clearGet = HttpGet(cfg.connect.url + "/api/messages").apply {
authorize()
}
private var cancelled: Boolean = false
override fun run() {
if (clear) {
val r = client.execute(clearGet)
r.entity.content.bufferedReader().forEachLine {
instance.debug("skipping $it")
}
}
try {
instance.info("Attemping to open Bridge Connection")
if (clear) {
val r = client.execute(clearGet)
r.entity.content.bufferedReader().forEachLine {
instance.debug("skipping $it")
}
}
val response = client.execute(get)
if (response.statusLine.statusCode != 200) {
instance.error("Bridge Connection rejected... status code ${response.statusLine.statusCode}")
setSuccess(false) //TODO: pass message
onClose()
when (response.statusLine.statusCode) {
400 -> {
instance.warn("Missing token, please use /bridge reload after entering correct information")
messageHandler.enabled = false
}
401 -> {
instance.warn("Incorrect token, please use /bridge reload after entering correct information")
messageHandler.enabled = false
}
}
return
} else {
instance.debug("Bridge Connection accepted")
@ -111,11 +128,15 @@ class HttpStreamConnection(private val rcvQueue: ConcurrentLinkedQueue<ApiMessag
content.close()
} catch (e: SocketException) {
instance.info("error {}", e)
instance.error(e.stackTraceString)
if (!cancelled) {
instance.error("Bridge Connection interrupted...")
setSuccess(false)
}
} catch (e: UnknownHostException) {
instance.error(e.message ?: e.stackTraceString)
// instance.error(e.stackTraceString())
setSuccess(false)
} finally {
instance.debug("thread finished")
onClose()
@ -124,23 +145,20 @@ class HttpStreamConnection(private val rcvQueue: ConcurrentLinkedQueue<ApiMessag
}
fun open() {
enabled = true
if (!isAlive && cfg.connect.enable) {
if (!isAlive) {
connecting = true
super.start()
// MessageHandler.transmit(ApiMessage(text="bridge connected", username="Server"))
}
if (isAlive) {
instance.info("Bridge Connection opened")
instance.info("Bridge is connecting")
}
}
fun close() {
instance.info("Closing bridge connection...")
// MessageHandler.transmit(ApiMessage(text="bridge closing", username="Server"))
try {
enabled = false
cancelled = true
get.abort()
join()

View File

@ -11,6 +11,7 @@ import java.util.concurrent.ConcurrentLinkedQueue
object MessageHandler {
private var sendErrors = 0
var connectErrors = 0
private var streamConnection: HttpStreamConnection
var rcvQueue = ConcurrentLinkedQueue<ApiMessage>()
private set
@ -23,11 +24,10 @@ object MessageHandler {
val connected get() = streamConnection.connected
private fun createThread(clear: Boolean = true): HttpStreamConnection {
instance.info("Attempting to open bridge connection.")
instance.info("queue: $rcvQueue")
return HttpStreamConnection(
rcvQueue,
clear
clear,
this
)
}
@ -38,12 +38,26 @@ object MessageHandler {
}
}
fun stop() = streamConnection.close()
fun stop() {
enabled = false
streamConnection.close()
}
fun start(clear: Boolean = true) {
if (!connected)
var enabled: Boolean = false
fun start(clear: Boolean = true, firstRun: Boolean = false) {
enabled = when {
firstRun -> cfg.connect.autoConnect
else -> true
}
if (!connected) {
streamConnection = createThread(clear)
streamConnection.open()
}
if (enabled) {
streamConnection.open()
}
}
private fun transmitMessage(message: ApiMessage) {
@ -78,9 +92,9 @@ object MessageHandler {
}
fun checkConnection(tick: Int) {
if (streamConnection.enabled && tick % 20 == 0 && !streamConnection.connected && !streamConnection.connecting) {
if (enabled && tick % 20 == 0 && !streamConnection.connected && !streamConnection.connecting) {
if (streamConnection.connectErrors > 5) {
if (connectErrors > 5) {
instance.fatal("Caught too many errors, closing bridge")
stop()
return

View File

@ -15,7 +15,7 @@ object PlayerListCommand : IBridgeCommand {
MessageHandler.transmit(ApiMessage(
username = cfg.relay.systemUser,
text = when {
playerList.isNotEmpty() -> "players: " + playerList.joinToString(" ") { it.antiping() }
playerList.isNotEmpty() -> "players: " + playerList.joinToString(" ") { it.antiping }
else -> "No Players online"
}
))

View File

@ -6,17 +6,19 @@ import matterlink.config.cfg
import matterlink.instance
object CommandCore {
fun getName() : String { return "bridge" }
fun getAliases() : List<String> { return listOf("BRIDGE","bridge") }
fun getUsage() : String { return "bridge <connect|disconnect|reload>"}
fun getName() = "bridge"
fun execute(args : Array<String>) : String {
fun getAliases() = listOf("BRIDGE", "bridge")
fun getUsage() = "bridge <connect|disconnect|reload>"
fun execute(args: Array<String>): String {
val cmd = args[0].toLowerCase()
return when (cmd) {
"connect" -> {
instance.connect()
"Bridge connected!"
"Attempting bridge connection!"
}
"disconnect" -> {
instance.disconnect()

View File

@ -1,24 +1,21 @@
package matterlink.config
import java.io.File
import java.util.regex.Pattern
lateinit var cfg: BaseConfig
abstract class BaseConfig {
abstract class BaseConfig(rootDir: File) {
companion object {
private val CATEGORY_RELAY_OPTIONS = "relay"
private val CATEGORY_FORMATTING_INCOMING = "formatting"
private val CATEGORY_JOIN_LEAVE = "join_leave"
private val CATEGORY_CONNECTION = "connection"
private val CATEGORY_COMMAND = "command"
private val CATEGORY_DEATH = "death"
private val CATEGORY_UPDATE = "update"
fun reload() {
cfg = cfg.load()
}
}
val cfgDirectory: File = rootDir.resolve("matterlink")
val mainCfgFile: File = cfgDirectory.resolve("matterlink.cfg")
var relay = RelayOptions()
var connect = ConnectOptions()
var formatting = FormattingOptions()
@ -50,14 +47,16 @@ abstract class BaseConfig {
var url: String = "http://localhost:4242",
var authToken: String = "",
var gateway: String = "minecraft",
var enable: Boolean = true
var autoConnect: Boolean = true
)
data class CommandOptions(
var prefix: String = "$",
var enable: Boolean = true,
var commandMapping: Map<String, String> = mapOf(
"tps" to "forge tps"
"tps" to "forge tps",
"list" to "list",
"seed" to "seed"
)
)
@ -97,10 +96,7 @@ abstract class BaseConfig {
"thrown" to "彡°",
"thorns" to "\uD83C\uDF39", //🌹
"explosion" to "\uD83D\uDCA3 \uD83D\uDCA5", //💣 💥
"explosion.player" to "\uD83D\uDCA3 \uD83D\uDCA5", //💣 💥
"electrocut" to "",
"radiation" to ""
"explosion.player" to "\uD83D\uDCA3 \uD83D\uDCA5" //💣 💥
)
)
@ -112,8 +108,8 @@ abstract class BaseConfig {
addCustomCategoryComment: (key: String, comment: String) -> Unit,
getStringList: (name: String, category: String, defaultValues: Array<String>, comment: String) -> Array<String>
) {
var category = CATEGORY_RELAY_OPTIONS
addCustomCategoryComment(CATEGORY_RELAY_OPTIONS, "Relay options")
var category = "relay"
addCustomCategoryComment(category, "Relay options")
relay = RelayOptions(
systemUser = getString(
"systemUser",
@ -136,8 +132,8 @@ abstract class BaseConfig {
)
)
category = CATEGORY_COMMAND
addCustomCategoryComment(CATEGORY_COMMAND, "User commands")
category = "commands"
addCustomCategoryComment(category, "User commands")
command = CommandOptions(
enable = getBoolean(
"enable",
@ -168,8 +164,8 @@ abstract class BaseConfig {
}
)
category = CATEGORY_FORMATTING_INCOMING
addCustomCategoryComment(CATEGORY_FORMATTING_INCOMING, "Gateway -> Server" +
category = "formatting"
addCustomCategoryComment(category, "Gateway -> Server" +
"Formatting options: " +
"Available variables: {username}, {text}, {gateway}, {channel}, {protocol}, {username:antiping}")
formatting = FormattingOptions(
@ -193,8 +189,8 @@ abstract class BaseConfig {
)
)
category = CATEGORY_JOIN_LEAVE
addCustomCategoryComment(CATEGORY_JOIN_LEAVE, "Server -> Gateway" +
category = "join_leave"
addCustomCategoryComment(category, "Server -> Gateway" +
"Formatting options: " +
"Available variables: {username}, {username:antiping}")
joinLeave = FormattingJoinLeave(
@ -226,8 +222,8 @@ abstract class BaseConfig {
)
)
category = CATEGORY_CONNECTION
addCustomCategoryComment(CATEGORY_CONNECTION, "Connection settings")
category = "connection"
addCustomCategoryComment(category, "Connection settings")
connect = ConnectOptions(
url = getString(
"connectURL",
@ -247,14 +243,14 @@ abstract class BaseConfig {
connect.gateway,
"MatterBridge gateway"
),
enable = getBoolean(
"enable",
autoConnect = getBoolean(
"autoConnect",
category,
connect.enable,
"Enable the relay, it will not work if it is not enabled"
connect.autoConnect,
"Connect the relay on startup"
)
)
category = CATEGORY_DEATH
category = "death"
addCustomCategoryComment(category, "Death message settings")
death = DeathOptions(
showDeath = getBoolean(
@ -287,7 +283,7 @@ abstract class BaseConfig {
)
category = CATEGORY_UPDATE
category = "update"
addCustomCategoryComment(category, "Update Settings")
update = UpdateOptions(
enable = getBoolean(

View File

@ -15,7 +15,7 @@ object DeathHandler {
damageType: String
) {
if (cfg.death.showDeath) {
var msg = deathMessage.replace(player, player.antiping())
var msg = deathMessage.replace(player, player.antiping)
if(cfg.death.showDamageType) {
val emojis = cfg.death.damageTypeMapping[damageType]?.split(' ') ?: listOf("\uD83D\uDC7B unknown type '$damageType'")
val damageEmoji = emojis[random.nextInt(emojis.size)]

View File

@ -13,7 +13,7 @@ object JoinLeaveHandler {
val msg = cfg.joinLeave.joinServer.mapFormat(
mapOf(
"{username}" to player,
"{username:antiping}" to player.antiping()
"{username:antiping}" to player.antiping
)
)
MessageHandler.transmit(ApiMessage(
@ -29,7 +29,7 @@ object JoinLeaveHandler {
val msg = cfg.joinLeave.leaveServer.mapFormat(
mapOf(
"{username}" to player,
"{username:antiping}" to player.antiping()
"{username:antiping}" to player.antiping
)
)
MessageHandler.transmit(ApiMessage(

View File

@ -9,7 +9,7 @@ object ProgressHandler {
fun handleProgress(name: String, message: String, display: String) {
if (!cfg.relay.advancements) return
val usr = name.antiping()
val usr = name.antiping
MessageHandler.transmit(ApiMessage(
username = cfg.relay.systemUser,
text = "$usr $message $display"