mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-09-11 10:45:38 -05:00
Update permissions
Permissions have gotten out-of-date, so this commit syncs them. Default permissions are now matched with Main, in particular including the new & rank as admin (removing the old Leader rank and ~ symbol). Relevant changes: - Admin (~) and Leader (&) have been merged into Admin (&) - The 'ban' permission was split into 'globalban' and 'ban' - The 'broadcast' permission was renamed 'show' (going forward, "broadcast" should only refer to the big red/blue/green announcement bars.) - Bots no longer have global moderation abilities, making it easier to give untrustworthy bots the "bot" rank.
This commit is contained in:
@@ -486,7 +486,8 @@ exports.chatlogreader = 'fs';
|
||||
* - makeroom: Create/delete chatrooms, and set modjoin/roomdesc/privacy
|
||||
* - editroom: Editing properties of rooms
|
||||
* - editprivacy: Set modjoin/privacy only for battles
|
||||
* - ban: Banning and unbanning.
|
||||
* - globalban: Banning and unbanning from the entire server.
|
||||
* - ban: Banning and unbanning in rooms.
|
||||
* - mute: Muting and unmuting.
|
||||
* - lock: locking (ipmute) and unlocking.
|
||||
* - receivemutedpms: Receive PMs from muted users.
|
||||
@@ -494,7 +495,8 @@ exports.chatlogreader = 'fs';
|
||||
* - ip: IP checking.
|
||||
* - alts: Alt checking.
|
||||
* - modlog: view the moderator logs.
|
||||
* - broadcast: Broadcast informational commands.
|
||||
* - show: Show command output to other users.
|
||||
* - showmedia: Show images and videos to other users.
|
||||
* - declare: /declare command.
|
||||
* - announce: /announce command.
|
||||
* - modchat: Set modchat.
|
||||
@@ -509,19 +511,17 @@ exports.chatlogreader = 'fs';
|
||||
*/
|
||||
exports.grouplist = [
|
||||
{
|
||||
symbol: '~',
|
||||
symbol: '&',
|
||||
id: "admin",
|
||||
name: "Administrator",
|
||||
root: true,
|
||||
globalonly: true,
|
||||
},
|
||||
{
|
||||
symbol: '&',
|
||||
id: "leader",
|
||||
name: "Leader",
|
||||
inherit: '@',
|
||||
jurisdiction: 'u',
|
||||
promote: 'u',
|
||||
globalonly: true,
|
||||
|
||||
console: true,
|
||||
bypassall: true,
|
||||
lockdown: true,
|
||||
promote: '&u',
|
||||
roomowner: true,
|
||||
roombot: true,
|
||||
roommod: true,
|
||||
@@ -531,12 +531,12 @@ exports.grouplist = [
|
||||
rangeban: true,
|
||||
makeroom: true,
|
||||
editroom: true,
|
||||
editprivacy: true,
|
||||
potd: true,
|
||||
disableladder: true,
|
||||
globalonly: true,
|
||||
gdeclare: true,
|
||||
gamemanagement: true,
|
||||
exportinputlog: true,
|
||||
editprivacy: true,
|
||||
},
|
||||
{
|
||||
symbol: '#',
|
||||
@@ -544,47 +544,57 @@ exports.grouplist = [
|
||||
name: "Room Owner",
|
||||
inherit: '@',
|
||||
jurisdiction: 'u',
|
||||
roomonly: true,
|
||||
|
||||
roombot: true,
|
||||
roommod: true,
|
||||
roomdriver: true,
|
||||
editroom: true,
|
||||
declare: true,
|
||||
addhtml: true,
|
||||
roomonly: true,
|
||||
gamemanagement: true,
|
||||
},
|
||||
{
|
||||
symbol: '*',
|
||||
id: "bot",
|
||||
name: "Bot",
|
||||
inherit: '%',
|
||||
jurisdiction: 'u',
|
||||
|
||||
addhtml: true,
|
||||
declare: true,
|
||||
bypassafktimer: true,
|
||||
|
||||
ip: false,
|
||||
globalban: false,
|
||||
lock: false,
|
||||
alts: false,
|
||||
},
|
||||
{
|
||||
symbol: '\u2605',
|
||||
id: "host",
|
||||
name: "Host",
|
||||
inherit: '@',
|
||||
jurisdiction: 'u',
|
||||
declare: true,
|
||||
addhtml: true,
|
||||
modchat: true,
|
||||
roomonly: true,
|
||||
|
||||
declare: true,
|
||||
modchat: true,
|
||||
gamemanagement: true,
|
||||
joinbattle: true,
|
||||
},
|
||||
{
|
||||
symbol: '*',
|
||||
id: "bot",
|
||||
name: "Bot",
|
||||
inherit: '@',
|
||||
jurisdiction: 'u',
|
||||
declare: true,
|
||||
addhtml: true,
|
||||
bypassafktimer: true,
|
||||
},
|
||||
{
|
||||
symbol: '@',
|
||||
id: "mod",
|
||||
name: "Moderator",
|
||||
inherit: '%',
|
||||
jurisdiction: 'u',
|
||||
|
||||
globalban: true,
|
||||
ban: true,
|
||||
modchatall: true,
|
||||
roomvoice: true,
|
||||
roomwhitelist: true,
|
||||
forcerename: true,
|
||||
ip: true,
|
||||
alts: '@u',
|
||||
@@ -597,10 +607,12 @@ exports.grouplist = [
|
||||
name: "Driver",
|
||||
inherit: '+',
|
||||
jurisdiction: 'u',
|
||||
globalGroupInPersonalRoom: '@',
|
||||
|
||||
announce: true,
|
||||
warn: '\u2606u',
|
||||
warn: '\u2605u',
|
||||
kick: true,
|
||||
mute: '\u2606u',
|
||||
mute: '\u2605u',
|
||||
lock: true,
|
||||
forcerename: true,
|
||||
timer: true,
|
||||
@@ -619,22 +631,29 @@ exports.grouplist = [
|
||||
id: "player",
|
||||
name: "Player",
|
||||
inherit: '+',
|
||||
battleonly: true,
|
||||
|
||||
roomvoice: true,
|
||||
modchat: true,
|
||||
roomonly: true,
|
||||
editprivacy: true,
|
||||
gamemanagement: true,
|
||||
tournaments: true,
|
||||
joinbattle: true,
|
||||
nooverride: true,
|
||||
editprivacy: true,
|
||||
exportinputlog: true,
|
||||
},
|
||||
{
|
||||
symbol: '+',
|
||||
id: "voice",
|
||||
name: "Voice",
|
||||
inherit: ' ',
|
||||
|
||||
alts: 's',
|
||||
broadcast: true,
|
||||
makegroupchat: true,
|
||||
joinbattle: true,
|
||||
show: true,
|
||||
showmedia: true,
|
||||
exportinputlog: true,
|
||||
importinputlog: true,
|
||||
},
|
||||
{
|
||||
symbol: 'whitelist',
|
||||
@@ -643,12 +662,14 @@ exports.grouplist = [
|
||||
inherit: ' ',
|
||||
roomonly: true,
|
||||
alts: 's',
|
||||
broadcast: true,
|
||||
importinputlog: true,
|
||||
show: true,
|
||||
showmedia: true,
|
||||
exportinputlog: true,
|
||||
importinputlog: true,
|
||||
},
|
||||
{
|
||||
symbol: ' ',
|
||||
ip: 's',
|
||||
},
|
||||
{
|
||||
name: 'Locked',
|
||||
|
||||
@@ -19,10 +19,12 @@ export const commands: ChatCommands = {
|
||||
alt: 'whois',
|
||||
alts: 'whois',
|
||||
whoare: 'whois',
|
||||
altsnorecurse: 'whois',
|
||||
whois(target, room: Room | null, user, connection, cmd) {
|
||||
if (room?.roomid === 'staff' && !this.runBroadcast()) return;
|
||||
const targetUser = this.targetUserOrSelf(target, user.group === ' ');
|
||||
const showAll = (cmd === 'ip' || cmd === 'whoare' || cmd === 'alt' || cmd === 'alts');
|
||||
const showAll = (cmd === 'ip' || cmd === 'whoare' || cmd === 'alt' || cmd === 'alts' || cmd === 'altsnorecurse');
|
||||
const showRecursiveAlts = showAll && (cmd !== 'altsnorecurse');
|
||||
if (!targetUser) {
|
||||
if (showAll) return this.parse('/offlinewhois ' + target);
|
||||
return this.errorReply("User " + this.targetUsername + " not found.");
|
||||
@@ -159,7 +161,7 @@ export const commands: ChatCommands = {
|
||||
ips = ips.map(ip => {
|
||||
const status = [];
|
||||
const punishment = Punishments.ips.get(ip);
|
||||
if (user.can('ip') && punishment) {
|
||||
if (user.can('globalban') && punishment) {
|
||||
const [punishType, userid] = punishment;
|
||||
let punishMsg = Punishments.punishmentTypes.get(punishType) || 'punished';
|
||||
if (userid !== targetUser.id) punishMsg += ` as ${userid}`;
|
||||
@@ -227,6 +229,15 @@ export const commands: ChatCommands = {
|
||||
}
|
||||
}
|
||||
this.sendReplyBox(buf);
|
||||
|
||||
if (showRecursiveAlts && canViewAlts) {
|
||||
const targetId = toID(target);
|
||||
for (const alt of Users.users.values()) {
|
||||
if (alt !== targetUser && targetId in alt.prevNames) {
|
||||
this.parse(`/altsnorecurse ${alt.name}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
whoishelp: [
|
||||
`/whois - Get details on yourself: alts, group, IP address, and rooms.`,
|
||||
@@ -351,7 +362,7 @@ export const commands: ChatCommands = {
|
||||
'!host': true,
|
||||
host(target, room, user, connection, cmd) {
|
||||
if (!target) return this.parse('/help host');
|
||||
if (!this.can('ip')) return;
|
||||
if (!this.can('globalban')) return;
|
||||
target = target.trim();
|
||||
if (!net.isIPv4(target)) return this.errorReply('You must pass a valid IPv4 IP to /host.');
|
||||
void IPTools.lookup(target).then(({dnsbl, host, hostType}) => {
|
||||
|
||||
@@ -844,7 +844,7 @@ export const commands: ChatCommands = {
|
||||
unlockip(target, room, user) {
|
||||
target = target.trim();
|
||||
if (!target) return this.parse('/help unlock');
|
||||
if (!this.can('ban')) return false;
|
||||
if (!this.can('globalban')) return false;
|
||||
const range = target.charAt(target.length - 1) === '*';
|
||||
if (range && !this.can('rangeban')) return false;
|
||||
|
||||
@@ -890,7 +890,7 @@ export const commands: ChatCommands = {
|
||||
if (!target && REQUIRE_REASONS) {
|
||||
return this.errorReply("Global bans require a reason.");
|
||||
}
|
||||
if (!this.can('ban', targetUser)) return false;
|
||||
if (!this.can('globalban', targetUser)) return false;
|
||||
const name = targetUser.getLastName();
|
||||
const userid = targetUser.getLastId();
|
||||
|
||||
@@ -963,7 +963,7 @@ export const commands: ChatCommands = {
|
||||
globalunban: 'unglobalban',
|
||||
unglobalban(target, room, user) {
|
||||
if (!target) return this.parse(`/help unglobalban`);
|
||||
if (!this.can('ban')) return false;
|
||||
if (!this.can('globalban')) return false;
|
||||
|
||||
const name = Punishments.unban(target);
|
||||
|
||||
@@ -1851,7 +1851,7 @@ export const commands: ChatCommands = {
|
||||
}
|
||||
}
|
||||
|
||||
if (user.can('ban')) {
|
||||
if (user.can('globalban')) {
|
||||
const roomIps = Punishments.roomIps.get(room.roomid);
|
||||
|
||||
if (roomIps) {
|
||||
@@ -1888,7 +1888,7 @@ export const commands: ChatCommands = {
|
||||
|
||||
markshared(target, room, user) {
|
||||
if (!target) return this.parse('/help markshared');
|
||||
if (!this.can('ban')) return false;
|
||||
if (!this.can('globalban')) return false;
|
||||
let [ip, note] = this.splitOne(target);
|
||||
if (!/^[0-9.*]+$/.test(ip)) return this.errorReply("Please enter a valid IP address.");
|
||||
|
||||
@@ -1916,7 +1916,7 @@ export const commands: ChatCommands = {
|
||||
|
||||
unmarkshared(target, room, user) {
|
||||
if (!target) return this.parse('/help unmarkshared');
|
||||
if (!this.can('ban')) return false;
|
||||
if (!this.can('globalban')) return false;
|
||||
if (!/^[0-9.*]+$/.test(target)) return this.errorReply("Please enter a valid IP address.");
|
||||
|
||||
if (!Punishments.sharedIps.has(target)) return this.errorReply("This IP isn't marked as shared.");
|
||||
|
||||
@@ -234,7 +234,7 @@ export const commands: ChatCommands = {
|
||||
if (!lottery) {
|
||||
return this.errorReply('This room does not have a lottery running.');
|
||||
}
|
||||
const canSeeIps = user.can('ban');
|
||||
const canSeeIps = user.can('globalban');
|
||||
const participants = Object.entries(lottery.participants).map(([ip, participant]) => {
|
||||
return `- ${participant}${canSeeIps ? ' (IP: ' + ip + ')' : ''}`;
|
||||
});
|
||||
|
||||
@@ -1939,7 +1939,7 @@ export const commands: ChatCommands = {
|
||||
if (!this.canTalk()) return;
|
||||
if (!room || room.type !== 'chat') return this.errorReply(`This command is only meant to be used in chat rooms.`);
|
||||
if (room.game) return this.errorReply(`There is already a game of ${room.game.title} in progress in this room.`);
|
||||
if (!user.can('broadcast', null, room)) return this.errorReply(`/mafia ${cmd} - Access denied.`);
|
||||
if (!user.can('show', null, room)) return this.errorReply(`/mafia ${cmd} - Access denied.`);
|
||||
|
||||
let nextHost = false;
|
||||
if (room.roomid === 'mafia') {
|
||||
@@ -2006,7 +2006,7 @@ export const commands: ChatCommands = {
|
||||
if (room.roomid !== 'mafia') return this.errorReply(`This command can only be used in the Mafia room.`);
|
||||
const args = target.split(',').map(toID);
|
||||
if (['forceadd', 'add', 'remove', 'del', 'delete'].includes(args[0])) {
|
||||
const permission = (user.id === args[1]) ? 'broadcast' : 'mute';
|
||||
const permission = (user.id === args[1]) ? 'show' : 'mute';
|
||||
if (['forceadd', 'add'].includes(args[0]) && !this.can(permission, null, room)) return;
|
||||
if (['remove', 'del', 'delete'].includes(args[0]) && user.id !== args[1] && !this.can('mute', null, room)) return;
|
||||
} else {
|
||||
@@ -2220,7 +2220,7 @@ export const commands: ChatCommands = {
|
||||
idea(target, room, user) {
|
||||
const game = room.getGame(MafiaTracker);
|
||||
if (!game) return this.errorReply(`There is no game of mafia running in this room.`);
|
||||
if (!this.can('broadcast', null, room)) return;
|
||||
if (!this.can('show', null, room)) return;
|
||||
if (!user.can('mute', null, room) && game.hostid !== user.id && !game.cohosts.includes(user.id)) {
|
||||
return this.errorReply(`/mafia idea - Access denied.`);
|
||||
}
|
||||
@@ -3127,7 +3127,7 @@ export const commands: ChatCommands = {
|
||||
}
|
||||
const game = targetRoom.getGame(MafiaTracker);
|
||||
if (!game) return user.sendTo(targetRoom, `|error|There is no game of mafia running in this room.`);
|
||||
if (game.hostid !== user.id && !game.cohosts.includes(user.id) && !this.can('broadcast', null, room)) return;
|
||||
if (game.hostid !== user.id && !game.cohosts.includes(user.id) && !this.can('show', null, room)) return;
|
||||
game.end();
|
||||
this.room = targetRoom;
|
||||
this.modlog('MAFIAEND', null);
|
||||
|
||||
@@ -1537,7 +1537,7 @@ const ScavengerCommands: ChatCommands = {
|
||||
const game = room.getGame(ScavengerHunt);
|
||||
if (!game) return this.errorReply(`There is no scavenger hunt currently running.`);
|
||||
if (
|
||||
(!game.hosts.some(h => h.id === user.id) || !user.can('broadcast', null, room)) &&
|
||||
(!game.hosts.some(h => h.id === user.id) || !user.can('show', null, room)) &&
|
||||
game.staffHostId !== user.id
|
||||
) {
|
||||
return this.errorReply("You cannot edit the hints and answers if you are not the host.");
|
||||
@@ -1554,7 +1554,7 @@ const ScavengerCommands: ChatCommands = {
|
||||
const game = room.getGame(ScavengerHunt);
|
||||
if (!game) return this.errorReply(`There is no scavenger hunt currently running.`);
|
||||
if (
|
||||
(!game.hosts.some(h => h.id === user.id) || !user.can('broadcast', null, room)) &&
|
||||
(!game.hosts.some(h => h.id === user.id) || !user.can('show', null, room)) &&
|
||||
game.staffHostId !== user.id
|
||||
) {
|
||||
return this.errorReply("You cannot add more hints if you are not the host.");
|
||||
@@ -1575,7 +1575,7 @@ const ScavengerCommands: ChatCommands = {
|
||||
const game = room.getGame(ScavengerHunt);
|
||||
if (!game) return this.errorReply(`There is no scavenger hunt currently running.`);
|
||||
if (
|
||||
(!game.hosts.some(h => h.id === user.id) || !user.can('broadcast', null, room)) &&
|
||||
(!game.hosts.some(h => h.id === user.id) || !user.can('show', null, room)) &&
|
||||
game.staffHostId !== user.id
|
||||
) {
|
||||
return this.errorReply("You cannot remove hints if you are not the host.");
|
||||
@@ -1598,7 +1598,7 @@ const ScavengerCommands: ChatCommands = {
|
||||
const game = room.getGame(ScavengerHunt);
|
||||
if (!game) return this.errorReply(`There is no scavenger hunt currently running.`);
|
||||
if (
|
||||
(!game.hosts.some(h => h.id === user.id) || !user.can('broadcast', null, room)) &&
|
||||
(!game.hosts.some(h => h.id === user.id) || !user.can('show', null, room)) &&
|
||||
game.staffHostId !== user.id
|
||||
) {
|
||||
return this.errorReply("You cannot edit hints if you are not the host.");
|
||||
|
||||
@@ -1064,7 +1064,7 @@ class TriumvirateModeTrivia extends Trivia {
|
||||
const commands: ChatCommands = {
|
||||
new(target, room, user) {
|
||||
if (!isTriviaRoom(room)) return this.errorReply("This command can only be used in the Trivia room.");
|
||||
if (!this.can('broadcast', null, room)) return false;
|
||||
if (!this.can('show', null, room)) return false;
|
||||
if (!this.canTalk()) return;
|
||||
if (room.game) {
|
||||
return this.errorReply(`There is already a game of ${room.game.title} in progress.`);
|
||||
@@ -1166,7 +1166,7 @@ const commands: ChatCommands = {
|
||||
|
||||
start(target, room) {
|
||||
if (!isTriviaRoom(room)) return this.errorReply("This command can only be used in Trivia.");
|
||||
if (!this.can('broadcast', null, room)) return false;
|
||||
if (!this.can('show', null, room)) return false;
|
||||
if (!this.canTalk()) return;
|
||||
const game = getTriviaGame(this);
|
||||
if (!game) return;
|
||||
@@ -1196,7 +1196,7 @@ const commands: ChatCommands = {
|
||||
|
||||
end(target, room, user) {
|
||||
if (!isTriviaRoom(room)) return this.errorReply("This command can only be used in Trivia.");
|
||||
if (!this.can('broadcast', null, room)) return false;
|
||||
if (!this.can('show', null, room)) return false;
|
||||
if (!this.canTalk()) return;
|
||||
const game = getTriviaGame(this);
|
||||
if (!game) return;
|
||||
@@ -1240,7 +1240,7 @@ const commands: ChatCommands = {
|
||||
add(target, room, user, connection, cmd) {
|
||||
if (room.roomid !== 'questionworkshop') return this.errorReply('This command can only be used in Question Workshop.');
|
||||
if (cmd === 'add' && !this.can('mute', null, room)) return false;
|
||||
if (cmd === 'submit' && !this.can('broadcast', null, room)) return false;
|
||||
if (cmd === 'submit' && !this.can('show', null, room)) return false;
|
||||
if (!target) return false;
|
||||
if (!this.canTalk()) return false;
|
||||
|
||||
@@ -1565,7 +1565,7 @@ const commands: ChatCommands = {
|
||||
|
||||
search(target, room, user) {
|
||||
if (room.roomid !== 'questionworkshop') return this.errorReply("This command can only be used in Question Workshop.");
|
||||
if (!this.can('broadcast', null, room)) return false;
|
||||
if (!this.can('show', null, room)) return false;
|
||||
if (!target.includes(',')) return this.errorReply("No valid search arguments entered.");
|
||||
|
||||
let [type, ...query] = target.split(',');
|
||||
|
||||
@@ -635,7 +635,7 @@ const cmds: ChatCommands = {
|
||||
if (isNaN(parseInt(tid)) || tid.length < 5 || tid.length > 6) return this.errorReply("Invalid TID");
|
||||
const targetUser = Users.get(giver);
|
||||
if (!targetUser || !targetUser.connected) return this.errorReply(`User '${giver}' is not online.`);
|
||||
if (!user.can('warn', null, room) && !(user.can('broadcast', null, room) && user === targetUser)) {
|
||||
if (!user.can('warn', null, room) && !(user.can('show', null, room) && user === targetUser)) {
|
||||
return this.errorReply("/qg - Access denied.");
|
||||
}
|
||||
if (!targetUser.autoconfirmed) {
|
||||
@@ -693,7 +693,7 @@ const cmds: ChatCommands = {
|
||||
if (isNaN(parseInt(tid)) || tid.length < 5 || tid.length > 6) return this.errorReply("Invalid TID");
|
||||
const targetUser = Users.get(giver);
|
||||
if (!targetUser || !targetUser.connected) return this.errorReply(`User '${giver}' is not online.`);
|
||||
if (!user.can('warn', null, room) && !(user.can('broadcast', null, room) && user === targetUser)) {
|
||||
if (!user.can('warn', null, room) && !(user.can('show', null, room) && user === targetUser)) {
|
||||
return this.errorReply("/lg - Access denied.");
|
||||
}
|
||||
if (!targetUser.autoconfirmed) {
|
||||
@@ -910,7 +910,7 @@ const cmds: ChatCommands = {
|
||||
let reply = '';
|
||||
switch (target) {
|
||||
case 'staff':
|
||||
if (!this.can('broadcast', null, room)) return;
|
||||
if (!this.can('show', null, room)) return;
|
||||
reply = '<strong>Staff commands:</strong><br />' +
|
||||
'- question or qg <em>User | OT | TID | Prize | Question | Answer[ | Answer2 | Answer3]</em> - Start a new question giveaway (voices can only host for themselves, staff can for all users) (Requires: + % @ # &)<br />' +
|
||||
'- lottery or lg <em>User | OT | TID | Prize[| Number of Winners]</em> - Starts a lottery giveaway (voices can only host for themselves, staff can for all users) (Requires: + % @ # &)<br />' +
|
||||
@@ -922,7 +922,7 @@ const cmds: ChatCommands = {
|
||||
'- count <em>Mon</em> - Displays how often a certain mon has been given away. Use <code>!giveaway count</code> to broadcast this to the entire room<br />';
|
||||
break;
|
||||
case 'gts':
|
||||
if (!this.can('broadcast', null, room)) return;
|
||||
if (!this.can('show', null, room)) return;
|
||||
reply = '<strong>GTS giveaway commands:</strong><br />' +
|
||||
'- gts start <em>User | Amount | Summary of given mon | What to deposit | What to look for</em> - Starts a gts giveaway (Requires: % @ # &)<br />' +
|
||||
'- gts left <em>Amount</em> - Updates the amount left for the current GTS giveaway. Without an amount specified, shows how many Pokémon are left, and who the latest winners are.<br />' +
|
||||
|
||||
@@ -168,7 +168,7 @@ export const commands: ChatCommands = {
|
||||
const data = await YouTube.randChannel();
|
||||
if (!data) return this.errorReply(`Error in getting channel data.`);
|
||||
if (this.broadcasting) {
|
||||
if (!this.can('broadcast', null, room)) return false;
|
||||
if (!this.can('show', null, room)) return false;
|
||||
this.addBox(data);
|
||||
room.update();
|
||||
} else {
|
||||
|
||||
@@ -593,7 +593,7 @@ export class CommandContext extends MessageContext {
|
||||
|
||||
checkSlowchat(room: Room | null | undefined, user: User) {
|
||||
if (!room || !room.settings.slowchat) return true;
|
||||
if (user.can('broadcast', null, room)) return true;
|
||||
if (user.can('show', null, room)) return true;
|
||||
const lastActiveSeconds = (Date.now() - user.lastMessageTime) / 1000;
|
||||
if (lastActiveSeconds < room.settings.slowchat) return false;
|
||||
return true;
|
||||
@@ -787,7 +787,7 @@ export class CommandContext extends MessageContext {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.room && !this.user.can('broadcast', null, this.room)) {
|
||||
if (this.room && !this.user.can('show', null, this.room)) {
|
||||
this.errorReply(`You need to be voiced to broadcast this command's information.`);
|
||||
this.errorReply(`To see it for yourself, use: /${this.message.slice(1)}`);
|
||||
return false;
|
||||
@@ -1034,7 +1034,7 @@ export class CommandContext extends MessageContext {
|
||||
|
||||
if (room?.settings.highTraffic &&
|
||||
toID(message).replace(/[^a-z]+/, '').length < 2 &&
|
||||
!user.can('broadcast', null, room)) {
|
||||
!user.can('show', null, room)) {
|
||||
this.errorReply(
|
||||
this.tr('Due to this room being a high traffic room, your message must contain at least two letters.')
|
||||
);
|
||||
|
||||
@@ -1424,7 +1424,7 @@ export const Punishments = new class {
|
||||
buf += `<th>Expire time</th>`;
|
||||
buf += `<th>Reason</th>`;
|
||||
buf += `<th>Alts</th>`;
|
||||
if (user.can('ban')) buf += `<th>IPs</th>`;
|
||||
if (user.can('globalban')) buf += `<th>IPs</th>`;
|
||||
buf += `</tr>`;
|
||||
for (const [userid, punishment] of punishments) {
|
||||
const expiresIn = new Date(punishment.expireTime).getTime() - Date.now();
|
||||
@@ -1436,7 +1436,7 @@ export const Punishments = new class {
|
||||
buf += `<td>${expireString}</td>`;
|
||||
buf += `<td>${punishment.reason || ' - '}</td>`;
|
||||
buf += `<td>${punishment.userids.join(", ") || ' - '}</td>`;
|
||||
if (user.can('ban')) buf += `<td>${punishment.ips.join(", ") || ' - '}</td>`;
|
||||
if (user.can('globalban')) buf += `<td>${punishment.ips.join(", ") || ' - '}</td>`;
|
||||
buf += `</tr>`;
|
||||
}
|
||||
buf += `</table>`;
|
||||
|
||||
@@ -4,14 +4,14 @@ export const PLAYER_SYMBOL: GroupSymbol = '\u2606';
|
||||
export const HOST_SYMBOL: GroupSymbol = '\u2605';
|
||||
|
||||
export const ROOM_PERMISSIONS = [
|
||||
'addhtml', 'announce', 'ban', 'broadcast', 'bypassafktimer', 'declare', 'editprivacy', 'editroom', 'exportinputlog', 'game', 'gamemanagement', 'gamemoderation', 'joinbattle', 'kick', 'minigame', 'modchat', 'modchatall', 'modlog', 'mute', 'nooverride', 'receiveauthmessages', 'roombot', 'roomdriver', 'roommod', 'roomowner', 'roomvoice', 'showmedia', 'timer', 'tournaments', 'warn',
|
||||
'addhtml', 'announce', 'ban', 'bypassafktimer', 'declare', 'editprivacy', 'editroom', 'exportinputlog', 'game', 'gamemanagement', 'gamemoderation', 'joinbattle', 'kick', 'minigame', 'modchat', 'modchatall', 'modlog', 'mute', 'nooverride', 'receiveauthmessages', 'roombot', 'roomdriver', 'roommod', 'roomowner', 'roomvoice', 'show', 'showmedia', 'timer', 'tournaments', 'warn',
|
||||
] as const;
|
||||
|
||||
export const GLOBAL_PERMISSIONS = [
|
||||
// administrative
|
||||
'bypassall', 'console', 'disableladder', 'lockdown', 'potd', 'rawpacket',
|
||||
// other
|
||||
'addhtml', 'alts', 'autotimer', 'ban', 'bypassblocks', 'bypassafktimer', 'forcepromote', 'forcerename', 'forcewin', 'gdeclare', 'ignorelimits', 'importinputlog', 'ip', 'lock', 'makeroom', 'modlog', 'rangeban', 'promote',
|
||||
'addhtml', 'alts', 'autotimer', 'globalban', 'bypassblocks', 'bypassafktimer', 'forcepromote', 'forcerename', 'forcewin', 'gdeclare', 'ignorelimits', 'importinputlog', 'ip', 'lock', 'makeroom', 'modlog', 'rangeban', 'promote',
|
||||
] as const;
|
||||
|
||||
export type RoomPermission = typeof ROOM_PERMISSIONS[number];
|
||||
|
||||
@@ -172,16 +172,16 @@ describe('Users features', function () {
|
||||
});
|
||||
it(`should allow 'u' permissions on lower ranked users`, function () {
|
||||
const user = new User();
|
||||
user.group = '&';
|
||||
assert.equal(user.can('promote', user), false, 'targeting self');
|
||||
user.group = '@';
|
||||
assert.equal(user.can('globalban', user), false, 'targeting self');
|
||||
|
||||
const target = new User();
|
||||
target.group = ' ';
|
||||
assert.equal(user.can('promote', target), true, 'targeting lower rank');
|
||||
assert.equal(user.can('globalban', target), true, 'targeting lower rank');
|
||||
target.group = '@';
|
||||
assert.equal(user.can('globalban', target), false, 'targeting same rank');
|
||||
target.group = '&';
|
||||
assert.equal(user.can('promote', target), false, 'targeting same rank');
|
||||
target.group = '~';
|
||||
assert.equal(user.can('promote', target), false, 'targeting higher rank');
|
||||
assert.equal(user.can('globalban', target), false, 'targeting higher rank');
|
||||
});
|
||||
it(`should not allow users to demote themselves`, function () {
|
||||
room = Rooms.createChatRoom("test");
|
||||
|
||||
Reference in New Issue
Block a user