-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbot.js
More file actions
291 lines (246 loc) · 18.7 KB
/
bot.js
File metadata and controls
291 lines (246 loc) · 18.7 KB
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/*******************************************************************
* Author: Shawn Ray
* Date: 7/9/2020
* Github: https://github.com/Asmodasis
* Discord: https://discord.js.org/#/
* Filename: bot.js
* Description: This file is the main driver program for the discord
bot loot-assistant, whose purpose is to assist in the
loot council management and distribution of loot in
the popular game World of Warcraft.
*******************************************************************/
const Discord = require('discord.js'); // The class client for connecting a bot to discord.
const fs = require('fs');
require('dotenv').config();
// External javascript files for the help functions.
const getClassFromMention = require('./get_class.js');
const helpMessage = require('./help.js');
const bot_file = require('./bot_file.js');
const addDate = require('./add_date.js');
const takeAttendance = require('./take_attendance.js');
const addPlayer = require('./add_player.js');
const editPlayer = require('./edit_player.js');
const readPlayer = require('./read_player.js');
const readClass= require('./read_class.js');
const removePlayer = require('./remove_player.js');
const removeRaid = require('./remove_raid.js');
const onlyOfficer = require('./conditionals.js');
const commandPrefix = '~'; // The prefix to initialize the commands
let raidFileName;
let raidDate;
const bot = new Discord.Client(); // Create a Client instance with our bot token.
bot.on('ready', () => { // When the bot is connected and ready, log to console.
console.log('Loot Assistant is connected and ready.');
bot.user.setPresence({
game: {
name: 'Loot Assistant',
type: 'WATCHING'
},
status: 'online'
})
raidFileName = 'NO FILE'; // when the bot turns on, there is no file
raidDate = undefined; // no raid date either. These are commands the user must implement
});
// Every time a message is sent anywhere the bot is present,
// this event will fire and and check the valid commands and display
// the appropriate responses
bot.on('message', async (msg) => {
const guild = bot.guilds.cache.get(process.env.guildID); // generate the guild list
var time;
if (msg.author.bot) return; // if the author of the message is a bot, don't do anything
if(!msg.content.startsWith(process.env.commandPrefix)) return; // only accept commands in the form of the prefix
if (!msg.guild) return; // won't respond to direct messages
if(!(msg.channel.id == process.env.testChannel || msg.channel.id == process.env.botChannel)) return;
let args = msg.content.split(' ');
let firstUser = (msg.mentions.users == null) ? null : msg.mentions.users.first() // enforce null conditions
let member = new Promise ((resolve, reject) => {
resolve(guild.members.fetch(firstUser)); // don't accept rejections
});
for(var i = 0; i < args.length; ++i){
let command = args[i].toLowerCase(); // force all arguments to lowercase for easy of use
await member.then((values) => {
let commandUsr = ''; // the user beind referenced
let commandString = ''; // The items in question
for(var pos = i+2; pos < args.length; ++pos){ // Start at the position in the command list when
if(args[pos].startsWith(process.env.commandPrefix)) break; // all commands shall start with '~' if they do, it's not an (item)
commandString += (args[pos]) + ' '; // append all string literals into an (item)
}
switch(command) { // check the valid commands
case process.env.commandPrefix+"help":
case process.env.commandPrefix+"h":
helpMessage.helpMessage(msg.author); // display the help message to the invokers private message
break;
case process.env.commandPrefix+"loot-history":
case process.env.commandPrefix+"lh":
if(args[i+1] == undefined) throw 'Please be sure to mention a player or a class for this command.';
var nick = (values.nickname == null) ? null : values.nickname; // enforce null conditions
if((nick == null)){ // if the nickname is null, the user doesn't have one
if(getClassFromMention.getClassFromMention(args[i+1], bot) == null) commandUsr = firstUser.username;
}else{
if(getClassFromMention.getClassFromMention(args[i+1], bot) == null) commandUsr = nick;
}
if(args[i+2] !== undefined && args[i+2].toLowerCase() == 'all'){
if(getClassFromMention.getClassFromMention(args[i+1], bot) == null){
readPlayer.readPlayer(raidFileName + '.txt', commandUsr, raidDate, 'all');
}
else readClass.readClass(raidFileName + '.txt', getClassFromMention.getClassFromMention(args[i+1], bot), raidDate, 'all');
}else if (args[i+2] > 0 ){
if(getClassFromMention.getClassFromMention(args[i+1], bot) == null){
readPlayer.readPlayer(raidFileName + '.txt', commandUsr, raidDate, args[i+2]);
}
else readClass.readClass(raidFileName + '.txt', getClassFromMention.getClassFromMention(args[i+1], bot), raidDate, args[i+2]);
}else {
if(getClassFromMention.getClassFromMention(args[i+1], bot) == null){
readPlayer.readPlayer(raidFileName + '.txt', commandUsr, raidDate, 4);
}
else readClass.readClass(raidFileName + '.txt', getClassFromMention.getClassFromMention(args[i+1], bot), raidDate, 4);
}
break;
//////////////////////////// Officer commands /////////////////////////////
//These commands will have limited access, only officers and programmers may use these commands
case process.env.commandPrefix+"loot":
case process.env.commandPrefix+"l":
onlyOfficer.onlyOfficer(msg);
if(args[i+1] == undefined) throw 'Please be sure to mention a player for this command.';
var nick = (values.nickname == null) ? null : values.nickname; // enforce null conditions
if((nick == null)){ // if the nickname is null, the user doesn't have one
commandUsr = firstUser.username;
}else{
commandUsr = nick;
}
editPlayer.editPlayer(raidFileName + '.txt', commandUsr, raidDate, commandString, false);
break;
case process.env.commandPrefix+"retract":
case process.env.commandPrefix+"r":
onlyOfficer.onlyOfficer(msg);
if(args[i+1] == undefined) throw 'Please be sure to mention a player for this command.';
var nick = (values.nickname == null) ? null : values.nickname; // enforce null conditions
if((nick == null)){ // if the nickname is null, the user doesn't have one
commandUsr = firstUser.username;
}else{
commandUsr = nick;
}
editPlayer.editPlayer(raidFileName + '.txt', commandUsr, raidDate, commandString, true);
break;
case process.env.commandPrefix+"add-player":
case process.env.commandPrefix+"ap":
onlyOfficer.onlyOfficer(msg);
if(args[i+1] == undefined) throw 'Please be sure to mention a player for this command.';
if(args[i+2] == undefined) throw 'Please be sure to mention a player\'s class for this command.';
var nick = (values.nickname == null) ? null : values.nickname; // enforce null conditions
if((nick == null)){ // if the nickname is null, the user doesn't have one
commandUsr = firstUser.username;
}else{
commandUsr = nick;
}
if(getClassFromMention.getClassFromMention(args[i+2], bot) == null) throw 'Can not add a player without a class!';
else addPlayer.addPlayer(raidFileName + '.txt', commandUsr, getClassFromMention.getClassFromMention(args[i+2], bot));
break;
case process.env.commandPrefix+"remove-player":
case process.env.commandPrefix+"rp":
onlyOfficer.onlyOfficer(msg);
if(args[i+1] == undefined) throw 'Please be sure to mention a player for this command.';
var nick = (values.nickname == null) ? null : values.nickname; // enforce null conditions
if((nick == null)){ // if the nickname is null, the user doesn't have one
commandUsr = firstUser.username;
}else{
commandUsr = nick;
}
removePlayer.removePlayer(raidFileName + '.txt', commandUsr);
break;
case process.env.commandPrefix+"attendance":
case process.env.commandPrefix+"a":
onlyOfficer.onlyOfficer(msg);
if(args[i+1] == undefined) throw 'Please be sure to mention a player for this command.';
var nick = (values.nickname == null) ? null : values.nickname; // enforce null conditions
if((nick == null)){ // if the nickname is null, the user doesn't have one
commandUsr = firstUser.username;
}else{
commandUsr = nick;
}
takeAttendance.takeAttendance(raidFileName + '.txt', commandUsr, raidDate)
break;
case process.env.commandPrefix+"set-raid": // requires raid date
case process.env.commandPrefix+"sr":
onlyOfficer.onlyOfficer(msg);
if(args[i+1] == undefined) throw 'Please be sure to type in a specific raid date.';
raidDate = args[i+1];
throw 'The Currently set raid date for modification purposes is ' + raidDate + ' be sure to either change this or ~create-raid {date attribute} by next raid.' ;
break;
case process.env.commandPrefix+"what-raid": // requires nothing extra
case process.env.commandPrefix+"wr":
throw ('The Currently set raid date for operations is ' + raidDate + ' if you wish to change this, either use create-raid or set-raid commands.') ;
break;
case process.env.commandPrefix+"create-raid": // requires raid date
case process.env.commandPrefix+"cr":
case process.env.commandPrefix+"c":
onlyOfficer.onlyOfficer(msg);
if(args[i+1] == undefined) throw 'Please be sure to type in a specific raid date.';
raidDate = args[i+1];
addDate.addDate(raidFileName + '.txt', args[i+1])
break;
case process.env.commandPrefix+"delete-raid": // requires raid date
case process.env.commandPrefix+"dr":
case process.env.commandPrefix+"d":
onlyOfficer.onlyOfficer(msg);
if(raidFileName == 'NO FILE') throw 'Can\'t delete a raid without a specified raid file. Please set-file first.';
if(args[i+1] == undefined) throw 'Please be sure to type in a specific raid date.';
removeRaid.removeRaid(raidFileName + '.txt', args[i+1])
break;
case process.env.commandPrefix+"set-file": // requires file name
onlyOfficer.onlyOfficer(msg);
if(args[i+1] == undefined) throw 'Please be sure to type in a specific raid file, no extensions.';
if(fs.existsSync(args[i+1]+'.txt')){
raidFileName = args[i+1];
throw ('The file ' + raidFileName + ' has been set for the lifespan of the bot. To change this please ~set-file again');
}else
throw ('That file does not exist, please use ~create-file {filename} first, no extensions.\nThen check the file name with ~what-file.\nThank you.');
break;
case process.env.commandPrefix+"what-file": // requires nothing extra
onlyOfficer.onlyOfficer(msg);
if(raidFileName == 'NO FILE')
msg.channel.send('There is not a currently set file, please use ~create-file {filename} if the file doesn\'t exist. \nThen use ~set-file {filename} to set the file for the lifespan of the bot.');
else
msg.channel.send('The currently set file to read from is : '+ raidFileName + '.txt' );
break;
case process.env.commandPrefix+"create-file": // requires file name
onlyOfficer.onlyOfficer(msg)
if(args[i+1] == undefined) throw 'Please be sure to type in a specific raid file, no extensions.';
raidFileName = args[i+1];
if(args[i+2] == undefined)
bot_file.createNewFile(args[i+1] + '.txt', null, null);
else
bot_file.createNewFile(args[i+1] + '.txt', args[i+2], args[i+3]);
break;
case process.env.commandPrefix+"backup-file": // requires nothing extra
onlyOfficer.onlyOfficer(msg);
if(raidFileName == 'NO FILE')
throw('There is not a currently set file, please use ~create-file {filename} if the file doesn\'t exist. \nThen use ~set-file {filename} to set the file for the lifespan of the bot.');
bot_file.backupFile(raidFileName + '.txt', raidFileName+'_backup.txt');
break;
case process.env.commandPrefix+"restore-file": // requires nothing extra
onlyOfficer.onlyOfficer(msg);
if(raidFileName == 'NO FILE')
throw('There is not a currently set file, please use ~create-file {filename} if the file doesn\'t exist. \nThen use ~set-file {filename} to set the file for the lifespan of the bot.');
bot_file.restoreBackup(raidFileName + '.txt', raidFileName+'_backup.txt');
break;
case process.env.commandPrefix+"delete-file": // requires file name
onlyOfficer.onlyOfficer(msg);
if(args[i+1] == undefined) throw 'Please be sure to type in a specific raid file, no extensions.';
if(fs.existsSync(args[i+1]+'.txt')){
fs.unlink(args[i+1]+'.txt', function (err) { // delete the previous backup file
if (err) throw err;
msg.channel.send('File has been Deleted.\nFile has been reset, please create a new file if needed\nPlease do ~set-file {filename} in order to keep using this bot.');
});
}
raidFileName = 'NO FILE';
break;
//////////////////////////// Officer commands /////////////////////////////
default:
}
}).catch((err) => { console.log(err); if(!(err == null)) msg.channel.send(err);}); // Catch any errors or messages, display to the console and the discord bot
}});
bot.on('error', err => {
console.warn(err);
});
bot.login(process.env.botToken); // connects the bot to the discord server.