diff --git a/1.10.2/src/main/kotlin/matterlink/EventHandler.kt b/1.10.2/src/main/kotlin/matterlink/EventHandler.kt index ffd2be3..dc525ec 100644 --- a/1.10.2/src/main/kotlin/matterlink/EventHandler.kt +++ b/1.10.2/src/main/kotlin/matterlink/EventHandler.kt @@ -103,6 +103,7 @@ object EventHandler { @SubscribeEvent @JvmStatic fun serverTickEvent(e: TickEvent.ServerTickEvent) { - TickHandler.handleTick() + if(e.phase == TickEvent.Phase.END) + TickHandler.handleTick() } } \ No newline at end of file diff --git a/1.11.2/src/main/kotlin/matterlink/EventHandler.kt b/1.11.2/src/main/kotlin/matterlink/EventHandler.kt index 68a1065..691fc9c 100644 --- a/1.11.2/src/main/kotlin/matterlink/EventHandler.kt +++ b/1.11.2/src/main/kotlin/matterlink/EventHandler.kt @@ -104,6 +104,7 @@ object EventHandler { @SubscribeEvent @JvmStatic fun serverTickEvent(e: TickEvent.ServerTickEvent) { - TickHandler.handleTick() + if(e.phase == TickEvent.Phase.END) + TickHandler.handleTick() } } \ No newline at end of file diff --git a/1.12.2/src/main/kotlin/matterlink/EventHandler.kt b/1.12.2/src/main/kotlin/matterlink/EventHandler.kt index eddb396..ceb42ed 100644 --- a/1.12.2/src/main/kotlin/matterlink/EventHandler.kt +++ b/1.12.2/src/main/kotlin/matterlink/EventHandler.kt @@ -96,6 +96,7 @@ object EventHandler { @SubscribeEvent @JvmStatic fun serverTickEvent(e: TickEvent.ServerTickEvent) { - TickHandler.handleTick() + if(e.phase == TickEvent.Phase.END) + TickHandler.handleTick() } } \ No newline at end of file diff --git a/1.7.10/src/main/kotlin/matterlink/EventHandler.kt b/1.7.10/src/main/kotlin/matterlink/EventHandler.kt index e05c639..0442801 100644 --- a/1.7.10/src/main/kotlin/matterlink/EventHandler.kt +++ b/1.7.10/src/main/kotlin/matterlink/EventHandler.kt @@ -96,6 +96,7 @@ object EventHandler { //FORGE-DEPENDENT @SubscribeEvent fun serverTickEvent(e: TickEvent.ServerTickEvent) { - TickHandler.handleTick() + if(e.phase == TickEvent.Phase.END) + TickHandler.handleTick() } } \ No newline at end of file diff --git a/README.md b/README.md index 9dea6f3..588dd11 100644 --- a/README.md +++ b/README.md @@ -5,59 +5,68 @@ A MatterBridge endpoint for MC servers! THIS MOD REQUIRES YOU TO ALSO RUN A MATTERBRIDGE RELAY https://github.com/42wim/matterbridge -requires api section to be setup along these lines +Chat with us on IRC: [#matterbridge @ irc.esper.net](irc://irc.esper.net/matterbridge) + +Requires the matterbridge config api section to be setup along these lines: ``` [api] [api.local] BindAddress="0.0.0.0:4242" # or listen only to localhost: 127.0.0.1:4242 - - #Bearer token used for authentication - #curl -H "Authorization: Bearer testtoken" http://localhost:4343/api/messages - #OPTIONAL (no authorization if token is empty) Token="mytoken" - Buffer=1000 - RemoteNickFormat="{NICK}" - ShowJoinPart = true ``` ## Features -* Individually configurable relaying of player deaths, achievements/advancements, server join, and server leave -* Configurable bridge commands sent from chat to MC: +* Custom bridge commands, including passthrough to MC! + Default commands: `help, tps, list, seed, uptime` + +Commands are specified in JSON format as follows: +Passthrough command (executes the configured command as if from the MC server console) +```json +{ + "alias": "tps", + "type": "PASSTHROUGH", + "execute": "forge tps", + "permLevel": 0, + "help": "Print server tps", + "allowArgs": false +} ``` -help: Lists all commands with no arguments, - or displays help for a command -players: Lists online players -uptime: Print server uptime +Response command +```json +{ + "alias": "uptime", + "type": "RESPONSE", + "response": "{uptime}", + "permLevel": 1, + "help": "Print server uptime", + "allowArgs": false +} +``` +* Command permissions! +Higher numbers mean more permissions. Configured on a network-by-network basis. +For IRC, this is your hostmask. +For Discord, this is your userid (NOT the four-digit number.) +```json +{ + "irc.esper": { + "~DaMachina@hostname.com":1000 + } +} ``` * Edit and reload the config file without restarting the server! ``` /config -Connect or disconnect the bridge, -or cycle the connection and reload the config file + connect: Connects the MC chat to the MatterBridge server + disconnect: Disconnects the chat from the MatterBridge server + reload: Disconnects, reloads the config and custom command files, + then reconnects. ``` -* Pass through commands to MineCraft! Fully configurable. -``` -# MC commands that can be executed through the bridge -# Separate bridge command and MC command with '=', -# separate multiple values with spaces -# [default: [tps=forge tps]] -S:commandMapping < - tps=forge tps - > -``` -This default example allows you to run `/forge tps` on the server by typing `$tps` in the chat -(replace $ with whatever you've configured as the command prefix). - -**WARNING: There is *NO* permissions checking of any kind for command passthrough! -Do not configure passthrough for any commands you would not be comfortable -with anyone on your IRC/Discord/etc. executing!** - ## Downloads @@ -65,22 +74,26 @@ https://github.com/elytra/MatterLink/releases https://ci.elytradev.com/job/elytra/job/MatterLink/job/master/lastSuccessfulBuild/ - may be unstable +https://minecraft.curseforge.com/projects/matterlink + ## Dependencies - forgelin: https://minecraft.curseforge.com/projects/shadowfacts-forgelin ## Setup +Now you just need to run MatterBridge on the server, the default configuration works with the provided sample. Install matterbridge and try out the basic sample: ``` go get github.com/42wim/matterbridge -mv matterbridge-sample.toml matterbridge.tom +mv matterbridge-sample.toml matterbridge.toml matterbridge ``` -Now you just need to run MatterBridge on the server, the default configuration works with the provided sample. +now start the server with matterlink (and forgelin )in the mods folder -and then [RTFM!!!](https://github.com/42wim/matterbridge#configuration) + +and then [RTFM!!!](https://github.com/42wim/matterbridge#configuration) and configure all your needed gateways, endpoints etc powered by wishful thinking \ No newline at end of file diff --git a/core/src/main/kotlin/matterlink/bridge/HttpStreamConnection.kt b/core/src/main/kotlin/matterlink/bridge/HttpStreamConnection.kt index 6028b22..693f5f2 100644 --- a/core/src/main/kotlin/matterlink/bridge/HttpStreamConnection.kt +++ b/core/src/main/kotlin/matterlink/bridge/HttpStreamConnection.kt @@ -49,8 +49,10 @@ class HttpStreamConnection(private val rcvQueue: ConcurrentLinkedQueue() private set @@ -103,14 +104,18 @@ object MessageHandler { fun checkConnection() { if (enabled && !streamConnection.connected && !streamConnection.connecting) { - if (connectErrors > 5) { + if (connectErrors >= 10) { instance.fatal("Caught too many errors, closing bridge") stop("Interrupting connection to matterbridge API due to accumulated connection errors") return } - instance.info("Trying to reconnect") - MessageHandler.start(clear = false, message = "Reconnecting to matterbridge API after connection error") + if (reconnectCoodown <= 0) { + instance.info("Trying to reconnect") + MessageHandler.start(clear = false, message = "Reconnecting to matterbridge API after connection error") + } else { + reconnectCoodown-- + } } } } diff --git a/core/src/main/kotlin/matterlink/config/CommandConfig.kt b/core/src/main/kotlin/matterlink/config/CommandConfig.kt index 575a819..af2a22e 100644 --- a/core/src/main/kotlin/matterlink/config/CommandConfig.kt +++ b/core/src/main/kotlin/matterlink/config/CommandConfig.kt @@ -35,10 +35,10 @@ object CommandConfig { ), CustomCommand( alias = "uptime", - type = CommandType.PASSTHROUGH, + type = CommandType.RESPONSE, permLevel = 1, response = "{uptime}", - help = "Print server world seed", + help = "Print server uptime", allowArgs = false ) ) diff --git a/core/src/main/kotlin/matterlink/handlers/TickHandler.kt b/core/src/main/kotlin/matterlink/handlers/TickHandler.kt index d6bb7f2..83642b9 100644 --- a/core/src/main/kotlin/matterlink/handlers/TickHandler.kt +++ b/core/src/main/kotlin/matterlink/handlers/TickHandler.kt @@ -12,16 +12,15 @@ import matterlink.update.UpdateChecker object TickHandler { private var totalTicks = 0 private var accumulator = 0 - private const val updateInterval = 12 * 60 * 20 + private const val updateInterval = 12 * 60 * 60 * 20 fun handleTick() { totalTicks++ - if (totalTicks % 20 == 0) { + if (totalTicks % 100 == 0) { MessageHandler.checkConnection() } ServerChatHandler.writeIncomingToChat() - if(accumulator++ > updateInterval) { accumulator -= updateInterval UpdateChecker.run() diff --git a/matterbridge-sample.toml b/matterbridge-sample.toml index e323875..83d2153 100644 --- a/matterbridge-sample.toml +++ b/matterbridge-sample.toml @@ -9,7 +9,7 @@ #You can configure multiple servers "[irc.name]" or "[irc.name2]" #In this example we use [irc.freenode] #REQUIRED -[irc.freenode] +[irc.esper] #irc server to connect to. #REQUIRED Server="irc.esper.net:6697" @@ -117,6 +117,10 @@ ReplaceMessages=[ ["cat","dog"] ] #optional (default empty) ReplaceNicks=[ ["user--","user"] ] +#extra label that can be used in the RemoteNickFormat +#optional (default empty) +Label="" + #RemoteNickFormat defines how remote users appear on this bridge #The string "{NICK}" (case sensitive) will be replaced by the actual nick / username. #The string "{BRIDGE}" (case sensitive) will be replaced by the sending bridge @@ -161,6 +165,10 @@ Buffer=1000 #OPTIONAL (no authorization if token is empty) Token="" +#extra label that can be used in the RemoteNickFormat +#optional (default empty) +Label="minecraft" + #RemoteNickFormat defines how remote users appear on this bridge #The string "{NICK}" (case sensitive) will be replaced by the actual nick / username. #The string "{BRIDGE}" (case sensitive) will be replaced by the sending bridge @@ -168,8 +176,6 @@ Token="" #OPTIONAL (default empty) RemoteNickFormat="{NICK}" - - ################################################################### #General configuration ################################################################### @@ -232,56 +238,11 @@ name="minecraft" ##OPTIONAL (default false) enable=true - #API example + # API [[gateway.inout]] account="api.minecraft" channel="api" - #To send data to the api: - #curl -XPOST -H 'Content-Type: application/json' -d '{"text":"test","username":"randomuser","gateway":"gateway1"}' http://localhost:4242/api/message - #To read from the api: - #curl http://localhost:4242/api/messages - - #[[gateway.in]] specifies the account and channels we will receive messages from. - #The following example bridges between mattermost and irc [[gateway.inout]] account="irc.freenode" - channel="#matterlink" - -# #OPTIONAL - only used for IRC protocol at the moment -# [gateway.in.options] -# #OPTIONAL - your irc channel key -# key="yourkey" - - -# #[[gateway.inout]] can be used when then channel will be used to receive from -# #and send messages to -# [[gateway.inout]] -# account="irc.freenode" -# channel="#matterlink-testing" - -# #OPTIONAL - only used for IRC protocol at the moment -# [gateway.out.options] -# #OPTIONAL - your irc channel key -# key="yourkey" - -# [[gateway.inout]] -# account="discord.game" -# channel="mygreatgame" -# -# #OPTIONAL - webhookurl only works for discord (it needs a different URL for each cahnnel) -# [gateway.inout.options] -# webhookurl=""https://discordapp.com/api/webhooks/123456789123456789/C9WPqExYWONPDZabcdef-def1434FGFjstasJX9pYht73y" - - - -##If you want to do a 1:1 mapping between protocols where the channelnames are the same -##e.g. slack and mattermost you can use the samechannelgateway configuration -##the example configuration below send messages from channel testing on mattermost to -##channel testing on slack and vice versa. (and for the channel testing2 and testing3) -# -#[[samechannelgateway]] -# name="samechannel1" -# enable = false -# accounts = [ "mattermost.work","slack.hobby" ] -# channels = [ "testing","testing2","testing3"] \ No newline at end of file + channel="#matterlink" \ No newline at end of file