Moderated chat was set to ${modchatSetting}! Only users of rank ${modchatSetting} and higher can talk.
`);
}
if (room.battle && !room.modchat && !user.can('modchat')) room.requestModchat(null);
this.privateModCommand(`(${user.name} set modchat to ${room.modchat})`);
if (room.chatRoomData) {
room.chatRoomData.modchat = room.modchat;
Rooms.global.writeChatRoomData();
}
},
modchathelp: ["/modchat [off/autoconfirmed/+/%/@/*/#/&/~] - Set the level of moderated chat. Requires: *, @ for off/autoconfirmed/+ options, # & ~ for all the options"],
ioo: function (target, room, user) {
return this.parse('/modjoin +');
},
inviteonly: function (target, room, user) {
if (!target) return this.parse('/help inviteonly');
if (target === 'on' || target === 'true' || target === 'yes') {
return this.parse("/modjoin +");
} else {
return this.parse(`/modjoin ${target}`);
}
},
inviteonlyhelp: ["/inviteonly [on|off] - Sets modjoin +. Users can't join unless invited with /invite. Requires: # & ~",
"/ioo - Shortcut for /inviteonly on"],
modjoin: function (target, room, user) {
if (!target) {
const modjoinSetting = room.modjoin === true ? "SYNC" : room.modjoin || "OFF";
return this.sendReply(`Modjoin is currently set to: ${modjoinSetting}`);
}
if (room.battle || room.isPersonal) {
if (!this.can('editroom', null, room)) return;
} else {
if (!this.can('makeroom')) return;
}
if (room.tour && !room.tour.modjoin) return this.errorReply(`You can't do this in tournaments where modjoin is prohibited.`);
if (target === 'off' || target === 'false') {
if (!room.modjoin) return this.errorReply(`Modjoin is already turned off in this room.`);
delete room.modjoin;
this.add(`|raw|
This room is no longer invite only! Anyone may now join.
`);
this.addModCommand(`${user.name} turned off modjoin.`);
if (room.chatRoomData) {
delete room.chatRoomData.modjoin;
Rooms.global.writeChatRoomData();
}
return;
} else if (target === 'sync') {
if (room.modjoin === true) return this.errorReply(`Modjoin is already set to sync modchat in this room.`);
room.modjoin = true;
this.add(`|raw|
Moderated join is set to sync with modchat! Only users who can speak in modchat can join.
`);
this.addModCommand(`${user.name} set modjoin to sync with modchat.`);
} else if (target in Config.groups) {
if (room.battle && !user.can('makeroom') && target !== '+') return this.errorReply(`/modjoin - Access denied from setting modjoin past + in battles.`);
if (room.isPersonal && !user.can('makeroom') && target !== '+') return this.errorReply(`/modjoin - Access denied from setting modjoin past + in group chats.`);
if (room.modjoin === target) return this.errorReply(`Modjoin is already set to ${target} in this room.`);
room.modjoin = target;
if (target === '+') {
this.add(`|raw|
This room is now invite only! Users must be rank + or invited with /invite to join
`);
} else {
this.add(Chat.html`|raw|
Moderated join was set to ${target}! Only users of rank ${target} and higher can join.
`);
}
this.addModCommand(`${user.name} set modjoin to ${target}.`);
} else {
this.errorReply(`Unrecognized modjoin setting.`);
this.parse('/help modjoin');
return false;
}
if (room.chatRoomData) {
room.chatRoomData.modjoin = room.modjoin;
Rooms.global.writeChatRoomData();
}
if (target === 'sync' && !room.modchat) this.parse(`/modchat ${Config.groupsranking[1]}`);
if (!room.isPrivate) this.parse('/hiddenroom');
},
modjoinhelp: ["/modjoin [+|%|@|*|&|~|#|off] - Sets modjoin. Users lower than the specified rank can't join this room. Requires: # & ~",
"/modjoin [sync|off] - Sets modjoin. Only users who can speak in modchat can join this room. Requires: # & ~"],
slowchat: function (target, room, user) {
if (!target) {
const slowchatSetting = (room.slowchat || "OFF");
return this.sendReply(`Slow chat is currently set to: ${slowchatSetting}`);
}
if (!this.canTalk()) return;
if (!this.can('modchat', null, room)) return false;
let targetInt = parseInt(target);
if (target === 'off' || target === 'disable' || target === 'false') {
if (!room.slowchat) return this.errorReply(`Slow chat is already disabled in this room.`);
room.slowchat = false;
this.add("|raw|
Slow chat was disabled! There is no longer a set minimum time between messages.
");
} else if (targetInt) {
if (!user.can('bypassall') && room.userCount < SLOWCHAT_USER_REQUIREMENT) return this.errorReply(`This room must have at least ${SLOWCHAT_USER_REQUIREMENT} users to set slowchat; it only has ${room.userCount} right now.`);
if (room.slowchat === targetInt) return this.errorReply(`Slow chat is already set to ${room.slowchat} seconds in this room.`);
if (targetInt < SLOWCHAT_MINIMUM) targetInt = SLOWCHAT_MINIMUM;
if (targetInt > SLOWCHAT_MAXIMUM) targetInt = SLOWCHAT_MAXIMUM;
room.slowchat = targetInt;
this.add(`|raw|
Slow chat was enabled! Messages must have at least ${room.slowchat} seconds between them.
`);
} else {
return this.parse("/help slowchat");
}
const slowchatSetting = (room.slowchat || "OFF");
this.privateModCommand(`(${user.name} set slowchat to ${slowchatSetting})`);
if (room.chatRoomData) {
room.chatRoomData.slowchat = room.slowchat;
Rooms.global.writeChatRoomData();
}
},
slowchathelp: ["/slowchat [number] - Sets a limit on how often users in the room can send messages, between 2 and 60 seconds. Requires @ * # & ~",
"/slowchat off - Disables slowchat in the room. Requires @ * # & ~"],
stretching: 'stretchfilter',
stretchingfilter: 'stretchfilter',
stretchfilter: function (target, room, user) {
if (!target) {
const stretchSetting = (room.filterStretching ? "ON" : "OFF");
return this.sendReply(`This room's stretch filter is currently: ${stretchSetting}`);
}
if (!this.canTalk()) return;
if (!this.can('editroom', null, room)) return false;
if (target === 'enable' || target === 'on') {
if (room.filterStretching) return this.errorReply(`This room's stretch filter is already ON`);
room.filterStretching = true;
} else if (target === 'disable' || target === 'off') {
if (!room.filterStretching) return this.errorReply(`This room's stretch filter is already OFF`);
room.filterStretching = false;
} else {
return this.parse("/help stretchfilter");
}
const stretchSetting = (room.filterStretching ? "ON" : "OFF");
this.privateModCommand(`(${user.name} turned the stretch filter ${stretchSetting})`);
if (room.chatRoomData) {
room.chatRoomData.filterStretching = room.filterStretching;
Rooms.global.writeChatRoomData();
}
},
stretchfilterhelp: ["/stretchfilter [on/off] - Toggles filtering messages in the room for stretchingggggggg. Requires # & ~"],
capitals: 'capsfilter',
capitalsfilter: 'capsfilter',
capsfilter: function (target, room, user) {
if (!target) {
const capsSetting = (room.filterCaps ? "ON" : "OFF");
return this.sendReply(`This room's caps filter is currently: ${capsSetting}`);
}
if (!this.canTalk()) return;
if (!this.can('editroom', null, room)) return false;
if (target === 'enable' || target === 'on' || target === 'true') {
if (room.filterCaps) return this.errorReply(`This room's caps filter is already ON`);
room.filterCaps = true;
} else if (target === 'disable' || target === 'off' || target === 'false') {
if (!room.filterCaps) return this.errorReply(`This room's caps filter is already OFF`);
room.filterCaps = false;
} else {
return this.parse("/help capsfilter");
}
const capsSetting = (room.filterCaps ? "ON" : "OFF");
this.privateModCommand(`(${user.name} turned the caps filter ${capsSetting})`);
if (room.chatRoomData) {
room.chatRoomData.filterCaps = room.filterCaps;
Rooms.global.writeChatRoomData();
}
},
capsfilterhelp: ["/capsfilter [on/off] - Toggles filtering messages in the room for EXCESSIVE CAPS. Requires # & ~"],
emojis: 'emojifilter',
emoji: 'emojifilter',
emojifilter : function (target, room, user) {
if (!target) {
const emojiSetting = (room.filterEmojis ? "ON" : "OFF");
return this.sendReply(`This room's emoji filter is currently: ${emojiSetting}`);
}
if (!this.canTalk()) return;
if (!this.can('editroom', null, room)) return false;
if (target === 'enable' || target === 'on' || target === 'true') {
if (room.filterEmojis) return this.errorReply(`This room's emoji filter is already ON`);
room.filterEmojis = true;
} else if (target === 'disable' || target === 'off' || target === 'false') {
if (!room.filterEmojis) return this.errorReply(`This room's emoji filter is already OFF`);
room.filterEmojis = false;
} else {
return this.parse("/help emojifilter");
}
const emojiSetting = (room.filterEmojis ? "ON" : "OFF");
this.privateModCommand(`(${user.name} turned the emoji filter ${emojiSetting})`);
if (room.chatRoomData) {
room.chatRoomData.filterEmojis = room.filterEmojis;
Rooms.global.writeChatRoomData();
}
},
emojifilterhelp: ["/emojifilter [on/off] - Toggles filtering messages in the room for emojis. Requires # & ~"],
banwords: 'banword',
banword: {
add: function (target, room, user) {
if (!target || target === ' ') return this.parse('/help banword');
if (!this.can('declare', null, room)) return false;
if (!room.banwords) room.banwords = [];
// Most of the regex code is copied from the client. TODO: unify them?
let words = target.match(/[^,]+(,\d*}[^,]*)?/g);
if (!words) return this.parse('/help banword');
words = words.map(word => word.replace(/\n/g, '').trim());
for (let i = 0; i < words.length; i++) {
if (/[\\^$*+?()|{}[\]]/.test(words[i])) {
if (!user.can('makeroom')) return this.errorReply("Regex banwords are only allowed for leaders or above.");
try {
let test = new RegExp(words[i]); // eslint-disable-line no-unused-vars
} catch (e) {
return this.errorReply(e.message.substr(0, 28) === 'Invalid regular expression: ' ? e.message : `Invalid regular expression: /${words[i]}/: ${e.message}`);
}
}
if (room.banwords.indexOf(words[i]) > -1) {
return this.errorReply(`${words[i]} is already a banned phrase.`);
}
}
room.banwords = room.banwords.concat(words);
room.banwordRegex = null;
if (words.length > 1) {
this.privateModCommand(`(The banwords ${words.map(w => `'${w}'`).join(', ')} were added by ${user.name}.)`);
this.sendReply(`Banned phrases succesfully added. The list is currently: ${room.banwords.join(', ')}`);
} else {
this.privateModCommand(`(The banword '${words[0]}' was added by ${user.name}.)`);
this.sendReply(`Banned phrase succesfully added. The list is currently: ${room.banwords.join(', ')}`);
}
if (room.chatRoomData) {
room.chatRoomData.banwords = room.banwords;
Rooms.global.writeChatRoomData();
}
},
delete: function (target, room, user) {
if (!target) return this.parse('/help banword');
if (!this.can('declare', null, room)) return false;
if (!room.banwords) return this.errorReply("This room has no banned phrases.");
let words = target.match(/[^,]+(,\d*}[^,]*)?/g);
if (!words) return this.parse('/help banword');
words = words.map(word => word.replace(/\n/g, '').trim());
for (let i = 0; i < words.length; i++) {
let index = room.banwords.indexOf(words[i]);
if (index < 0) return this.errorReply(`${words[i]} is not a banned phrase in this room.`);
}
room.banwords = room.banwords.filter(w => !words.includes(w));
room.banwordRegex = null;
if (words.length > 1) {
this.privateModCommand(`(The banwords ${words.map(w => `'${w}'`).join(', ')} were removed by ${user.name}.)`);
this.sendReply(`Banned phrases succesfully deleted. The list is currently: ${room.banwords.join(', ')}`);
} else {
this.privateModCommand(`(The banword '${words[0]}' was removed by ${user.name}.)`);
this.sendReply(`Banned phrase succesfully deleted. The list is currently: ${room.banwords.join(', ')}`);
}
if (room.chatRoomData) {
room.chatRoomData.banwords = room.banwords;
Rooms.global.writeChatRoomData();
}
},
list: function (target, room, user) {
if (!this.can('mute', null, room)) return false;
if (!room.banwords) return this.sendReply("This room has no banned phrases.");
return this.sendReply(`Banned phrases in room ${room.id}: ${room.banwords.join(', ')}`);
},
"": function (target, room, user) {
return this.parse("/help banword");
},
},
banwordhelp: [
"/banword add [words] - Adds the comma-separated list of phrases (& or ~ can also input regex) to the banword list of the current room. Requires: # & ~",
"/banword delete [words] - Removes the comma-separated list of phrases from the banword list. Requires: # & ~",
"/banword list - Shows the list of banned words in the current room. Requires: % @ * # & ~",
],
};