summary refs log tree commit diff homepage
path: root/index.js
blob: fae323c3b9a9e314cf91bdf6f663e7af38d4261a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
'use strict'

const Discord = require('discord.js')
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 configFile = (process.argv.length > 2) ? process.argv[2] : './config.json'

console.log('[INFO] Using configuration file:', configFile)

const c = require(configFile)

const fixUsername = (username) => username.replace(/(ยง[A-Z-a-z0-9])/g, '')

function makeDiscordMessage (username, message) {
  // make a discord message string by formatting the configured template with the given parameters
  return c.DISCORD_MESSAGE_TEMPLATE
    .replace('%username%', username)
    .replace('%message%', message)
}

function makeDiscordWebhook (username, message) {
  return {
    username: username,
    content: message,
    'avatar_url': `https://minotar.net/helm/${username}/256.png`
  }
}

function makeMinecraftTellraw (message) {
  // same as the discord side but with discord message parameters
  const username = emojiStrip(message.author.username)
  const discriminator = message.author.discriminator
  const text = emojiStrip(message.cleanContent)

  return c.MINECRAFT_TELLRAW_TEMPLATE
    .replace('%username%', username)
    .replace('%discriminator%', discriminator)
    .replace('%message%', text)
}

const debug = c.DEBUG
const shulker = new Discord.Client()

app.use(function (request, response, next) {
  request.rawBody = ''
  request.setEncoding('utf8')

  request.on('data', function (chunk) {
    request.rawBody += chunk
  })

  request.on('end', function () {
    next()
  })
})

shulker.on('ready', function () {
  app.post(c.WEBHOOK, function (request, response) {
    const body = request.rawBody
    console.log('[INFO] Recieved ' + body)
    const re = new RegExp(c.REGEX_MATCH_CHAT_MC)
    const ignored = new RegExp(c.REGEX_IGNORED_CHAT)
    if (!ignored.test(body)) {
      const bodymatch = body.match(re)
      const username = fixUsername(bodymatch[1])
      const message = bodymatch[2]
      if (debug) {
        console.log('[DEBUG] Username: ' + bodymatch[1])
        console.log('[DEBUG] Text: ' + bodymatch[2])
      }
      if (c.USE_WEBHOOKS) {
        const webhook = makeDiscordWebhook(username, message)
        axios.post(c.WEBHOOK_URL, {
          ...webhook
        }, {
          headers: {
            'Content-Type': 'application/json'
          }
        })
      } else {
        // find the channel
        const channel = shulker.channels.find((ch) => ch.id === c.DISCORD_CHANNEL_ID && ch.type === 'text')
        channel.send(makeDiscordMessage(username, message))
      }
    }
    response.send('')
  })
})

shulker.on('message', function (message) {
  if (message.channel.id === c.DISCORD_CHANNEL_ID && message.channel.type === 'text') {
    if (c.USE_WEBHOOKS && message.webhookID) {
      return // ignore webhooks if using a webhook
    }
    if (message.author.id !== shulker.user.id) {
      if (message.attachments.length) { // skip images/attachments
        return
      }
      const client = new Rcon(c.MINECRAFT_SERVER_RCON_IP, c.MINECRAFT_SERVER_RCON_PORT) // create rcon client
      client.auth(c.MINECRAFT_SERVER_RCON_PASSWORD, function () { // only authenticate when needed
        client.command('tellraw @a ' + makeMinecraftTellraw(message), function (err) {
          if (err) {
            console.log('[ERROR]', err)
          }
          client.close() // close the rcon connection
        })
      })
    }
  }
})

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)
  })
}