2023-12-02 19:04:51 +01:00
import { chat _metadata , getCurrentChatId , saveSettingsDebounced , sendSystemMessage , system _message _types } from '../script.js' ;
import { extension _settings , saveMetadataDebounced } from './extensions.js' ;
2024-09-25 12:45:44 +02:00
import { callGenericPopup , POPUP _TYPE } from './popup.js' ;
2024-06-17 03:30:52 +02:00
import { executeSlashCommandsWithOptions } from './slash-commands.js' ;
2024-05-12 21:15:05 +02:00
import { SlashCommand } from './slash-commands/SlashCommand.js' ;
2024-05-18 20:48:31 +02:00
import { SlashCommandAbortController } from './slash-commands/SlashCommandAbortController.js' ;
2024-05-12 21:15:05 +02:00
import { ARGUMENT _TYPE , SlashCommandArgument , SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js' ;
2024-06-24 14:42:33 +02:00
import { SlashCommandBreakController } from './slash-commands/SlashCommandBreakController.js' ;
2024-05-12 21:15:05 +02:00
import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js' ;
2024-05-18 20:48:31 +02:00
import { SlashCommandClosureResult } from './slash-commands/SlashCommandClosureResult.js' ;
2024-06-23 18:07:45 +02:00
import { commonEnumProviders , enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js' ;
import { SlashCommandEnumValue , enumTypes } from './slash-commands/SlashCommandEnumValue.js' ;
2024-05-18 20:48:31 +02:00
import { PARSER _FLAG , SlashCommandParser } from './slash-commands/SlashCommandParser.js' ;
2024-10-01 00:23:00 +02:00
import { slashCommandReturnHelper } from './slash-commands/SlashCommandReturnHelper.js' ;
2024-05-12 21:15:05 +02:00
import { SlashCommandScope } from './slash-commands/SlashCommandScope.js' ;
2024-09-22 07:42:51 +02:00
import { isFalseBoolean , convertValueType , isTrueBoolean } from './utils.js' ;
2023-11-06 21:50:32 +01:00
2024-06-17 03:30:52 +02:00
/** @typedef {import('./slash-commands/SlashCommandParser.js').NamedArguments} NamedArguments */
/** @typedef {import('./slash-commands/SlashCommand.js').UnnamedArguments} UnnamedArguments */
2023-12-15 20:47:40 +01:00
const MAX _LOOPS = 100 ;
2023-11-06 21:50:32 +01:00
2023-12-06 21:08:06 +01:00
function getLocalVariable ( name , args = { } ) {
2023-11-23 23:18:07 +01:00
if ( ! chat _metadata . variables ) {
chat _metadata . variables = { } ;
}
2024-05-12 21:15:05 +02:00
let localVariable = chat _metadata ? . variables [ args . key ? ? name ] ;
2023-12-06 20:03:10 +01:00
if ( args . index !== undefined ) {
try {
localVariable = JSON . parse ( localVariable ) ;
2023-12-07 13:56:28 +01:00
const numIndex = Number ( args . index ) ;
if ( Number . isNaN ( numIndex ) ) {
localVariable = localVariable [ args . index ] ;
} else {
localVariable = localVariable [ Number ( args . index ) ] ;
}
if ( typeof localVariable == 'object' ) {
localVariable = JSON . stringify ( localVariable ) ;
}
2023-12-06 20:03:10 +01:00
} catch {
// that didn't work
}
}
2023-11-06 21:50:32 +01:00
2024-07-20 17:59:52 +02:00
return ( localVariable ? . trim ? . ( ) === '' || isNaN ( Number ( localVariable ) ) ) ? ( localVariable || '' ) : Number ( localVariable ) ;
2023-11-06 21:50:32 +01:00
}
2023-12-07 17:48:24 +01:00
function setLocalVariable ( name , value , args = { } ) {
2023-11-06 21:50:32 +01:00
if ( ! chat _metadata . variables ) {
chat _metadata . variables = { } ;
}
2023-12-07 17:48:24 +01:00
if ( args . index !== undefined ) {
try {
let localVariable = JSON . parse ( chat _metadata . variables [ name ] ? ? 'null' ) ;
const numIndex = Number ( args . index ) ;
if ( Number . isNaN ( numIndex ) ) {
if ( localVariable === null ) {
localVariable = { } ;
}
2024-09-01 22:02:01 +02:00
localVariable [ args . index ] = convertValueType ( value , args . as ) ;
2023-12-07 17:48:24 +01:00
} else {
2023-12-07 23:33:27 +01:00
if ( localVariable === null ) {
2023-12-07 17:48:24 +01:00
localVariable = [ ] ;
}
2024-09-01 22:02:01 +02:00
localVariable [ numIndex ] = convertValueType ( value , args . as ) ;
2023-12-07 17:48:24 +01:00
}
chat _metadata . variables [ name ] = JSON . stringify ( localVariable ) ;
} catch {
// that didn't work
}
} else {
chat _metadata . variables [ name ] = value ;
}
2023-11-24 00:32:02 +01:00
saveMetadataDebounced ( ) ;
2023-11-23 21:36:48 +01:00
return value ;
2023-11-06 21:50:32 +01:00
}
2023-12-06 21:08:06 +01:00
function getGlobalVariable ( name , args = { } ) {
2024-05-12 21:15:05 +02:00
let globalVariable = extension _settings . variables . global [ args . key ? ? name ] ;
2023-12-06 20:03:10 +01:00
if ( args . index !== undefined ) {
try {
globalVariable = JSON . parse ( globalVariable ) ;
2023-12-07 13:56:28 +01:00
const numIndex = Number ( args . index ) ;
if ( Number . isNaN ( numIndex ) ) {
globalVariable = globalVariable [ args . index ] ;
} else {
globalVariable = globalVariable [ Number ( args . index ) ] ;
}
if ( typeof globalVariable == 'object' ) {
globalVariable = JSON . stringify ( globalVariable ) ;
}
2023-12-06 20:03:10 +01:00
} catch {
// that didn't work
}
}
2023-11-06 21:50:32 +01:00
2024-07-20 17:59:52 +02:00
return ( globalVariable ? . trim ? . ( ) === '' || isNaN ( Number ( globalVariable ) ) ) ? ( globalVariable || '' ) : Number ( globalVariable ) ;
2023-11-06 21:50:32 +01:00
}
2023-12-07 17:48:24 +01:00
function setGlobalVariable ( name , value , args = { } ) {
if ( args . index !== undefined ) {
try {
let globalVariable = JSON . parse ( extension _settings . variables . global [ name ] ? ? 'null' ) ;
const numIndex = Number ( args . index ) ;
if ( Number . isNaN ( numIndex ) ) {
if ( globalVariable === null ) {
globalVariable = { } ;
}
2024-09-01 22:02:01 +02:00
globalVariable [ args . index ] = convertValueType ( value , args . as ) ;
2023-12-07 17:48:24 +01:00
} else {
2023-12-07 23:33:27 +01:00
if ( globalVariable === null ) {
2023-12-07 17:48:24 +01:00
globalVariable = [ ] ;
}
2024-09-01 22:02:01 +02:00
globalVariable [ numIndex ] = convertValueType ( value , args . as ) ;
2023-12-07 17:48:24 +01:00
}
extension _settings . variables . global [ name ] = JSON . stringify ( globalVariable ) ;
} catch {
// that didn't work
}
} else {
extension _settings . variables . global [ name ] = value ;
}
2023-11-24 00:32:02 +01:00
saveSettingsDebounced ( ) ;
2024-06-17 03:30:52 +02:00
return value ;
2023-11-06 21:50:32 +01:00
}
2023-11-23 21:36:48 +01:00
function addLocalVariable ( name , value ) {
const currentValue = getLocalVariable ( name ) || 0 ;
2023-12-07 19:12:05 +01:00
try {
const parsedValue = JSON . parse ( currentValue ) ;
2023-12-07 19:27:11 +01:00
if ( Array . isArray ( parsedValue ) ) {
2023-12-07 19:12:05 +01:00
parsedValue . push ( value ) ;
2024-01-16 23:20:46 +01:00
setLocalVariable ( name , JSON . stringify ( parsedValue ) ) ;
2023-12-07 19:12:05 +01:00
return parsedValue ;
}
2023-12-07 23:33:27 +01:00
} catch {
// ignore non-array values
}
2023-11-23 21:36:48 +01:00
const increment = Number ( value ) ;
2023-11-28 00:46:44 +01:00
if ( isNaN ( increment ) || isNaN ( Number ( currentValue ) ) ) {
2023-11-25 16:45:40 +01:00
const stringValue = String ( currentValue || '' ) + value ;
setLocalVariable ( name , stringValue ) ;
return stringValue ;
2023-11-23 21:36:48 +01:00
}
const newValue = Number ( currentValue ) + increment ;
if ( isNaN ( newValue ) ) {
return '' ;
}
setLocalVariable ( name , newValue ) ;
return newValue ;
}
function addGlobalVariable ( name , value ) {
const currentValue = getGlobalVariable ( name ) || 0 ;
2023-12-07 19:12:05 +01:00
try {
const parsedValue = JSON . parse ( currentValue ) ;
2023-12-07 19:27:11 +01:00
if ( Array . isArray ( parsedValue ) ) {
2023-12-07 19:12:05 +01:00
parsedValue . push ( value ) ;
setGlobalVariable ( name , JSON . stringify ( parsedValue ) ) ;
return parsedValue ;
}
2023-12-07 23:33:27 +01:00
} catch {
// ignore non-array values
}
2023-11-23 21:36:48 +01:00
const increment = Number ( value ) ;
2023-11-28 15:00:04 +01:00
if ( isNaN ( increment ) || isNaN ( Number ( currentValue ) ) ) {
2023-11-25 16:45:40 +01:00
const stringValue = String ( currentValue || '' ) + value ;
setGlobalVariable ( name , stringValue ) ;
return stringValue ;
2023-11-23 21:36:48 +01:00
}
const newValue = Number ( currentValue ) + increment ;
if ( isNaN ( newValue ) ) {
return '' ;
}
setGlobalVariable ( name , newValue ) ;
return newValue ;
}
2023-11-28 15:00:04 +01:00
function incrementLocalVariable ( name ) {
return addLocalVariable ( name , 1 ) ;
}
function incrementGlobalVariable ( name ) {
return addGlobalVariable ( name , 1 ) ;
}
function decrementLocalVariable ( name ) {
return addLocalVariable ( name , - 1 ) ;
}
function decrementGlobalVariable ( name ) {
return addGlobalVariable ( name , - 1 ) ;
}
/ * *
* Resolves a variable name to its value or returns the string as is if the variable does not exist .
* @ param { string } name Variable name
2024-05-12 21:15:05 +02:00
* @ param { SlashCommandScope } scope Scope
2023-11-28 15:00:04 +01:00
* @ returns { string } Variable value or the string literal
* /
2024-05-12 21:15:05 +02:00
export function resolveVariable ( name , scope = null ) {
if ( scope ? . existsVariable ( name ) ) {
return scope . getVariable ( name ) ;
}
2023-11-24 16:41:49 +01:00
if ( existsLocalVariable ( name ) ) {
return getLocalVariable ( name ) ;
}
if ( existsGlobalVariable ( name ) ) {
return getGlobalVariable ( name ) ;
}
return name ;
}
2023-11-25 19:52:17 +01:00
export function replaceVariableMacros ( input ) {
const lines = input . split ( '\n' ) ;
for ( let i = 0 ; i < lines . length ; i ++ ) {
let line = lines [ i ] ;
// Skip lines without macros
if ( ! line || ! line . includes ( '{{' ) ) {
continue ;
}
2023-11-25 21:02:40 +01:00
// Replace {{getvar::name}} with the value of the variable name
line = line . replace ( /{{getvar::([^}]+)}}/gi , ( _ , name ) => {
name = name . trim ( ) ;
return getLocalVariable ( name ) ;
} ) ;
2023-11-25 19:52:17 +01:00
// Replace {{setvar::name::value}} with empty string and set the variable name to value
line = line . replace ( /{{setvar::([^:]+)::([^}]+)}}/gi , ( _ , name , value ) => {
name = name . trim ( ) ;
setLocalVariable ( name , value ) ;
return '' ;
} ) ;
// Replace {{addvar::name::value}} with empty string and add value to the variable value
line = line . replace ( /{{addvar::([^:]+)::([^}]+)}}/gi , ( _ , name , value ) => {
name = name . trim ( ) ;
2023-12-02 16:15:03 +01:00
addLocalVariable ( name , value ) ;
2023-11-25 19:52:17 +01:00
return '' ;
} ) ;
2023-12-01 02:02:23 +01:00
// Replace {{incvar::name}} with empty string and increment the variable name by 1
line = line . replace ( /{{incvar::([^}]+)}}/gi , ( _ , name ) => {
name = name . trim ( ) ;
return incrementLocalVariable ( name ) ;
} ) ;
// Replace {{decvar::name}} with empty string and decrement the variable name by 1
line = line . replace ( /{{decvar::([^}]+)}}/gi , ( _ , name ) => {
name = name . trim ( ) ;
return decrementLocalVariable ( name ) ;
} ) ;
2023-11-25 21:02:40 +01:00
// Replace {{getglobalvar::name}} with the value of the global variable name
line = line . replace ( /{{getglobalvar::([^}]+)}}/gi , ( _ , name ) => {
name = name . trim ( ) ;
return getGlobalVariable ( name ) ;
} ) ;
2023-11-25 19:52:17 +01:00
// Replace {{setglobalvar::name::value}} with empty string and set the global variable name to value
line = line . replace ( /{{setglobalvar::([^:]+)::([^}]+)}}/gi , ( _ , name , value ) => {
name = name . trim ( ) ;
setGlobalVariable ( name , value ) ;
return '' ;
} ) ;
// Replace {{addglobalvar::name::value}} with empty string and add value to the global variable value
line = line . replace ( /{{addglobalvar::([^:]+)::([^}]+)}}/gi , ( _ , name , value ) => {
name = name . trim ( ) ;
addGlobalVariable ( name , value ) ;
return '' ;
} ) ;
2023-12-01 02:02:23 +01:00
// Replace {{incglobalvar::name}} with empty string and increment the global variable name by 1
line = line . replace ( /{{incglobalvar::([^}]+)}}/gi , ( _ , name ) => {
name = name . trim ( ) ;
return incrementGlobalVariable ( name ) ;
} ) ;
// Replace {{decglobalvar::name}} with empty string and decrement the global variable name by 1
line = line . replace ( /{{decglobalvar::([^}]+)}}/gi , ( _ , name ) => {
name = name . trim ( ) ;
return decrementGlobalVariable ( name ) ;
} ) ;
2023-11-25 19:52:17 +01:00
lines [ i ] = line ;
}
2023-11-06 21:50:32 +01:00
2023-11-25 19:52:17 +01:00
return lines . join ( '\n' ) ;
2023-11-06 21:50:32 +01:00
}
2024-09-25 12:45:44 +02:00
async function listVariablesCallback ( args ) {
2024-10-01 00:23:00 +02:00
/** @type {import('./slash-commands/SlashCommandReturnHelper.js').SlashCommandReturnType} */
let returnType = args . return ;
// Old legacy return type handling
if ( args . format ) {
toastr . warning ( ` Legacy argument 'format' with value ' ${ args . format } ' is deprecated. Please use 'return' instead. Routing to the correct return type... ` , 'Deprecation warning' ) ;
const type = String ( args ? . format ) . toLowerCase ( ) . trim ( ) ;
switch ( type ) {
case 'none' :
returnType = 'none' ;
break ;
case 'chat' :
returnType = 'chat-html' ;
break ;
case 'popup' :
default :
returnType = 'popup-html' ;
break ;
}
}
// Now the actual new return type handling
2024-09-25 12:45:44 +02:00
const scope = String ( args ? . scope || '' ) . toLowerCase ( ) . trim ( ) || 'all' ;
2023-11-06 21:50:32 +01:00
if ( ! chat _metadata . variables ) {
chat _metadata . variables = { } ;
}
2024-09-25 12:45:44 +02:00
const includeLocalVariables = scope === 'all' || scope === 'local' ;
const includeGlobalVariables = scope === 'all' || scope === 'global' ;
const localVariables = includeLocalVariables ? Object . entries ( chat _metadata . variables ) . map ( ( [ name , value ] ) => ` ${ name } : ${ value } ` ) : [ ] ;
const globalVariables = includeGlobalVariables ? Object . entries ( extension _settings . variables . global ) . map ( ( [ name , value ] ) => ` ${ name } : ${ value } ` ) : [ ] ;
2024-10-01 00:23:00 +02:00
const buildTextValue = ( _ ) => {
const localVariablesString = localVariables . length > 0 ? localVariables . join ( '\n\n' ) : 'No local variables' ;
const globalVariablesString = globalVariables . length > 0 ? globalVariables . join ( '\n\n' ) : 'No global variables' ;
const chatName = getCurrentChatId ( ) ;
const message = [
includeLocalVariables ? ` ### Local variables ( ${ chatName } ): \n ${ localVariablesString } ` : '' ,
includeGlobalVariables ? ` ### Global variables: \n ${ globalVariablesString } ` : '' ,
] . filter ( x => x ) . join ( '\n\n' ) ;
return message ;
} ;
2024-09-25 12:45:44 +02:00
const jsonVariables = [
... Object . entries ( chat _metadata . variables ) . map ( x => ( { key : x [ 0 ] , value : x [ 1 ] , scope : 'local' } ) ) ,
... Object . entries ( extension _settings . variables . global ) . map ( x => ( { key : x [ 0 ] , value : x [ 1 ] , scope : 'global' } ) ) ,
] ;
2023-11-06 21:50:32 +01:00
2024-10-01 00:23:00 +02:00
return await slashCommandReturnHelper . doReturn ( returnType ? ? 'popup-html' , jsonVariables , { objectToStringFunc : buildTextValue } ) ;
2023-11-06 21:50:32 +01:00
}
2024-05-19 12:24:32 +02:00
/ * *
*
2024-06-17 03:30:52 +02:00
* @ param { NamedArguments } args
2024-05-19 12:24:32 +02:00
* @ param { ( string | SlashCommandClosure ) [ ] } value
* /
async function whileCallback ( args , value ) {
2024-06-20 20:33:45 +02:00
if ( args . guard instanceof SlashCommandClosure ) throw new Error ( 'argument \'guard\' cannot be a closure for command /while' ) ;
2023-12-15 20:48:25 +01:00
const isGuardOff = isFalseBoolean ( args . guard ) ;
2023-11-24 11:49:14 +01:00
const iterations = isGuardOff ? Number . MAX _SAFE _INTEGER : MAX _LOOPS ;
2024-05-19 12:24:32 +02:00
/**@type {string|SlashCommandClosure} */
let command ;
if ( value ) {
if ( value [ 0 ] instanceof SlashCommandClosure ) {
command = value [ 0 ] ;
2024-05-18 20:48:31 +02:00
} else {
2024-05-19 12:24:32 +02:00
command = value . join ( ' ' ) ;
2024-05-18 20:48:31 +02:00
}
}
2023-11-24 11:49:14 +01:00
2024-05-18 20:48:31 +02:00
let commandResult ;
2023-11-24 11:49:14 +01:00
for ( let i = 0 ; i < iterations ; i ++ ) {
const { a , b , rule } = parseBooleanOperands ( args ) ;
const result = evalBoolean ( rule , a , b ) ;
if ( result && command ) {
2024-05-18 20:48:31 +02:00
if ( command instanceof SlashCommandClosure ) {
2024-06-24 14:42:33 +02:00
command . breakController = new SlashCommandBreakController ( ) ;
2024-05-18 20:48:31 +02:00
commandResult = await command . execute ( ) ;
} else {
commandResult = await executeSubCommands ( command , args . _scope , args . _parserFlags , args . _abortController ) ;
2024-05-19 11:19:08 +02:00
}
2024-05-19 13:34:09 +02:00
if ( commandResult . isAborted ) break ;
2024-06-24 14:42:33 +02:00
if ( commandResult . isBreak ) break ;
2023-11-24 11:49:14 +01:00
} else {
break ;
}
}
2023-11-26 00:49:37 +01:00
2024-05-18 20:48:31 +02:00
if ( commandResult ) {
return commandResult . pipe ;
}
2023-11-26 00:49:37 +01:00
return '' ;
2023-11-24 11:49:14 +01:00
}
2024-05-18 20:48:31 +02:00
/ * *
*
2024-06-17 03:30:52 +02:00
* @ param { NamedArguments } args
* @ param { UnnamedArguments } value
2024-05-18 20:48:31 +02:00
* @ returns
* /
2023-12-15 13:38:26 +01:00
async function timesCallback ( args , value ) {
2024-06-21 20:04:55 +02:00
if ( args . guard instanceof SlashCommandClosure ) throw new Error ( 'argument \'guard\' cannot be a closure for command /while' ) ;
2024-05-12 21:15:05 +02:00
let repeats ;
let command ;
if ( Array . isArray ( value ) ) {
2024-05-18 20:48:31 +02:00
[ repeats , ... command ] = value ;
if ( command [ 0 ] instanceof SlashCommandClosure ) {
command = command [ 0 ] ;
} else {
command = command . join ( ' ' ) ;
}
2024-05-12 21:15:05 +02:00
} else {
2024-05-18 20:48:31 +02:00
[ repeats , ... command ] = /**@type {string}*/ ( value ) . split ( ' ' ) ;
2024-05-12 21:15:05 +02:00
command = command . join ( ' ' ) ;
}
2023-12-15 20:48:25 +01:00
const isGuardOff = isFalseBoolean ( args . guard ) ;
2023-12-15 13:38:26 +01:00
const iterations = Math . min ( Number ( repeats ) , isGuardOff ? Number . MAX _SAFE _INTEGER : MAX _LOOPS ) ;
2024-05-18 20:48:31 +02:00
let result ;
2023-12-15 13:38:26 +01:00
for ( let i = 0 ; i < iterations ; i ++ ) {
2024-05-12 21:15:05 +02:00
if ( command instanceof SlashCommandClosure ) {
2024-06-24 14:42:33 +02:00
command . breakController = new SlashCommandBreakController ( ) ;
2024-05-12 21:15:05 +02:00
command . scope . setMacro ( 'timesIndex' , i ) ;
2024-05-18 20:48:31 +02:00
result = await command . execute ( ) ;
2024-05-12 21:15:05 +02:00
}
else {
2024-05-19 12:25:19 +02:00
result = await executeSubCommands ( command . replace ( /\{\{timesIndex\}\}/g , i . toString ( ) ) , args . _scope , args . _parserFlags , args . _abortController ) ;
2024-05-12 21:15:05 +02:00
}
2024-05-19 13:34:09 +02:00
if ( result . isAborted ) break ;
2024-06-24 14:42:33 +02:00
if ( result . isBreak ) break ;
2023-12-15 13:38:26 +01:00
}
2024-05-18 20:48:31 +02:00
return result ? . pipe ? ? '' ;
2023-12-15 13:38:26 +01:00
}
2024-05-19 12:40:08 +02:00
/ * *
*
2024-06-17 03:30:52 +02:00
* @ param { NamedArguments } args
2024-05-19 12:40:08 +02:00
* @ param { ( string | SlashCommandClosure ) [ ] } value
* /
async function ifCallback ( args , value ) {
2023-11-24 11:49:14 +01:00
const { a , b , rule } = parseBooleanOperands ( args ) ;
const result = evalBoolean ( rule , a , b ) ;
2024-05-19 12:40:08 +02:00
/**@type {string|SlashCommandClosure} */
let command ;
if ( value ) {
if ( value [ 0 ] instanceof SlashCommandClosure ) {
command = value [ 0 ] ;
} else {
command = value . join ( ' ' ) ;
}
}
2024-05-18 20:48:31 +02:00
let commandResult ;
2023-11-24 11:49:14 +01:00
if ( result && command ) {
2024-05-12 21:15:05 +02:00
if ( command instanceof SlashCommandClosure ) return ( await command . execute ( ) ) . pipe ;
2024-05-19 12:26:16 +02:00
commandResult = await executeSubCommands ( command , args . _scope , args . _parserFlags , args . _abortController ) ;
2024-05-12 21:15:05 +02:00
} else if ( ! result && args . else && ( ( typeof args . else === 'string' && args . else !== '' ) || args . else instanceof SlashCommandClosure ) ) {
2024-05-19 12:40:08 +02:00
if ( args . else instanceof SlashCommandClosure ) return ( await args . else . execute ( ) ) . pipe ;
2024-05-19 12:26:16 +02:00
commandResult = await executeSubCommands ( args . else , args . _scope , args . _parserFlags , args . _abortController ) ;
2023-11-24 11:49:14 +01:00
}
2024-05-18 20:48:31 +02:00
if ( commandResult ) {
return commandResult . pipe ;
}
2023-11-24 11:49:14 +01:00
return '' ;
}
2023-11-28 15:00:04 +01:00
/ * *
* Checks if a local variable exists .
* @ param { string } name Local variable name
* @ returns { boolean } True if the local variable exists , false otherwise
* /
2023-11-24 13:44:11 +01:00
function existsLocalVariable ( name ) {
return chat _metadata . variables && chat _metadata . variables [ name ] !== undefined ;
}
2023-11-28 15:00:04 +01:00
/ * *
* Checks if a global variable exists .
* @ param { string } name Global variable name
* @ returns { boolean } True if the global variable exists , false otherwise
* /
2023-11-24 13:44:11 +01:00
function existsGlobalVariable ( name ) {
return extension _settings . variables . global && extension _settings . variables . global [ name ] !== undefined ;
}
2023-11-28 15:00:04 +01:00
/ * *
* Parses boolean operands from command arguments .
* @ param { object } args Command arguments
2024-09-22 07:42:51 +02:00
* @ returns { { a : string | number , b : string | number ? , rule : string } } Boolean operands
2023-11-28 15:00:04 +01:00
* /
2024-06-24 13:44:27 +02:00
export function parseBooleanOperands ( args ) {
2023-11-28 15:00:04 +01:00
// Resolution order: numeric literal, local variable, global variable, string literal
/ * *
* @ param { string } operand Boolean operand candidate
* /
2023-11-24 11:49:14 +01:00
function getOperand ( operand ) {
2023-11-24 13:44:11 +01:00
if ( operand === undefined ) {
2024-09-22 07:42:51 +02:00
return undefined ;
}
if ( operand === '' ) {
2023-11-24 13:44:11 +01:00
return '' ;
}
2024-10-11 20:01:32 +02:00
// parseFloat will return NaN for spaces.
const operandNumber = parseFloat ( operand ) ;
2023-11-24 11:49:14 +01:00
if ( ! isNaN ( operandNumber ) ) {
return operandNumber ;
}
2024-05-12 21:15:05 +02:00
if ( args . _scope . existsVariable ( operand ) ) {
const operandVariable = args . _scope . getVariable ( operand ) ;
return operandVariable ? ? '' ;
}
2023-11-24 13:44:11 +01:00
if ( existsLocalVariable ( operand ) ) {
const operandLocalVariable = getLocalVariable ( operand ) ;
2023-11-24 13:53:12 +01:00
return operandLocalVariable ? ? '' ;
2023-11-24 11:49:14 +01:00
}
2023-11-24 13:44:11 +01:00
if ( existsGlobalVariable ( operand ) ) {
const operandGlobalVariable = getGlobalVariable ( operand ) ;
2023-11-24 13:53:12 +01:00
return operandGlobalVariable ? ? '' ;
2023-11-24 11:49:14 +01:00
}
2023-11-24 13:44:11 +01:00
const stringLiteral = String ( operand ) ;
2023-11-25 17:16:53 +01:00
return stringLiteral || '' ;
2023-11-24 11:49:14 +01:00
}
2024-09-22 07:42:51 +02:00
const left = getOperand ( args . a ? ? args . left ? ? args . first ? ? args . x ) ;
const right = getOperand ( args . b ? ? args . right ? ? args . second ? ? args . y ) ;
2024-09-25 19:40:13 +02:00
const rule = args . rule ;
2023-11-23 21:36:48 +01:00
2023-11-24 11:49:14 +01:00
return { a : left , b : right , rule } ;
}
2023-11-28 15:00:04 +01:00
/ * *
* Evaluates a boolean comparison rule .
2024-09-25 19:40:13 +02:00
*
* @ param { string ? } rule Boolean comparison rule
2023-11-28 15:00:04 +01:00
* @ param { string | number } a The left operand
2024-09-22 07:42:51 +02:00
* @ param { string | number ? } b The right operand
2023-11-28 15:00:04 +01:00
* @ returns { boolean } True if the rule yields true , false otherwise
* /
2024-06-24 13:44:10 +02:00
export function evalBoolean ( rule , a , b ) {
2024-09-25 20:51:56 +02:00
if ( a === undefined ) {
throw new Error ( 'Left operand is not provided' ) ;
}
2024-09-25 19:40:13 +02:00
// If right-hand side was not provided, whe just check if the left side is truthy
if ( b === undefined ) {
switch ( rule ) {
case undefined :
2024-09-25 20:44:28 +02:00
case 'not' : {
2024-09-25 19:40:13 +02:00
const resultOnTruthy = rule !== 'not' ;
if ( isTrueBoolean ( String ( a ) ) ) return resultOnTruthy ;
if ( isFalseBoolean ( String ( a ) ) ) return ! resultOnTruthy ;
2024-09-25 20:44:28 +02:00
return a ? resultOnTruthy : ! resultOnTruthy ;
}
2024-09-25 19:40:13 +02:00
default :
2024-09-25 20:10:14 +02:00
throw new Error ( ` Unknown boolean comparison rule for truthy check. If right operand is not provided, the rule must not provided or be 'not'. Provided: ${ rule } ` ) ;
2024-09-25 19:40:13 +02:00
}
2023-11-23 21:36:48 +01:00
}
2024-09-25 19:40:13 +02:00
// If no rule was provided, we are implicitly using 'eq', as defined for the slash commands
rule ? ? = 'eq' ;
2024-09-22 07:42:51 +02:00
2024-06-24 13:44:10 +02:00
if ( typeof a === 'number' && typeof b === 'number' ) {
// only do numeric comparison if both operands are numbers
2023-11-23 23:18:07 +01:00
const aNumber = Number ( a ) ;
const bNumber = Number ( b ) ;
switch ( rule ) {
case 'gt' :
2024-09-22 07:58:16 +02:00
return aNumber > bNumber ;
2023-11-23 23:18:07 +01:00
case 'gte' :
2024-09-22 07:58:16 +02:00
return aNumber >= bNumber ;
2023-11-23 23:18:07 +01:00
case 'lt' :
2024-09-22 07:58:16 +02:00
return aNumber < bNumber ;
2023-11-23 23:18:07 +01:00
case 'lte' :
2024-09-22 07:58:16 +02:00
return aNumber <= bNumber ;
2023-11-23 23:18:07 +01:00
case 'eq' :
2024-09-22 07:58:16 +02:00
return aNumber === bNumber ;
2023-11-23 23:18:07 +01:00
case 'neq' :
2024-09-22 07:58:16 +02:00
return aNumber !== bNumber ;
2024-09-25 20:10:14 +02:00
case 'in' :
case 'nin' :
// Fall through to string comparison. Otherwise you could not check if 12345 contains 45 for example.
console . debug ( ` Boolean comparison rule ' ${ rule } ' is not supported for type number. Falling back to string comparison. ` ) ;
break ;
2023-11-23 23:18:07 +01:00
default :
2024-09-25 19:40:13 +02:00
throw new Error ( ` Unknown boolean comparison rule for type number. Accepted: gt, gte, lt, lte, eq, neq. Provided: ${ rule } ` ) ;
2023-11-23 23:18:07 +01:00
}
2024-09-25 19:40:13 +02:00
}
2024-06-24 13:44:10 +02:00
2024-09-25 19:40:13 +02:00
// otherwise do case-insensitive string comparsion, stringify non-strings
let aString = ( typeof a === 'string' ) ? a . toLowerCase ( ) : JSON . stringify ( a ) . toLowerCase ( ) ;
let bString = ( typeof b === 'string' ) ? b . toLowerCase ( ) : JSON . stringify ( b ) . toLowerCase ( ) ;
switch ( rule ) {
case 'in' :
return aString . includes ( bString ) ;
case 'nin' :
return ! aString . includes ( bString ) ;
case 'eq' :
return aString === bString ;
case 'neq' :
return aString !== bString ;
default :
throw new Error ( ` Unknown boolean comparison rule for type number. Accepted: in, nin, eq, neq. Provided: ${ rule } ` ) ;
2023-11-23 21:36:48 +01:00
}
2023-11-23 23:18:07 +01:00
}
2023-11-23 21:36:48 +01:00
2023-11-28 15:00:04 +01:00
/ * *
* Executes a slash command from a string ( may be enclosed in quotes ) and returns the result .
* @ param { string } command Command to execute . May contain escaped macro and batch separators .
2024-05-18 20:48:31 +02:00
* @ param { SlashCommandScope } [ scope ] The scope to use .
2024-05-19 12:27:09 +02:00
* @ param { { [ id : PARSER _FLAG ] : boolean } } [ parserFlags ] The parser flags to use .
2024-05-19 11:19:08 +02:00
* @ param { SlashCommandAbortController } [ abortController ] The abort controller to use .
2024-05-18 20:48:31 +02:00
* @ returns { Promise < SlashCommandClosureResult > } Closure execution result
2023-11-28 15:00:04 +01:00
* /
2024-05-19 11:19:08 +02:00
async function executeSubCommands ( command , scope = null , parserFlags = null , abortController = null ) {
2024-05-12 21:15:05 +02:00
if ( command . startsWith ( '"' ) && command . endsWith ( '"' ) ) {
command = command . slice ( 1 , - 1 ) ;
2023-11-23 23:18:07 +01:00
}
2023-11-23 21:36:48 +01:00
2024-05-18 20:48:31 +02:00
const result = await executeSlashCommandsWithOptions ( command , {
handleExecutionErrors : false ,
handleParserErrors : false ,
parserFlags ,
scope ,
2024-05-19 11:19:08 +02:00
abortController : abortController ? ? new SlashCommandAbortController ( ) ,
2024-05-18 20:48:31 +02:00
} ) ;
2023-11-23 21:36:48 +01:00
2024-05-18 20:48:31 +02:00
return result ;
2023-11-23 21:36:48 +01:00
}
2023-11-28 15:00:04 +01:00
/ * *
* Deletes a local variable .
* @ param { string } name Variable name to delete
* @ returns { string } Empty string
* /
2023-11-25 18:53:00 +01:00
function deleteLocalVariable ( name ) {
if ( ! existsLocalVariable ( name ) ) {
console . warn ( ` The local variable " ${ name } " does not exist. ` ) ;
return '' ;
}
delete chat _metadata . variables [ name ] ;
saveMetadataDebounced ( ) ;
return '' ;
}
2023-11-28 15:00:04 +01:00
/ * *
* Deletes a global variable .
* @ param { string } name Variable name to delete
* @ returns { string } Empty string
* /
2023-11-25 18:53:00 +01:00
function deleteGlobalVariable ( name ) {
if ( ! existsGlobalVariable ( name ) ) {
console . warn ( ` The global variable " ${ name } " does not exist. ` ) ;
return '' ;
}
delete extension _settings . variables . global [ name ] ;
saveSettingsDebounced ( ) ;
return '' ;
}
2023-11-28 15:00:04 +01:00
/ * *
2024-09-30 20:28:52 +02:00
* Parses a series of numeric values from a string or a string array .
* @ param { string | string [ ] } value A space - separated list of numeric values or variable names
2024-05-12 21:15:05 +02:00
* @ param { SlashCommandScope } scope Scope
2023-11-28 15:00:04 +01:00
* @ returns { number [ ] } An array of numeric values
* /
2024-05-12 21:15:05 +02:00
function parseNumericSeries ( value , scope = null ) {
2023-11-27 20:10:50 +01:00
if ( typeof value === 'number' ) {
return [ value ] ;
}
2024-09-30 21:24:22 +02:00
/** @type {(string|number)[]} */
let values = Array . isArray ( value ) ? value : value . split ( ' ' ) ;
// If a JSON array was provided as the only value, convert it to an array
if ( values . length === 1 && typeof values [ 0 ] === 'string' && values [ 0 ] . startsWith ( '[' ) ) {
values = convertValueType ( values [ 0 ] , 'array' ) ;
}
const array = values . map ( i => typeof i === 'string' ? i . trim ( ) : i )
2023-11-27 20:10:50 +01:00
. filter ( i => i !== '' )
2024-09-30 21:24:22 +02:00
. map ( i => isNaN ( Number ( i ) ) ? Number ( resolveVariable ( String ( i ) , scope ) ) : Number ( i ) )
2023-11-27 20:10:50 +01:00
. filter ( i => ! isNaN ( i ) ) ;
return array ;
}
2024-05-12 21:15:05 +02:00
function performOperation ( value , operation , singleOperand = false , scope = null ) {
2024-08-29 14:55:54 +02:00
function getResult ( ) {
if ( ! value ) {
return 0 ;
}
2023-11-27 20:10:50 +01:00
2024-08-29 14:55:54 +02:00
const array = parseNumericSeries ( value , scope ) ;
2023-11-27 20:10:50 +01:00
2024-08-29 14:55:54 +02:00
if ( array . length === 0 ) {
return 0 ;
}
2023-11-27 20:10:50 +01:00
2024-08-29 14:55:54 +02:00
const result = singleOperand ? operation ( array [ 0 ] ) : operation ( array ) ;
2023-11-27 20:10:50 +01:00
2024-09-30 22:52:01 +02:00
if ( isNaN ( result ) ) {
2024-08-29 14:55:54 +02:00
return 0 ;
}
return result ;
2023-11-27 20:10:50 +01:00
}
2024-08-29 14:55:54 +02:00
const result = getResult ( ) ;
return String ( result ) ;
2023-11-27 20:10:50 +01:00
}
2024-05-12 21:15:05 +02:00
function addValuesCallback ( args , value ) {
return performOperation ( value , ( array ) => array . reduce ( ( a , b ) => a + b , 0 ) , false , args . _scope ) ;
2023-11-27 20:10:50 +01:00
}
2024-05-12 21:15:05 +02:00
function mulValuesCallback ( args , value ) {
return performOperation ( value , ( array ) => array . reduce ( ( a , b ) => a * b , 1 ) , false , args . _scope ) ;
2023-11-27 20:10:50 +01:00
}
2024-05-12 21:15:05 +02:00
function minValuesCallback ( args , value ) {
return performOperation ( value , ( array ) => Math . min ( ... array ) , false , args . _scope ) ;
2023-11-27 23:52:50 +01:00
}
2024-05-12 21:15:05 +02:00
function maxValuesCallback ( args , value ) {
return performOperation ( value , ( array ) => Math . max ( ... array ) , false , args . _scope ) ;
2023-11-27 23:52:50 +01:00
}
2024-05-12 21:15:05 +02:00
function subValuesCallback ( args , value ) {
2024-09-30 20:50:18 +02:00
return performOperation ( value , ( array ) => array . reduce ( ( a , b ) => a - b , array . shift ( ) ? ? 0 ) , false , args . _scope ) ;
2023-11-27 20:10:50 +01:00
}
2024-05-12 21:15:05 +02:00
function divValuesCallback ( args , value ) {
2023-11-27 20:10:50 +01:00
return performOperation ( value , ( array ) => {
if ( array [ 1 ] === 0 ) {
console . warn ( 'Division by zero.' ) ;
return 0 ;
}
return array [ 0 ] / array [ 1 ] ;
2024-05-12 21:15:05 +02:00
} , false , args . _scope ) ;
2023-11-27 20:10:50 +01:00
}
2024-05-12 21:15:05 +02:00
function modValuesCallback ( args , value ) {
2023-11-27 20:10:50 +01:00
return performOperation ( value , ( array ) => {
if ( array [ 1 ] === 0 ) {
console . warn ( 'Division by zero.' ) ;
return 0 ;
}
return array [ 0 ] % array [ 1 ] ;
2024-05-12 21:15:05 +02:00
} , false , args . _scope ) ;
2023-11-27 20:10:50 +01:00
}
2024-05-12 21:15:05 +02:00
function powValuesCallback ( args , value ) {
return performOperation ( value , ( array ) => Math . pow ( array [ 0 ] , array [ 1 ] ) , false , args . _scope ) ;
2023-11-27 20:10:50 +01:00
}
2024-05-12 21:15:05 +02:00
function sinValuesCallback ( args , value ) {
return performOperation ( value , Math . sin , true , args . _scope ) ;
2023-11-27 20:10:50 +01:00
}
2024-05-12 21:15:05 +02:00
function cosValuesCallback ( args , value ) {
return performOperation ( value , Math . cos , true , args . _scope ) ;
2023-11-27 20:10:50 +01:00
}
2024-05-12 21:15:05 +02:00
function logValuesCallback ( args , value ) {
return performOperation ( value , Math . log , true , args . _scope ) ;
2023-11-27 20:10:50 +01:00
}
2024-05-12 21:15:05 +02:00
function roundValuesCallback ( args , value ) {
return performOperation ( value , Math . round , true , args . _scope ) ;
2023-11-27 20:10:50 +01:00
}
2024-05-12 21:15:05 +02:00
function absValuesCallback ( args , value ) {
return performOperation ( value , Math . abs , true , args . _scope ) ;
2023-11-27 20:10:50 +01:00
}
2024-05-12 21:15:05 +02:00
function sqrtValuesCallback ( args , value ) {
return performOperation ( value , Math . sqrt , true , args . _scope ) ;
2023-11-27 23:52:50 +01:00
}
2023-12-06 20:03:20 +01:00
function lenValuesCallback ( value ) {
let parsedValue = value ;
try {
parsedValue = JSON . parse ( value ) ;
} catch {
// could not parse
}
2024-02-03 01:06:49 +01:00
if ( Array . isArray ( parsedValue ) ) {
return parsedValue . length ;
}
switch ( typeof parsedValue ) {
case 'string' :
return parsedValue . length ;
case 'object' :
return Object . keys ( parsedValue ) . length ;
case 'number' :
return String ( parsedValue ) . length ;
default :
return 0 ;
}
2023-12-06 20:03:20 +01:00
}
2023-12-15 13:16:46 +01:00
function randValuesCallback ( from , to , args ) {
2023-12-14 23:26:24 +01:00
const range = to - from ;
2023-12-15 13:16:46 +01:00
const value = from + Math . random ( ) * range ;
if ( args . round == 'round' ) {
return Math . round ( value ) ;
}
if ( args . round == 'ceil' ) {
return Math . ceil ( value ) ;
}
if ( args . round == 'floor' ) {
return Math . floor ( value ) ;
}
2024-06-17 03:30:52 +02:00
return value ;
2023-12-14 23:26:24 +01:00
}
2024-10-09 23:09:30 +02:00
function customSortComparitor ( a , b ) {
if ( typeof a != typeof b ) {
a = typeof a ;
b = typeof b ;
}
return a > b ? 1 : a < b ? - 1 : 0 ;
}
2024-10-09 21:49:03 +02:00
function sortArrayObjectCallback ( args , value ) {
let parsedValue ;
if ( typeof value == 'string' ) {
try {
parsedValue = JSON . parse ( value ) ;
2024-10-09 23:41:43 +02:00
} catch {
// return the original input if it was invalid
return value ;
2024-10-09 21:49:03 +02:00
}
} else {
2024-10-09 23:41:43 +02:00
parsedValue = value ;
2024-10-09 21:49:03 +02:00
}
if ( Array . isArray ( parsedValue ) ) {
// always sort lists by value
2024-10-09 23:41:43 +02:00
parsedValue . sort ( customSortComparitor ) ;
2024-10-09 21:49:03 +02:00
} else if ( typeof parsedValue == 'object' ) {
let keysort = args . keysort ;
if ( isFalseBoolean ( keysort ) ) {
2024-10-09 23:41:43 +02:00
parsedValue = Object . keys ( parsedValue ) . sort ( function ( a , b ) { return customSortComparitor ( parsedValue [ a ] , parsedValue [ b ] ) ; } ) ;
2024-10-09 21:49:03 +02:00
} else {
2024-10-09 23:09:30 +02:00
parsedValue = Object . keys ( parsedValue ) . sort ( customSortComparitor ) ;
2024-10-09 21:49:03 +02:00
}
}
2024-10-09 23:41:43 +02:00
return JSON . stringify ( parsedValue ) ;
2024-10-09 21:49:03 +02:00
}
2024-05-12 21:15:05 +02:00
/ * *
* Declare a new variable in the current scope .
2024-06-17 03:30:52 +02:00
* @ param { NamedArguments } args Named arguments .
* @ param { string | SlashCommandClosure | ( string | SlashCommandClosure ) [ ] } value Name and optional value for the variable .
2024-05-12 21:15:05 +02:00
* @ returns The variable ' s value
* /
function letCallback ( args , value ) {
2024-07-20 18:00:22 +02:00
if ( ! Array . isArray ( value ) ) value = [ value ] ;
2024-05-12 21:15:05 +02:00
if ( args . key !== undefined ) {
const key = args . key ;
2024-07-20 18:00:22 +02:00
if ( typeof key != 'string' ) throw new Error ( 'Key must be a string' ) ;
if ( args . _hasUnnamedArgument ) {
2024-07-20 20:03:10 +02:00
const val = typeof value [ 0 ] == 'string' ? value . join ( ' ' ) : value [ 0 ] ;
2024-07-20 18:00:22 +02:00
args . _scope . letVariable ( key , val ) ;
return val ;
} else {
args . _scope . letVariable ( key ) ;
return '' ;
}
2024-06-17 03:30:52 +02:00
}
2024-07-20 18:00:22 +02:00
const key = value . shift ( ) ;
if ( typeof key != 'string' ) throw new Error ( 'Key must be a string' ) ;
if ( value . length > 0 ) {
2024-07-20 20:03:10 +02:00
const val = typeof value [ 0 ] == 'string' ? value . join ( ' ' ) : value [ 0 ] ;
2024-05-12 21:15:05 +02:00
args . _scope . letVariable ( key , val ) ;
return val ;
2024-07-20 18:00:22 +02:00
} else {
args . _scope . letVariable ( key ) ;
return '' ;
2024-05-12 21:15:05 +02:00
}
}
/ * *
* Set or retrieve a variable in the current scope or nearest ancestor scope .
2024-06-17 03:30:52 +02:00
* @ param { NamedArguments } args Named arguments .
2024-05-22 16:21:49 +02:00
* @ param { string | SlashCommandClosure | ( string | SlashCommandClosure ) [ ] } value Name and optional value for the variable .
2024-05-12 21:15:05 +02:00
* @ returns The variable ' s value
* /
function varCallback ( args , value ) {
2024-05-22 16:21:49 +02:00
if ( ! Array . isArray ( value ) ) value = [ value ] ;
2024-05-12 21:15:05 +02:00
if ( args . key !== undefined ) {
const key = args . key ;
2024-07-20 18:00:22 +02:00
if ( typeof key != 'string' ) throw new Error ( 'Key must be a string' ) ;
2024-06-14 23:48:41 +02:00
if ( args . _hasUnnamedArgument ) {
2024-07-20 20:03:10 +02:00
const val = typeof value [ 0 ] == 'string' ? value . join ( ' ' ) : value [ 0 ] ;
2024-09-01 22:02:01 +02:00
args . _scope . setVariable ( key , val , args . index , args . as ) ;
2024-06-14 23:48:41 +02:00
return val ;
} else {
return args . _scope . getVariable ( key , args . index ) ;
}
2024-05-22 16:21:49 +02:00
}
const key = value . shift ( ) ;
2024-07-20 18:00:22 +02:00
if ( typeof key != 'string' ) throw new Error ( 'Key must be a string' ) ;
2024-05-22 16:21:49 +02:00
if ( value . length > 0 ) {
2024-07-20 20:03:10 +02:00
const val = typeof value [ 0 ] == 'string' ? value . join ( ' ' ) : value [ 0 ] ;
2024-09-01 22:02:01 +02:00
args . _scope . setVariable ( key , val , args . index , args . as ) ;
2024-05-12 21:15:05 +02:00
return val ;
2024-05-22 16:21:49 +02:00
} else {
return args . _scope . getVariable ( key , args . index ) ;
2024-05-12 21:15:05 +02:00
}
}
2024-06-14 23:48:41 +02:00
/ * *
2024-06-17 03:30:52 +02:00
* @ param { NamedArguments } args
2024-06-14 23:48:41 +02:00
* @ param { SlashCommandClosure } value
* @ returns { string }
* /
function closureSerializeCallback ( args , value ) {
if ( ! ( value instanceof SlashCommandClosure ) ) {
throw new Error ( 'unnamed argument must be a closure' ) ;
}
return value . rawText ;
}
/ * *
2024-06-17 03:30:52 +02:00
* @ param { NamedArguments } args
* @ param { UnnamedArguments } value
2024-06-14 23:48:41 +02:00
* @ returns { SlashCommandClosure }
* /
function closureDeserializeCallback ( args , value ) {
const parser = new SlashCommandParser ( ) ;
const closure = parser . parse ( value , true , args . _parserFlags , args . _abortController ) ;
closure . scope . parent = args . _scope ;
return closure ;
}
2023-11-06 21:50:32 +01:00
export function registerVariableCommands ( ) {
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'listvar' ,
2024-05-12 21:15:05 +02:00
callback : listVariablesCallback ,
2024-07-21 23:17:57 +02:00
aliases : [ 'listchatvar' ] ,
2024-10-01 00:23:00 +02:00
helpString : 'List registered chat variables. Displays variables in a popup by default. Use the <code>return</code> argument to change the return type.' ,
2024-09-25 12:45:44 +02:00
returns : 'JSON list of local variables' ,
namedArgumentList : [
SlashCommandNamedArgument . fromProps ( {
name : 'scope' ,
description : 'filter variables by scope' ,
typeList : [ ARGUMENT _TYPE . STRING ] ,
defaultValue : 'all' ,
isRequired : false ,
forceEnum : true ,
enumList : [
new SlashCommandEnumValue ( 'all' , 'All variables' , enumTypes . enum , enumIcons . variable ) ,
new SlashCommandEnumValue ( 'local' , 'Local variables' , enumTypes . enum , enumIcons . localVariable ) ,
new SlashCommandEnumValue ( 'global' , 'Global variables' , enumTypes . enum , enumIcons . globalVariable ) ,
] ,
} ) ,
2024-10-01 00:23:00 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'return' ,
description : 'The way how you want the return value to be provided' ,
typeList : [ ARGUMENT _TYPE . STRING ] ,
defaultValue : 'popup-html' ,
enumList : slashCommandReturnHelper . enumList ( { allowPipe : false , allowObject : true , allowChat : true , allowPopup : true , allowTextVersion : false } ) ,
forceEnum : true ,
} ) ,
// TODO remove some day
2024-09-25 12:45:44 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'format' ,
2024-10-01 00:37:21 +02:00
description : '!!! DEPRECATED - use "return" instead !!! output format' ,
2024-09-25 12:45:44 +02:00
typeList : [ ARGUMENT _TYPE . STRING ] ,
isRequired : true ,
forceEnum : true ,
enumList : [
new SlashCommandEnumValue ( 'popup' , 'Show variables in a popup.' , enumTypes . enum , enumIcons . default ) ,
new SlashCommandEnumValue ( 'chat' , 'Post a system message to the chat.' , enumTypes . enum , enumIcons . message ) ,
new SlashCommandEnumValue ( 'none' , 'Just return the variables as a JSON list.' , enumTypes . enum , enumIcons . array ) ,
] ,
} ) ,
] ,
2024-05-12 21:15:05 +02:00
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'setvar' ,
callback : ( args , value ) => String ( setLocalVariable ( args . key || args . name , value , args ) ) ,
2024-07-21 23:17:57 +02:00
aliases : [ 'setchatvar' ] ,
2024-05-12 21:15:05 +02:00
returns : 'the set variable value' ,
namedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
description : 'variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
enumProvider : commonEnumProviders . variables ( 'local' ) ,
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
new SlashCommandNamedArgument (
'index' , 'list index' , [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . STRING ] , false ,
) ,
2024-08-29 14:55:54 +02:00
SlashCommandNamedArgument . fromProps ( {
2024-09-01 10:50:16 +02:00
name : 'as' ,
2024-09-01 10:49:32 +02:00
description : 'change the type of the value when used with index' ,
2024-08-29 14:55:54 +02:00
forceEnum : true ,
enumProvider : commonEnumProviders . types ,
isRequired : false ,
defaultValue : 'string' ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
unnamedArgumentList : [
new SlashCommandArgument (
'value' , [ ARGUMENT _TYPE . STRING , ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . BOOLEAN , ARGUMENT _TYPE . LIST , ARGUMENT _TYPE . DICTIONARY ] , true ,
) ,
] ,
helpString : `
< div >
Set a local variable value and pass it down the pipe . The < code > index < / c o d e > a r g u m e n t i s o p t i o n a l .
2024-09-01 10:50:16 +02:00
To convert the value to a specific JSON type when using < code > index < / c o d e > , u s e t h e < c o d e > a s < / c o d e > a r g u m e n t .
2024-05-12 21:15:05 +02:00
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / s e t v a r k e y = c o l o r g r e e n < / c o d e > < / p r e >
< / l i >
2024-08-29 14:55:54 +02:00
< li >
2024-09-01 22:05:51 +02:00
< pre > < code class = "language-stscript" > / s e t v a r k e y = a g e s i n d e x = J o h n a s = n u m b e r 2 1 < / c o d e > < / p r e >
2024-08-29 14:55:54 +02:00
< / l i >
2024-05-12 21:15:05 +02:00
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'getvar' ,
callback : ( args , value ) => String ( getLocalVariable ( value , args ) ) ,
2024-07-21 23:17:57 +02:00
aliases : [ 'getchatvar' ] ,
2024-05-12 21:15:05 +02:00
returns : 'the variable value' ,
namedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
description : 'variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
enumProvider : commonEnumProviders . variables ( 'local' ) ,
} ) ,
2024-05-12 21:15:05 +02:00
new SlashCommandNamedArgument (
'index' , 'list index' , [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . STRING ] , false ,
) ,
] ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'key' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : false ,
enumProvider : commonEnumProviders . variables ( 'local' ) ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Get a local variable value and pass it down the pipe . The < code > index < / c o d e > a r g u m e n t i s o p t i o n a l .
< / d i v >
< div >
< strong > Examples : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / g e t v a r h e i g h t < / c o d e > < / p r e >
< / l i >
< li >
< pre > < code class = "language-stscript" > / g e t v a r k e y = h e i g h t < / c o d e > < / p r e >
< / l i >
< li >
< pre > < code class = "language-stscript" > / g e t v a r i n d e x = 3 c o s t u m e s < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'addvar' ,
callback : ( args , value ) => String ( addLocalVariable ( args . key || args . name , value ) ) ,
2024-07-21 23:17:57 +02:00
aliases : [ 'addchatvar' ] ,
2024-05-12 21:15:05 +02:00
returns : 'the new variable value' ,
namedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
description : 'variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
enumProvider : commonEnumProviders . variables ( 'local' ) ,
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
unnamedArgumentList : [
new SlashCommandArgument (
'value to add to the variable' , [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . STRING ] , true ,
) ,
] ,
helpString : `
< div >
Add a value to a local variable and pass the result down the pipe .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / a d d v a r k e y = s c o r e 1 0 < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'setglobalvar' ,
callback : ( args , value ) => String ( setGlobalVariable ( args . key || args . name , value , args ) ) ,
2024-05-12 21:15:05 +02:00
returns : 'the set global variable value' ,
namedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
description : 'variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
enumProvider : commonEnumProviders . variables ( 'global' ) ,
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
new SlashCommandNamedArgument (
'index' , 'list index' , [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . STRING ] , false ,
) ,
2024-08-29 14:55:54 +02:00
SlashCommandNamedArgument . fromProps ( {
2024-09-01 10:50:16 +02:00
name : 'as' ,
2024-09-01 10:49:32 +02:00
description : 'change the type of the value when used with index' ,
2024-08-29 14:55:54 +02:00
forceEnum : true ,
enumProvider : commonEnumProviders . types ,
isRequired : false ,
defaultValue : 'string' ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
unnamedArgumentList : [
new SlashCommandArgument (
'value' , [ ARGUMENT _TYPE . STRING , ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . BOOLEAN , ARGUMENT _TYPE . LIST , ARGUMENT _TYPE . DICTIONARY ] , true ,
) ,
] ,
helpString : `
< div >
Set a global variable value and pass it down the pipe . The < code > index < / c o d e > a r g u m e n t i s o p t i o n a l .
2024-09-01 10:50:16 +02:00
To convert the value to a specific JSON type when using < code > index < / c o d e > , u s e t h e < c o d e > a s < / c o d e > a r g u m e n t .
2024-05-12 21:15:05 +02:00
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / s e t g l o b a l v a r k e y = c o l o r g r e e n < / c o d e > < / p r e >
< / l i >
2024-08-29 14:55:54 +02:00
< li >
2024-09-01 22:05:51 +02:00
< pre > < code class = "language-stscript" > / s e t g l o b a l v a r k e y = a g e s i n d e x = J o h n a s = n u m b e r 2 1 < / c o d e > < / p r e >
2024-08-29 14:55:54 +02:00
< / l i >
2024-05-12 21:15:05 +02:00
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'getglobalvar' ,
callback : ( args , value ) => String ( getGlobalVariable ( value , args ) ) ,
2024-05-12 21:15:05 +02:00
returns : 'global variable value' ,
namedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
description : 'variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
enumProvider : commonEnumProviders . variables ( 'global' ) ,
} ) ,
2024-05-12 21:15:05 +02:00
new SlashCommandNamedArgument (
'index' , 'list index' , [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . STRING ] , false ,
) ,
] ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'key' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
enumProvider : commonEnumProviders . variables ( 'global' ) ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Get a global variable value and pass it down the pipe . The < code > index < / c o d e > a r g u m e n t i s o p t i o n a l .
< / d i v >
< div >
< strong > Examples : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / g e t g l o b a l v a r h e i g h t < / c o d e > < / p r e >
< / l i >
< li >
< pre > < code class = "language-stscript" > / g e t g l o b a l v a r k e y = h e i g h t < / c o d e > < / p r e >
< / l i >
< li >
< pre > < code class = "language-stscript" > / g e t g l o b a l v a r i n d e x = 3 c o s t u m e s < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'addglobalvar' ,
callback : ( args , value ) => String ( addGlobalVariable ( args . key || args . name , value ) ) ,
2024-05-12 21:15:05 +02:00
returns : 'the new variable value' ,
namedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
description : 'variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
enumProvider : commonEnumProviders . variables ( 'global' ) ,
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
unnamedArgumentList : [
new SlashCommandArgument (
'value to add to the variable' , [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . STRING ] , true ,
) ,
] ,
helpString : `
< div >
Add a value to a global variable and pass the result down the pipe .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / a d d g l o b a l v a r k e y = s c o r e 1 0 < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'incvar' ,
callback : ( _ , value ) => String ( incrementLocalVariable ( value ) ) ,
2024-07-21 23:17:57 +02:00
aliases : [ 'incchatvar' ] ,
2024-05-12 21:15:05 +02:00
returns : 'the new variable value' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
description : 'variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
enumProvider : commonEnumProviders . variables ( 'local' ) ,
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Increment a local variable by 1 and pass the result down the pipe .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / i n c v a r s c o r e < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'decvar' ,
callback : ( _ , value ) => String ( decrementLocalVariable ( value ) ) ,
2024-07-21 23:17:57 +02:00
aliases : [ 'decchatvar' ] ,
2024-05-12 21:15:05 +02:00
returns : 'the new variable value' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
description : 'variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
enumProvider : commonEnumProviders . variables ( 'local' ) ,
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Decrement a local variable by 1 and pass the result down the pipe .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / d e c v a r s c o r e < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'incglobalvar' ,
callback : ( _ , value ) => String ( incrementGlobalVariable ( value ) ) ,
2024-05-12 21:15:05 +02:00
returns : 'the new variable value' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
description : 'variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
enumProvider : commonEnumProviders . variables ( 'global' ) ,
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Increment a global variable by 1 and pass the result down the pipe .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / i n c g l o b a l v a r s c o r e < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'decglobalvar' ,
callback : ( _ , value ) => String ( decrementGlobalVariable ( value ) ) ,
2024-05-12 21:15:05 +02:00
returns : 'the new variable value' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
description : 'variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
enumProvider : commonEnumProviders . variables ( 'global' ) ,
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Decrement a global variable by 1 and pass the result down the pipe .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / d e c g l o b a l v a r s c o r e < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'if' ,
2024-05-12 21:15:05 +02:00
callback : ifCallback ,
returns : 'result of the executed command ("then" or "else")' ,
namedArgumentList : [
2024-06-20 20:33:45 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'left' ,
description : 'left operand' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME , ARGUMENT _TYPE . STRING , ARGUMENT _TYPE . NUMBER ] ,
isRequired : true ,
enumProvider : commonEnumProviders . variables ( 'all' ) ,
} ) ,
SlashCommandNamedArgument . fromProps ( {
name : 'right' ,
description : 'right operand' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME , ARGUMENT _TYPE . STRING , ARGUMENT _TYPE . NUMBER ] ,
enumProvider : commonEnumProviders . variables ( 'all' ) ,
} ) ,
2024-09-22 02:32:43 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'rule' ,
description : 'comparison rule' ,
typeList : [ ARGUMENT _TYPE . STRING ] ,
2024-09-22 07:42:51 +02:00
defaultValue : 'eq' ,
2024-09-22 02:32:43 +02:00
enumList : [
2024-09-25 20:10:14 +02:00
new SlashCommandEnumValue ( 'eq' , 'a == b (strings & numbers)' ) ,
new SlashCommandEnumValue ( 'neq' , 'a !== b (strings & numbers)' ) ,
new SlashCommandEnumValue ( 'in' , 'a includes b (strings & numbers as strings)' ) ,
new SlashCommandEnumValue ( 'nin' , 'a not includes b (strings & numbers as strings)' ) ,
new SlashCommandEnumValue ( 'gt' , 'a > b (numbers)' ) ,
new SlashCommandEnumValue ( 'gte' , 'a >= b (numbers)' ) ,
new SlashCommandEnumValue ( 'lt' , 'a < b (numbers)' ) ,
new SlashCommandEnumValue ( 'lte' , 'a <= b (numbers)' ) ,
new SlashCommandEnumValue ( 'not' , '!a (truthy)' ) ,
2024-08-29 15:04:46 +02:00
] ,
2024-09-22 07:42:51 +02:00
forceEnum : true ,
2024-09-22 02:32:43 +02:00
} ) ,
SlashCommandNamedArgument . fromProps ( {
name : 'else' ,
description : 'command to execute if not true' ,
typeList : [ ARGUMENT _TYPE . CLOSURE , ARGUMENT _TYPE . SUBCOMMAND ] ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
unnamedArgumentList : [
new SlashCommandArgument (
'command to execute if true' , [ ARGUMENT _TYPE . CLOSURE , ARGUMENT _TYPE . SUBCOMMAND ] , true ,
) ,
] ,
2024-05-19 12:40:08 +02:00
splitUnnamedArgument : true ,
2024-05-12 21:15:05 +02:00
helpString : `
< div >
Compares the value of the left operand < code > a < / c o d e > w i t h t h e v a l u e o f t h e r i g h t o p e r a n d < c o d e > b < / c o d e > ,
and if the condition yields true , then execute any valid slash command enclosed in quotes and pass the
result of the command execution down the pipe .
< / d i v >
< div >
Numeric values and string literals for left and right operands supported .
< / d i v >
2024-09-22 07:42:51 +02:00
< div >
2024-09-25 20:10:14 +02:00
If the rule is not provided , it defaults to < code > eq < / c o d e > .
< / d i v >
< div >
2024-09-22 07:42:51 +02:00
If no right operand is provided , it defaults to checking the < code > left < / c o d e > v a l u e t o b e t r u t h y .
2024-09-25 20:10:14 +02:00
A non - empty string or non - zero number is considered truthy , as is the value < code > true < / c o d e > o r < c o d e > o n < / c o d e > . < b r / >
Only acceptable rules for no provided right operand are < code > not < / c o d e > , a n d n o p r o v i d e d r u l e - w h i c h d e f a u l t t o r e t u r n i n g w h e t h e r i t i s n o t o r i s t r u t h y .
2024-09-22 07:42:51 +02:00
< / d i v >
2024-05-12 21:15:05 +02:00
< div >
< strong > Available rules : < / s t r o n g >
< ul >
2024-09-25 20:10:14 +02:00
< li > < code > eq < / c o d e > = > a = = b < s m a l l > ( s t r i n g s & n u m b e r s ) < / s m a l l > < / l i >
< li > < code > neq < / c o d e > = > a ! = = b < s m a l l > ( s t r i n g s & n u m b e r s ) < / s m a l l > < / l i >
< li > < code > in < / c o d e > = > a i n c l u d e s b < s m a l l > ( s t r i n g s & n u m b e r s a s s t r i n g s ) < / s m a l l > < / l i >
< li > < code > nin < / c o d e > = > a n o t i n c l u d e s b < s m a l l > ( s t r i n g s & n u m b e r s a s s t r i n g s ) < / s m a l l > < / l i >
< li > < code > gt < / c o d e > = > a > b < s m a l l > ( n u m b e r s ) < / s m a l l > < / l i >
< li > < code > gte < / c o d e > = > a > = b < s m a l l > ( n u m b e r s ) < / s m a l l > < / l i >
< li > < code > lt < / c o d e > = > a < b < s m a l l > ( n u m b e r s ) < / s m a l l > < / l i >
< li > < code > lte < / c o d e > = > a < = b < s m a l l > ( n u m b e r s ) < / s m a l l > < / l i >
< li > < code > not < / c o d e > = > ! a < s m a l l > ( t r u t h y ) < / s m a l l > < / l i >
2024-05-12 21:15:05 +02:00
< / u l >
< / d i v >
< div >
< strong > Examples : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / i f l e f t = s c o r e r i g h t = 1 0 r u l e = g t e " / s p e a k Y o u w i n " < / c o d e > < / p r e >
triggers a / speak command if the value of "score" is greater or equals 10.
< / l i >
2024-09-22 07:42:51 +02:00
< li >
< pre > < code class = "language-stscript" > / i f l e f t = { { l a s t M e s s a g e } } r u l e = i n r i g h t = s u r p r i s e { : / e c h o S U R P I S E ! : } < / c o d e > < / p r e >
executes a subcommand defined as a closure if the given value contains a specified word .
< li >
2024-09-25 20:10:14 +02:00
< pre > < code class = "language-stscript" > / i f l e f t = m y C o n t e n t { : / e c h o M y c o n t e n t h a d s o m e c o n t e n t . : } < / c o d e > < / p r e >
2024-09-22 07:42:51 +02:00
executes the defined subcommand , if the provided value of left is truthy ( contains some kind of contant that is not empty or false )
< / l i >
2024-09-25 20:10:14 +02:00
< li >
< pre > < code class = "language-stscript" > / i f l e f t = t r e e r i g h t = { { g e t v a r : : o b j e c t } } { : / e c h o T h e o b j e c t i s a t r e e ! : } < / c o d e > < / p r e >
executes the defined subcommand , if the left and right values are equals .
< / l i >
2024-05-12 21:15:05 +02:00
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'while' ,
2024-05-12 21:15:05 +02:00
callback : whileCallback ,
returns : 'result of the last executed command' ,
namedArgumentList : [
2024-06-20 20:33:45 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'left' ,
description : 'left operand' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME , ARGUMENT _TYPE . STRING , ARGUMENT _TYPE . NUMBER ] ,
isRequired : true ,
enumProvider : commonEnumProviders . variables ( 'all' ) ,
} ) ,
SlashCommandNamedArgument . fromProps ( {
name : 'right' ,
description : 'right operand' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME , ARGUMENT _TYPE . STRING , ARGUMENT _TYPE . NUMBER ] ,
enumProvider : commonEnumProviders . variables ( 'all' ) ,
} ) ,
2024-09-22 08:09:19 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'rule' ,
description : 'comparison rule' ,
typeList : [ ARGUMENT _TYPE . STRING ] ,
defaultValue : 'eq' ,
enumList : [
2024-09-25 20:10:14 +02:00
new SlashCommandEnumValue ( 'eq' , 'a == b (strings & numbers)' ) ,
new SlashCommandEnumValue ( 'neq' , 'a !== b (strings & numbers)' ) ,
new SlashCommandEnumValue ( 'in' , 'a includes b (strings & numbers as strings)' ) ,
new SlashCommandEnumValue ( 'nin' , 'a not includes b (strings & numbers as strings)' ) ,
new SlashCommandEnumValue ( 'gt' , 'a > b (numbers)' ) ,
new SlashCommandEnumValue ( 'gte' , 'a >= b (numbers)' ) ,
new SlashCommandEnumValue ( 'lt' , 'a < b (numbers)' ) ,
new SlashCommandEnumValue ( 'lte' , 'a <= b (numbers)' ) ,
new SlashCommandEnumValue ( 'not' , '!a (truthy)' ) ,
2024-08-29 15:04:46 +02:00
] ,
2024-09-22 08:09:19 +02:00
forceEnum : true ,
} ) ,
SlashCommandNamedArgument . fromProps ( {
name : 'guard' ,
description : 'disable loop iteration limit' ,
typeList : [ ARGUMENT _TYPE . STRING ] ,
defaultValue : 'off' ,
enumList : commonEnumProviders . boolean ( 'onOff' ) ( ) ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
unnamedArgumentList : [
new SlashCommandArgument (
'command to execute while true' , [ ARGUMENT _TYPE . CLOSURE , ARGUMENT _TYPE . SUBCOMMAND ] , true ,
) ,
] ,
2024-05-18 20:48:31 +02:00
splitUnnamedArgument : true ,
2024-05-12 21:15:05 +02:00
helpString : `
< div >
Compares the value of the left operand < code > a < / c o d e > w i t h t h e v a l u e o f t h e r i g h t o p e r a n d < c o d e > b < / c o d e > ,
and if the condition yields true , then execute any valid slash command enclosed in quotes .
< / d i v >
< div >
Numeric values and string literals for left and right operands supported .
< / d i v >
< div >
< strong > Available rules : < / s t r o n g >
< ul >
2024-09-25 20:10:14 +02:00
< li > < code > eq < / c o d e > = > a = = b < s m a l l > ( s t r i n g s & n u m b e r s ) < / s m a l l > < / l i >
< li > < code > neq < / c o d e > = > a ! = = b < s m a l l > ( s t r i n g s & n u m b e r s ) < / s m a l l > < / l i >
< li > < code > in < / c o d e > = > a i n c l u d e s b < s m a l l > ( s t r i n g s & n u m b e r s a s s t r i n g s ) < / s m a l l > < / l i >
< li > < code > nin < / c o d e > = > a n o t i n c l u d e s b < s m a l l > ( s t r i n g s & n u m b e r s a s s t r i n g s ) < / s m a l l > < / l i >
< li > < code > gt < / c o d e > = > a > b < s m a l l > ( n u m b e r s ) < / s m a l l > < / l i >
< li > < code > gte < / c o d e > = > a > = b < s m a l l > ( n u m b e r s ) < / s m a l l > < / l i >
< li > < code > lt < / c o d e > = > a < b < s m a l l > ( n u m b e r s ) < / s m a l l > < / l i >
< li > < code > lte < / c o d e > = > a < = b < s m a l l > ( n u m b e r s ) < / s m a l l > < / l i >
< li > < code > not < / c o d e > = > ! a < s m a l l > ( t r u t h y ) < / s m a l l > < / l i >
2024-05-12 21:15:05 +02:00
< / u l >
< / d i v >
< div >
< strong > Examples : < / s t r o n g >
< ul >
< li >
2024-05-15 00:36:10 +02:00
< pre > < code class = "language-stscript" > / s e t v a r k e y = i 0 | / w h i l e l e f t = i r i g h t = 1 0 r u l e = l t e " / a d d v a r k e y = i 1 " < / c o d e > < / p r e >
2024-05-12 21:15:05 +02:00
adds 1 to the value of "i" until it reaches 10.
< / l i >
2024-09-22 08:09:19 +02:00
< li >
< pre > < code class = "language-stscript" > / w h i l e l e f t = { { g e t v a r : : c u r r e n t w o r d } } { : / s e t v a r k e y = c u r r e n t w o r d { : / d o - s o m e t h i n g - a n d - r e t u r n : } ( ) | / e c h o T h e c u r r e n t w o r k i s " { { g e t v a r : : c u r r e n t w o r d } } " : } < / c o d e > < / p r e >
executes the defined subcommand as long as the "currentword" variable is truthy ( has any content that is not false / empty )
2024-09-25 20:46:40 +02:00
< / u l >
< / l i >
2024-05-12 21:15:05 +02:00
< / d i v >
< div >
Loops are limited to 100 iterations by default , pass < code > guard = off < / c o d e > t o d i s a b l e .
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'times' ,
2024-05-12 21:15:05 +02:00
callback : timesCallback ,
returns : 'result of the last executed command' ,
2024-06-30 22:00:36 +02:00
namedArgumentList : [
new SlashCommandNamedArgument (
'guard' , 'disable loop iteration limit' , [ ARGUMENT _TYPE . STRING ] , false , false , null , commonEnumProviders . boolean ( 'onOff' ) ( ) ,
) ,
] ,
2024-05-12 21:15:05 +02:00
unnamedArgumentList : [
new SlashCommandArgument (
'repeats' ,
[ ARGUMENT _TYPE . NUMBER ] ,
true ,
) ,
new SlashCommandArgument (
'command' ,
[ ARGUMENT _TYPE . CLOSURE , ARGUMENT _TYPE . SUBCOMMAND ] ,
true ,
) ,
] ,
2024-05-18 20:48:31 +02:00
splitUnnamedArgument : true ,
2024-06-24 00:18:44 +02:00
splitUnnamedArgumentCount : 1 ,
2024-05-12 21:15:05 +02:00
helpString : `
< div >
Execute any valid slash command enclosed in quotes < code > repeats < / c o d e > n u m b e r o f t i m e s .
< / d i v >
< div >
< strong > Examples : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / s e t v a r k e y = i 1 | / t i m e s 5 " / a d d v a r k e y = i 1 " < / c o d e > < / p r e >
adds 1 to the value of "i" 5 times .
< / l i >
< li >
< pre > < code class = "language-stscript" > / t i m e s 4 " / e c h o { { t i m e s I n d e x } } " < / c o d e > < / p r e >
echos the numbers 0 through 4. < code > { { timesIndex } } < / c o d e > i s r e p l a c e d w i t h t h e i t e r a t i o n n u m b e r ( z e r o - b a s e d ) .
< / l i >
< / u l >
< / d i v >
< div >
Loops are limited to 100 iterations by default , pass < code > guard = off < / c o d e > t o d i s a b l e .
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'flushvar' ,
callback : async ( _ , value ) => deleteLocalVariable ( value instanceof SlashCommandClosure ? ( await value . execute ( ) ) ? . pipe : String ( value ) ) ,
2024-07-21 23:17:57 +02:00
aliases : [ 'flushchatvar' ] ,
2024-05-12 21:15:05 +02:00
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
2024-06-23 17:28:22 +02:00
description : 'variable name or closure that returns a variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME , ARGUMENT _TYPE . CLOSURE ] ,
2024-06-17 03:30:52 +02:00
enumProvider : commonEnumProviders . variables ( 'local' ) ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Delete a local variable .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / f l u s h v a r s c o r e < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'flushglobalvar' ,
callback : async ( _ , value ) => deleteGlobalVariable ( value instanceof SlashCommandClosure ? ( await value . execute ( ) ) ? . pipe : String ( value ) ) ,
2024-05-12 21:15:05 +02:00
namedArgumentList : [ ] ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
2024-06-23 17:28:22 +02:00
description : 'variable name or closure that returns a variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME , ARGUMENT _TYPE . CLOSURE ] ,
2024-06-17 03:30:52 +02:00
enumProvider : commonEnumProviders . variables ( 'global' ) ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Deletes the specified global variable .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / f l u s h g l o b a l v a r s c o r e < / c o d e > < / p r e >
Deletes the global variable < code > score < / c o d e > .
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'add' ,
2024-09-30 20:28:52 +02:00
callback : ( args , value ) => addValuesCallback ( args , value ) ,
2024-05-12 21:15:05 +02:00
returns : 'sum of the provided values' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'values to sum' ,
2024-09-30 21:24:22 +02:00
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME , ARGUMENT _TYPE . LIST ] ,
2024-06-17 03:30:52 +02:00
isRequired : true ,
acceptsMultiple : true ,
2024-09-30 20:45:39 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
2024-06-23 17:51:26 +02:00
splitUnnamedArgument : true ,
2024-05-12 21:15:05 +02:00
helpString : `
< div >
Performs an addition of the set of values and passes the result down the pipe .
2024-09-30 21:24:22 +02:00
< / d i v >
< div >
Can use variable names , or a JSON array consisting of numbers and variables ( with quotes ) .
2024-05-12 21:15:05 +02:00
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / a d d 1 0 i 3 0 j < / c o d e > < / p r e >
< / l i >
2024-09-30 21:24:22 +02:00
< li >
< pre > < code class = "language-stscript" > / a d d [ " c o u n t " , 1 5 , 2 , " i " ] < / c o d e > < / p r e >
< / l i >
2024-05-12 21:15:05 +02:00
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'mul' ,
2024-05-12 21:15:05 +02:00
callback : ( args , value ) => mulValuesCallback ( args , value ) ,
2024-06-17 03:30:52 +02:00
returns : 'product of the provided values' ,
2024-05-12 21:15:05 +02:00
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'values to multiply' ,
2024-09-30 21:24:22 +02:00
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME , ARGUMENT _TYPE . LIST ] ,
2024-06-17 03:30:52 +02:00
isRequired : true ,
acceptsMultiple : true ,
2024-09-30 20:45:39 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
2024-09-30 20:45:39 +02:00
splitUnnamedArgument : true ,
2024-05-12 21:15:05 +02:00
helpString : `
< div >
2024-09-30 21:24:22 +02:00
Performs a multiplication of the set of values and passes the result down the pipe .
< / d i v >
< div >
Can use variable names , or a JSON array consisting of numbers and variables ( with quotes ) .
2024-05-12 21:15:05 +02:00
< / d i v >
< div >
< strong > Examples : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / m u l 1 0 i 3 0 j < / c o d e > < / p r e >
< / l i >
2024-09-30 21:24:22 +02:00
< li >
< pre > < code class = "language-stscript" > / m u l [ " c o u n t " , 1 5 , 2 , " i " ] < / c o d e > < / p r e >
< / l i >
2024-05-12 21:15:05 +02:00
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'max' ,
2024-05-12 21:15:05 +02:00
callback : maxValuesCallback ,
returns : 'maximum value of the set of values' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'values to find the max' ,
2024-09-30 21:24:22 +02:00
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME , ARGUMENT _TYPE . LIST ] ,
2024-06-17 03:30:52 +02:00
isRequired : true ,
acceptsMultiple : true ,
2024-09-30 20:45:39 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
2024-09-30 20:45:39 +02:00
splitUnnamedArgument : true ,
2024-05-12 21:15:05 +02:00
helpString : `
< div >
2024-09-30 21:24:22 +02:00
Returns the maximum value of the set of values and passes the result down the pipe .
< / d i v >
< div >
Can use variable names , or a JSON array consisting of numbers and variables ( with quotes ) .
2024-05-12 21:15:05 +02:00
< / d i v >
< div >
< strong > Examples : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / m a x 1 0 i 3 0 j < / c o d e > < / p r e >
< / l i >
2024-09-30 21:24:22 +02:00
< li >
< pre > < code class = "language-stscript" > / m a x [ " c o u n t " , 1 5 , 2 , " i " ] < / c o d e > < / p r e >
< / l i >
2024-05-12 21:15:05 +02:00
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'min' ,
2024-05-12 21:15:05 +02:00
callback : minValuesCallback ,
returns : 'minimum value of the set of values' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'values to find the min' ,
2024-09-30 21:24:22 +02:00
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME , ARGUMENT _TYPE . LIST ] ,
2024-06-17 03:30:52 +02:00
isRequired : true ,
acceptsMultiple : true ,
2024-09-30 20:45:39 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
2024-09-30 20:45:39 +02:00
splitUnnamedArgument : true ,
2024-05-12 21:15:05 +02:00
helpString : `
< div >
Returns the minimum value of the set of values and passes the result down the pipe .
2024-09-30 21:24:22 +02:00
< / d i v >
< div >
Can use variable names , or a JSON array consisting of numbers and variables ( with quotes ) .
2024-05-12 21:15:05 +02:00
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / m i n 1 0 i 3 0 j < / c o d e > < / p r e >
< / l i >
2024-09-30 21:24:22 +02:00
< li >
< pre > < code class = "language-stscript" > / m i n [ " c o u n t " , 1 5 , 2 , " i " ] < / c o d e > < / p r e >
< / l i >
2024-05-12 21:15:05 +02:00
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'sub' ,
2024-05-12 21:15:05 +02:00
callback : subValuesCallback ,
returns : 'difference of the provided values' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
2024-09-30 20:50:18 +02:00
description : 'values to subtract, starting form the first provided value' ,
2024-09-30 21:24:22 +02:00
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME , ARGUMENT _TYPE . LIST ] ,
2024-06-17 03:30:52 +02:00
isRequired : true ,
acceptsMultiple : true ,
2024-09-30 20:50:18 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
2024-09-30 20:50:18 +02:00
splitUnnamedArgument : true ,
2024-05-12 21:15:05 +02:00
helpString : `
< div >
Performs a subtraction of the set of values and passes the result down the pipe .
2024-09-30 21:24:22 +02:00
< / d i v >
< div >
Can use variable names , or a JSON array consisting of numbers and variables ( with quotes ) .
2024-05-12 21:15:05 +02:00
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / s u b i 5 < / c o d e > < / p r e >
< / l i >
2024-09-30 21:24:22 +02:00
< li >
< pre > < code class = "language-stscript" > / s u b [ " c o u n t " , 4 , " i " ] < / c o d e > < / p r e >
< / l i >
2024-05-12 21:15:05 +02:00
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'div' ,
2024-05-12 21:15:05 +02:00
callback : divValuesCallback ,
returns : 'result of division' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'dividend' ,
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
2024-09-30 20:59:42 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
SlashCommandArgument . fromProps ( {
description : 'divisor' ,
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
2024-09-30 20:59:42 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
2024-09-30 20:59:42 +02:00
splitUnnamedArgument : true ,
2024-05-12 21:15:05 +02:00
helpString : `
< div >
Performs a division of two values and passes the result down the pipe .
Can use variable names .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / d i v 1 0 i < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'mod' ,
2024-05-12 21:15:05 +02:00
callback : modValuesCallback ,
returns : 'result of modulo operation' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'dividend' ,
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
2024-09-30 20:59:42 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
SlashCommandArgument . fromProps ( {
description : 'divisor' ,
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
2024-09-30 20:59:42 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
2024-09-30 20:59:42 +02:00
splitUnnamedArgument : true ,
2024-05-12 21:15:05 +02:00
helpString : `
< div >
Performs a modulo operation of two values and passes the result down the pipe .
Can use variable names .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / m o d i 2 < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'pow' ,
2024-05-12 21:15:05 +02:00
callback : powValuesCallback ,
returns : 'result of power operation' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'base' ,
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
2024-09-30 20:59:42 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
SlashCommandArgument . fromProps ( {
description : 'exponent' ,
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
2024-09-30 20:59:42 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
2024-09-30 20:59:42 +02:00
splitUnnamedArgument : true ,
2024-05-12 21:15:05 +02:00
helpString : `
< div >
Performs a power operation of two values and passes the result down the pipe .
Can use variable names .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / p o w i 2 < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'sin' ,
2024-05-12 21:15:05 +02:00
callback : sinValuesCallback ,
returns : 'sine of the provided value' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'value' ,
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
2024-09-30 20:59:42 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Performs a sine operation of a value and passes the result down the pipe .
Can use variable names .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / s i n i < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'cos' ,
2024-05-12 21:15:05 +02:00
callback : cosValuesCallback ,
returns : 'cosine of the provided value' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'value' ,
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
2024-09-30 20:59:42 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Performs a cosine operation of a value and passes the result down the pipe .
Can use variable names .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / c o s i < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'log' ,
2024-05-12 21:15:05 +02:00
callback : logValuesCallback ,
returns : 'log of the provided value' ,
namedArgumentList : [ ] ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'value' ,
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
2024-09-30 20:59:42 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Performs a logarithm operation of a value and passes the result down the pipe .
Can use variable names .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / l o g i < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'abs' ,
2024-05-12 21:15:05 +02:00
callback : absValuesCallback ,
returns : 'absolute value of the provided value' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'value' ,
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
2024-09-30 20:59:42 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Performs an absolute value operation of a value and passes the result down the pipe .
Can use variable names .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / a b s i < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'sqrt' ,
2024-05-12 21:15:05 +02:00
callback : sqrtValuesCallback ,
returns : 'square root of the provided value' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'value' ,
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
2024-09-30 20:59:42 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Performs a square root operation of a value and passes the result down the pipe .
Can use variable names .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / s q r t i < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'round' ,
2024-05-12 21:15:05 +02:00
callback : roundValuesCallback ,
returns : 'rounded value' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'value' ,
typeList : [ ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . VARIABLE _NAME ] ,
isRequired : true ,
2024-09-30 20:59:42 +02:00
enumProvider : commonEnumProviders . numbersAndVariables ,
2024-06-17 03:30:52 +02:00
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
Rounds a value and passes the result down the pipe .
Can use variable names .
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / r o u n d i < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'len' ,
callback : ( _ , value ) => String ( lenValuesCallback ( value ) ) ,
2024-07-21 23:17:57 +02:00
aliases : [ 'length' ] ,
2024-05-12 21:15:05 +02:00
returns : 'length of the provided value' ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'value' ,
2024-07-10 10:11:16 +02:00
typeList : [ ARGUMENT _TYPE . STRING , ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . LIST , ARGUMENT _TYPE . DICTIONARY ] ,
2024-06-17 03:30:52 +02:00
isRequired : true ,
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
helpString : `
< div >
2024-07-10 10:11:16 +02:00
Gets the length of a value and passes the result down the pipe .
< ul >
< li >
For strings , returns the number of characters .
< / l i >
< li >
For lists and dictionaries , returns the number of elements .
< / l i >
< li >
For numbers , returns the number of digits ( including the sign and decimal point ) .
< / l i >
< / u l >
2024-05-12 21:15:05 +02:00
< / d i v >
< div >
< strong > Example : < / s t r o n g >
< ul >
< li >
2024-07-10 10:11:16 +02:00
< pre > < code class = "language-stscript" > / l e n L o r e m i p s u m | / e c h o < / c o d e > < / p r e >
2024-05-12 21:15:05 +02:00
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-10-09 21:49:03 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'sort' ,
callback : sortArrayObjectCallback ,
returns : 'the sorted list or dictionary keys' ,
namedArgumentList : [
SlashCommandNamedArgument . fromProps ( { name : 'keysort' ,
description : 'whether to sort by key or value; ignored for lists' ,
typeList : [ ARGUMENT _TYPE . BOOLEAN ] ,
enumList : [ 'true' , 'false' ] ,
defaultValue : 'true' ,
} ) ,
] ,
unnamedArgumentList : [
SlashCommandArgument . fromProps ( {
description : 'value' ,
typeList : [ ARGUMENT _TYPE . STRING , ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . LIST , ARGUMENT _TYPE . DICTIONARY ] ,
isRequired : true ,
forceEnum : false ,
} ) ,
] ,
helpString : `
< div >
Sorts a list or dictionary in ascending order and passes the result down the pipe .
< ul >
< li >
For lists , returns the list sorted by value .
< / l i >
< li >
For dictionaries , returns the ordered list of keys after sorting . Setting keysort = false means keys are sorted by associated value .
< / l i >
< / u l >
< / d i v >
< div >
< strong > Examples : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / s o r t [ 5 , 3 , 4 , 1 , 2 ] | / e c h o < / c o d e > < / p r e >
< / l i >
< li >
< pre > < code class = "language-stscript" > / s o r t k e y s o r t = f a l s e { " a " : 1 , " d " : 3 , " c " : 2 , " b " : 5 } | / e c h o < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'rand' ,
callback : ( args , value ) => String ( randValuesCallback ( Number ( args . from ? ? 0 ) , Number ( args . to ? ? ( value ? value : 1 ) ) , args ) ) ,
2024-05-12 21:15:05 +02:00
returns : 'random number' ,
namedArgumentList : [
new SlashCommandNamedArgument (
'from' ,
'starting value for the range (inclusive)' ,
[ ARGUMENT _TYPE . NUMBER ] ,
false ,
false ,
'0' ,
) ,
new SlashCommandNamedArgument (
'to' ,
'ending value for the range (inclusive)' ,
[ ARGUMENT _TYPE . NUMBER ] ,
false ,
false ,
'1' ,
) ,
new SlashCommandNamedArgument (
'round' ,
'rounding method for the result' ,
[ ARGUMENT _TYPE . STRING ] ,
false ,
false ,
null ,
[ 'round' , 'ceil' , 'floor' ] ,
) ,
] ,
helpString : `
< div >
Returns a random number between < code > from < / c o d e > a n d < c o d e > t o < / c o d e > ( i n c l u s i v e ) .
< / d i v >
< div >
< strong > Examples : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / r a n d < / c o d e > < / p r e >
Returns a random number between 0 and 1.
< / l i >
< li >
< pre > < code class = "language-stscript" > / r a n d 1 0 < / c o d e > < / p r e >
Returns a random number between 0 and 10.
< / l i >
< li >
< pre > < code class = "language-stscript" > / r a n d f r o m = 5 t o = 1 0 < / c o d e > < / p r e >
Returns a random number between 5 and 10.
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'var' ,
callback : ( /** @type {NamedArguments} */ args , value ) => varCallback ( args , value ) ,
2024-05-12 21:15:05 +02:00
returns : 'the variable value' ,
namedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
description : 'variable name; forces setting the variable, even if no value is provided' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
enumProvider : commonEnumProviders . variables ( 'scope' ) ,
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
new SlashCommandNamedArgument (
'index' ,
'optional index for list or dictionary' ,
[ ARGUMENT _TYPE . NUMBER ] ,
false , // isRequired
false , // acceptsMultiple
) ,
2024-08-29 14:55:54 +02:00
SlashCommandNamedArgument . fromProps ( {
2024-09-01 10:50:16 +02:00
name : 'as' ,
2024-09-01 10:49:32 +02:00
description : 'change the type of the value when used with index' ,
2024-08-29 14:55:54 +02:00
forceEnum : true ,
enumProvider : commonEnumProviders . types ,
isRequired : false ,
defaultValue : 'string' ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
enumProvider : commonEnumProviders . variables ( 'scope' ) ,
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
new SlashCommandArgument (
'variable value' ,
[ ARGUMENT _TYPE . STRING , ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . BOOLEAN , ARGUMENT _TYPE . LIST , ARGUMENT _TYPE . DICTIONARY , ARGUMENT _TYPE . CLOSURE ] ,
false , // isRequired
false , // acceptsMultiple
) ,
] ,
splitUnnamedArgument : true ,
2024-06-24 00:18:44 +02:00
splitUnnamedArgumentCount : 1 ,
2024-05-12 21:15:05 +02:00
helpString : `
< div >
2024-09-01 22:04:51 +02:00
Get or set a variable . Use < code > index < / c o d e > t o a c c e s s e l e m e n t s o f a J S O N - s e r i a l i z e d l i s t o r d i c t i o n a r y .
2024-09-01 10:50:16 +02:00
To convert the value to a specific JSON type when using with < code > index < / c o d e > , u s e t h e < c o d e > a s < / c o d e > a r g u m e n t .
2024-05-12 21:15:05 +02:00
< / d i v >
< div >
< strong > Examples : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / l e t x f o o | / v a r x f o o b a r | / v a r x | / e c h o < / c o d e > < / p r e >
< / l i >
< li >
2024-05-22 16:21:49 +02:00
< pre > < code class = "language-stscript" > / l e t x f o o | / v a r k e y = x f o o b a r | / v a r x | / e c h o < / c o d e > < / p r e >
2024-05-12 21:15:05 +02:00
< / l i >
2024-09-01 22:07:49 +02:00
< li >
< pre > < code class = "language-stscript" > / l e t x { } | / v a r i n d e x = c o o l a s = n u m b e r x 1 3 3 7 | / e c h o { { v a r : : x } } < / c o d e > < / p r e >
< / l i >
2024-05-12 21:15:05 +02:00
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'let' ,
callback : ( /** @type {NamedArguments} */ args , value ) => letCallback ( args , value ) ,
2024-05-12 21:15:05 +02:00
returns : 'the variable value' ,
namedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandNamedArgument . fromProps ( {
name : 'key' ,
description : 'variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
enumProvider : commonEnumProviders . variables ( 'scope' ) ,
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
] ,
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'variable name' ,
typeList : [ ARGUMENT _TYPE . VARIABLE _NAME ] ,
enumProvider : commonEnumProviders . variables ( 'scope' ) ,
forceEnum : false ,
} ) ,
2024-05-12 21:15:05 +02:00
new SlashCommandArgument (
'variable value' , [ ARGUMENT _TYPE . STRING , ARGUMENT _TYPE . NUMBER , ARGUMENT _TYPE . BOOLEAN , ARGUMENT _TYPE . LIST , ARGUMENT _TYPE . DICTIONARY , ARGUMENT _TYPE . CLOSURE ] ,
) ,
] ,
splitUnnamedArgument : true ,
2024-06-24 00:18:44 +02:00
splitUnnamedArgumentCount : 1 ,
2024-05-12 21:15:05 +02:00
helpString : `
< div >
Declares a new variable in the current scope .
< / d i v >
< div >
< strong > Examples : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / l e t x f o o b a r | / e c h o { { v a r : : x } } < / c o d e > < / p r e >
< / l i >
< li >
< pre > < code class = "language-stscript" > / l e t k e y = x f o o b a r | / e c h o { { v a r : : x } } < / c o d e > < / p r e >
< / l i >
< li >
< pre > < code class = "language-stscript" > / l e t y < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'closure-serialize' ,
2024-06-14 23:48:41 +02:00
/ * *
*
2024-06-17 03:30:52 +02:00
* @ param { NamedArguments } args
2024-06-14 23:48:41 +02:00
* @ param { SlashCommandClosure } value
* @ returns { string }
* /
2024-06-17 03:30:52 +02:00
callback : ( args , value ) => closureSerializeCallback ( args , value ) ,
2024-06-14 23:48:41 +02:00
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'the closure to serialize' ,
2024-06-14 23:48:41 +02:00
typeList : [ ARGUMENT _TYPE . CLOSURE ] ,
isRequired : true ,
} ) ,
] ,
returns : 'serialized closure as string' ,
helpString : `
< div >
Serialize a closure as text that can be stored in global and chat variables .
< / d i v >
< div >
< strong > Examples : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / c l o s u r e - s e r i a l i z e { : x = 1 / e c h o x i s { { v a r : : x } } a n d y i s { { v a r : : y } } : } | \ n / s e t v a r k e y = m y C l o s u r e < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2024-06-17 03:30:52 +02:00
SlashCommandParser . addCommandObject ( SlashCommand . fromProps ( {
name : 'closure-deserialize' ,
2024-06-14 23:48:41 +02:00
/ * *
2024-06-17 03:30:52 +02:00
* @ param { NamedArguments } args
* @ param { UnnamedArguments } value
2024-06-14 23:48:41 +02:00
* @ returns { SlashCommandClosure }
* /
2024-06-17 03:30:52 +02:00
callback : ( args , value ) => closureDeserializeCallback ( args , value ) ,
2024-06-14 23:48:41 +02:00
unnamedArgumentList : [
2024-06-17 03:30:52 +02:00
SlashCommandArgument . fromProps ( {
description : 'serialized closure' ,
2024-06-14 23:48:41 +02:00
typeList : [ ARGUMENT _TYPE . STRING ] ,
isRequired : true ,
} ) ,
] ,
returns : 'deserialized closure' ,
helpString : `
< div >
Deserialize a closure from text .
< / d i v >
< div >
< strong > Examples : < / s t r o n g >
< ul >
< li >
< pre > < code class = "language-stscript" > / c l o s u r e - d e s e r i a l i z e { { g e t v a r : : m y C l o s u r e } } | \ n / l e t m y C l o s u r e { { p i p e } } | \ n / l e t y b a r | \ n / : m y C l o s u r e x = f o o < / c o d e > < / p r e >
< / l i >
< / u l >
< / d i v >
` ,
} ) ) ;
2023-11-06 21:50:32 +01:00
}