release 1.2.1

proxy logger calls


fix Exception on startup with invalid / default connection data


also fix Exception when closing Server
release 1.2.1


Merge branch 'dev'
This commit is contained in:
NikkyAI 2018-02-11 03:55:54 +01:00
parent 087d516e3e
commit 1b82b037d6
12 changed files with 165 additions and 71 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@
.idea
out
build
classes
#eclipse
.project

View File

@ -1,5 +1,6 @@
package matterlink
import jline.internal.Log
import matterlink.bridge.MessageHandler
import matterlink.bridge.command.BridgeCommandRegistry
import matterlink.bridge.command.HelpCommand
@ -9,6 +10,7 @@ import net.minecraft.util.text.TextComponentString
import net.minecraftforge.fml.common.FMLCommonHandler
import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.common.event.*
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Logger
const val MODID = "matterlink"
@ -70,5 +72,7 @@ object MatterLink : IMatterLink() {
override fun wrappedPlayerList(): Array<String> {
return FMLCommonHandler.instance().minecraftServerInstance.playerList.onlinePlayerNames
}
override fun log(level: String, formatString: String, vararg data: Any) =
logger.log(Level.toLevel(level, Level.INFO),formatString, *data)
}

View File

@ -9,6 +9,7 @@ import net.minecraft.util.text.TextComponentString
import net.minecraftforge.fml.common.FMLCommonHandler
import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.common.event.*
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Logger
const val MODID = "matterlink"
@ -45,7 +46,7 @@ object MatterLink : IMatterLink() {
@Mod.EventHandler
fun serverAboutToStart(event: FMLServerAboutToStartEvent) {
MessageHandler.start(clear = true)
// MessageHandler.start(clear = true)
}
@Mod.EventHandler
@ -70,5 +71,7 @@ object MatterLink : IMatterLink() {
override fun wrappedPlayerList(): Array<String> {
return FMLCommonHandler.instance().minecraftServerInstance.playerList.onlinePlayerNames
}
override fun log(level: String, formatString: String, vararg data: Any) =
logger.log(Level.toLevel(level, Level.INFO),formatString, *data)
}

View File

@ -1,39 +1,31 @@
package matterlink
import matterlink.bridge.MessageHandler
//import org.apache.logging.log4j.Logger
lateinit var instance: IMatterLink
//lateinit var logger: Logger
abstract class IMatterLink {
var interrupted: Boolean = false
// var interrupted: Boolean = false
abstract fun wrappedSendToPlayers(msg: String)
abstract fun wrappedPlayerList(): Array<String>
fun connect() {
if (MessageHandler.start(clear = true)) {
println("Connected to matterbridge relay")
} else {
System.err.println("Connection to matterbridge relay failed.")
}
MessageHandler.start(clear = true)
}
fun disconnect () {
fun disconnect() {
MessageHandler.stop()
}
abstract fun log(level: String, formatString: String, vararg data: Any)
fun fatal(formatString: String, vararg data: Any) = log(Level.FATAL.name, formatString, *data)
fun error(formatString: String, vararg data: Any) = log(Level.ERROR.name, formatString, *data)
fun warn(formatString: String, vararg data: Any) = log(Level.WARN.name, formatString, *data)
fun info(formatString: String, vararg data: Any) = log(Level.INFO.name, formatString, *data)
fun debug(formatString: String, vararg data: Any) = log(Level.DEBUG.name, formatString, *data)
fun trace(formatString: String, vararg data: Any) = log(Level.TRACE.name, formatString, *data)
fun reconnect(tick: Int) {
if(tick % 20 == 0 && interrupted) {
println("Trying to reconnect")
if (MessageHandler.start(clear = false)) {
println("Reconnected to matterbridge relay")
} else {
System.err.println("Reconnection to matterbridge relay failed.")
}
}
}
}

View File

@ -0,0 +1,38 @@
package matterlink
enum class Level(val level: Int) {
/**
* No events will be logged.
*/
OFF(0),
/**
* A severe error that will prevent the application from continuing.
*/
FATAL(1),
/**
* An error in the application, possibly recoverable.
*/
ERROR(2),
/**
* An event that might possible lead to an error.
*/
WARN(3),
/**
* An event for informational purposes.
*/
INFO(4),
/**
* A general debugging event.
*/
DEBUG(5),
/**
* A fine-grained debug message, typically capturing the flow through the application.
*/
TRACE(6),
}

View File

@ -1,7 +1,6 @@
package matterlink.bridge;
import matterlink.instance
//import matterlink.logger
import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.HttpClients
import java.io.InputStream
@ -9,7 +8,13 @@ import java.net.SocketException
val BUFFER_SIZE = 1000
class HttpStreamConnection(getClosure: () -> HttpGet, clearClosure: () -> HttpGet, private val mhandler: (String) -> Unit, private val onClose: () -> Unit, private val clear: Boolean = true) : Thread() {
class HttpStreamConnection(getClosure: () -> HttpGet,
clearClosure: () -> HttpGet,
private val mhandler: (String) -> Unit,
private val onClose: () -> Unit,
private val setSuccess: (Boolean) -> Unit,
private val clear: Boolean = true
) : Thread() {
private val client = HttpClients.createDefault()
private var stream: InputStream? = null
@ -18,28 +23,36 @@ class HttpStreamConnection(getClosure: () -> HttpGet, clearClosure: () -> HttpGe
var cancelled: Boolean = false
private set
override fun run() {
instance.interrupted = false
if (clear) {
val r = client.execute(clearGet)
r.entity.content.bufferedReader().forEachLine {
println("DEBUG: skipping $it")
instance.debug("skipping $it")
}
}
val response = client.execute(get)
val content = response.entity.content.buffered()
stream = content
//val reader = content.bufferedReader()
var buffer = ""
val buf = ByteArray(BUFFER_SIZE)
try {
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()
return
} else {
setSuccess(true) //TODO: pass message
}
val content = response.entity.content.buffered()
stream = content
var buffer = ""
val buf = ByteArray(BUFFER_SIZE)
instance.info("initialized buffer")
while (!get.isAborted) {
val chars = content.read(buf)
if (chars > 0) {
buffer += String(buf.dropLast(buf.count() - chars).toByteArray())
println("DEBUG: " + buffer)
instance.debug(buffer)
while (buffer.contains("\n")) {
val line = buffer.substringBefore("\n")
@ -50,17 +63,20 @@ class HttpStreamConnection(getClosure: () -> HttpGet, clearClosure: () -> HttpGe
break
}
}
instance.debug("closing stream")
content.close()
} catch (e: SocketException) {
instance.info("error {}", e)
if (!cancelled) {
System.err.println("Bridge Connection interrupted...")
instance.interrupted = true
//TODO: mark connection as interrupted and try to reconnect
instance.error("Bridge Connection interrupted...")
setSuccess(false)
}
} finally {
instance.debug("thread finished")
onClose()
}
println("DEBUG: closing stream")
content.close()
println("DEBUG: thread finished")
onClose()
return
}

View File

@ -1,7 +1,7 @@
package matterlink.bridge
import matterlink.config.cfg
//import matterlink.logger
import matterlink.instance
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.methods.HttpPost
import org.apache.http.client.methods.HttpRequestBase
@ -9,11 +9,15 @@ import org.apache.http.entity.ContentType
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.HttpClients
import java.io.IOException
import java.net.SocketException
import java.util.concurrent.ConcurrentLinkedQueue
object MessageHandler {
private var connected = false
var connected = false
private var connecting = false
private var enabled = true
private var connectErrors = 0
private var sendErrors = 0
private var streamConnection: HttpStreamConnection
var rcvQueue = ConcurrentLinkedQueue<ApiMessage>()
@ -30,7 +34,7 @@ object MessageHandler {
}
private fun createThread(clear: Boolean = true): HttpStreamConnection {
println("Attempting to open bridge connection.")
instance.info("Attempting to open bridge connection.")
return HttpStreamConnection(
{
HttpGet(cfg!!.connect.url + "/api/stream").apply {
@ -46,11 +50,23 @@ object MessageHandler {
rcvQueue.add(
ApiMessage.decode(it)
)
// println("Received: " + it)
instance.debug("Received: " + it)
},
{
println("Bridge connection closed!")
instance.warn("Bridge connection closed!")
connected = false
connecting = false
},
{ success ->
connecting = false
if (success) {
instance.info("connected successfully")
connectErrors = 0
connected = true
} else {
connectErrors++
connected = false
}
},
clear
)
@ -58,27 +74,32 @@ object MessageHandler {
fun transmit(msg: ApiMessage) {
if (connected && streamConnection.isAlive) {
println("Transmitting: " + msg)
instance.debug("Transmitting: " + msg)
transmitMessage(msg)
}
}
fun stop() {
println("Closing bridge connection...")
enabled = false
instance.info("Closing bridge connection...")
// MessageHandler.transmit(ApiMessage(text="bridge closing", username="Server"))
streamConnection.close()
try {
streamConnection.close()
} catch(e: SocketException) {
instance.error("exception: $e")
}
}
fun start(clear: Boolean = true): Boolean {
fun start(clear: Boolean = true) {
enabled = true
if (!connected)
streamConnection = createThread(clear)
if (!streamConnection.isAlive) {
connecting = true
streamConnection.start()
// MessageHandler.transmit(ApiMessage(text="bridge connected", username="Server"))
connected = true
return connected
}
return connected
}
private fun transmitMessage(message: ApiMessage) {
@ -93,17 +114,36 @@ object MessageHandler {
val response = client.execute(post)
val code = response.statusLine.statusCode
if (code != 200) {
System.err.println("Server returned $code for $post")
instance.error("Server returned $code for $post")
sendErrors++
if (sendErrors > 5) {
instance.error("caught too many errors, closing bridge")
stop()
}
}
sendErrors = 0
} catch (e: IOException) {
System.err.println("sending message caused $e")
instance.error("sending message caused $e")
sendErrors++
if (sendErrors > 5) {
System.err.println("caught too many errors, closing bridge")
instance.error("caught too many errors, closing bridge")
stop()
}
}
}
fun checkConnection(tick: Int) {
if (enabled && tick % 20 == 0 && !MessageHandler.connected && !connecting) {
if (connectErrors > 5) {
instance.fatal("caught too many errors, closing bridge")
stop()
return
}
instance.info("Trying to reconnect")
MessageHandler.start(clear = false)
}
}
}

View File

@ -1,6 +1,5 @@
package matterlink.bridge
//import matterlink.logger
import matterlink.instance
import matterlink.bridge.command.BridgeCommandRegistry
import matterlink.config.cfg
@ -11,14 +10,13 @@ object ServerChatHandler {
* This method must be called every server tick with no arguments.
*/
fun writeIncomingToChat(tick: Int) {
instance.reconnect(tick)
MessageHandler.checkConnection(tick)
if (MessageHandler.rcvQueue.isNotEmpty())
println("incoming: " + MessageHandler.rcvQueue.toString())
instance.debug("incoming: " + MessageHandler.rcvQueue.toString())
val nextMessage = MessageHandler.rcvQueue.poll()
if (nextMessage != null && nextMessage.gateway == cfg!!.connect.gateway) {
if (!nextMessage.text.isBlank()) {
val section = '\u00A7'
val message = when (nextMessage.event) {
"user_action" -> nextMessage.format(cfg!!.formatting.action)
"" -> {
@ -30,11 +28,11 @@ object ServerChatHandler {
val user = nextMessage.username
val text = nextMessage.text
val json = nextMessage.encode()
println("Threw out message with unhandled event: ${nextMessage.event}")
println(" Message contents:")
println(" User: $user")
println(" Text: $text")
println(" JSON: $json")
instance.debug("Threw out message with unhandled event: ${nextMessage.event}")
instance.debug(" Message contents:")
instance.debug(" User: $user")
instance.debug(" Text: $text")
instance.debug(" JSON: $json")
return
}
}

View File

@ -1,7 +1,7 @@
package matterlink.bridge.command
import matterlink.config.cfg
//import matterlink.logger
import matterlink.instance
import java.util.*
object BridgeCommandRegistry {
@ -23,7 +23,7 @@ object BridgeCommandRegistry {
fun register(cmd: IBridgeCommand): Boolean {
if (cmd.name.isBlank() || commandMap.containsKey(cmd.name)) {
System.out.println("Failed to register command: '${cmd.name}'")
instance.info("Failed to register command: '${cmd.name}'")
return false
}
commandMap[cmd.name] = cmd

View File

@ -2,7 +2,7 @@ package matterlink.handlers
import matterlink.bridge.ApiMessage
import matterlink.bridge.MessageHandler
//import matterlink.logger
import matterlink.instance
object ChatHandler {
fun handleChat(user: String, msg: String) {
@ -12,7 +12,7 @@ object ChatHandler {
username = user,
text = message
))
else -> println("WARN: dropped blank message by '$user'")
else -> instance.warn("WARN: dropped blank message by '$user'")
}
}
}

View File

@ -4,6 +4,8 @@
"description": "Minecraft Server Matterbridge link",
"version": "${version}",
"mcversion": "${mcversion}",
"url": "https://github.com/elytra/MatterLink",
"authorList":["Arcanitor", "NikkyAi"],
"credits": "Blame Nikky for talking me into this."
"credits": "Blame Nikky for talking me into this.",
"dependencies": ["forgelin"]
}]

View File

@ -1 +1 @@
mod_version = 1.2
mod_version = 1.2.1