Spaces:
Paused
Paused
| Pokémon Showdown Command API | |
| ======================================================================== | |
| Defining a Command | |
| ------------------------------------------------------------------------ | |
| You can define the commands such as 'whois', then use them by typing | |
| `/whois` into Pokémon Showdown. | |
| A command can be in the form: | |
| ip: 'whois', | |
| This is called an alias: it makes it so `/ip` does the same thing as | |
| `/whois`. | |
| But to actually define a command, it's a function: | |
| avatars(target, room, user) { | |
| if (!this.runBroadcast()) return; | |
| this.sendReplyBox( | |
| 'You can <button name="avatars">change ' + | |
| 'your avatar</button> by clicking on it in the <button ' + | |
| 'name="openOptions"><i class="icon-cog"></i> Options' + | |
| '</button> menu in the upper right. Custom avatars are ' + | |
| 'only obtainable by staff.' | |
| ); | |
| } | |
| Parameters | |
| ------------------------------------------------------------------------ | |
| Commands are actually passed six parameters: | |
| function (target, room, user, connection, cmd, message) | |
| Most of the time, you only need the first three, though. | |
| - `target` = the part of the message after the command | |
| - `room` = the room object the message was sent to | |
| (The room name is `room.roomid`) | |
| - `user` = the user object that sent the message | |
| (The user's name is `user.name`) | |
| - `connection` = the connection that the message was sent from | |
| - `cmd` = the name of the command | |
| - `message` = the entire message sent by the user | |
| For instance, if a user types in `/msg zarel, hello`, | |
| `target` = `"zarel, hello"` | |
| `cmd` = `"msg"` | |
| `message` = `"/msg zarel, hello"` | |
| Commands return the message the user should say. If they don't | |
| return anything or return something falsy, the user won't say | |
| anything. | |
| Help Entries | |
| ------------------------------------------------------------------------ | |
| A `/help` entry can be added for a command by adding a command in the | |
| form `<command>help: ["<help text>"],`, where `<command>` is the primary function | |
| name, followed by an array or function. | |
| If the help entry is an array, each element of the array will be sent as a | |
| new line. If the help entry is a function, the help command will execute | |
| that function. | |
| As an example: | |
| ip: 'whois', | |
| rooms: 'whois', | |
| whois(target, room, user) { | |
| <function body> | |
| }, | |
| whoishelp:[ | |
| "/whois - Get details on yourself: alts, group, IP address, | |
| and rooms.", | |
| "/whois [username] - Get details on a username: group and rooms.", | |
| ], | |
| `/help whois` will send the information in `whoishelp`. | |
| Plines | |
| ------------------------------------------------------------------------ | |
| A lot of the functions refering "plines". A pline is a protocol line, | |
| documented in [PROTOCOL.md][https://github.com/smogon/pokemon-showdown/blob/master/PROTOCOL.md] | |
| Plines are the ones that usually start with `|MESSAGETYPE|`, but a pline | |
| that doesn't start with `|` will be shown as text directly to the user. | |
| Note that currently, most plines starting with `|` break horribly when | |
| sent in PMs, so please be careful about that. | |
| Functions | |
| ------------------------------------------------------------------------ | |
| Commands have access to the following functions: | |
| `this.sendReply(pline)` | |
| * Sends a pline to the room/PM the user typed the command into. | |
| `this.sendReplyBox(html)` | |
| * Same as sendReply, but shows it in a box, and you can put HTML in it. | |
| `this.popupReply(message)` | |
| * Shows a popup in the window the user typed the command into. | |
| `this.add(pline)` | |
| * Adds a pline to the room so that everyone can see it. | |
| This is like `this.sendReply`, except everyone in the room sees it, | |
| instead of just the user that typed the command. | |
| `this.send(pline)` | |
| * Sends a pline to the room so that everyone can see it. | |
| This is like `this.add`, except it's not logged, and users who join the | |
| room later won't see it in the log, and if it's a battle, it won't show | |
| up in saved replays. | |
| You USUALLY want to use `this.add` instead. | |
| `this.roomlog(pline)` | |
| * Log a pline to the room's log without sending it to anyone. This is | |
| like `this.add`, except no one will see it. | |
| `this.addModAction(message)` | |
| * Like `this.add`, but the message is treated like a chat message from the | |
| user who used the command (notifying and potentially highlighting other | |
| users). This does not log anything into the modlog. | |
| `this.modlog(action, user, note, options)` | |
| * Adds a log line into the room's modlog, similar to `this.globalModlog`. | |
| The arguments `user` (the targeted user), `note` (details), and `options` | |
| (no ip, no alts) are optional. | |
| `this.checkCan(permission)` | |
| `this.checkCan(permission, targetUser)` | |
| * Checks if the user has the permission to do something, or if a | |
| targetUser is passed, check if the user has permission to do it to that | |
| user. Will automatically give the user an "Access denied" message, and | |
| stop the command there, if the user doesn't have permission: use | |
| `user.can()` if you don't want that message. | |
| Should usually be near the top of the command, like: | |
| this.checkCan('potd'); | |
| `this.runBroadcast()` | |
| * Signifies that a message can be broadcast, as long as the user has | |
| permission to. This will check to see if the user used `!command` | |
| instead of `/command`. If so, it will check to see if the user has | |
| permission to broadcast (by default, voice+ can), and return `false` if | |
| not. Otherwise, it will add the message to the room, and turn on the | |
| flag `this.broadcasting`, so that `this.sendReply` and `this.sendReplyBox` | |
| will broadcast to the room instead of just the user that used the | |
| command. | |
| Should usually be near the top of the command, like: | |
| this.checkBroadcast(); | |
| `this.runBroadcast(suppressMessage)` | |
| * Functionally the same as `this.canBroadcast()`. However, it will look as | |
| if the user had written the text `suppressMessage`. | |
| `this.checkChat()` | |
| * Checks to see if the user can speak in the room. Returns false if the | |
| user can't speak (is muted, the room has modchat on, etc), or true | |
| otherwise. | |
| Should usually be near the top of the command, like: | |
| this.checkChat(); | |
| `this.checkChat(message, room)` | |
| * Checks to see if the user can say the message in the room. | |
| If a room is not specified, it will default to the current one. | |
| If it has a falsy value, the check won't be attached to any room. | |
| In addition to running the checks from `this.checkChat()`, it also checks | |
| to see if the message has any banned words, is too long, or was just | |
| sent by the user. Returns the filtered message, or a falsy value if the | |
| user can't speak. | |
| Should usually be near the top of the command, like: | |
| target = this.checkChat(target); | |
| if (!target) return false; | |
| `this.parse(message, inNamespace)` | |
| * Runs the message as if the user had typed it in. | |
| Mostly useful for giving help messages, like for commands that require | |
| a target: | |
| if (!target) return this.parse('/help msg'); | |
| If `inNamespace` is true, then the message is parsed in that | |
| corresponding namespace: | |
| // command msg is in namespace test. (ie. /test msg) | |
| this.parse('/help', true); | |
| // is parsed as if the user said '/test help' | |
| After 10 levels of recursion (calling `this.parse` from a command called | |
| by `this.parse` from a command called by `this.parse` etc) we will assume | |
| it's a bug in your command and error out. | |
| `this.getUserOrSelf(target, exactName)` | |
| * If `target` is blank, returns the user that sent the message. | |
| Otherwise, returns the user with the username in target, or a falsy | |
| value if no user with that username exists. | |
| By default, this will track users across name changes. However, if | |
| `exactName` is true, it will enforce exact matches. | |
| `this.splitUser(target, exactName)` | |
| * Splits a target in the form `<user>, <rest>` into its constituent parts; | |
| returning | |
| `{targetUser: User | null, targetUsername: string, inputUsername: string, rest: string}`. | |
| `inputUsername` will be exactly `<user>` and `rest` will be `<rest>`. | |
| If a user doesn't exist (because they are offline or otherwise), | |
| `targetUser` will be null but `targetUsername` will be `inputUsername`. | |
| If `targetUser` exists, `targetUsername` will be `targetUser.name` | |
| (fixing capitalization and following name changes if applicable). | |
| By default, this will track users across name changes. However, if | |
| `exactName` is true, it will enforce exact matches. | |
| Unless otherwise specified, these functions will return undefined, so you | |
| can `return this.sendReply` or something to send a reply and stop the command | |
| there. | |
| Namespace Commands | |
| ------------------------------------------------------------------------ | |
| A command can also be an object, in which case is treated like | |
| a namespace: | |
| game: { | |
| play(target, room, user) { | |
| user.isPlaying = true; | |
| this.sendReply("Playing."); | |
| }, | |
| stop(target, room, user) { | |
| user.isPlaying = false; | |
| this.sendReply("Stopped."); | |
| } | |
| } | |
| These commands can be called by `/game play` and `/game stop`. | |
| Namespaces help organise commands, and nest them under | |
| one main command. | |
| Note: Multiple namespaces can be nested, but the final (innermost) | |
| command must be a function. | |
| Namespace objects can have help entries and so can the internal | |
| commands: | |
| game: { | |
| play(target, room, user) { | |
| user.isPlaying = true; | |
| this.sendReply("Playing."); | |
| }, | |
| playhelp: ["Tells you if the user is playing."], | |
| stop(target, room, user) { | |
| user.isPlaying = false; | |
| this.sendReply("Stopped."); | |
| }, | |
| }, | |
| gamehelp: [ | |
| "commands for /game are:", | |
| "/game play - Tells you if the user is playing.", | |
| "/game stop - Tells you if the user stopped playing.", | |
| ], | |
| The help entries are accessed with `/help game play` and `/help game` | |
| respectively. If help for `/help game stop` doesn't exist, it will show | |
| help for `/help game` instead. | |