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