Commit Graph

275 Commits

Author SHA1 Message Date
Guangcong Luo
2e9328eada Support annotating chat commands
The nullable room refactor made it so there was no longer an easy way
to tell if a command could be used in PMs. This adds it back, as a
property on the handler function itself.

Now that we have properties on handler functions, I also added
`broadcastable` for whether or not the command is broadcastable.

It uses `Function#toString`, which is generally frowned-upon, but it's
well-specified and only happens during startup, so it shouldn't affect
performance after startup.

This also allows us not to need to repeat ourselves or give up
flexibility to have metadata about commands, which I think is worth the
tradeoff of reflection generally.
2020-07-13 00:55:23 -07:00
Guangcong Luo
52f0096c30 Refactor Auth.hasPermission
Half the permissions checks were previously in `user.can`, which is
unintuitive. It's now completely self-contained and should be pretty
readable, now, with `getEffectiveSymbol` and `hasJurisdiction` as
separate functions.
2020-07-13 00:55:23 -07:00
Annika
b590d3c907
Add /noreply command (#6953)
This command should never be used by users.

This is for scripting, like buttons, like:

    <button name="send" value="/nofeedback /ionext">

so they don't spam your PMs.
2020-07-10 22:01:15 -07:00
Guangcong Luo
9fe5a0e063 Improve "Message can't be blank" error
It was previously a popup, but there's no need for that anymore. An
`errorReply` is much friendlier.
2020-07-10 05:06:02 -07:00
Guangcong Luo
faab60a618 Unify command logging code
Global punishments like /lock will notify Staff, and admin commands
like /updateserver will log to Staff, but this has been done ad-hoc
in the past.

To handle these cases, this commit introduces new chat-context
functions:

- `this.addGlobalModAction`,
- `this.privateGlobalModAction`
- `this.stafflog`

Other updates:

- the issue where Staff notifications didn't show up until someone talks
  has been fixed
- `privateModAction`s in Staff will now be visible in the scrollback
  log
- a bunch of commands that should notify Staff but didn't now do
- some typos in modlogs have been fixed
2020-07-07 18:51:29 -07:00
Guangcong Luo
d6de3ce6eb Fix typo in HTML scripted button validator 2020-07-07 21:27:04 -04:00
Kirk Scheibelhut
eea2196280
Server side changes to support persistent user settings and privacy changes (#6947)
NOTE: This is changes the semantics of `hidenext`/`ionext` from
applying to the next created *battle* to applying to the next
created *search*/*challenge*.
2020-07-06 21:18:38 -07:00
Guangcong Luo
c124720885
Support throwing error messages (#6946)
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.
2020-07-06 14:07:02 -07:00
Mia
4997a47314
Commands: Allow the room parameter to be null (#6948)
Co-authored-by: Guangcong Luo <guangcongluo@gmail.com>
2020-07-05 14:25:09 -07:00
Guangcong Luo
d7ba455e2b 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.
2020-07-03 17:32:49 -04:00
Guangcong Luo
f16849eda3 Support addModAction/privateModAction in PMs 2020-07-03 01:18:17 -04:00
Guangcong Luo
26615490f7 Merge BasicChatRoom and BasicRoom
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.
2020-07-02 18:54:02 -07:00
Guangcong Luo
ba1730900f Support comments in /roomintro etc 2020-07-02 14:34:53 -04:00
Guangcong Luo
46c9afa2f3
"Remove" the global room (#6885)
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")
2020-07-02 11:31:34 -07:00
Guangcong Luo
6af875af8b Improve RoomPermission/GlobalPermission checks
Global permissions can no longer be used as room permissions. Instead,
the two are entirely separate lists, with only a few permissions in
both lists.
2020-06-21 03:53:06 -07:00
Guangcong Luo
ee6e43b552 Strongly type RoomPermission and GlobalPermission
`user-groups.ts` now tracks the list of possible values for
`RoomPermission` and `GlobalPermission` in a const.
2020-06-21 01:43:27 -07:00
Mia
d2b255b934
/eval: Log in dev room and broadcast (#6871)
Co-authored-by: Guangcong Luo <guangcongluo@gmail.com>
2020-06-18 23:28:15 -07:00
Guangcong Luo
ba53a2831c Fix bugs in /show
- Chat.getImageDimensions and Chat.fitImage now throw if passed things
  that aren't image URLs.
- Fix help message if you use /show by itself
- Link to full aize image if image is shrunk
2020-06-17 21:11:52 -04:00
Charlie Kobayashi
95b29974fd
Fix server crash from overlength posts (#6847)
(Server would crash and be unable to handle any further inputs from users)

Byproduct of #6745
2020-06-16 19:42:55 -07:00
Mia
6c97866f83
Add commands to show media in chat (#6745) 2020-06-16 14:40:10 -07:00
Guangcong Luo
e0f97dcf6b Replace Chat.uncache* with Utils.clearRequireCache
This replaces the old approach with a new "clear everything except a
whitelist" approach, which should overall involve much less code and
lead to fewer bugs of the "the path changed for a module and I forgot
to update the uncache paths" variety.

I considered a lot of other approaches, but they seem to have more
flaws without any advantages in exchange for them. (We moved away
from `uncacheTree` because it only tracks the first require: there's
no way to get a full list of dependents for a module, only its first
dependent.)
2020-06-12 22:02:32 -07:00
Austin Couturier
c9b2b9dbf2
Change |pm|~ to |pm|& (#6827) 2020-06-10 21:53:36 -07:00
Guangcong Luo
140f4ad936 Support /forceroompromote
Previously, forcepromotes were done with a !!! sigil, which was
kind of silly. They now use a command starting with "force", as
is standard.
2020-06-10 11:23:20 -04:00
Mia
6839a1f4db
Add a library for utility functions (#6817) 2020-06-09 22:06:43 -07:00
Mia
15fed24b40
Refactor auth and room.settings (#6777)
This implements two big changes:

- All settings shared between `room.chatRoomData` and `room` have been
  merged into `room.settings` (so, for instance, `room.slowchat` is now
  only `room.settings.slowchat`).

  This makes it so we never have to worry about them getting "out of
  sync".

  - Checking to see if a room is persistent is now `if (room.persist)`
    instead of `if (room.chatRoomData)`

  - `Rooms.global.writeChatRoomData()` is now rarely called directly;
    there's a new `room.saveSettings()` which will handle it for you.

  - All properties of `room.settings` are now optional (except
    `title`).

- There's a new file `user-groups.ts` which handles authority.

  - `room.auth` and `Users.globalAuth` are now
    `Auth extends Map<ID, GroupSymbol>` objects.

  - `room.auth` is now always defined, removing the need for
    `room.auth?.[userid]` workarounds.

  - A lot of code relating to usergroups and permission checks have
    been refactored.

Co-authored-by: Guangcong Luo <guangcongluo@gmail.com>
2020-06-09 08:22:25 -07:00
Guangcong Luo
08420c7feb Reassign hotpatch permissions
Currently, 'hotpatch' and 'lockdown' are admin permissions, and
'console' is a console admin permission. In preparation for the
admin/leader unification, I'm removing the hotpatch permission:

- /memoryusage, /loadbanlist, /adddatacenters, /refreshpage,
  /loadbanlist have been moved from 'hotpatch' to 'lockdown'. This
	doesn't change anything, I'm just unifying the permission name.

- /updateserver has been moved from 'hotpatch' to 'console'.
  /updateserver in combination with either hotpatch or lockdown can be
	used for arbitrary code execution, and is approximately as dangerous
	as any other console command.

- /hotpatch, /savelearnsets have been moved from 'hotpatch' to
  'console'. They're reasonably harmless, but they don't do anything
	without console access, so a non-console admin using them is nearly
	definitely some sort of mistake.

`user.hasConsoleAccess` now also has a CommandContext function
`this.canUseConsole` to handle its error message.
2020-06-06 07:44:31 -07:00
Mia
f52b456b9a
Chat: Make HTML pages display an error on crash (#6782) 2020-06-02 09:02:48 -07:00
Guangcong Luo
6a8e166af1 Improve broadcast (!command) errors 2020-05-29 04:22:40 -04:00
PartMan
10a50d68a5
Allow scripted buttons to PM bots (#6724) 2020-05-22 18:21:48 -07:00
PartMan
d1394a6346
Add case insensitivity to Scripted Buttons (#6711) 2020-05-17 14:50:16 -07:00
Guangcong Luo
88365abc4a Fix overzealous HTML validator
I forgot h1-h6 could have numbers in them...
2020-05-16 11:55:14 -04:00
Guangcong Luo
1d6d8f73da Refactor HTML validator
Mostly, extraneous `<` tags are now correctly detected, with a better tag tokenizer.
I also removed the separate passes for <img> and <button> validation.

Fixes #6685

Thanks PartMan for contributing some ideas.
2020-05-16 10:51:45 -04:00
fart
160a737979
escapeHTML when notifications blocked (#6644) 2020-05-02 15:27:44 -07:00
Guangcong Luo
1dada44a2a Support server/chat-plugins/private as symlink 2020-04-25 15:51:11 -04:00
Guangcong Luo
a049d85a98 Fix build errors from TypeScript update
I'm not entirely sure why these two errors are cropping up now, but
they are.

The "thenable" one seems to be a bug, but in what?
2020-04-17 23:00:28 -07:00
Kris Johnson
994fc60aed
Rename Template to Species (#6478) 2020-03-25 23:29:27 -07:00
Guangcong Luo
7de51956c5 Change BasicChatRoom to Room in some types
`user.can` and `user.authAtLeast` now take `Room | BasicChatRoom`
instead of `BasicChatRoom`. It's now significantly less necessary to
cast things to `BasicChatRoom`.
2020-03-15 19:52:59 -07:00
Guangcong Luo
35aad974f8 Implement Chat.normalize 2020-03-13 22:30:17 -04:00
Guangcong Luo
647ba61a46 Turn on prefer-regex-exec in eslint 2020-03-07 13:39:02 -08:00
Guangcong Luo
125fe31d06 Improve eslintrc
Fixed some more code style, allowing these rules to be enabled:

- `comma-dangle`
- `function-paren-newline`
- `member-delimiter-style`
- `no-eval`
- `no-fallthrough`
- `no-misused-promises`
- `no-unused-vars`
- `operator-linebreak`
2020-03-06 22:35:55 -08:00
Waleed Hassan
8aa4f053bb
Use optional chaining and linter improvements (#6422)
This is mostly just a follow up to #6342.

`prefer-optional-chaining` was turned on and fixed in every location it
complained in. The transformed function [0] looks expensive from a
glance but from skimming through the replaced sites it doesn't appear
to be ran in any important place, so it should be OK.

The linter improvements are:
- Increase linter performance
	- Make `full-lint` and `lint` write to different caches so we
	  avoid overwriting their caches since they're different configs
	- Change husky's hook to `npm run lint` so as to write to the
	  same cache
	- Remove `@typescript-eslint/eslint-plugin-tslint` which is
	  essentially a wrapper to TSLint because the rules aren't worth
	  running another linter
- Convert `.eslintrc.json` and `.eslintrc-syntax.json` to two spaces
  rather than four tabs to respect PS' `.editorconfig`
- Rename `fulllint` to `full-lint` to ease spelling it

[0] - https://pastie.io/mmtxpf.js (prettified)
2020-03-06 11:44:32 -08:00
Guangcong Luo
b21c9047e2
Migrate to typescript-eslint (#6342) 2020-03-05 08:33:06 -08:00
Kris Johnson
9aaab2c57b
Typescript Help Tickets and Modlog and fix warnings (#6352) 2020-02-12 21:48:03 -08:00
Ben Davies
e8c8e0d9bd Add CommandContext#shouldBroadcast and fix !code permission checks (#6198) 2019-12-28 16:26:50 +09:00
whales
0b9d8dd109 Support declarative roomsettings syntax (#6119) 2019-12-06 23:16:55 +09:00
whales
f7d5cefc7d Refactor tournament plugin loading (#6118) 2019-11-30 17:53:01 +13:00
Guangcong Luo
23f9bfa1b7
Split up server/chat-commands/ (#5943)
`server/chat-commands.js` is now a directory. It's been split into
`core`, `moderation`, and `admin`. `info` and `roomsettings` from
`chat-plugins` have also moved to `chat-commands`.

Some cleanup:

- Bot commands for inserting HTML into rooms like `/adduhtml` have been
  moved from `info` into `admin`.

- `/a` has been renamed `/addline`, for clarity (and also moved from
  `info` into `admin`).

- Room management commands like `/createroom` and `/roomintro` were
  moved to `room-settings`

- `chat-commands/admin` has been TypeScripted
2019-11-15 11:12:54 +13:00
Guangcong Luo
c40a7d2fb2 Allow broadcastable commands in command console
Command consoles previously would silently fail if you used a
broadcastable command (like `/dt` or `/learn`). They are now let
through, although actually trying to broadcast (like `!dt`) will
still show an error message.
2019-11-11 02:13:48 +13:00
Astrid Halberkamp
a3244a7449
Fix URL detection in usernames 2019-11-10 13:23:11 +01:00
Waleed Hassan
28e870c4fb Server: Use readonly where appropriate (#5902) 2019-10-21 16:12:32 +10:30
Astrid Halberkamp
a1d4b420cd
Refactor filters to always use regex (#5859)
* Refactor filters to always use regex

* Update server/chat-plugins/chat-monitor.js

Co-Authored-By: Kirk Scheibelhut <scheibo@users.noreply.github.com>

* Simplify evasion detection regex storage after peach rightfully pointed out how fucking stupid i am

* Put this garbage in adminlog if that room exists

* fix tslint
2019-10-18 21:19:39 +02:00
Lusamine
9d6fbdba41 Fix globalModlog modlogging twice in some cases (#5890) 2019-10-18 09:41:13 +10:30
asgdf
edebcbc4a9 Support loading plugins from chat-plugins/private/ (#5867) 2019-10-14 11:11:37 +11:00
TheMezStrikes
3178912a52 Trim all command arguments (#5865) 2019-10-11 05:32:07 +11:00
whales
ea2dea1283 Rooms: Rooms.get can return null (#5860) 2019-10-09 18:52:33 +11:00
Guangcong Luo
71498d451d
New validator (#5840)
* Refactor validator

This is a major refactor intended to make the default rules easier to
understand, and also easier for OMs to bypass.

Removed rules:
- `Pokemon`: This is now `-Nonexistent`. Its previous name was intended
  to be interpreted as "simulate the Pokémon games exactly, and only
  allow what they allow". The new name should make it clearer that it
  mainly bans CAPs and other nonexistent Pokémon and functionality.
- `-Illegal`: This is now `Obtainable` (see below).
- `Allow CAP`: This is now `+CAP`. Instead of having a hardcoded rule,
  OMs can now be manually whitelist any pokemon/item/etc or group of
  them, overriding `-Nonexistent`.
- `Ignore Illegal Abilities`: This is now `!Obtainable Abilities` (see
  below).

`Obtainable` was previously `-Illegal`, and does the same thing: Makes
sure you have a regular Pokémon game with only Pokémon that can be
obtained without hacking.

But instead of being a ban, it's now a rule that does nothing by
itself, except contain more rules:
- `Obtainable Moves`
- `Obtainable Abilities`
- `Obtainable Formes`
- `Obtainable Misc`
- `-Nonexistent`
- `-Unreleased`

This allows OMs to piecemeal repeal and unban any of these individual
rules, instead of the previous approach of unbanning them all and
manually reimplementing every single validation you wanted to keep.

* Refactor PokemonSources into a class

This mostly just makes a lot of the weirder checks in the validator
substantially more readable.

This also renames `lsetData` to `setSources`, which should also help
readability.

* Validate Bottle Cap HP types

Fixes an issue reported here:

https://github.com/Zarel/Pokemon-Showdown/issues/5742#issuecomment-533850288

* Fix several move validation issues

Fixes #5742

We have a new MoveSource type: R for Restricted. R moves work like
level-up/tutor/TM moves, except you're limited to one R move.

- Shedinja move stolen from Ninjask in Gen 3-4 are now R moves instead
  of event moves. This allows them to coexist with Nincada egg moves.

- Necrozma-DW/DM now inherit moves/events from Necrozma (like Rotom,
  but with event validation). This allows them to be shiny.

- Pokemon can now get egg moves from their own evolutions. This fixes
  some Tyrogue, Charmander, and Treecko sets mentioned in #5742

- Some more C moves were added, fixing some Hitmontop and Chatot sets
  mentioned in #5742

* Improve ability/move compatibility validator
2019-10-06 04:21:30 +11:00
Waleed Hassan
5607c158e4 Use void in promises to appease TSLint (#5827) 2019-10-03 19:08:30 +10:00
Waleed Hassan
da4b887054 Rename Room#id -> Room#roomid, User#userid -> User#id (#5826)
These should make it clearer that userids are IDs but roomids aren't.
2019-10-03 18:57:38 +10:00
whales
31ead12588 Type Chat.tr properly (#5814) 2019-09-25 15:06:12 +02:00
Astrid Halberkamp
c02bd7c53f Chat: fix indentation
TODO: fix my VSC installation so this doesn't happen again
2019-09-25 13:29:35 +02:00
Astrid Halberkamp
35d9cb6ec6 Make canTalk() translatable
Thanks peach for figuring out the absolute hell of a type signature for Chat.tr
2019-09-25 13:27:38 +02:00
whales
cdff583606 Fix blocking PMs (#5797) 2019-09-19 15:05:24 +09:30
whales
4d9e87cd78 Support blockPMs ac / trusted (#5790) 2019-09-17 18:22:40 +10:00
TheJetOU
f51a1f3742 Add CommandContext method for Chat#(status)filter (#5737)
* Add CommandContext method for Chat#(status)filter

* Don't use instanceof
2019-09-15 06:25:54 +02:00
whales
b8114fbae0 Improve username punishments (#5743)
* Improve username punishments

Track how many times a name has been forcerenamed, note differently for offline warns and forcerenames

* Hyperlink names, show trusted/ac/registered

* rebase

* pseudorank -> accountstatus
2019-09-15 06:25:15 +02:00
whales
16551a7c5c Typescript lottery (#5739) 2019-08-30 09:12:49 -05:00
whales
f143d83a67 Refactor Chat to a big class (#5729) 2019-08-27 08:08:33 -07:00
TheJetOU
2b28c9fd6b Refactor Rooms(), Users() to Rooms.get(), Users.get() (#5725) 2019-08-25 06:33:56 -07:00
Jeremy Piemonte
9a2b2fed90 Allow non-ac users to send links in help tickets (#5726) 2019-08-25 05:04:28 -07:00
Guangcong Luo
e0a2cf07e1 Correctly define global types for .ts files
Global types are defined differently for `.ts` files than for `.js`
files, leading to some confusion for past refactors.

This commit defines them correctly.

I'm also considering making certain global types only available under
namespaces, but I don't want to do that to `User` or `Room`, so for
now, there are no changes there, besides putting streams in the
`Streams` namespace (so `WriteStream` is now `Streams.WriteStream`).
2019-08-23 09:33:49 -07:00
TheJetOU
5597916644 TypeScript Rooms and Roomlogs (#5699) 2019-08-14 20:44:57 +02:00
TheJetOU
f586e88326 Simplify Map declarations (#5702) 2019-08-13 17:23:27 +02:00
Kirk Scheibelhut
9ab3f5a668
Make /hotpatch fail if git history hasn't changed (#5688)
/forcehotpatch can be used to perform the hotpatch regardless.
2019-08-12 10:23:24 +02:00
TheJetOU
af93684d5e Fix Chat#collapseLineBreaksHTML 2019-08-11 11:03:35 -05:00
whales
10266ffe92 Typescript chat (#5620) 2019-08-10 15:30:34 -07:00