mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-08-22 00:54:31 -05:00
Improvements to command broadcast API
- Method `this.runBroadcast()` has been split from `this.canBroadcast()`. It's now the only method handling command-usage and intended as the main API for synchronous commands. Async commands will execute both separately. Note that the `suppressMessage` parameter is now passed to `runBroadcast`. - The semantics of `broadcasting` have been similarly split. `this,broadcastMessage` will be set to a truthy value when `this.canBroadcast` is run. `this,broadcasting` will only be set to `true` once `this.runBroadcast` is executed.
This commit is contained in:
@@ -17,7 +17,7 @@ This is called an alias: it makes it so `/ip` does the same thing as
|
||||
But to actually define a command, it's a function:
|
||||
|
||||
avatars: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox('You can <button name="avatars">change ' +
|
||||
'your avatar</button> by clicking on it in the <button ' +
|
||||
'name="openOptions"><i class="icon-cog"></i> Options' +
|
||||
@@ -129,7 +129,7 @@ Commands have access to the following functions:
|
||||
|
||||
if (!this.can('potd')) return false;
|
||||
|
||||
`this.canBroadcast(checkOnly)`
|
||||
`this.runBroadcast()`
|
||||
* Signifies that a message can be broadcast, as long as the user has
|
||||
permission to. This will check to see if the user used `!command`
|
||||
instead of `/command`. If so, it will check to see if the user has
|
||||
@@ -137,14 +137,13 @@ Commands have access to the following functions:
|
||||
not. Otherwise, it will add the message to the room, and turn on the
|
||||
flag `this.broadcasting`, so that `this.sendReply` and `this.sendReplyBox`
|
||||
will broadcast to the room instead of just the user that used the
|
||||
command. If checkOnly is set to true, it returns without putting anything
|
||||
in the room.
|
||||
command.
|
||||
|
||||
Should usually be near the top of the command, like:
|
||||
|
||||
if (!this.canBroadcast()) return false;
|
||||
|
||||
`this.canBroadcast(checkOnly, suppressMessage)`
|
||||
`this.runBroadcast(suppressMessage)`
|
||||
* Functionally the same as `this.canBroadcast()`. However, it will look as
|
||||
if the user had written the text `suppressMessage`.
|
||||
|
||||
|
||||
@@ -68,16 +68,16 @@ exports.commands = {
|
||||
ds: 'dexsearch',
|
||||
dsearch: 'dexsearch',
|
||||
dexsearch: function (target, room, user, connection, cmd, message) {
|
||||
if (!this.canBroadcast(true)) return;
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!target) return this.parse('/help dexsearch');
|
||||
|
||||
return runSearch({
|
||||
target: target,
|
||||
cmd: 'dexsearch',
|
||||
canAll: (!this.broadcasting || room.isPersonal),
|
||||
message: (this.broadcasting ? "" : message),
|
||||
canAll: (!this.broadcastMessage || room.isPersonal),
|
||||
message: (this.broadcastMessage ? "" : message),
|
||||
}).then(response => {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (response.reply) {
|
||||
this.sendReplyBox(response.reply);
|
||||
} else if (response.dt) {
|
||||
@@ -101,7 +101,7 @@ exports.commands = {
|
||||
rollpokemon: 'randompokemon',
|
||||
randpoke: 'randompokemon',
|
||||
randompokemon: function (target, room, user, connection, cmd, message) {
|
||||
if (!this.canBroadcast(true)) return;
|
||||
if (!this.canBroadcast()) return;
|
||||
let targets = target.split(",");
|
||||
let targetsBuffer = [];
|
||||
let qty;
|
||||
@@ -122,11 +122,11 @@ exports.commands = {
|
||||
return runSearch({
|
||||
target: targetsBuffer.join(","),
|
||||
cmd: 'randpoke',
|
||||
canAll: (!this.broadcasting || room.isPersonal),
|
||||
message: (this.broadcasting ? "" : message),
|
||||
canAll: (!this.broadcastMessage || room.isPersonal),
|
||||
message: (this.broadcastMessage ? "" : message),
|
||||
}).then(response => {
|
||||
if (response.reply) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox(response.reply);
|
||||
} else if (response.dt) {
|
||||
CommandParser.commands.data.call(this, response.dt, room, user, connection, 'dt');
|
||||
@@ -141,16 +141,16 @@ exports.commands = {
|
||||
ms: 'movesearch',
|
||||
msearch: 'movesearch',
|
||||
movesearch: function (target, room, user, connection, cmd, message) {
|
||||
if (!this.canBroadcast(true)) return;
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!target) return this.parse('/help movesearch');
|
||||
|
||||
return runSearch({
|
||||
target: target,
|
||||
cmd: 'movesearch',
|
||||
canAll: (!this.broadcasting || room.isPersonal),
|
||||
message: (this.broadcasting ? "" : message),
|
||||
canAll: (!this.broadcastMessage || room.isPersonal),
|
||||
message: (this.broadcastMessage ? "" : message),
|
||||
}).then(response => {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (response.reply) {
|
||||
this.sendReplyBox(response.reply);
|
||||
} else if (response.dt) {
|
||||
@@ -171,16 +171,16 @@ exports.commands = {
|
||||
|
||||
isearch: 'itemsearch',
|
||||
itemsearch: function (target, room, user, connection, cmd, message) {
|
||||
if (!this.canBroadcast(true)) return;
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!target) return this.parse('/help itemsearch');
|
||||
|
||||
return runSearch({
|
||||
target: target,
|
||||
cmd: 'itemsearch',
|
||||
canAll: (!this.broadcasting || room.isPersonal),
|
||||
message: (this.broadcasting ? "" : message),
|
||||
canAll: (!this.broadcastMessage || room.isPersonal),
|
||||
message: (this.broadcastMessage ? "" : message),
|
||||
}).then(response => {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (response.reply) {
|
||||
this.sendReplyBox(response.reply);
|
||||
} else if (response.dt) {
|
||||
@@ -204,7 +204,7 @@ exports.commands = {
|
||||
dpplearn: 'learn',
|
||||
bw2learn: 'learn',
|
||||
learn: function (target, room, user, connection, cmd, message) {
|
||||
if (!this.canBroadcast(true)) return;
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!target) return this.parse('/help learn');
|
||||
|
||||
return runSearch({
|
||||
@@ -212,7 +212,7 @@ exports.commands = {
|
||||
cmd: 'learn',
|
||||
message: cmd,
|
||||
}).then(response => {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (response.reply) {
|
||||
this.sendReplyBox(response.reply);
|
||||
} else if (response.error) {
|
||||
|
||||
@@ -274,7 +274,7 @@ exports.commands = {
|
||||
|
||||
display: function (target, room, user) {
|
||||
if (!room.game || room.game.title !== 'Hangman') return this.errorReply("There is no game of hangman running in this room.");
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
room.update();
|
||||
|
||||
room.game.display(user, this.broadcasting);
|
||||
|
||||
@@ -22,7 +22,7 @@ exports.commands = {
|
||||
alts: 'whois',
|
||||
whoare: 'whois',
|
||||
whois: function (target, room, user, connection, cmd) {
|
||||
if (room.id === 'staff' && !this.canBroadcast()) return;
|
||||
if (room.id === 'staff' && !this.runBroadcast()) return;
|
||||
let targetUser = this.targetUserOrSelf(target, user.group === ' ');
|
||||
if (!targetUser) {
|
||||
return this.errorReply("User " + this.targetUsername + " not found.");
|
||||
@@ -214,7 +214,7 @@ exports.commands = {
|
||||
dex: 'data',
|
||||
pokedex: 'data',
|
||||
data: function (target, room, user, connection, cmd) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
|
||||
let buffer = '';
|
||||
let targetId = toId(target);
|
||||
@@ -377,7 +377,7 @@ exports.commands = {
|
||||
resist: 'weakness',
|
||||
weakness: function (target, room, user) {
|
||||
if (!target) return this.parse('/help weakness');
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
target = target.trim();
|
||||
let targets = target.split(/ ?[,\/ ] ?/);
|
||||
|
||||
@@ -475,7 +475,7 @@ exports.commands = {
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
|
||||
let factor = 0;
|
||||
if (Tools.getImmunity(source, defender) || source.ignoreImmunity && (source.ignoreImmunity === true || source.ignoreImmunity[source.type])) {
|
||||
@@ -500,7 +500,7 @@ exports.commands = {
|
||||
|
||||
cover: 'coverage',
|
||||
coverage: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (!target) return this.parse("/help coverage");
|
||||
|
||||
let targets = target.split(/[,+]/);
|
||||
@@ -679,7 +679,7 @@ exports.commands = {
|
||||
|
||||
statcalc: function (target, room, user) {
|
||||
if (!target) return this.parse("/help statcalc");
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
|
||||
let targets = target.split(' ');
|
||||
|
||||
@@ -879,7 +879,7 @@ exports.commands = {
|
||||
*********************************************************/
|
||||
|
||||
uptime: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
let uptime = process.uptime();
|
||||
let uptimeText;
|
||||
if (uptime > 24 * 60 * 60) {
|
||||
@@ -894,7 +894,7 @@ exports.commands = {
|
||||
},
|
||||
|
||||
groups: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox(
|
||||
"+ <b>Voice</b> - They can use ! commands like !groups, and talk during moderated chat<br />" +
|
||||
"% <b>Driver</b> - The above, and they can mute. Global % can also lock users and check for alts<br />" +
|
||||
@@ -911,7 +911,7 @@ exports.commands = {
|
||||
repository: 'opensource',
|
||||
git: 'opensource',
|
||||
opensource: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox(
|
||||
"Pokémon Showdown is open source:<br />" +
|
||||
"- Language: JavaScript (Node.js)<br />" +
|
||||
@@ -924,23 +924,23 @@ exports.commands = {
|
||||
"!opensource - Show everyone that information. Requires: + % @ # & ~"],
|
||||
|
||||
staff: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox("<a href=\"https://www.smogon.com/sim/staff_list\">Pokémon Showdown Staff List</a>");
|
||||
},
|
||||
|
||||
forums: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox("<a href=\"https://www.smogon.com/forums/forums/pok%C3%A9mon-showdown.209\">Pokémon Showdown Forums</a>");
|
||||
},
|
||||
|
||||
suggestions: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox("<a href=\"https://www.smogon.com/forums/threads/3534365/\">Make a suggestion for Pokémon Showdown</a>");
|
||||
},
|
||||
|
||||
bugreport: 'bugs',
|
||||
bugs: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (room.battle) {
|
||||
this.sendReplyBox("<center><button name=\"saveReplay\"><i class=\"fa fa-upload\"></i> Save Replay</button> — <a href=\"https://www.smogon.com/forums/threads/3520646/\">Questions</a> — <a href=\"https://www.smogon.com/forums/threads/3469932/\">Bug Reports</a></center>");
|
||||
} else {
|
||||
@@ -953,7 +953,7 @@ exports.commands = {
|
||||
},
|
||||
|
||||
avatars: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox("You can <button name=\"avatars\">change your avatar</button> by clicking on it in the <button name=\"openOptions\"><i class=\"fa fa-cog\"></i> Options</button> menu in the upper right. Custom avatars are only obtainable by staff.");
|
||||
},
|
||||
avatarshelp: ["/avatars - Explains how to change avatars.",
|
||||
@@ -961,7 +961,7 @@ exports.commands = {
|
||||
|
||||
introduction: 'intro',
|
||||
intro: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox(
|
||||
"New to competitive Pokémon?<br />" +
|
||||
"- <a href=\"https://www.smogon.com/sim/ps_guide\">Beginner's Guide to Pokémon Showdown</a><br />" +
|
||||
@@ -976,7 +976,7 @@ exports.commands = {
|
||||
mentoring: 'smogintro',
|
||||
smogonintro: 'smogintro',
|
||||
smogintro: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox(
|
||||
"Welcome to Smogon's official simulator! The <a href=\"https://www.smogon.com/forums/forums/264\">Smogon Info / Intro Hub</a> can help you get integrated into the community.<br />" +
|
||||
"- <a href=\"https://www.smogon.com/forums/threads/3526346\">Useful Smogon Info</a><br />" +
|
||||
@@ -986,7 +986,7 @@ exports.commands = {
|
||||
|
||||
calculator: 'calc',
|
||||
calc: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox(
|
||||
"Pokémon Showdown! damage calculator. (Courtesy of Honko)<br />" +
|
||||
"- <a href=\"https://pokemonshowdown.com/damagecalc/\">Damage Calculator</a>"
|
||||
@@ -997,7 +997,7 @@ exports.commands = {
|
||||
|
||||
capintro: 'cap',
|
||||
cap: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox(
|
||||
"An introduction to the Create-A-Pokémon project:<br />" +
|
||||
"- <a href=\"https://www.smogon.com/cap/\">CAP project website and description</a><br />" +
|
||||
@@ -1010,7 +1010,7 @@ exports.commands = {
|
||||
"!cap - Show everyone that information. Requires: + % @ # & ~"],
|
||||
|
||||
gennext: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox(
|
||||
"NEXT (also called Gen-NEXT) is a mod that makes changes to the game:<br />" +
|
||||
"- <a href=\"https://github.com/Zarel/Pokemon-Showdown/blob/master/mods/gennext/README.md\">README: overview of NEXT</a><br />" +
|
||||
@@ -1022,7 +1022,7 @@ exports.commands = {
|
||||
|
||||
om: 'othermetas',
|
||||
othermetas: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
target = toId(target);
|
||||
let buffer = "";
|
||||
|
||||
@@ -1065,7 +1065,7 @@ exports.commands = {
|
||||
tiershelp: 'formathelp',
|
||||
formatshelp: 'formathelp',
|
||||
formathelp: function (target, room, user, connection, cmd) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (!target) {
|
||||
return this.sendReplyBox(
|
||||
"- <a href=\"https://www.smogon.com/tiers/\">Smogon Tiers</a><br />" +
|
||||
@@ -1128,7 +1128,7 @@ exports.commands = {
|
||||
|
||||
roomhelp: function (target, room, user) {
|
||||
if (room.id === 'lobby' || room.battle) return this.sendReply("This command is too spammy for lobby/battles.");
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox(
|
||||
"Room drivers (%) can use:<br />" +
|
||||
"- /warn OR /k <em>username</em>: warn a user and show the Pokémon Showdown rules<br />" +
|
||||
@@ -1173,7 +1173,7 @@ exports.commands = {
|
||||
|
||||
restarthelp: function (target, room, user) {
|
||||
if (room.id === 'lobby' && !this.can('lockdown')) return false;
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox(
|
||||
"The server is restarting. Things to know:<br />" +
|
||||
"- We wait a few minutes before restarting so people can finish up their battles<br />" +
|
||||
@@ -1205,7 +1205,7 @@ exports.commands = {
|
||||
rule: 'rules',
|
||||
rules: function (target, room, user) {
|
||||
if (!target) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox("Please follow the rules:<br />" +
|
||||
(room.rulesLink ? "- <a href=\"" + Tools.escapeHTML(room.rulesLink) + "\">" + Tools.escapeHTML(room.title) + " room rules</a><br />" : "") +
|
||||
"- <a href=\"https://pokemonshowdown.com/rules\">" + (room.rulesLink ? "Global rules" : "Rules") + "</a>");
|
||||
@@ -1229,7 +1229,7 @@ exports.commands = {
|
||||
"/rules [url] - Change the room rules URL. Requires: # & ~"],
|
||||
|
||||
faq: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
target = target.toLowerCase();
|
||||
let buffer = "";
|
||||
let matched = false;
|
||||
@@ -1301,7 +1301,7 @@ exports.commands = {
|
||||
analysis: 'smogdex',
|
||||
strategy: 'smogdex',
|
||||
smogdex: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
|
||||
let targets = target.split(',');
|
||||
let pokemon = Tools.getTemplate(targets[0]);
|
||||
@@ -1414,7 +1414,7 @@ exports.commands = {
|
||||
"!analysis [pokemon], [generation] - Shows everyone this link. Requires: + % @ # & ~"],
|
||||
|
||||
veekun: function (target, broadcast, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
|
||||
let baseLink = 'http://veekun.com/dex/';
|
||||
|
||||
@@ -1484,7 +1484,7 @@ exports.commands = {
|
||||
"!veekun [pokemon] - Shows everyone this link. Requires: + % @ # & ~"],
|
||||
|
||||
register: function () {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox('You will be prompted to register upon winning a rated battle. Alternatively, there is a register button in the <button name="openOptions"><i class="fa fa-cog"></i> Options</button> menu in the upper right.');
|
||||
},
|
||||
|
||||
@@ -1509,7 +1509,7 @@ exports.commands = {
|
||||
roll: 'dice',
|
||||
dice: function (target, room, user) {
|
||||
if (!target || target.match(/[^d\d\s\-\+HL]/i)) return this.parse('/help dice');
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
|
||||
// ~30 is widely regarded as the sample size required for sum to be a Gaussian distribution.
|
||||
// This also sets a computation time constraint for safety.
|
||||
@@ -1602,7 +1602,7 @@ exports.commands = {
|
||||
pickrandom: function (target, room, user) {
|
||||
let options = target.split(',');
|
||||
if (options.length < 2) return this.parse('/help pick');
|
||||
if (!this.canBroadcast()) return false;
|
||||
if (!this.runBroadcast()) return false;
|
||||
const pickedOption = options[Math.floor(Math.random() * options.length)];
|
||||
return this.sendReplyBox('<em>We randomly picked:</em> ' + Tools.escapeHTML(pickedOption).trim());
|
||||
},
|
||||
@@ -1611,7 +1611,7 @@ exports.commands = {
|
||||
showimage: function (target, room, user) {
|
||||
if (!target) return this.parse('/help showimage');
|
||||
if (!this.can('declare', null, room)) return false;
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (this.room.isPersonal && !this.user.can('announce')) {
|
||||
return this.errorReply("Images are not allowed in personal rooms.");
|
||||
}
|
||||
@@ -1663,7 +1663,7 @@ exports.commands = {
|
||||
if (message.charAt(0) === '!') this.broadcasting = true;
|
||||
} else {
|
||||
if (!this.can('declare', null, room)) return;
|
||||
if (!this.canBroadcast(false, '!htmlbox')) return;
|
||||
if (!this.runBroadcast('!htmlbox')) return;
|
||||
}
|
||||
|
||||
this.sendReplyBox(target);
|
||||
|
||||
@@ -487,7 +487,7 @@ function renderGrid(questions, mode) {
|
||||
|
||||
let commands = {
|
||||
help: function () {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
|
||||
this.sendReplyBox(
|
||||
"All commands are run under /jeopardy or /jp. For example, /jeopardy viewgrid.<br />" +
|
||||
@@ -510,7 +510,7 @@ let commands = {
|
||||
|
||||
'': 'viewgrid',
|
||||
viewgrid: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
|
||||
let jeopardy = jeopardies[room.id];
|
||||
let questions = null;
|
||||
|
||||
@@ -238,7 +238,7 @@ exports.commands = {
|
||||
room.add("The poll timer was turned on: the poll will end in " + timeout + " minute(s).");
|
||||
return this.privateModCommand("(The poll timer was set to " + timeout + " minute(s) by " + user.name + ".)");
|
||||
} else {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (room.poll.timeout) {
|
||||
return this.sendReply("The poll timer is on and will end in " + room.poll.timeoutMins + " minute(s).");
|
||||
} else {
|
||||
@@ -272,7 +272,7 @@ exports.commands = {
|
||||
show: 'display',
|
||||
display: function (target, room, user, connection) {
|
||||
if (!room.poll) return this.errorReply("There is no poll running in this room.");
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
room.update();
|
||||
|
||||
if (this.broadcasting) {
|
||||
|
||||
@@ -133,7 +133,7 @@ exports.commands = {
|
||||
scavengershelp: 'scavengerhelp',
|
||||
scavengerhelp: function (target, room, user) {
|
||||
if (room.id !== 'scavengers') return this.errorReply('This command can only be used in the Scavengers room.');
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox(
|
||||
'<strong>Player commands:</strong><br />' +
|
||||
'- /scavengers - Join the scavengers room<br />' +
|
||||
|
||||
@@ -39,12 +39,12 @@ function wikiaSearch(subdomain, query, callback) {
|
||||
exports.commands = {
|
||||
ygo: 'yugioh',
|
||||
yugioh: function (target, room, user) {
|
||||
if (!this.canBroadcast(true)) return;
|
||||
if (!this.canBroadcast()) return;
|
||||
let subdomain = 'yugioh';
|
||||
let query = target.trim();
|
||||
|
||||
wikiaSearch(subdomain, query, (err, data) => {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (err) {
|
||||
if (err instanceof SyntaxError || err.message === 'Malformed data') {
|
||||
if (!this.broadcasting) return this.sendReply("Error: Something went wrong in the request: " + err.message);
|
||||
|
||||
@@ -14,7 +14,7 @@ exports.commands = {
|
||||
if (room.id !== 'thehappyplace') return this.errorReply("This command can only be used in The Happy Place.");
|
||||
if (!room.chatRoomData) return;
|
||||
if (!target) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (!room.chatRoomData.quote) return this.sendReplyBox("The Quote of the Day has not been set.");
|
||||
return this.sendReplyBox(
|
||||
"The current <strong>Inspirational Quote of the Day</strong> is:<br />" +
|
||||
|
||||
@@ -167,7 +167,7 @@ let commands = {
|
||||
return this.sendReplyBox(buffer);
|
||||
}
|
||||
|
||||
if (!this.canBroadcast()) return false;
|
||||
if (!this.runBroadcast()) return false;
|
||||
if (!artistOfTheDay.nominations.size) return this.sendReplyBox("No nominations have been submitted yet.");
|
||||
|
||||
let nominations = Array.from(artistOfTheDay.nominations).sort((a, b) => a[1].localeCompare(b[1]));
|
||||
@@ -225,7 +225,7 @@ let commands = {
|
||||
if (room.id !== 'thestudio') return this.errorReply('This command can only be used in The Studio.');
|
||||
if (!room.chatRoomData) return false;
|
||||
if (!target) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (!room.chatRoomData.artistQuoteOfTheDay) return this.sendReplyBox("The Artist Quote of the Day has not been set.");
|
||||
return this.sendReplyBox(
|
||||
"The current <strong>Artist Quote of the Day</strong> is:<br />" +
|
||||
@@ -256,13 +256,13 @@ let commands = {
|
||||
|
||||
'': function (target, room) {
|
||||
if (room.id !== 'thestudio') return this.errorReply('This command can only be used in The Studio.');
|
||||
if (!room.chatRoomData || !this.canBroadcast()) return false;
|
||||
if (!room.chatRoomData || !this.runBroadcast()) return false;
|
||||
this.sendReplyBox("The Artist of the Day " + (room.chatRoomData.artistOfTheDay ? "is " + room.chatRoomData.artistOfTheDay + "." : "has not been set yet."));
|
||||
},
|
||||
|
||||
help: function (target, room) {
|
||||
if (room.id !== 'thestudio') return this.errorReply('This command can only be used in The Studio.');
|
||||
if (!room.chatRoomData || !this.canBroadcast()) return false;
|
||||
if (!room.chatRoomData || !this.runBroadcast()) return false;
|
||||
this.sendReply("Use /help aotd to view help for all commands, or /help aotd [command] for help on a specific command.");
|
||||
},
|
||||
};
|
||||
|
||||
@@ -822,7 +822,7 @@ let commands = {
|
||||
let buffer = "|raw|<div class=\"ladder\"><table>";
|
||||
|
||||
if (!target) {
|
||||
if (!this.canBroadcast()) return false;
|
||||
if (!this.runBroadcast()) return false;
|
||||
|
||||
let questions = triviaData.questions;
|
||||
let questionsLen = questions.length;
|
||||
@@ -882,7 +882,7 @@ let commands = {
|
||||
'': 'status',
|
||||
status: function (target, room, user) {
|
||||
if (room.id !== 'trivia') return this.errorReply('This command can only be used in Trivia.');
|
||||
if (!this.canBroadcast()) return false;
|
||||
if (!this.runBroadcast()) return false;
|
||||
let trivium = trivia[room.id];
|
||||
if (!trivium) return this.errorReply("There is no trivia game in progress.");
|
||||
trivium.getStatus(this, user);
|
||||
@@ -891,7 +891,7 @@ let commands = {
|
||||
|
||||
players: function (target, room) {
|
||||
if (room.id !== 'trivia') return this.errorReply('This command can only be used in Trivia.');
|
||||
if (!this.canBroadcast()) return false;
|
||||
if (!this.runBroadcast()) return false;
|
||||
let trivium = trivia[room.id];
|
||||
if (!trivium) return this.errorReply("There is no trivia game in progress.");
|
||||
trivium.getParticipants(this);
|
||||
@@ -926,7 +926,7 @@ let commands = {
|
||||
|
||||
ladder: function (target, room) {
|
||||
if (room.id !== 'trivia') return this.errorReply('This command can only be used in Trivia.');
|
||||
if (!this.canBroadcast()) return false;
|
||||
if (!this.runBroadcast()) return false;
|
||||
|
||||
let ladder = triviaData.ladder;
|
||||
let leaderboard = triviaData.leaderboard;
|
||||
|
||||
@@ -361,7 +361,7 @@ let commands = {
|
||||
if (room.id !== 'wifi') return this.errorReply("This command can only be used in the Wi-Fi room.");
|
||||
let giveaway = giveaways[room.id];
|
||||
if (!giveaway) return this.errorReply("There is no giveaway going on at the moment.");
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (giveaway.type === 'question') {
|
||||
if (giveaway.phase !== 'started') return this.errorReply("The giveaway has not started yet.");
|
||||
this.sendReply("|html|<div class='broadcast-blue'><font size='1'>Question Giveaway started by " + Tools.escapeHTML(giveaway.host.name) + "</font><br/>" +
|
||||
@@ -390,7 +390,7 @@ let commands = {
|
||||
case 'game':
|
||||
case 'giveaway':
|
||||
case 'user':
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
reply = '<strong>Giveaway participation commands: </strong> (start with /giveaway, except for /ga) <br />' +
|
||||
'- guess or /ga <em>answer</em> - Guesses the answer for a question giveaway<br />' +
|
||||
'- viewanswer - Shows the answer in a question giveaway (only to host/giver)<br />' +
|
||||
@@ -399,7 +399,7 @@ let commands = {
|
||||
'- leave or leavelottery - Leaves a lottery giveaway<br />';
|
||||
break;
|
||||
default:
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
reply = '<b>Wi-Fi room Giveaway help and info</b><br />' +
|
||||
'- help user - shows list of participation commands<br />' +
|
||||
'- help staff - shows giveaway staff commands (Requires: % @ # & ~)';
|
||||
|
||||
@@ -170,31 +170,54 @@ class CommandContext {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
canBroadcast(checkOnly, suppressMessage) {
|
||||
let message = this.canTalk(this.message);
|
||||
if (!message) return false;
|
||||
let normalized = message.toLowerCase().replace(/[^a-z0-9\s!,]/g, '');
|
||||
|
||||
canBroadcast() {
|
||||
if (!this.broadcasting && this.cmdToken === BROADCAST_TOKEN) {
|
||||
if (this.user.broadcasting) {
|
||||
this.errorReply("You can't broadcast another command too soon.");
|
||||
return false;
|
||||
}
|
||||
|
||||
let message = this.canTalk(this.message);
|
||||
if (!message) return false;
|
||||
if (!this.user.can('broadcast', null, this.room)) {
|
||||
this.errorReply("You need to be voiced to broadcast this command's information.");
|
||||
this.errorReply("To see it for yourself, use: /" + message.substr(1));
|
||||
this.errorReply("To see it for yourself, use: /" + this.message.substr(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
// broadcast cooldown
|
||||
if (this.room.lastBroadcast === normalized &&
|
||||
let broadcastMessage = message.toLowerCase().replace(/[^a-z0-9\s!,]/g, '');
|
||||
|
||||
if (this.room.lastBroadcast === this.broadcastMessage &&
|
||||
this.room.lastBroadcastTime >= Date.now() - BROADCAST_COOLDOWN) {
|
||||
this.errorReply("You can't broadcast this because it was just broadcast.");
|
||||
return false;
|
||||
}
|
||||
this.broadcasting = true;
|
||||
|
||||
this.message = message;
|
||||
this.broadcastMessage = broadcastMessage;
|
||||
this.user.broadcasting = true;
|
||||
}
|
||||
if (this.broadcasting && !checkOnly) {
|
||||
this.add('|c|' + this.user.getIdentity(this.room.id) + '|' + (suppressMessage || message));
|
||||
this.room.lastBroadcast = normalized;
|
||||
this.room.lastBroadcastTime = Date.now();
|
||||
return true;
|
||||
}
|
||||
runBroadcast(suppressMessage) {
|
||||
if (this.broadcasting || this.cmdToken !== BROADCAST_TOKEN) {
|
||||
// Already being broadcast, or the user doesn't intend to broadcast.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!this.broadcastMessage) {
|
||||
// Permission hasn't been checked yet. Do it now.
|
||||
if (!this.canBroadcast()) return false;
|
||||
}
|
||||
|
||||
this.add('|c|' + this.user.getIdentity(this.room.id) + '|' + (suppressMessage || this.message));
|
||||
this.room.lastBroadcast = this.broadcastMessage;
|
||||
this.room.lastBroadcastTime = Date.now();
|
||||
|
||||
this.broadcasting = true;
|
||||
this.user.broadcasting = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
parse(message, inNamespace, room) {
|
||||
|
||||
12
commands.js
12
commands.js
@@ -25,7 +25,7 @@ const HOURMUTE_LENGTH = 60 * 60 * 1000;
|
||||
exports.commands = {
|
||||
|
||||
version: function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReplyBox("Server version: <b>" + CommandParser.package.version + "</b>");
|
||||
},
|
||||
|
||||
@@ -594,7 +594,7 @@ exports.commands = {
|
||||
|
||||
roomdesc: function (target, room, user) {
|
||||
if (!target) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (!room.desc) return this.sendReply("This room does not have a description set.");
|
||||
this.sendReplyBox("The room description is: " + Tools.escapeHTML(room.desc));
|
||||
return;
|
||||
@@ -627,7 +627,7 @@ exports.commands = {
|
||||
topic: 'roomintro',
|
||||
roomintro: function (target, room, user) {
|
||||
if (!target) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (!room.introMessage) return this.sendReply("This room does not have an introduction set.");
|
||||
this.sendReply('|raw|<div class="infobox infobox-limited">' + room.introMessage + '</div>');
|
||||
if (!this.broadcasting && user.can('declare', null, room)) {
|
||||
@@ -696,7 +696,7 @@ exports.commands = {
|
||||
|
||||
roomalias: function (target, room, user) {
|
||||
if (!target) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (!room.aliases || !room.aliases.length) return this.sendReplyBox("This room does not have any aliases.");
|
||||
return this.sendReplyBox("This room has the following aliases: " + room.aliases.join(", ") + "");
|
||||
}
|
||||
@@ -2241,7 +2241,7 @@ exports.commands = {
|
||||
if (!user.hasConsoleAccess(connection)) {
|
||||
return this.errorReply("/eval - Access denied.");
|
||||
}
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
|
||||
if (!this.broadcasting) this.sendReply('||>> ' + target);
|
||||
try {
|
||||
@@ -2259,7 +2259,7 @@ exports.commands = {
|
||||
if (!user.hasConsoleAccess(connection)) {
|
||||
return this.errorReply("/evalbattle - Access denied.");
|
||||
}
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
if (!room.battle) {
|
||||
return this.errorReply("/evalbattle - This isn't a battle room.");
|
||||
}
|
||||
|
||||
@@ -806,7 +806,7 @@ let commands = {
|
||||
}
|
||||
},
|
||||
getusers: function (tournament) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
let users = usersToNames(tournament.generator.getUsers(true).sort());
|
||||
this.sendReplyBox("<strong>" + users.length + " users remain in this tournament:</strong><br />" + Tools.escapeHTML(users.join(", ")));
|
||||
},
|
||||
@@ -993,7 +993,7 @@ CommandParser.commands.tournament = function (paramString, room, user) {
|
||||
if (!params[0]) params = [];
|
||||
|
||||
if (cmd === '') {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
this.sendReply('|tournaments|info|' + JSON.stringify(Object.keys(exports.tournaments).filter(tournament => {
|
||||
tournament = exports.tournaments[tournament];
|
||||
return !tournament.room.isPrivate && !tournament.room.isPersonal && !tournament.room.staffRoom;
|
||||
@@ -1112,7 +1112,7 @@ CommandParser.commands.tournament = function (paramString, room, user) {
|
||||
}
|
||||
};
|
||||
CommandParser.commands.tournamenthelp = function (target, room, user) {
|
||||
if (!this.canBroadcast()) return;
|
||||
if (!this.runBroadcast()) return;
|
||||
return this.sendReplyBox(
|
||||
"- create/new <format>, <type> [, <comma-separated arguments>]: Creates a new tournament in the current room.<br />" +
|
||||
"- settype <type> [, <comma-separated arguments>]: Modifies the type of tournament after it's been created, but before it has started.<br />" +
|
||||
|
||||
Reference in New Issue
Block a user