summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--README.md12
-rw-r--r--config.json8
-rw-r--r--index.js117
-rw-r--r--package.json3
-rw-r--r--yarn.lock5
5 files changed, 111 insertions, 34 deletions
diff --git a/README.md b/README.md
index 43c2141..5917a3c 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
 > Connects [Discord](https://discordapp.com/) and [Minecraft](https://minecraft.net) Servers by sending messages back and forth without any mods or plugins.
 
 ## In Action
-![discord-irc](http://i.thedestruc7i0n.ca/I5anbg.gif)
+![discord-mc](http://i.thedestruc7i0n.ca/I5anbg.gif)
 
 ## Installation and usage
 
@@ -27,7 +27,8 @@ $ yarn
 $ yarn start
 ```
 
-Run the following on your server hosting (in a screen/tmux session or background process, make sure to replace your `YOUR_URL` with whatever URL you're using (`localhost:8000` if running on the same server and default config) and `PATH_TO_MINECRAFT_SERVER_INSTALL` with the path to the Minecraft server installation, such as `/usr/home/minecraft_server/`):
+If you are running this locally, check the `IS_LOCAL_FILE` flag and related options below. Otherwise, perform the following command: 
+On your server hosting (in a screen/tmux session or background process, make sure to replace your `YOUR_URL` with whatever URL you're using (`localhost:8000` if running on the same server and default config) and `PATH_TO_MINECRAFT_SERVER_INSTALL` with the path to the Minecraft server installation, such as `/usr/home/minecraft_server/`):
 
 ``` sh
 tail -F /PATH_TO_MINECRAFT_SERVER_INSTALL/logs/latest.log | grep --line-buffered ": <" | while read x ; do echo -ne $x | curl -X POST -d @- http://YOUR_URL/minecraft/hook ; done
@@ -42,15 +43,22 @@ You can also easily Deploy to Heroku and the like, just be sure to edit `YOUR_UR
 ```js
 {
     "PORT": 8000, /* Port you want to run the webserver for the hook on */
+    
     "USE_WEBHOOKS": true, /* If you want to use snazzy webhooks */
     "WEBHOOK_URL": "DISCORD_WEBHOOK_URL_HERE", /* Be sure to create a webhook in the channel settings and place it here! */
     "DISCORD_TOKEN": "<12345>", /* Discord bot token. [Click here](https://discordapp.com/developers/applications/me) to create you application and add a bot to it. */
     "DISCORD_CHANNEL_ID": "<channel>", /* Discord channel ID for for the discord bot. Enable developer mode in your Discord client, then right click channel and select "Copy ID". */
     "DISCORD_MESSAGE_TEMPLATE": "`%username%`:%message%", /* Message template to display in Discord */
+    
     "MINECRAFT_SERVER_RCON_IP": "127.0.0.1", /* Minecraft server IP (make sure you have enabled rcon) */
     "MINECRAFT_SERVER_RCON_PORT": <1-65535>, /* Minecraft server rcon port */
     "MINECRAFT_SERVER_RCON_PASSWORD": "<your password>", /* Minecraft server rcon password */
     "MINECRAFT_TELLRAW_TEMPLATE": "[{\"color\": \"white\", \"text\": \"<%username%> %message%\"}]", /* Tellraw template to display in Minecraft */
+    
+    "IS_LOCAL_FILE": false, /* should tail the local file, may be a little buggy. please report any you find */
+    "LOCAL_FILE_PATH": "/usr/home/minecraft_server/logs/latest.log", /* the path to the local file if specified */
+    "ALLOW_USER_MENTIONS": false, /* should replace @mentions with the mention in discord */
+    
     "WEBHOOK": "/minecraft/hook", /* Web hook, where to send the log to */
     "REGEX_MATCH_CHAT_MC": "\\[Server thread/INFO\\]: <(.*)> (.*)", /* What to match for chat (best to leave as default) */
     "REGEX_IGNORED_CHAT": "packets too frequently", /* What to ignore, you can put any regex for swear words for example and it will  be ignored */
diff --git a/config.json b/config.json
index 6f2dee1..e845cf1 100644
--- a/config.json
+++ b/config.json
@@ -1,14 +1,22 @@
 {
     "PORT": 8000,
+
     "USE_WEBHOOKS": true,
     "WEBHOOK_URL": "DISCORD_WEBHOOK_URL_HERE",
     "DISCORD_TOKEN": "TOKEN_HERE",
     "DISCORD_CHANNEL_ID": "1234",
     "DISCORD_MESSAGE_TEMPLATE": "`%username%`: %message%",
+
     "MINECRAFT_SERVER_RCON_IP": "127.0.0.1",
     "MINECRAFT_SERVER_RCON_PORT": 25575,
     "MINECRAFT_SERVER_RCON_PASSWORD": "password",
     "MINECRAFT_TELLRAW_TEMPLATE": "[{\"color\": \"white\", \"text\": \"<%username%> %message%\"}]",
+
+    "IS_LOCAL_FILE": false,
+    "LOCAL_FILE_PATH": "/usr/home/minecraft_server/logs/latest.log",
+
+    "ALLOW_USER_MENTIONS": false,
+
     "WEBHOOK": "/minecraft/hook",
     "REGEX_MATCH_CHAT_MC": "\\[Server thread/INFO\\]: <([^>]*)> (.*)",
     "REGEX_IGNORED_CHAT": "packets too frequently",
diff --git a/index.js b/index.js
index fae323c..e7b399e 100644
--- a/index.js
+++ b/index.js
@@ -5,8 +5,8 @@ const Rcon = require('./lib/rcon.js')
 const express = require('express')
 const axios = require('axios')
 const emojiStrip = require('emoji-strip')
-const app = express()
-const http = require('http').Server(app)
+const { Tail } = require('tail')
+const fs = require('fs')
 
 const configFile = (process.argv.length > 2) ? process.argv[2] : './config.json'
 
@@ -14,16 +14,45 @@ console.log('[INFO] Using configuration file:', configFile)
 
 const c = require(configFile)
 
-const fixUsername = (username) => username.replace(/(§[A-Z-a-z0-9])/g, '')
+let app = null
+let tail = null
+
+function fixUsername (username) {
+  return username.replace(/(§[A-Z-a-z0-9])/g, '')
+}
+
+// replace mentions with discriminator with the actual mention
+function replaceDiscordMentions (message) {
+  if (c.ALLOW_USER_MENTIONS) {
+    const possibleMentions = message.match(/@(\S+)/gim)
+    if (possibleMentions) {
+      for (let mention of possibleMentions) {
+        const mentionParts = mention.split('#')
+        let username = mentionParts[0].replace('@', '')
+        if (mentionParts.length > 1) {
+          const user = shulker.users.find(user => user.username === username && user.discriminator === mentionParts[1])
+          if (user) {
+            message = message.replace(mention, '<@' + user.id + '>')
+          }
+        }
+      }
+    }
+  }
+  return message
+}
 
 function makeDiscordMessage (username, message) {
   // make a discord message string by formatting the configured template with the given parameters
+  message = replaceDiscordMentions(message)
+
   return c.DISCORD_MESSAGE_TEMPLATE
     .replace('%username%', username)
     .replace('%message%', message)
 }
 
 function makeDiscordWebhook (username, message) {
+  message = replaceDiscordMentions(message)
+
   return {
     username: username,
     content: message,
@@ -36,32 +65,70 @@ function makeMinecraftTellraw (message) {
   const username = emojiStrip(message.author.username)
   const discriminator = message.author.discriminator
   const text = emojiStrip(message.cleanContent)
+  // hastily use JSON to encode the strings
+  const variables = JSON.parse(JSON.stringify({ username, discriminator, text }))
 
   return c.MINECRAFT_TELLRAW_TEMPLATE
-    .replace('%username%', username)
-    .replace('%discriminator%', discriminator)
-    .replace('%message%', text)
+    .replace('%username%', variables.username)
+    .replace('%discriminator%', variables.discriminator)
+    .replace('%message%', variables.text)
 }
 
 const debug = c.DEBUG
 const shulker = new Discord.Client()
 
-app.use(function (request, response, next) {
-  request.rawBody = ''
-  request.setEncoding('utf8')
+function initApp () {
+  // run a server if not local
+  if (!c.IS_LOCAL_FILE) {
+    app = express()
+    const http = require('http').Server(app)
 
-  request.on('data', function (chunk) {
-    request.rawBody += chunk
-  })
+    app.use(function (request, response, next) {
+      request.rawBody = ''
+      request.setEncoding('utf8')
 
-  request.on('end', function () {
-    next()
-  })
-})
+      request.on('data', function (chunk) {
+        request.rawBody += chunk
+      })
+
+      request.on('end', function () {
+        next()
+      })
+    })
+
+    const serverport = process.env.PORT || c.PORT
+
+    http.listen(serverport, function () {
+      console.log('[INFO] Bot listening on *:' + serverport)
+    })
+  } else {
+    if (fs.existsSync(c.LOCAL_FILE_PATH)) {
+      console.log('[INFO] Using configuration for local file at "' + c.LOCAL_FILE_PATH + '"')
+      tail = new Tail(c.LOCAL_FILE_PATH)
+    } else {
+      throw new Error('[ERROR] Local file not found at "' + c.LOCAL_FILE_PATH + '"')
+    }
+  }
+}
+
+function watch (callback) {
+  if (c.IS_LOCAL_FILE) {
+    tail.on('line', function (data) {
+      // ensure that this is a message
+      if (data.indexOf(': <') !== -1) {
+        callback(data)
+      }
+    })
+  } else {
+    app.post(c.WEBHOOK, function (request, response) {
+      callback(request.rawBody)
+      response.send('')
+    })
+  }
+}
 
 shulker.on('ready', function () {
-  app.post(c.WEBHOOK, function (request, response) {
-    const body = request.rawBody
+  watch(function (body) {
     console.log('[INFO] Recieved ' + body)
     const re = new RegExp(c.REGEX_MATCH_CHAT_MC)
     const ignored = new RegExp(c.REGEX_IGNORED_CHAT)
@@ -88,7 +155,6 @@ shulker.on('ready', function () {
         channel.send(makeDiscordMessage(username, message))
       }
     }
-    response.send('')
   })
 })
 
@@ -114,16 +180,5 @@ shulker.on('message', function (message) {
   }
 })
 
+initApp()
 shulker.login(c.DISCORD_TOKEN)
-
-const ipaddress = process.env.OPENSHIFT_NODEJS_IP || process.env.IP || '127.0.0.1'
-const serverport = process.env.OPENSHIFT_NODEJS_PORT || process.env.PORT || c.PORT
-if (process.env.OPENSHIFT_NODEJS_IP !== undefined) {
-  http.listen(serverport, ipaddress, function () {
-    console.log('[INFO] Bot listening on *:' + serverport)
-  })
-} else {
-  http.listen(serverport, function () {
-    console.log('[INFO] Bot listening on *:' + c.PORT)
-  })
-}
diff --git a/package.json b/package.json
index 081c541..0b03fca 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,8 @@
     "axios": "^0.18.0",
     "discord.js": "^11.4.2",
     "emoji-strip": "^1.0.1",
-    "express": "^4.16.4"
+    "express": "^4.16.4",
+    "tail": "^2.0.1"
   },
   "devDependencies": {
     "standard": "^12.0.1"
diff --git a/yarn.lock b/yarn.lock
index fda7a7c..fd581ee 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1703,6 +1703,11 @@ table@^4.0.3:
     slice-ansi "1.0.0"
     string-width "^2.1.1"
 
+tail@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/tail/-/tail-2.0.1.tgz#f4cd9d514512e77d0eb2aaacd5520d578fe20271"
+  integrity sha512-9vPPjlv63kuIHLKVR7T65ey3CeukjcWA3f/JnfPyFd1KPSqWMh3qWyz2M5T7osAYQNYlaYtddovJ/X27tL0w1w==
+
 text-table@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"