diff --git a/server/chat-commands/core.ts b/server/chat-commands/core.ts index 07fb6c7da7b0..28e787daa341 100644 --- a/server/chat-commands/core.ts +++ b/server/chat-commands/core.ts @@ -16,7 +16,7 @@ /* eslint no-else-return: "error" */ import {Utils} from '../../lib'; import type {UserSettings} from '../users'; -import type {GlobalPermission} from '../user-groups'; +import type {GlobalPermission, RoomPermission} from '../user-groups'; export const crqHandlers: {[k: string]: Chat.CRQHandler} = { userdetails(target, user, trustable) { @@ -144,6 +144,37 @@ export const crqHandlers: {[k: string]: Chat.CRQHandler} = { return targetRoom.battle.format; }, + cmdsearch(target, user, trustable) { + // in no world should ths be a thing. our longest command name is 37 chars + if (target.length > 40) return null; + const cmdPrefix = target.charAt(0); + if (!['/', '!'].includes(cmdPrefix)) return null; + target = toID(target.slice(1)); + + const results = []; + for (const command of Chat.allCommands()) { + if (cmdPrefix === '!' && !command.broadcastable) continue; + const req = command.requiredPermission as GlobalPermission; + if (req && + !(command.hasRoomPermissions ? this.room && user.can(req as RoomPermission, null, this.room) : user.can(req)) + ) { + continue; + } + const cmds = [ + command.fullCmd, + ...command.aliases.map(x => command.fullCmd.replace(command.cmd, `${x}`)), + ]; + for (const cmd of cmds) { + if (toID(cmd).startsWith(target)) { + results.push(cmdPrefix + cmd); + break; + } + } + // limit number of results to prevent spam + if (results.length >= 20) break; + } + return results; + }, }; export const commands: Chat.ChatCommands = {