The idea is that throwing `ErrorMessage` will replace needing to pass
`context` variables around (which make it hard to unit test a lot of
chat functions).
I recognize the drawback is that it makes it harder to tell where
chat commands might return from. This might be somewhat alleviated by
a convention such as prefixing everything with `check`
this.checkBroadcastable();
this.checkCan('lock');
I honestly didn't like the old approach of `if (!this.can(...)) return`,
though. It didn't seem very obvious which commands would show error
messages and which needed you to write your own error messages. I think
the new system would at least be clearer about that.
We can also consider things such as some sort of sigil, such as:
!this.checkCan('lock');
There's no other reason to use `!` at the beginning of a line, so I
think this is reasonably unambiguous, although it might take some
time to learn. Also we'd have to screw with eslint.
Another alternative is something all-caps?
this.CHECK_can('lock');
In the end, I still think `this.checkCan('lock')` would be enough, and
I still think it's already an improvement in many ways.
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.
They were only ever kept separate because of GlobalRoom. It might be
useful to support rooms that aren't ChatRooms, but we've been chucking
properties into either BasicChatRoom or BasicRoom essentially at
random, so I think it makes sense to wait until we actually have a
use-case for a non-Chat room before carefully deciding which properties
belong where.
I couldn't completely remove the global room in one commit, but this
solves basically every problem with it by making it no longer a `Room`.
In particular, this means:
- It's no longer of type `Room`
- It's no longer in the `Rooms.rooms` table
- Its class name is now `GlobalRoomState` rather than `GlobalRoom`
- It no longer tracks its own user list (online user count is now
provided by `Users.onlineCount`)
- It's no longer a socket channel (there's new syntax for "send this
message to every user")