disconnecting bridges works again
also refactored the configuration
This commit is contained in:
parent
a70c54f804
commit
932c98da69
|
@ -7,7 +7,6 @@ import civilengineering.eventhandlers.ChatMessageHandler
|
|||
import civilengineering.eventhandlers.DeathEventHandler
|
||||
import civilengineering.eventhandlers.UserActionHandler
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
import net.minecraftforge.common.config.Configuration
|
||||
import net.minecraftforge.fml.common.Mod
|
||||
import net.minecraftforge.fml.common.event.*
|
||||
import org.apache.logging.log4j.Level
|
||||
|
@ -15,7 +14,6 @@ import org.apache.logging.log4j.Logger
|
|||
import org.apache.logging.log4j.message.SimpleMessageFactory
|
||||
import org.apache.logging.log4j.simple.SimpleLogger
|
||||
import org.apache.logging.log4j.util.PropertiesUtil
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
const val MODID = "civilengineering"
|
||||
|
@ -31,8 +29,6 @@ const val VERSION = "0.0.1"
|
|||
modLanguageAdapter = "net.shadowfacts.forgelin.KotlinAdapter"
|
||||
)
|
||||
object CivilEngineering {
|
||||
var config: Configuration = Configuration()
|
||||
|
||||
//create fake logger to get around Nullability
|
||||
var logger: Logger = SimpleLogger("",
|
||||
Level.OFF,
|
||||
|
@ -50,10 +46,7 @@ object CivilEngineering {
|
|||
logger = event.modLog
|
||||
logger.info("loading logger")
|
||||
|
||||
CivilEngineering.logger.info("Reading bridge blueprints...")
|
||||
val directory = event.modConfigurationDirectory
|
||||
config = Configuration(File(directory.path, "CivilEngineering.cfg"))
|
||||
Config.readConfig()
|
||||
CivilEngineeringConfig(event.modConfigurationDirectory)
|
||||
}
|
||||
|
||||
@Mod.EventHandler
|
||||
|
@ -63,9 +56,6 @@ object CivilEngineering {
|
|||
|
||||
@Mod.EventHandler
|
||||
fun postInit(event: FMLPostInitializationEvent) {
|
||||
if (config.hasChanged()) {
|
||||
config.save()
|
||||
}
|
||||
// MinecraftForge.EVENT_BUS.register(ServerChatHelper::class.java)
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package civilengineering
|
||||
|
||||
import net.minecraftforge.common.config.Configuration
|
||||
import java.io.File
|
||||
|
||||
var cfg: CivilEngineeringConfig? = null
|
||||
|
||||
class CivilEngineeringConfig(file: File) {
|
||||
private val CATEGORY_RELAY_OPTIONS = "relay"
|
||||
private val CATEGORY_CONNECTION = "connection"
|
||||
|
||||
val relay: RelayOptions
|
||||
val connect: ConnectOptions
|
||||
|
||||
data class RelayOptions(
|
||||
val deathEvents: Boolean,
|
||||
val advancements: Boolean,
|
||||
val joinLeave: Boolean
|
||||
)
|
||||
|
||||
data class ConnectOptions(
|
||||
val url: String,
|
||||
val authToken: String,
|
||||
val gateway: String
|
||||
)
|
||||
|
||||
init {
|
||||
CivilEngineering.logger.info("Reading bridge blueprints...")
|
||||
val config = Configuration(file.resolve("CivilEngineering.cfg"))
|
||||
|
||||
config.addCustomCategoryComment(CATEGORY_RELAY_OPTIONS, "Relay options")
|
||||
config.addCustomCategoryComment(CATEGORY_CONNECTION, "Connection settings")
|
||||
|
||||
relay = RelayOptions(
|
||||
deathEvents = config.getBoolean(
|
||||
"deathEvents",
|
||||
CATEGORY_RELAY_OPTIONS,
|
||||
false,
|
||||
"Relay player death messages"
|
||||
),
|
||||
advancements = config.getBoolean(
|
||||
"advancements",
|
||||
CATEGORY_RELAY_OPTIONS,
|
||||
false,
|
||||
"Relay player advancements [NOT IMPLEMENTED]"
|
||||
),
|
||||
joinLeave = config.getBoolean(
|
||||
"joinLeave",
|
||||
CATEGORY_RELAY_OPTIONS,
|
||||
false,
|
||||
"Relay when a player joins or leaves the game [NOT IMPLEMENTED]"
|
||||
)
|
||||
)
|
||||
|
||||
connect = ConnectOptions(
|
||||
url = config.getString(
|
||||
"connectURL",
|
||||
CATEGORY_CONNECTION,
|
||||
"http://example.com:1234",
|
||||
"The URL or IP address of the bridge server"
|
||||
),
|
||||
authToken = config.getString(
|
||||
"authToken",
|
||||
CATEGORY_CONNECTION,
|
||||
"",
|
||||
"Auth token used to connect to the bridge server"
|
||||
),
|
||||
gateway = config.getString(
|
||||
"gateway",
|
||||
CATEGORY_CONNECTION,
|
||||
"minecraft",
|
||||
"MatterBridge gateway"
|
||||
)
|
||||
)
|
||||
|
||||
if (config.hasChanged()) config.save()
|
||||
|
||||
cfg = this
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
package civilengineering
|
||||
|
||||
import net.minecraftforge.common.config.Configuration
|
||||
import org.apache.logging.log4j.Level
|
||||
|
||||
object Config {
|
||||
private val CATEGORY_RELAY_OPTIONS = "relay_options"
|
||||
private val CATEGORY_CONNECTION = "connection"
|
||||
|
||||
var relayDeathEvents = false
|
||||
var relayAdvancements = false //unused for now
|
||||
var relayJoinLeave = false
|
||||
|
||||
var connectURL = "http://localhost"
|
||||
var authToken = ""
|
||||
var gateway = ""
|
||||
|
||||
fun readConfig() {
|
||||
|
||||
val config = CivilEngineering.config
|
||||
try {
|
||||
config.load()
|
||||
initConfig(config)
|
||||
} catch (e: Exception) {
|
||||
CivilEngineering.logger!!.log(Level.ERROR, "Could not read config file!", e)
|
||||
} finally {
|
||||
if (config.hasChanged()) {
|
||||
config.save()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initConfig(cfg: Configuration) {
|
||||
cfg.addCustomCategoryComment(CATEGORY_RELAY_OPTIONS, "Relay options")
|
||||
cfg.addCustomCategoryComment(CATEGORY_CONNECTION, "Connection settings")
|
||||
relayDeathEvents = cfg.getBoolean(
|
||||
"relayDeathEvents",
|
||||
CATEGORY_RELAY_OPTIONS,
|
||||
false,
|
||||
"Relay player death messages"
|
||||
)
|
||||
relayAdvancements = cfg.getBoolean(
|
||||
"relayAdvancements",
|
||||
CATEGORY_RELAY_OPTIONS,
|
||||
false,
|
||||
"Relay player advancements [NOT IMPLEMENTED]"
|
||||
)
|
||||
relayJoinLeave = cfg.getBoolean(
|
||||
"relayJoinLeave",
|
||||
CATEGORY_RELAY_OPTIONS,
|
||||
false,
|
||||
"Relay when a player joins or leaves the game [NOT IMPLEMENTED]"
|
||||
)
|
||||
|
||||
connectURL = cfg.getString(
|
||||
"connectURL",
|
||||
CATEGORY_CONNECTION,
|
||||
"http://example.com:1234",
|
||||
"The URL or IP address of the bridge server, ex. http://example.com:1234"
|
||||
)
|
||||
authToken = cfg.getString(
|
||||
"auth_token",
|
||||
CATEGORY_CONNECTION,
|
||||
"",
|
||||
"Auth token used to connect to the bridge server"
|
||||
)
|
||||
gateway = cfg.getString(
|
||||
"gateway",
|
||||
CATEGORY_CONNECTION,
|
||||
"",
|
||||
"MatterBridge gateway"
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
package civilengineering.bridge
|
||||
|
||||
import civilengineering.Config
|
||||
import civilengineering.cfg
|
||||
import com.google.gson.Gson
|
||||
|
||||
data class ApiMessage(
|
||||
val username: String = "",
|
||||
val text: String = "",
|
||||
val gateway: String = Config.gateway,
|
||||
val gateway: String = cfg!!.connect.gateway,
|
||||
val channel: String = "",
|
||||
val userid: String = "",
|
||||
val avatar: String = "",
|
||||
|
@ -17,10 +17,6 @@ data class ApiMessage(
|
|||
val id: String = ""
|
||||
// val Extra: Any? = null
|
||||
) {
|
||||
fun encode(): String {
|
||||
return gson.toJson(this)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val gson = Gson()
|
||||
|
||||
|
@ -28,4 +24,8 @@ data class ApiMessage(
|
|||
return gson.fromJson(json, ApiMessage::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
fun encode(): String {
|
||||
return gson.toJson(this)
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package civilengineering.bridge
|
||||
|
||||
import java.io.InputStreamReader
|
||||
import java.net.HttpURLConnection
|
||||
|
||||
/**
|
||||
* Created by nikky on 20/01/18.
|
||||
* @author Nikky
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
class CancellableConnectionFollowThread(httpConnClosure: () -> HttpURLConnection, private val mhandler: (String) -> Unit) : Thread() {
|
||||
private val cancelGuard = Object()
|
||||
private var waitingOnNetwork = true
|
||||
var cancelled = false
|
||||
private set
|
||||
private val httpConn = httpConnClosure()
|
||||
|
||||
override fun run() {
|
||||
try {
|
||||
httpConn.allowUserInteraction = false
|
||||
httpConn.instanceFollowRedirects = true
|
||||
httpConn.requestMethod = "GET"
|
||||
|
||||
InputStreamReader(httpConn.inputStream).useLines {
|
||||
it.forEach {
|
||||
synchronized(cancelGuard) {
|
||||
if (cancelled) return
|
||||
waitingOnNetwork = false
|
||||
}
|
||||
mhandler(it)
|
||||
synchronized(cancelGuard) {
|
||||
if (cancelled) return
|
||||
waitingOnNetwork = true
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
} finally {
|
||||
httpConn.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
fun abort() {
|
||||
synchronized(cancelGuard) {
|
||||
httpConn.disconnect()
|
||||
cancelled = true
|
||||
if (waitingOnNetwork) stop()
|
||||
}
|
||||
join()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package civilengineering.bridge;
|
||||
|
||||
import civilengineering.CivilEngineering
|
||||
import org.apache.http.client.methods.HttpGet
|
||||
import org.apache.http.impl.client.HttpClients
|
||||
import java.io.InputStream
|
||||
import java.net.SocketException
|
||||
|
||||
val BUFFER_SIZE = 1000
|
||||
|
||||
class HttpStreamConnection(private val getClosure: () -> HttpGet, private val mhandler: (String) -> Unit) : Thread() {
|
||||
private val client = HttpClients.createDefault()
|
||||
private var stream: InputStream? = null
|
||||
|
||||
val get = getClosure()
|
||||
var cancelled: Boolean = false
|
||||
private set
|
||||
|
||||
|
||||
override fun run() {
|
||||
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 {
|
||||
while (!get.isAborted) {
|
||||
val chars = content.read(buf)
|
||||
CivilEngineering.logger.debug("incoming: $chars ")
|
||||
if (chars > 0) {
|
||||
buffer += String(buf.dropLast(buf.count() - chars).toByteArray())
|
||||
|
||||
CivilEngineering.logger.info(buffer)
|
||||
|
||||
while (buffer.contains("\n")) {
|
||||
val line = buffer.substringBefore("\n")
|
||||
buffer = buffer.substringAfter("\n")
|
||||
mhandler(line)
|
||||
}
|
||||
} else if (chars < 0) {
|
||||
break
|
||||
}
|
||||
}
|
||||
} catch (e: SocketException) {
|
||||
|
||||
}
|
||||
CivilEngineering.logger.info("closing stream")
|
||||
content.close()
|
||||
CivilEngineering.logger.info("thread finished")
|
||||
return
|
||||
}
|
||||
|
||||
fun close() {
|
||||
cancelled = true
|
||||
get.abort()
|
||||
join()
|
||||
println("killed thread")
|
||||
|
||||
}
|
||||
}
|
|
@ -1,24 +1,31 @@
|
|||
package civilengineering.bridge
|
||||
|
||||
import civilengineering.CivilEngineering
|
||||
import civilengineering.Config
|
||||
import java.io.DataOutputStream
|
||||
import civilengineering.cfg
|
||||
import org.apache.http.client.methods.HttpGet
|
||||
import org.apache.http.client.methods.HttpPost
|
||||
import org.apache.http.client.methods.HttpRequestBase
|
||||
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.HttpURLConnection
|
||||
import java.net.URL
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
|
||||
|
||||
object MessageHandler {
|
||||
|
||||
private fun createThread(): CancellableConnectionFollowThread {
|
||||
fun HttpRequestBase.authorize() {
|
||||
if (cfg!!.connect.authToken.isNotEmpty() && getHeaders("Authorization").isEmpty())
|
||||
setHeader("Authorization", "Bearer " + cfg!!.connect.authToken)
|
||||
}
|
||||
|
||||
private fun createThread(): HttpStreamConnection {
|
||||
CivilEngineering.logger.info("building bridge")
|
||||
return CancellableConnectionFollowThread(
|
||||
return HttpStreamConnection(
|
||||
{
|
||||
CivilEngineering.logger.info("Connecting to bridge server @ " + Config.connectURL)
|
||||
val httpConn = URL(Config.connectURL + "/api/stream").openConnection() as HttpURLConnection
|
||||
if (Config.authToken.isNotBlank())
|
||||
httpConn.setRequestProperty("Authorization", "Bearer ${Config.authToken}")
|
||||
httpConn
|
||||
HttpGet(cfg!!.connect.url + "/api/stream").apply {
|
||||
authorize()
|
||||
}
|
||||
},
|
||||
{
|
||||
rcvQueue.add(
|
||||
|
@ -29,9 +36,7 @@ object MessageHandler {
|
|||
)
|
||||
}
|
||||
|
||||
private var cancellableThread: CancellableConnectionFollowThread = createThread()
|
||||
|
||||
private var xmitQueue = ConcurrentLinkedQueue<ApiMessage>()
|
||||
private var streamConnection: HttpStreamConnection = createThread()
|
||||
|
||||
var rcvQueue = ConcurrentLinkedQueue<ApiMessage>()
|
||||
|
||||
|
@ -43,16 +48,17 @@ object MessageHandler {
|
|||
fun stop() {
|
||||
CivilEngineering.logger.info("bridge closing")
|
||||
// MessageHandler.transmit(ApiMessage(text="bridge closing", username="Server"))
|
||||
cancellableThread.abort()
|
||||
streamConnection.close()
|
||||
|
||||
CivilEngineering.logger.info("bridge closed")
|
||||
}
|
||||
|
||||
fun start(): Boolean {
|
||||
if (cancellableThread.cancelled) {
|
||||
cancellableThread = createThread()
|
||||
if (streamConnection.cancelled) {
|
||||
streamConnection = createThread()
|
||||
}
|
||||
if (!cancellableThread.isAlive) {
|
||||
cancellableThread.start()
|
||||
if (!streamConnection.isAlive) {
|
||||
streamConnection.start()
|
||||
// MessageHandler.transmit(ApiMessage(text="bridge connected", username="Server"))
|
||||
return true
|
||||
}
|
||||
|
@ -62,31 +68,16 @@ object MessageHandler {
|
|||
@Throws(IOException::class)
|
||||
private fun transmitMessage(message: ApiMessage) {
|
||||
//open a connection
|
||||
val url = URL(Config.connectURL + "/api/message")
|
||||
val urlConnection = url.openConnection()
|
||||
val connection = urlConnection as HttpURLConnection
|
||||
val client = HttpClients.createDefault()
|
||||
val post = HttpPost(cfg!!.connect.url + "/api/message")
|
||||
|
||||
//configure the connection
|
||||
connection.allowUserInteraction = false
|
||||
connection.instanceFollowRedirects = true
|
||||
connection.setRequestProperty("Content-Type", "application/json")
|
||||
connection.requestMethod = "POST"
|
||||
if (Config.authToken.isNotEmpty()) {
|
||||
connection.setRequestProperty("Authorization", "Bearer " + Config.authToken)
|
||||
}
|
||||
post.entity = StringEntity(message.encode(), ContentType.APPLICATION_JSON)
|
||||
post.authorize()
|
||||
|
||||
//encode the ApiMessage for sending
|
||||
val json = message.encode()
|
||||
|
||||
//send the message
|
||||
connection.doOutput = true
|
||||
val post = DataOutputStream(connection.outputStream)
|
||||
post.writeBytes(json)
|
||||
post.flush()
|
||||
post.close()
|
||||
|
||||
if (connection.responseCode != 200) {
|
||||
CivilEngineering.logger.error("Server returned " + connection.responseCode)
|
||||
val response = client.execute(post)
|
||||
val code = response.statusLine.statusCode
|
||||
if (code != 200) {
|
||||
CivilEngineering.logger.error("Server returned $code for $post")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package civilengineering.eventhandlers
|
||||
|
||||
import civilengineering.Config
|
||||
import civilengineering.bridge.ApiMessage
|
||||
import civilengineering.bridge.MessageHandler
|
||||
import civilengineering.cfg
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraftforge.event.entity.living.LivingDeathEvent
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
||||
|
@ -10,7 +10,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
|||
class DeathEventHandler {
|
||||
@SubscribeEvent
|
||||
fun handleLivingDeathEvent(event: LivingDeathEvent) {
|
||||
if (Config.relayDeathEvents) {
|
||||
if (cfg!!.relay.deathEvents) {
|
||||
val entity = event.entityLiving
|
||||
if (entity is EntityPlayer) {
|
||||
val message = entity.getCombatTracker().deathMessage.unformattedText
|
||||
|
|
Loading…
Reference in New Issue