forked from sirDonovan/Cassius
-
Notifications
You must be signed in to change notification settings - Fork 0
/
commands.js
210 lines (202 loc) · 8.99 KB
/
commands.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
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
/**
* Commands
* Cassius - https://github.com/sirDonovan/Cassius
*
* This file contains the base commands for Cassius.
*
* @license MIT license
*/
'use strict';
// Users who use the settour command when a tournament is already
// scheduled will be added here and prompted to reuse the command.
// This prevents accidentally overwriting a scheduled tournament.
/**@type {Map<string, string>} */
let overwriteWarnings = new Map();
/**@type {{[k: string]: Command | string}} */
let commands = {
// Developer commands
js: 'eval',
eval: function (target, room, user) {
if (!user.isDeveloper()) return;
try {
target = eval(target);
this.say(JSON.stringify(target));
} catch (e) {
this.say(e.name + ": " + e.message);
}
},
// General commands
about: function (target, room, user) {
if (!(room instanceof Users.User) && !user.hasRank(room, '+')) return;
this.say(Config.username + " code by sirDonovan: https://github.com/sirDonovan/Cassius");
},
help: function (target, room, user) {
if (!(room instanceof Users.User) && !user.hasRank(room, '+')) return;
if (!Config.guide) return this.say("There is no guide available.");
this.say(Users.self.name + " guide: " + Config.guide);
},
mail: function (target, room, user) {
if (!(room instanceof Users.User) || !Config.allowMail) return;
let targets = target.split(',');
if (targets.length < 2) return this.say("Please use the following format: .mail user, message");
let to = Tools.toId(targets[0]);
if (!to || to.length > 18 || to === Users.self.id || to.startsWith('guest')) return this.say("Please enter a valid username");
let message = targets.slice(1).join(',').trim();
let id = Tools.toId(message);
if (!id) return this.say("Please include a message to send.");
if (message.length > (258 - user.name.length)) return this.say("Your message is too long.");
let database = Storage.getDatabase('global');
if (to in database.mail) {
let queued = 0;
for (let i = 0, len = database.mail[to].length; i < len; i++) {
if (Tools.toId(database.mail[to][i].from) === user.id) queued++;
}
if (queued >= 3) return this.say("You have too many messages queued for " + Users.add(targets[0]).name + ".");
} else {
database.mail[to] = [];
}
database.mail[to].push({time: Date.now(), from: user.name, text: message});
Storage.exportDatabase('global');
this.say("Your message has been sent to " + Users.add(targets[0]).name + "!");
},
// Game commands
signups: 'creategame',
creategame: function (target, room, user) {
if (room instanceof Users.User) return;
if (!user.hasRank(room, '+')) return;
if (!Config.games || !Config.games.includes(room.id)) return this.say("Games are not enabled for this room.");
let format = Games.getFormat(target);
if (!format || format.inheritOnly) return this.say("The game '" + target + "' was not found.");
if (format.internal) return this.say(format.name + " cannot be started manually.");
Games.createGame(format, room);
if (!room.game) return;
room.game.signups();
},
start: 'startgame',
startgame: function (target, room, user) {
if (!(room instanceof Users.User) && !user.hasRank(room, '+')) return;
if (room.game) room.game.start();
},
cap: 'capgame',
capgame: function (target, room, user) {
if (room instanceof Users.User || !room.game || !user.hasRank(room, '+')) return;
let cap = parseInt(target);
if (isNaN(cap)) return this.say("Please enter a valid player cap.");
if (cap < room.game.minPlayers) return this.say(room.game.name + " must have at least " + room.game.minPlayers + " players.");
if (room.game.maxPlayers && cap > room.game.maxPlayers) return this.say(room.game.name + " cannot have more than " + room.game.maxPlayers + " players.");
room.game.playerCap = cap;
this.say("The game will automatically start at **" + cap + "** players!");
},
end: 'endgame',
endgame: function (target, room, user) {
if (!(room instanceof Users.User) && !user.hasRank(room, '+')) return;
if (room.game) room.game.forceEnd();
},
join: 'joingame',
joingame: function (target, room, user) {
if (room instanceof Users.User || !room.game) return;
room.game.join(user);
},
leave: 'leavegame',
leavegame: function (target, room, user) {
if (room instanceof Users.User || !room.game) return;
room.game.leave(user);
},
// Storage commands
bits: 'points',
points: function (target, room, user) {
if (room !== user) return;
let targetUserid = target ? Tools.toId(target) : user.id;
/**@type {Array<string>} */
let points = [];
user.rooms.forEach((rank, room) => {
if (!(room.id in Storage.databases) || !('leaderboard' in Storage.databases[room.id])) return;
if (targetUserid in Storage.databases[room.id].leaderboard) points.push("**" + room.id + "**: " + Storage.databases[room.id].leaderboard[targetUserid].points);
});
if (!points.length) return this.say((target ? target.trim() + " does not" : "You do not") + " have points on any leaderboard.");
this.say(points.join(" | "));
},
// Tournament commands
tour: 'tournament',
tournament: function (target, room, user) {
if (room instanceof Users.User || !Config.tournaments || !Config.tournaments.includes(room.id)) return;
if (!target) {
if (!user.hasRank(room, '+')) return;
if (!room.tour) return this.say("I am not currently tracking a tournament in this room.");
let info = "``" + room.tour.name + " tournament info``";
if (room.tour.startTime) {
return this.say(info + ": **Time**: " + Tools.toDurationString(Date.now() - room.tour.startTime) + " | **Remaining players**: " + room.tour.getRemainingPlayerCount() + '/' + room.tour.totalPlayers);
} else if (room.tour.started) {
return this.say(info + ": **Remaining players**: " + room.tour.getRemainingPlayerCount() + '/' + room.tour.totalPlayers);
} else {
return this.say(info + ": " + room.tour.playerCount + " player" + (room.tour.playerCount > 1 ? "s" : ""));
}
} else {
if (!user.hasRank(room, '%')) return;
let targets = target.split(',');
let cmd = Tools.toId(targets[0]);
let format;
switch (cmd) {
case 'end':
this.say("/tour end");
break;
case 'start':
this.say("/tour start");
break;
default:
format = Tools.getFormat(cmd);
if (!format) return this.say('**Error:** invalid format.');
if (!format.playable) return this.say(format.name + " cannot be played, please choose another format.");
let cap;
if (targets[1]) {
cap = parseInt(Tools.toId(targets[1]));
if (cap < 2 || cap > Tournaments.maxCap || isNaN(cap)) return this.say("**Error:** invalid participant cap.");
}
this.say("/tour new " + format.id + ", elimination, " + (cap ? cap + ", " : "") + (targets.length > 2 ? ", " + targets.slice(2).join(", ") : ""));
}
}
},
settour: 'settournament',
settournament: function (target, room, user) {
if (room instanceof Users.User || !Config.tournaments || !Config.tournaments.includes(room.id) || !user.hasRank(room, '%')) return;
if (room.id in Tournaments.tournamentTimers) {
let warned = overwriteWarnings.has(room.id) && overwriteWarnings.get(room.id) === user.id;
if (!warned) {
overwriteWarnings.set(room.id, user.id);
return this.say("A tournament has already been scheduled in this room. To overwrite it, please reuse this command.");
}
overwriteWarnings.delete(room.id);
}
let targets = target.split(',');
if (targets.length < 2) return this.say(Config.commandCharacter + "settour - tier, time, cap (optional)");
let format = Tools.getFormat(targets[0]);
if (!format) return this.say('**Error:** invalid format.');
if (!format.playable) return this.say(format.name + " cannot be played, please choose another format.");
let date = new Date();
let currentTime = (date.getHours() * 60 * 60 * 1000) + (date.getMinutes() * (60 * 1000)) + (date.getSeconds() * 1000) + date.getMilliseconds();
let targetTime = 0;
if (targets[1].includes(':')) {
let parts = targets[1].split(':');
let hours = parseInt(parts[0]);
let minutes = parseInt(parts[1]);
if (isNaN(hours) || isNaN(minutes)) return this.say("Please enter a valid time.");
targetTime = (hours * 60 * 60 * 1000) + (minutes * (60 * 1000));
} else {
let hours = parseFloat(targets[1]);
if (isNaN(hours)) return this.say("Please enter a valid time.");
targetTime = currentTime + (hours * 60 * 60 * 1000);
}
let timer = targetTime - currentTime;
if (timer <= 0) timer += 24 * 60 * 60 * 1000;
Tournaments.setTournamentTimer(room, timer, format.id, targets[2] ? parseInt(targets[2]) : 0);
this.say("The " + format.name + " tournament is scheduled for " + Tools.toDurationString(timer) + ".");
},
canceltour: 'canceltournament',
canceltournament: function (target, room, user) {
if (room instanceof Users.User || !Config.tournaments || !Config.tournaments.includes(room.id) || !user.hasRank(room, '%')) return;
if (!(room.id in Tournaments.tournamentTimers)) return this.say("There is no tournament scheduled for this room.");
clearTimeout(Tournaments.tournamentTimers[room.id]);
this.say("The scheduled tournament was canceled.");
},
};
module.exports = commands;