/yearlockip works like /lockip, but lasts for a year. It's intended to
be used to punish users who troll over a long term, but from a static
IP.
I've also separated strings out in a way that should make them slightly
easier to translate in the future.
This adds a bunch of minor fixes to /updateserver. The big one is that
we no longer stash untracked files, which should fix the problem where
it sometimes takes forever to update.
However, it seems like conflicting untracked files sometimes corrupts
the Git system?
zarel@cytosine ~/W/psserver (master)> git rebase FETCH_HEAD
Created autostash: abc06bdca
First, rewinding head to replay your work on top of it...
error: The following untracked working tree files would be overwritten by checkout:
server/chat-plugins/help.ts
Please move or remove them before you switch branches.
Aborting
fatal: Could not detach HEAD
zarel@cytosine ~/W/psserver (master|AM/REBASE)> git rebase --abort
error: could not read '.git/rebase-apply/head-name': No such file or directory
I couldn't reliably reproduce this, unfortunately, but I've switched to
`git rebase --no-autostash FETCH_HEAD` to be safe. File conflicts
are really rare in general, so I don't think that needs to be a
blocker.
This doesn't really have any nice-to-have automatic restoration
features but it should be all the important parts.
`user.group` no longer exists, and has been replaced with
`user.tempGroup`, which now applies both to temporary promotions of
unregistered users, as well as temporary hidden ranks of auth.
The crashes in the daily spotlight plugin were caused by `/queuedailyat` leaving an empty daily that can't be parsed before failing. This should solve it, but some rooms' spotlight data may still cause crashes. (These rooms should use `/removedaily`.)
`this.dex.deepClone` still exists as an alias to `Utils.deepClone` for
use in `data/`. I'll need to spend more time figuring out the correct
solution there.
At the moment, the staff intro and pending requests only appear on manual joins, not on autojoin. This is because `user.can('mute', null, this)` results false when it is run since the user is not yet logged in. This change creates a new method for generating the staff intro that is run after the user is fully logged in. It also modifies the original `getIntroMessage` so that the staff intro and pending requests still appear on manual joins.
Co-authored-by: Guangcong Luo <guangcongluo@gmail.com>
Changes this makes:
a) Lets people use `/pm` or `/w` instead of `/msg` in buttons.
b) Permits the author of the HTML to direct messages towards themselves via buttons (useful for when Bots creates subroomgroupchats and become *, or if they suddenly want hugs from random people).
Co-authored-by: Guangcong Luo <guangcongluo@gmail.com>
Co-authored-by: Mia <49593536+mia-pi-git@users.noreply.github.com>
Private commands can now use `this.privatelyCan` instead of `this.can`
to automatically display "command not found" in the command
(and in Help) for permission failure. They can also use
`this.commandDoesNotExist` to explicitly invoke the error message.
I'm not merging #7141 because I wrote basically all of the code
in this commit, and future blames should go to me if something here
is wrong.
Closes#7141
Co-authored-by: Mia <49593536+mia-pi-git@users.noreply.github.com>
Regular ReadStreams still can't; I now believe they shouldn't have a
"default" read method, and you should explicitly choose whether you
want to read "by chunks as they become available", "by chunks of a
specific line" or "by a delimiter".
So you would specifically use `stream.byLine()` or
`stream.byChunk([size])`, which would return an
`ObjectReadStream<string>`.
Inspired by #7195
After a Policy decision within Wi-Fi Staff, it's been decided to update the
Lottery Giveaway to still pick winners when there are less than maxWinners,
but people entered. This will allow low entry GA's to overestimate and still
have winners.
We were previously using `type Foo = import('bar').Foo` which works
actually equally well, because sucrase didn't support `import type`,
but now it does!
- Add new command to directly stuff a hunt back into the queue
- Better queue response
- Fix extra spaces in teamscav team names
- Get rid of some old code tidbits that were neccessary when roomlogs were still bork
This removes any extra unnecessary newlines at the end of each message sent to each client, and will always handle all messages assigned to the buffer properly.
onChatMessage previously took `string | false`, where `false` means
"let the message through". This is a reversal of what `false` usually
means, so this is now updated to `string | void`, which should be
much clearer.
- `ip` and `ipself` are now separate permissions. This means that `ip`
is now a generalized permission for viewing IPs (no more need to use
`globalban`, since `ipself` now controls the ability to see your own
IP address)
- `alts` and `altsself` are now also separate (all users used to be
able to `altsself`).
- `modchat`, `modchatall`, and `manageroom` are now just one `modchat`
permission whose jurisdiction controls how high you can set modchat.
`BattlePokedex` is now `Pokedex`, `BattleItems` is now `Items`, etc.
I also renamed `Movedex` to `Moves` and `Statuses` to `Conditions`.
`TypeChart` isn't `Types` yet, because unlike the others, it's not
indexed by ID. That should probably be fixed one day.
Previously, group config inheritance inherited everything, including
obviously wrong things like `name`. This commit fixes it so only
permissions are inherited.
In particular, this means that `globalGroupInPersonalRoom` is not
inherited, finally solving that particular bug although I'm still
not sure what made it originally work correctly and what changed.
Fixes#7043
This will actually destroy groupchats when a user is locked/globally banned, which to my understanding is the intended behavior.
`continue`ing when a room isn't persistent makes no sense, since groupchats are by definition not persistent.
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.
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.
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.
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
NOTE: This is changes the semantics of `hidenext`/`ionext` from
applying to the next created *battle* to applying to the next
created *search*/*challenge*.
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")
String#split with an empty string as an argument butchers Unicode
codepoints that are more than one character long.
String#[Symbol.iterator] doesn't, and is also faster.
- 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
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.)
Previously, ending a read stream was `stream.push(null)`, and ending a
write stream was `stream.end()`. This was often confusing, and so now,
these are consistently `stream.pushEnd()` and `stream.writeEnd()`.
This refactor already found a bug in which `stream.end()` was used
where `stream.push(null)` should have been.
Also in this refactor: By default, `pushError` ends the stream. You can
pass `true` as the second parameter if the error is recoverable (the
stream shouldn't end).
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>
A lot of people had been asking about whether it was possible to search for moves with a high critical-hit ratio (relevant for building with things like Sniper or Focus Energy).
(Also includes a refactor to cut down on the number of type assertions
necessary in movesearch code, by Zarel)
Co-authored-by: Guangcong Luo <guangcongluo@gmail.com>
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.
PR #6781 only fixed one of the crashes; the real problem was that the
code expects aliases to be an empty array if rooms have no aliases,
which have multiple flaws including unnecessarily taking up JSON
space.
- Long answers now wrap (I tried so many different ways to do this
in CSS, involving nested divs with max-width, and ended up giving
up and just inserting `<wbr />`s into the code.
- Hints are now in boxes, making them easier to see
- There's a "to answer, use /scavenge ANSWER" prompt next to the
hunt start message, to help new players.
- Fixed a bug with help permissions
This is a really minor thing, but fewer words tend to make
sentences more readable, and crash messages should focus more
on why something crashed than the crash itself.
I didn't notice that this command was named `/rename` and not
`/renameroom`. The problem was that `/rename` looks like it renames
users (like a non-forced version of `/forcerename`), and all other
room commands with this ambiguity do have `room` in them, like
`/deleteroom`, for this exact reason.
uhtmlchange messages, which should never have been in the chatlog
in the first place, are now always hidden.
uhtml messages are now hidden by default (can be shown with the `all`
option), because they lead to huge message sizes which cause problems
with the server, in gamecorner and a few other rooms which use it a
lot.
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.
This mostly serves to provide cleaner and more consistent field
naming. maxMove currently doesn't have boosts or effects to group
together but who knows what will be thrown at us via DLC, and being
symmetrical with zMoves is a nice.
Guests usually don't appear in join/leave/rename messages, but it's
possible for a bot to /trn to a guest nick with an assertion from the
login server and trigger a leave message for a guest nick to get sent.
This shouldn't have any consequences for the official client, but can
crash bots that keep state for users.
For historical reasons, move property definitions have been very blurry
across `EffectData`. Fortunately, recent refactors have made it
possible to put them all where they're supposed to be.
Not having prefer-const on the JS side makes JS -> TS refactors really
unreadable. This commit just auto-fixes it so we're using
`prefer-const` everywhere.
Custom room rank symbols will now override all other ranks in the
userlist.
Their permissions now also fall back to global permissions.
(Also fix an obscure crash with custom rank symbols.)
Previously, if you gave e.g. roomvoice to a global moderator, that
would demote their room rank to voice. Now, they will remain a
moderator, with "voice" only appearing in `/roomauth` and `/auth`.
(Includes a refactor of Config.groups)
* Attribute non-host mod commands
* Fix crash in queue
* Add command for listing all data entries
* Update permissions in help box
credits to @Claire238
We previously only reported the first line of the stack trace, but now that .readmore exists, showing
the full stack trace isn't too spammy anymore.
Also, private logs are now put into Upper Staff.
Pokemon that are not available in-game are now consolidated into `isNonstandard`. 'Past' indicates that the Pokemon no longer works in the current generation. 'Unobtainable' indicates that the Pokemon works but can only be obtained through hacking.
If /hidetext is used with a linecount parameter on a trusted user, it currently says "USER, 4 is a trusted user, are you sure you want to hide their messages? Use /forcehidetext if you're sure." This change hides the additional linecount parameter from the message.
- apply them as "formats"/"mods" instead of a large parent game with another room game nested inside
- the parent game is attached to ``room.scavgame`` as an independent object instead.
- add a command to set the twist (/scav settwist) and reset the twist (/scav resettwist) for scripted formats
- this means that scavenger-games.js might be updated once per month as new twists are created.
- add a command to start a regular hunt with twists
More than one twist can be loaded into a single scavenger hunt (from scavenger game mode + /scav createtwist)
- global auth should now be able to see chat logs of rooms they can't
moderate
- secret and personal rooms that a staff member is either currently in,
or has auth in, will now show up in the main logs list (although
you should just use /chatlog, it's much easier)
`user.can` and `user.authAtLeast` now take `Room | BasicChatRoom`
instead of `BasicChatRoom`. It's now significantly less necessary to
cast things to `BasicChatRoom`.
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)
The most recent change to this file prevents "/tour autodq off" from working and sends a "That isn't a valid timeout value." error to the client. This is because it checks for a condition where timeout is greater than 1 hour, but when turning autodq off, the timeout variable is set to Infinity. This proposed change adds a check in the condition for if the timeout value is Infinity and does not send the error if that is the case (but if timeout is a numeric value greater than 1 hour, it still will fail).
We try to feature-detect for dependencies, but this one is hard and
I don't want to actually do an actual sucrase compile to check if it's
up to date, hence digging through its version number. Too bad they
added a major feature in a minor version, complicating the check. :/
There is no lottery editmarkup command. The proper use is to use /lottery edit, which allows you to edit the number of max winners, the name of the lottery, and the HTML, but also requires all three parameters be included.
By adding a `getGame` function of type:
```
// null is returned if the gameids don't match
// or the game doesn't exist
getGame<T extends RoomGame>(constructor: new (...args: any[]) => T) => T | null
```
(Credits @urkerab and @whalemer for the function signature.)
It allows refactoring previous code of:
```
if (room.game && room.game.gameid !== 'hangman') return;
const game = room.game as Hangman;
```
to:
```
const game = room.getGame(Hangman);
if (!game) return;
```
This has a couple of advantages:
- TypeScript will throw an error if the if condition is not present.
- In the new code, the template must extends `RoomGame` and be assignable to the same ID, so it's 100% typesafe
Date strings can have inconsitensies between browsers and apparently node versions too.
sim3 uses a newer node version and as a result date calculations are off by one.
I have swapped to using individual date componets eg `new Date(2020, 0)` to fix this.
This commit adds a `challengeType` property to `RoomBattle` of
type `rated | unrated | challenge | tour`.
Previously, there was no way to programatically differ an unrated
battle from a challenge, which is useful in places like filters.
If the remote ladder's update rating method dosen't receive
a response from the login server, it will not change the user's
mmrCache for the format, resulting in future ladder matches using
an outdated ELO until the server receives a response at the end of
a future match.
This is the cause of issues such as users with 1400 ELO being matched
with users with 1000 ELO with a 10 second wait time in current gen OU.
Ensuring the rating is up to date was discussed, but for cases such as
a user searching for a new match before a response is received (or an
error occurs) we decided to accept the mmrCache being at most 1 game
behind, which this change.
`item.itemUser` replaces `item.zMoveUser`, and is a new field
representing a list of possible users of an item, for items that are
restricted to specific species.
`item.zMoveUser` is a base forme for items that affect every forme, and
a forme name otherwise (forme name is currently only used for
`forcedForme` uses).
Arceus is a weird case. Both generic Z crystals and Plates, while
having unique effects on Arceus, also have effects on other Pokémon.
For this reason, Arceus isn't listed as an `itemUser` of either of
these item types - use-cases that want this should also check
`item.forcedForme`.
This is mostly intended to be useful to move-searching and custom
rules (like NatDex, which will only allow past-gen items associated
with removed species).
Right now the /mnm command results in warnings that the mega stone is a CAP stone, even when it is not. This is because isNonstandard is now set to "Past" instead of undefined.
`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
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.
- Automatically request PM logs from users when possible in PM harrasment tickets.
- Add a button to check a reported user's global modlog to all tickets.
- Add buttons for force-renaming/clearing the status of a user in inappropriate name/status tickets.
- Add a button for checking shared battles between a the reporter and reported user for battle harrasment tickets.
- Other minor improvements.
This commit changes the TypeScript global variable of `Config` from
`AnyObject` to `Config & AnyObject`.
It still falls back to `AnyObject` (hence the 'Take steps') because of
the main-specific `Config` properties that are used without being in the
`Config` object itself.
These can be added by someone with access to the PS main server.
Regardlesss, this is an improvement as IntelliSense can display and
autocomplete the known properies.
In addition, the TypeScript compiler will now report bugs
concerning the types of the properties, which I have fixed in this
commit.
* Make /events view visually match /events
Lack of consistency was bothering me
* This is why I shouldn't code when I'm sick
* Generalize formatEvent to function
I'm just going to pretend this code is good
* Update room-events.js
* Modnote Tours Format and Player Count Start
* Fix Trailing Whitespace on line 610
* String Interpolation Injects Integers Too
No need for a method to change the Integer's type to String
* Add a Private Modaction
* Simplify modnote to just player count
* Update server/tournaments/index.ts
Co-Authored-By: Guangcong Luo <guangcongluo@gmail.com>
* Change CommandContext Element to output
Co-Authored-By: Guangcong Luo <guangcongluo@gmail.com>
* Shorten Modlog Entry
Closing an inactive ticket indicates that there was no communication
between the user and staff, do not credit a ticket to the staff member.
Also fixes an issue with a error message for closing tickets with a
negative result that were already closed.
One issue I ran into this morning was a player not being in the battle
when the log was requested or leaving and then rejoining the battle
after the log was requested. In these situations, the player cannot
see the export request button. This allows the requester to re-send
the request message + button to the players who have not allowed
the input log to be exported yet.
- Remove ticket escalation because its not used.
- Simpliy report category to hopefully reduce the number of tickets opened in the wrong category.
- Improve ticket form interaction with namelocked users.
- Add a button to PM Harrasment ticket staffintros to allow staff to quickly request pm logs.
- - Only works when the reporter reports a user through their usercard.
* 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
We no longer have a need to long-term ban IPs. In the long term, we
should actively rename ipbans.txt and figure out better solutions, but
for now, they should just be revised to lock instead of ban.
Previously, we split gen 2-5 egg move validation into two phases,
`checkLearnset` where we searched for a valid father, and
`reconcileLearnset` where we made sure the father could learn the move
combination.
Egg move validation has now been completely moved out of these
functions and into `validateSource`, which calls `findEggMoveFathers`.
The new algorithm no longer requires `C` moves to be hardcoded into
`learnsets.js`, now doing a more thorough check validation for the
father's move combination. This should be slower than before, but
net performance should be massively improved due to two other
optimizations in this refactor:
- We no longer do any father-searching if the moveset can be obtained
any other way - in particular, this means no more father validation
in gen 6+ where all egg move combinations are legal anyway.
- We only check fully-evolved pokemon as fathers (because anything a
prevo can learn, its evos can learn, too - yes, we remember to make
exceptions for Salazzle, Combee, and future-gen evos)
In addition, `/learn` should now provide significantly better
information for egg move breeding, since it uses a more thorough check
instead of the validator's short-circuiting the moment it finds a valid
father.
This also improves some baby-only move validation, specifically fixing
the issue with Seismic Toss Charm Chansey.
* Update chat monitor to include a battle filter, as well as evasion detection
* Forgot about the roomid rename thing
* Mitigate the first problem hopefully
* Mitigate the second problem in an extremely elegant way
* Precompile the substitutions
* Make this new filter not racist towards nigerians
* Totally not ghostwritten code because i'm really smart
* Small edit
- Repealing rules now always works, regardless of rule order
(Fixes AAA validation)
- Fix a check for egg move hidden ability validation
(Fixes a Gen 4 Dragon Dance Charizard set)
- Always ban AG when banning Uber
(Fixes allowing Rayquaza-Mega in lower tiers)
- Fix ability validation in Let's Go
- Fix valid-move-combo dexsearch
* 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
eslint:recommended seems tohave gotten more sensitive.
require-atomic-updates was disabled because "I think this is
intentional behavior because that someObj object was read before
await expression and written after await expression." is wayyy
to aggressive: https://github.com/eslint/eslint/issues/11899
* Add more hunt management options
- Hints: add a command to display hints that can be recalled using /scav hint and /viewhunt for hunts that last several hours. This allows previously given hints to still be visible even after it scrolls out of chat, or the user uses /clear after completing some difficult param question. This command cannot be used until after 10 minutes of the hunt.
- /scav status is enhanced to show users who have tried to guess in the last 5 minutes in bold (<strong> for you HTML purists)
This has been approved by all 4 roomowners.
* 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
- Anyone can now see the amount of participants
- Max winners can't go above `Number.MAX_SAFE_INTEGER`
- `/lottery edit` can be used to edit the lottery
- "Page unavailable" is not shown to guest users, instead the not "allowing guests to join" is deferred to `/lottery join`.
- Punished users are dropped before generating winners
* Remove the new xhr-streaming ghost connection hack
Once the client uses timeouts, this is no longer necessary.
* Update SockJS client to v1.4.0
This fixes an issue where it would attempt to parse the entire HTTP
response received as JSON, not the response's body alone.
This seemed desirable in tested, but probably because I hadn't
refreshed. Also, the creator can wrap their content in a div and
give it a margin-bottom.
Sometimes when the server gets killed, the TCP closing handshake on
sockets currently open never actually gets completed, screwing with
things like bots that don't implement keepalive/timeouts of any kind.
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`).
Created distinctions between:
Role Cop and Role Cop (Classic)
Red Goo and Red Goo (Cracking Idea)
Neapolitan and Vanilla Cop
Also clarified some roles and standardized how Idea Variant roles are listed.
Added a distinction between Silencer and Silencer (Greater Idea) and between Grey Goo and Grey Goo (Cracking Idea). Also added the (xxx Idea) tag to the roles in their respective ideas.
Added:
- nate-dueldisk
- rosa-dueldisk
- bianca-pwt
We only had dueldisk versions before, so they've been swapped for their
regular avatars (previously, `nate` was the duel disk version, now, it's
the normal version, and `nate-dueldisk` is the duel disk version).
In addition, wally-gen7 has been removed - it was a duplicate of the
normal wally.
- Ensure the first card of the dealer is on the top of the turnlog
- Don't allow people to use the command to start the game if the game has already started
- Use user names instead of user ids in the initial playerlist for join messages
- Modlog conditionally if the game was ended forcibly or not
- hide the room as well so that it doesnt show up in a user's trainer card and end up auto-linking to replays
- upload a replay after the game to ensure the hidden setting is properly written
This command was originally restricted because users would complain
about lag when the uptime hit about a week. I'm removing this because
it makes it alot harder to verify a server's uptime meets the
requirements when registering servers, and its been a year or so
since lag complaints related to uptime were an issue.
- Modchat permission code should be simpler now
- Mods now have 'modchatall' (can set modchat up to their own rank)
- 'modchatall' (ROs) can no longer remove modchat higher than their own
rank
- 'makeroom' (Leaders) still can remove higher modchat
The previous solution had some rough edges, like accidentally
knocking global leaders down to roommod.
This also restores the corresponding symbols, for better clarity.
This was originally added in the original design when we were
actively logging Idle users out of their account. Currently it
serves mostly to explain what Idle is, but mostly it just annoys
users.
This adds a Config setting, `globalGroupInPersonalRoom`, which will
just straight-up let global drivers act as mods in battles and
groupchats.
Fixes#5564
This makes it easier to automatically set the status on connect. Instead
of making it so users can't set their status if they can't talk at all,
make it so they can't set it if they're locked or semilocked.
Namefilter is a complete mismatch for status messages, since names
have very specific requirements that don't apply to status messages.
Nicknames have no such restriction, and work basically the same as
status messages.
It's possible to spam /warn in groupchats, preventing users from being
able to close the warn modal. This mitigates that by limiting the rate
you can warn a user to once every 15 seconds, which is longer than the
amount of time it takes for the warn modal to allow you to close it.
By default, PS doesn't have very many tools for dealing with ban
evaders on proxies - most of the main server's protection is in private
code.
This commit adds a basic IP evaluator to PS. It categorizes IPs into
residential, mobile, and proxy (and a few other determinations), and
locks proxy IPs by default. DNSBL entries remain semilocked.
This behavior can, as always, be customized via hostfilter. Detect
`user.locked === '#hostfilter'` for the proxy IP lock, which you can
just set `user.locked = null` to disable.
Fixes#5239
userdetails and roominfo are now guaranteed to send a response, with an
`id` field guaranteed to be equal to the target of the original client
query.
Fixes#5525
* Scavengers: Viewhunt/Queue improvements/fixes
- Add "unrated" hunts to queue system
- fix /forcestarthunt, an add an unrated option for this.
- allow /viewhunt to show the current question while leaving the unknown answer blank
* Update scavengers.js
`import =` and `export =` are really only intended for backwards
compatibility with CommonJS. While I really don't like the new module
system TC39 has designed for us, it's what we should be using, and
consistency is important.
This is mostly a TypeScript refactor, but it does come with several
renames:
Dnsbl -> IPTools
Dnsbl.query -> IPTools.queryDnsbl
Dnsbl.reverse -> IPTools.getHost
- The big change here is that player.userid can now be empty. You can
now fit state into RoomGamePlayer subclasses even when there are no
users associated with them.
- `game.players` has been introduced as the new canonical list of
players, including userless players. The old `game.players` has been
renamed `game.playerTable`, for clarity.
- `game.addPlayer` now returns the added player
All existing RoomGames have been updated for the new API, and
RoomBattle is now officially a RoomGame subclass.
Tournaments was also massively refactored to be properly updated for
the old API, since that never happened, and should now be a lot more
readable.
It turns out the line `let Punishments = module.exports;` makes it into
`any`, and disables nearly all typechecking of anything to do with
`Punishments`. This refactor fixes that, and also fixes a bunch of flaws
newly caught by TypeScript.
I tried my best not to make any changes to actual functionality. These
changes should be effectively purely code cleanup.
Rebuilding on /updateserver is nicer than needing to do it individually
per hotpatch function, and also makes it apply to restarts (in case
you're manually launching `node server` instead of
`./pokemon-showdown`).
Buttons with content like "S" aren't accessible as it's not obvious
that "S" means Skip, and they don't mention which color the card is,
which before this change was visible only by checking the style
attribute.
Having an aria-label attribute gives an accessible alternative for
screen readers. A screen reader probably won't tell an user a button
is red, and this is somewhat important while playing Uno.
There were a couple of edgecases that caused punishments to be duplicated due to remnants of the old, overly
ambitious, spreading of punishments
Also check all users for potential unlocks, even when the user being unlocked is offline
* Improve SP
* Remove useless code
which fixes a build error, killing two birds with one stone
* Move sorting code to page
* Increase readability
* Further increase redability
* Remove useless alts filtering
* Add semicolon
* Standardize output in punishments.js
* Remove punishDesc
* Close div tag
* Don't show if they end in 0s
* Improve conditional
This should (hopefully) fix a bug where a roomban showed up as 12 months, which is what happenes when `Chat.toDurationString` gets a negative number, `Chat.toDurationString` doesn't recognize anything below 1000ms anyway.
* Prevent rooms with '-' to use /sp
* Pluralize IP
* Fix mismatched tags
* Fix sort callback
* Remove useless conditional
* Info: Add /roomstatus command
https://www.smogon.com/forums/threads/3534365/page-81#post-7977912
I'm not a big fan of the approach used here, but I didn't have any better ideas that worked.
* Fix build errors
* Remove response function
* Change command name
* Rewrite
* Use HTML pages
* Reword entries
* Check username map instead of IP map
* Prevent duplicate punishments from appearing.
* Use this.title
* Remove debug code
* Add a check if punishments exists
* Show ip and alts
* Pluralize IP
* Slight refactor in punishDesc
* Add check for Punishments.roomIps existence
* Return an error message for rooms without '-'
More specifically, rooms that aren't public, hidden or private. They couldn't use them anyway. This just handles them correctly.
* Join ip
* Use room.chatRoomData instead of...
checking for '-' in roomids.
* Update help command
* Clarify error message
* Simplify permission check
* Remove muteQueue variable
* Fix punishDesc
Alts would overwrite reason if it existed and punishDesc would always contain undefined due to not being defined empty. This commit fixes both bugs.
* Allow roomstaff to use /sp
* Refactor store iteration to for...of
As per CONTRIBUTING.md
Hotpatching and running `./pokemon-showdown` now automatically run
`./build`. There should now mostly not be any reason you'd want to
manually run `./build`, except if you're invoking tests directly.
In addition, a lot of redundant code has been removed.
I'm not 100% sure this works on Windows, but I'm sure I'll get reports
if anything breaks.
PS prefers to keep battle streams open (for `/evalbattle`) until
manually ended, but this is confusing some other users. We now
automatically end streams unless the `keepAlive` option is set.
Fixes#5157
This warning is strictly speaking correct, the URL isn't verified
properly. However, in this case, this isn't a practical issue, as
it's possible to use /forcebattleban command anyways.
Chat.uncache functions now consistently take a path relative to repo
root, just like FS.
Next step will probably be to have FS handle all text-based databases.
Also move mods/ to data/mods/
This makes PS more monorepo-like. The intent is to further separate
the sim and the server code, but without fully committing to splitting
the repository itself.
We now support `./pokemon-showdown start` in addition to
`./pokemon-showdown`. I'm not clear which I want to be the default
yet.