This repository has been archived by the owner on Mar 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbot.js
167 lines (157 loc) · 5.74 KB
/
bot.js
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
const Discord = require('discord.io')
const logger = require('winston')
const request = require('request')
const uuidv4 = require('uuid/v4')
const auth = require('./auth.json')
const fs = require('fs')
const saveFile = './.saves' // file containing saved game names and UUIDs
const baseURL = 'http://zork.ruf.io/' // the API base URL
let saves = {} // {channel ID: {saved game ID : UUID}}
let activeUUIDs = {} // {channel ID: active UUID}
let activeMsg = {} // {channel ID: true or false}
// configure logger settings
logger.remove(logger.transports.Console)
logger.add(logger.transports.Console, {
colorize: true
})
logger.level = 'debug'
// load the saved game data
fs.readFile(saveFile, (err, data) => {
if (err) {
logger.error(err)
} else {
saves = JSON.parse(data)
}
})
// initialize discord bot
let bot = new Discord.Client({
token: auth.token,
autorun: true
})
// log when bot connects
bot.on('ready', function (evt) {
logger.info('Connected')
logger.info('Logged in as: ')
logger.info(bot.username + ' - (' + bot.id + ')')
})
function sendMessage (userID, channelID, message) {
bot.sendMessage({
to: channelID,
message: '<@' + userID + '>\n' + message
})
activeMsg[channelID] = false
}
// react when message is sent in the server chat
bot.on('message', function (user, userID, channelID, message, evt) {
// send a command to the Zork API and say the response
function sendCommand (cmd) {
request(baseURL + activeUUIDs[channelID] + '>' + cmd, function (error, response, body) {
// handle API error
if (error) {
sendMessage(userID, channelID, 'Error recieving Zork game data, please try again')
return
}
// say response as long as it exists
let msg = ''
try {
msg = JSON.parse(body)['msg'].substring(1)
} catch (err) {
msg = 'Something seems to have gone wrong... try again'
}
sendMessage(userID, channelID, msg)
})
}
// message to say if no games are currently loaded
function noneLoaded () {
sendMessage(userID, channelID, "No games are currently loaded\nTry '!zload' to see the current saved games")
}
// handle zork command
if (message.substring(0, 2) === '!z') {
// only accept messages after the current message has been responded to
if (channelID in activeMsg && activeMsg[channelID] === true) {
return
}
activeMsg[channelID] = true
// if it's the special bot command '!zload' then handle accordingly
if (message.substring(2, 3) === 'l' || message.substring(2, 6) === 'load') {
// get the saves that correspond to the specific channel
let localSaves = {}
if (channelID in saves) {
localSaves = saves[channelID]
}
// split message by spaces
let args = []
if (message.substring(2, 6) === 'load') {
args = message.toLowerCase().substring(6).split(/\s+/)
} else {
args = message.toLowerCase().substring(3).split(/\s+/)
}
// if there's no arguments then just list the saved games
if (args.length < 2) {
let keys = Object.keys(localSaves)
if (keys.length === 0) {
sendMessage(userID, channelID, "No games found\nTry '!zload New Game Name' to create a new game with the name 'New Game Name'")
} else {
// create a nicely formatted saved game list
let savedList = ''
for (let i = 0; i < keys.length; i++) {
savedList += '\t' + (i + 1).toString() + '. ' + keys[i] + '\n'
}
sendMessage(userID, channelID, 'Current saved games:\n' + savedList + "\nTo load '" + keys[0] + "', try '!zload 1' or '!zload " + keys[0] + "'")
}
// try to load the specified saved game
} else {
let savedGameName = args.slice(1).join(' ')
// if the game is specified by an index, transform it into the string name equivalent
let index = parseInt(savedGameName)
if (!isNaN(index) && isFinite(savedGameName)) {
let keys = Object.keys(localSaves)
if (keys.length < index || index <= 0) {
sendMessage(userID, channelID, "I can't find that game, try again")
return
}
savedGameName = keys[index - 1]
}
// load the saved game
if (savedGameName in localSaves) {
activeUUIDs[channelID] = localSaves[savedGameName]
// create a new game
} else {
activeUUIDs[channelID] = uuidv4()
localSaves[savedGameName] = activeUUIDs[channelID]
saves[channelID] = localSaves
fs.writeFile(saveFile, JSON.stringify(saves), function (err) {
if (err) {
sendMessage(userID, channelID, 'There was a problem creating your game, try again')
}
logger.info('Game ' + savedGameName + ' successfully created!')
})
}
// send the 'look' command for the newly loaded/created game
sendCommand('look')
}
return
// try to quit the current game
} else if (message.substring(2, 3) === 'q' || message.substring(2, 6) === 'quit') {
if (channelID in activeUUIDs) {
delete activeUUIDs[channelID]
sendMessage(userID, channelID, 'Thanks for playing!')
// handle if no game is currently loaded
} else {
noneLoaded()
}
return
// get the list of commands
} else if (message.substring(2, 3) === 'h' || message.substring(2, 6) === 'help') {
sendMessage(userID, channelID, 'Commands:\n\t!zl[oad] [saved game]\n\t!zq[uit]\n\t!zh[elp]\n\t!z [command]')
return
}
// handle if no game is currently loaded
if (!(channelID in activeUUIDs)) {
noneLoaded()
// send the message as a command for the current game
} else {
sendCommand(message.substring(2))
}
}
})