mirror of
https://github.com/Burn-E99/TheArtificer.git
synced 2026-06-04 09:03:50 -04:00
Implement full roll alias system with support for yVars, currently untested. Additionally: made numbers in code more readable, change indentation to spaces in db init files, fix simulatedNominal system defaults to be config driven
This commit is contained in:
1
src/artigen/dice/dice.d.ts
vendored
1
src/artigen/dice/dice.d.ts
vendored
@@ -63,6 +63,7 @@ export interface RollModifiers {
|
||||
rollDist: boolean;
|
||||
numberVariables: boolean;
|
||||
customDiceShapes: CustomDiceShapes;
|
||||
yVars: Map<string, number>;
|
||||
apiWarn: string;
|
||||
valid: boolean;
|
||||
error: Error;
|
||||
|
||||
@@ -46,6 +46,7 @@ export const getModifiers = (args: string[]): [RollModifiers, string[]] => {
|
||||
rollDist: false,
|
||||
numberVariables: false,
|
||||
customDiceShapes: new Map<string, number[]>(),
|
||||
yVars: new Map<string, number>(),
|
||||
apiWarn: '',
|
||||
valid: true,
|
||||
error: new Error(),
|
||||
@@ -88,7 +89,7 @@ export const getModifiers = (args: string[]): [RollModifiers, string[]] => {
|
||||
|
||||
modifiers.simulatedNominal = parseInt(args[i]);
|
||||
} else {
|
||||
modifiers.simulatedNominal = 10000;
|
||||
modifiers.simulatedNominal = config.limits.defaultSimulatedNominal;
|
||||
}
|
||||
break;
|
||||
case Modifiers.ConfirmCrit:
|
||||
@@ -225,9 +226,9 @@ export const getModifiers = (args: string[]): [RollModifiers, string[]] => {
|
||||
}
|
||||
|
||||
// simulatedNominal cannot be greater than config.limits.simulatedNominal
|
||||
if (modifiers.simulatedNominal > config.limits.simulatedNominal) {
|
||||
if (modifiers.simulatedNominal > config.limits.maxSimulatedNominal) {
|
||||
modifiers.error.name = 'SimNominalTooBig';
|
||||
modifiers.error.message = `Number of iterations for \`simulatedNominal\` cannot be greater than \`${config.limits.simulatedNominal}\``;
|
||||
modifiers.error.message = `Number of iterations for \`simulatedNominal\` cannot be greater than \`${config.limits.maxSimulatedNominal}\``;
|
||||
modifiers.valid = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import { botId, DiscordenoMessage, Embed, FileContent, sendDirectMessage, sendMe
|
||||
import { log, LogTypes as LT } from '@Log4Deno';
|
||||
|
||||
import config from '~config';
|
||||
import { DEVMODE } from '~flags';
|
||||
|
||||
import { SolvedRoll } from 'artigen/artigen.d.ts';
|
||||
|
||||
@@ -23,6 +22,12 @@ import utils from 'utils/utils.ts';
|
||||
import { infoColor1 } from 'embeds/colors.ts';
|
||||
import { basicReducer } from 'artigen/utils/reducers.ts';
|
||||
|
||||
const getUserIdForEmbed = (rollRequest: QueuedRoll): bigint => {
|
||||
if (rollRequest.apiRoll) return rollRequest.api.userId;
|
||||
if (rollRequest.ddRoll) return rollRequest.dd.originalMessage.authorId;
|
||||
return 0n;
|
||||
};
|
||||
|
||||
export const onWorkerComplete = async (workerMessage: MessageEvent<SolvedRoll>, workerTimeout: number, rollRequest: QueuedRoll) => {
|
||||
let apiErroredOut = false;
|
||||
try {
|
||||
@@ -32,12 +37,8 @@ export const onWorkerComplete = async (workerMessage: MessageEvent<SolvedRoll>,
|
||||
const returnMsg = workerMessage.data;
|
||||
loggingEnabled && log(LT.LOG, `Roll came back from worker: ${returnMsg.line1.length} |&| ${returnMsg.line2.length} |&| ${returnMsg.line3.length} `);
|
||||
loggingEnabled && log(LT.LOG, `Roll came back from worker: ${returnMsg.line1} |&| ${returnMsg.line2} |&| ${returnMsg.line3} `);
|
||||
const pubEmbedDetails = generateRollEmbed(
|
||||
rollRequest.apiRoll ? rollRequest.api.userId : rollRequest.dd.originalMessage.authorId,
|
||||
returnMsg,
|
||||
rollRequest.modifiers,
|
||||
);
|
||||
const gmEmbedDetails = generateRollEmbed(rollRequest.apiRoll ? rollRequest.api.userId : rollRequest.dd.originalMessage.authorId, returnMsg, {
|
||||
const pubEmbedDetails = generateRollEmbed(getUserIdForEmbed(rollRequest), returnMsg, rollRequest.modifiers);
|
||||
const gmEmbedDetails = generateRollEmbed(getUserIdForEmbed(rollRequest), returnMsg, {
|
||||
...rollRequest.modifiers,
|
||||
gmRoll: false,
|
||||
});
|
||||
@@ -81,24 +82,34 @@ export const onWorkerComplete = async (workerMessage: MessageEvent<SolvedRoll>,
|
||||
if (returnMsg.error) {
|
||||
if (rollRequest.apiRoll) {
|
||||
rollRequest.api.resolve(stdResp.InternalServerError(returnMsg.errorMsg));
|
||||
} else {
|
||||
} else if (rollRequest.ddRoll) {
|
||||
rollRequest.dd.myResponse.edit({ embeds: pubEmbeds });
|
||||
} else if (rollRequest.testRoll) {
|
||||
rollRequest.test.resolve({
|
||||
error: true,
|
||||
errorMsg: returnMsg.errorMsg,
|
||||
errorCode: returnMsg.errorCode,
|
||||
});
|
||||
}
|
||||
|
||||
if (rollRequest.apiRoll || (DEVMODE && config.logRolls)) {
|
||||
if (rollRequest.apiRoll) {
|
||||
// If enabled, log rolls so we can see what went wrong
|
||||
dbClient
|
||||
.execute(queries.insertRollLogCmd(rollRequest.apiRoll ? 1 : 0, 1), [
|
||||
rollRequest.originalCommand,
|
||||
returnMsg.errorCode,
|
||||
rollRequest.apiRoll ? null : rollRequest.dd.myResponse.id,
|
||||
])
|
||||
.execute(queries.insertRollLogCmd(rollRequest.apiRoll ? 1 : 0, 1), [rollRequest.originalCommand, returnMsg.errorCode, null])
|
||||
.catch((e) => utils.commonLoggers.dbError('rollQueue.ts:82', 'insert into', e));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Test roll will assume that messages send successfully
|
||||
if (rollRequest.testRoll) {
|
||||
rollRequest.test.resolve({
|
||||
error: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let newMsg: DiscordenoMessage | void = undefined;
|
||||
// Determine if we are to send a GM roll or a normal roll
|
||||
if (rollRequest.modifiers.gmRoll) {
|
||||
@@ -213,7 +224,7 @@ export const onWorkerComplete = async (workerMessage: MessageEvent<SolvedRoll>,
|
||||
}
|
||||
} catch (e) {
|
||||
log(LT.ERROR, `Unhandled rollRequest Error: ${JSON.stringify(e)}`);
|
||||
if (!rollRequest.apiRoll) {
|
||||
if (rollRequest.ddRoll) {
|
||||
rollRequest.dd.myResponse.edit({
|
||||
embeds: [
|
||||
(
|
||||
@@ -230,9 +241,14 @@ export const onWorkerComplete = async (workerMessage: MessageEvent<SolvedRoll>,
|
||||
).embed,
|
||||
],
|
||||
});
|
||||
}
|
||||
if (rollRequest.apiRoll && !apiErroredOut) {
|
||||
} else if (rollRequest.apiRoll && !apiErroredOut) {
|
||||
rollRequest.api.resolve(stdResp.InternalServerError(JSON.stringify(e)));
|
||||
} else if (rollRequest.testRoll) {
|
||||
rollRequest.test.resolve({
|
||||
error: true,
|
||||
errorMsg: 'Something weird went wrong.',
|
||||
errorCode: 'UnhandledWorkerComplete',
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ export const terminateWorker = async (rollWorker: Worker, rollRequest: QueuedRol
|
||||
|
||||
if (rollRequest.apiRoll) {
|
||||
rollRequest.api.resolve(stdResp.RequestTimeout('Roll took too long to process, try breaking roll down into simpler parts'));
|
||||
} else {
|
||||
} else if (rollRequest.ddRoll) {
|
||||
rollRequest.dd.myResponse
|
||||
.edit({
|
||||
embeds: [
|
||||
@@ -35,5 +35,11 @@ export const terminateWorker = async (rollWorker: Worker, rollRequest: QueuedRol
|
||||
],
|
||||
})
|
||||
.catch((e) => utils.commonLoggers.messageEditError('rollQueue.ts:51', rollRequest.dd.myResponse, e));
|
||||
} else if (rollRequest.testRoll) {
|
||||
rollRequest.test.resolve({
|
||||
error: true,
|
||||
errorCode: 'TooComplex',
|
||||
errorMsg: 'Error: Roll took too long to process, try breaking roll down into simpler parts',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
27
src/artigen/managers/manager.d.ts
vendored
27
src/artigen/managers/manager.d.ts
vendored
@@ -8,19 +8,40 @@ interface BaseQueuedRoll {
|
||||
modifiers: RollModifiers;
|
||||
originalCommand: string;
|
||||
}
|
||||
export interface ApiQueuedRoll extends BaseQueuedRoll {
|
||||
interface ApiQueuedRoll extends BaseQueuedRoll {
|
||||
apiRoll: true;
|
||||
ddRoll: false;
|
||||
testRoll: false;
|
||||
api: {
|
||||
resolve: (value: Response | PromiseLike<Response>) => void;
|
||||
channelId: bigint;
|
||||
userId: bigint;
|
||||
};
|
||||
}
|
||||
export interface DDQueuedRoll extends BaseQueuedRoll {
|
||||
interface DDQueuedRoll extends BaseQueuedRoll {
|
||||
apiRoll: false;
|
||||
ddRoll: true;
|
||||
testRoll: false;
|
||||
dd: {
|
||||
myResponse: DiscordenoMessage;
|
||||
originalMessage: DiscordenoMessage;
|
||||
};
|
||||
}
|
||||
export type QueuedRoll = ApiQueuedRoll | DDQueuedRoll;
|
||||
interface TestResultFail {
|
||||
error: true;
|
||||
errorMsg: string;
|
||||
errorCode: string;
|
||||
}
|
||||
interface TestResultSuccess {
|
||||
error: false;
|
||||
}
|
||||
export type TestResults = TestResultFail | TestResultSuccess;
|
||||
interface TestQueuedRoll extends BaseQueuedRoll {
|
||||
apiRoll: false;
|
||||
ddRoll: false;
|
||||
testRoll: true;
|
||||
test: {
|
||||
resolve: (value: TestResults) => void;
|
||||
};
|
||||
}
|
||||
export type QueuedRoll = ApiQueuedRoll | DDQueuedRoll | TestQueuedRoll;
|
||||
|
||||
@@ -16,25 +16,24 @@ const rollQueue: Array<QueuedRoll> = [];
|
||||
|
||||
// Runs the roll or queues it depending on how many workers are currently running
|
||||
export const sendRollRequest = (rollRequest: QueuedRoll) => {
|
||||
if (rollRequest.apiRoll) {
|
||||
handleRollRequest(rollRequest);
|
||||
} else if (!rollQueue.length && getWorkerCnt() < config.limits.maxWorkers) {
|
||||
if (!rollQueue.length && getWorkerCnt() < config.limits.maxWorkers) {
|
||||
handleRollRequest(rollRequest);
|
||||
} else {
|
||||
rollQueue.push(rollRequest);
|
||||
rollRequest.dd.myResponse
|
||||
.edit({
|
||||
embeds: [
|
||||
{
|
||||
color: infoColor2,
|
||||
title: `${config.name} currently has its hands full and has queued your roll.`,
|
||||
description: `There are currently ${getWorkerCnt() + rollQueue.length} rolls ahead of this roll.
|
||||
rollRequest.ddRoll &&
|
||||
rollRequest.dd.myResponse
|
||||
.edit({
|
||||
embeds: [
|
||||
{
|
||||
color: infoColor2,
|
||||
title: `${config.name} currently has its hands full and has queued your roll.`,
|
||||
description: `There are currently ${getWorkerCnt() + rollQueue.length} rolls ahead of this roll.
|
||||
|
||||
The results for this roll will replace this message when it is done.`,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageEditError('rollQueue.ts:197', rollRequest.dd.myResponse, e));
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageEditError('rollQueue.ts:197', rollRequest.dd.myResponse, e));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -46,11 +45,12 @@ setInterval(() => {
|
||||
);
|
||||
if (rollQueue.length && getWorkerCnt() < config.limits.maxWorkers) {
|
||||
const rollRequest = rollQueue.shift();
|
||||
if (rollRequest && !rollRequest.apiRoll) {
|
||||
rollRequest.dd.myResponse.edit(rollingEmbed).catch((e: Error) => utils.commonLoggers.messageEditError('rollQueue.ts:208', rollRequest.dd.myResponse, e));
|
||||
handleRollRequest(rollRequest);
|
||||
} else if (rollRequest && rollRequest.apiRoll) {
|
||||
if (rollRequest) {
|
||||
rollRequest.ddRoll &&
|
||||
rollRequest.dd.myResponse
|
||||
.edit(rollingEmbed)
|
||||
.catch((e: Error) => utils.commonLoggers.messageEditError('rollQueue.ts:208', rollRequest.dd.myResponse, e));
|
||||
handleRollRequest(rollRequest);
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
}, 1_000);
|
||||
|
||||
@@ -179,6 +179,19 @@ export const tokenizeMath = (
|
||||
} else {
|
||||
throw new Error(`IllegalVariable_${curMathConfStr}`);
|
||||
}
|
||||
} else if (/(y\d+(\.\d*)?)/.test(curMathConfStr)) {
|
||||
// Identify when someone is using a variable from alias input
|
||||
if (curMathConfStr.includes('.')) {
|
||||
// Verify someone did not enter y1.1 as a variable
|
||||
throw new Error(`IllegalVariable_${curMathConfStr}`);
|
||||
}
|
||||
|
||||
const yValue = modifiers.yVars.get(curMathConfStr);
|
||||
if (typeof yValue === 'number') {
|
||||
mathConf[i] = yValue;
|
||||
} else {
|
||||
throw new Error(`VariableMissingValue_${curMathConfStr}`);
|
||||
}
|
||||
} else if (![...allOps, ...legalMathOperators].includes(curMathConfStr)) {
|
||||
// If nothing else has handled it by now, try it as a roll
|
||||
const executedRoll = executeRoll(curMathConfStr, modifiers);
|
||||
|
||||
@@ -128,7 +128,7 @@ export const generateRollDistsEmbed = (rollDists: RollDistributionMap): ArtigenE
|
||||
const rollDistTitle = 'Roll Distributions:';
|
||||
|
||||
const totalSize = fields.map((field) => field.name.length + field.value.length).reduce(basicReducer, 0);
|
||||
if (totalSize > 4000 || fields.length > 25 || fields.some((field) => field.name.length > 256 || field.value.length > 1024)) {
|
||||
if (totalSize > 4_000 || fields.length > 25 || fields.some((field) => field.name.length > 256 || field.value.length > 1024)) {
|
||||
const rollDistBlob = new Blob([fields.map((field) => `# ${field.name}\n${field.value}`).join('\n\n') as BlobPart], { type: 'text' });
|
||||
if (rollDistBlob.size > config.maxFileSize) {
|
||||
const rollDistErrDesc =
|
||||
@@ -227,7 +227,7 @@ export const generateRollEmbed = (
|
||||
const baseDesc = `${line1Details}**${line2Details.shift()}:**\n${line2Details.join(': ')}`;
|
||||
|
||||
// Embed desc limit is 4096
|
||||
if (baseDesc.length + details.length < 4000) {
|
||||
if (baseDesc.length + details.length < 4_000) {
|
||||
// Response is valid size
|
||||
const desc = `${baseDesc}\n\n${details}`;
|
||||
return {
|
||||
|
||||
@@ -27,7 +27,7 @@ const escapePrefixPostfix = (str: string): string => str.replace(/[.*+?^${}()|[\
|
||||
export const cmdSplitRegex = new RegExp(`(${escapePrefixPostfix(config.prefix)})|(${escapePrefixPostfix(config.postfix)})`, 'g');
|
||||
|
||||
// breaks the string on the following: (\*\*) ** for exponents ([+()*/^] for basic algebra (?<![d%])% for breaking on d%%%% dice correctly (?<![rsfop!=<>])- for breaking on - correctly with fate dice) (x\d+(\.\d*)?) x# for variables
|
||||
export const mathSplitRegex = /(\*\*)|([+()*/^]|(?<![d%])%|(?<![rsfop!=<>])-)|(x\d+(\.\d*)?)/g;
|
||||
export const mathSplitRegex = /(\*\*)|([+()*/^]|(?<![d%])%|(?<![rsfop!=<>])-)|([xy]\d+(\.\d*)?)/g;
|
||||
|
||||
// Internal is used for recursive text replacement, these will always be the top level as they get replaced with config.prefix/postfix when exiting each level
|
||||
export const openInternal = '\u2045';
|
||||
|
||||
@@ -9,12 +9,20 @@ import { MathConf } from 'artigen/math/math.d.ts';
|
||||
import { closeInternal, closeInternalGrp, openInternal, openInternalGrp } from 'artigen/utils/escape.ts';
|
||||
import { loggingEnabled } from 'artigen/utils/logFlag.ts';
|
||||
|
||||
const checkBalance = (conf: MathConf[], openStr: string, closeStr: string, errorType: string, getMatching: boolean, openIdx: number): number => {
|
||||
const checkBalance = (
|
||||
conf: MathConf[],
|
||||
openStr: string,
|
||||
closeStr: string,
|
||||
errorType: string,
|
||||
getMatching: boolean,
|
||||
openIdx: number,
|
||||
countLoops = true,
|
||||
): number => {
|
||||
let parenCnt = 0;
|
||||
|
||||
// Verify there are equal numbers of opening and closing parenthesis by adding 1 for opening parens and subtracting 1 for closing parens
|
||||
for (let i = openIdx; i < conf.length; i++) {
|
||||
loopCountCheck();
|
||||
countLoops && loopCountCheck();
|
||||
loggingEnabled &&
|
||||
log(
|
||||
LT.LOG,
|
||||
@@ -55,11 +63,11 @@ const checkBalance = (conf: MathConf[], openStr: string, closeStr: string, error
|
||||
// assertXBalance verifies the entire conf has balanced X
|
||||
export const assertGroupBalance = (conf: MathConf[]) => checkBalance(conf, '{', '}', 'Group', false, 0);
|
||||
export const assertParenBalance = (conf: MathConf[]) => checkBalance(conf, '(', ')', 'Paren', false, 0);
|
||||
export const assertPrePostBalance = (conf: MathConf[]) => checkBalance(conf, config.prefix, config.postfix, 'PrefixPostfix', false, 0);
|
||||
export const assertPrePostBalance = (conf: MathConf[], countLoops = true) => checkBalance(conf, config.prefix, config.postfix, 'PrefixPostfix', false, 0, countLoops);
|
||||
|
||||
// getMatchingXIdx gets the matching X, also partially verifies the conf has balanced X
|
||||
export const getMatchingGroupIdx = (conf: MathConf[], openIdx: number): number => checkBalance(conf, '{', '}', 'Group', true, openIdx);
|
||||
export const getMatchingInternalIdx = (conf: MathConf[], openIdx: number): number => checkBalance(conf, openInternal, closeInternal, 'Internal', true, openIdx);
|
||||
export const getMatchingInternalGrpIdx = (conf: MathConf[], openIdx: number): number => checkBalance(conf, openInternalGrp, closeInternalGrp, 'InternalGrp', true, openIdx);
|
||||
export const getMatchingParenIdx = (conf: MathConf[], openIdx: number): number => checkBalance(conf, '(', ')', 'Paren', true, openIdx);
|
||||
export const getMatchingPostfixIdx = (conf: MathConf[], openIdx: number): number => checkBalance(conf, config.prefix, config.postfix, 'PrefixPostfix', true, openIdx);
|
||||
export const getMatchingPostfixIdx = (conf: MathConf[], openIdx: number, countLoops = true): number => checkBalance(conf, config.prefix, config.postfix, 'PrefixPostfix', true, openIdx, countLoops);
|
||||
|
||||
@@ -123,6 +123,9 @@ export const translateError = (solverError: Error): [string, string] => {
|
||||
case 'IllegalVariable':
|
||||
errorMsg = `Error: \`${errorDetails}\` is not a valid variable`;
|
||||
break;
|
||||
case 'VariableMissingValue':
|
||||
errorMsg = `Error: \`${errorDetails}\` is missing a valid value`;
|
||||
break;
|
||||
case 'TooManyLabels':
|
||||
errorMsg = `Error: ${config.name} can only support a maximum of \`${errorDetails}\` labels when using the dice matching options (\`m\` or \`mt\`)`;
|
||||
break;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { alias } from 'commands/aliasCmd.ts';
|
||||
import { api } from 'commands/apiCmd.ts';
|
||||
import { audit } from 'commands/audit.ts';
|
||||
import { emoji } from 'commands/emoji.ts';
|
||||
@@ -18,6 +19,7 @@ import { toggleInline } from 'commands/toggleInline.ts';
|
||||
import { version } from 'commands/version.ts';
|
||||
|
||||
export default {
|
||||
alias,
|
||||
api,
|
||||
audit,
|
||||
emoji,
|
||||
|
||||
81
src/commands/aliasCmd.ts
Normal file
81
src/commands/aliasCmd.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { DiscordenoMessage } from '@discordeno';
|
||||
|
||||
import aliasCommands from 'commands/aliasCmd/_index.ts';
|
||||
|
||||
import dbClient from 'db/client.ts';
|
||||
import { queries } from 'db/common.ts';
|
||||
|
||||
import { failColor } from 'embeds/colors.ts';
|
||||
|
||||
import utils from 'utils/utils.ts';
|
||||
|
||||
export const alias = (message: DiscordenoMessage, argSpaces: string[]) => {
|
||||
// Light telemetry to see how many times a command is being run
|
||||
dbClient.execute(queries.callIncCnt('alias')).catch((e) => utils.commonLoggers.dbError('aliasCmd.ts:16', 'call sproc INC_CNT on', e));
|
||||
|
||||
// argSpaces will come in with a space or \n before every real arg, so extra shifts exist to remove them
|
||||
argSpaces.shift();
|
||||
let aliasArg = (argSpaces.shift() || '').toLowerCase().trim();
|
||||
argSpaces.shift();
|
||||
|
||||
let guildMode = false;
|
||||
if (aliasArg === 'guild') {
|
||||
guildMode = true;
|
||||
aliasArg = (argSpaces.shift() || '').toLowerCase().trim();
|
||||
argSpaces.shift();
|
||||
}
|
||||
|
||||
if (guildMode && message.guildId === 0n) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: 'Guild Aliases can only be modified from within the desired guild.',
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('aliasCmd.ts:38', message, e));
|
||||
return;
|
||||
}
|
||||
|
||||
// Makes sure the user is authenticated to run the API command
|
||||
switch (aliasArg) {
|
||||
case 'help':
|
||||
case 'h':
|
||||
case '?':
|
||||
case '':
|
||||
aliasCommands.help(message, guildMode);
|
||||
break;
|
||||
case 'list':
|
||||
case 'list-all':
|
||||
aliasCommands.list(message, guildMode);
|
||||
break;
|
||||
case 'add':
|
||||
case 'create':
|
||||
case 'set':
|
||||
aliasCommands.add(message, guildMode, argSpaces);
|
||||
break;
|
||||
case 'update':
|
||||
case 'replace':
|
||||
aliasCommands.update(message, guildMode, argSpaces);
|
||||
break;
|
||||
case 'preview':
|
||||
case 'view':
|
||||
aliasCommands.view(message, guildMode, argSpaces);
|
||||
break;
|
||||
case 'delete':
|
||||
case 'remove':
|
||||
aliasCommands.deleteOne(message, guildMode, argSpaces);
|
||||
break;
|
||||
case 'delete-all':
|
||||
case 'remove-all':
|
||||
aliasCommands.deleteAll(message, guildMode, argSpaces);
|
||||
break;
|
||||
case 'run':
|
||||
case 'execute':
|
||||
default:
|
||||
aliasCommands.run(message, guildMode, aliasArg, argSpaces);
|
||||
break;
|
||||
}
|
||||
};
|
||||
17
src/commands/aliasCmd/_index.ts
Normal file
17
src/commands/aliasCmd/_index.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { add, update } from './aliasAddUpdate.ts';
|
||||
import { deleteAll, deleteOne } from './aliasDelete.ts';
|
||||
import { help } from 'commands/aliasCmd/aliasHelp.ts';
|
||||
import { list } from 'commands/aliasCmd/list.ts';
|
||||
import { run } from 'commands/aliasCmd/run.ts';
|
||||
import { view } from 'commands/aliasCmd/view.ts';
|
||||
|
||||
export default {
|
||||
add,
|
||||
deleteAll,
|
||||
deleteOne,
|
||||
help,
|
||||
list,
|
||||
run,
|
||||
update,
|
||||
view,
|
||||
};
|
||||
392
src/commands/aliasCmd/aliasAddUpdate.ts
Normal file
392
src/commands/aliasCmd/aliasAddUpdate.ts
Normal file
@@ -0,0 +1,392 @@
|
||||
import { DiscordenoMessage, EmbedField, hasGuildPermissions } from '@discordeno';
|
||||
|
||||
import config from '~config';
|
||||
|
||||
import { getModifiers } from 'artigen/dice/getModifiers.ts';
|
||||
|
||||
import { TestResults } from 'artigen/managers/manager.d.ts';
|
||||
import { sendRollRequest } from 'artigen/managers/queueManager.ts';
|
||||
|
||||
import { cmdSplitRegex } from 'artigen/utils/escape.ts';
|
||||
import { assertPrePostBalance, getMatchingPostfixIdx } from 'artigen/utils/parenBalance.ts';
|
||||
|
||||
import { ReservedWords } from 'commands/aliasCmd/reservedWords.ts';
|
||||
|
||||
import dbClient from 'db/client.ts';
|
||||
|
||||
import { generateAliasError } from 'embeds/alias.ts';
|
||||
import { failColor, infoColor1, successColor } from 'embeds/colors.ts';
|
||||
|
||||
import utils from 'utils/utils.ts';
|
||||
|
||||
interface QueryShape {
|
||||
aliasName: string;
|
||||
}
|
||||
|
||||
const sortYVars = (a: string, b: string) => {
|
||||
if (a.length < b.length) return -1;
|
||||
if (a.length > b.length) return 1;
|
||||
if (a < b) return -1;
|
||||
if (a > b) return 1;
|
||||
return 0;
|
||||
};
|
||||
|
||||
const handleAddUpdate = async (message: DiscordenoMessage, guildMode: boolean, argSpaces: string[], replaceAlias: boolean) => {
|
||||
if (guildMode && !(await hasGuildPermissions(message.authorId, message.guildId, ['ADMINISTRATOR']))) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: `Error: Only Guild Owners and Admins can add/update guild aliases`,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('add.ts:45', message, e));
|
||||
return;
|
||||
}
|
||||
|
||||
const aliasName = (argSpaces.shift() || '').trim();
|
||||
argSpaces.shift();
|
||||
|
||||
if (aliasName.length > 100) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: 'Error: Alias Name is too long',
|
||||
description: `\`${aliasName}\` (\`${aliasName.length}\` characters) is longer than the allowed max length of \`100\` characters. Please choose a shorter alias name.`,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('add.ts:64', message, e));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ReservedWords.includes(aliasName?.toLowerCase())) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: `Error: \`${aliasName}\` is a reserved word`,
|
||||
description: `Please choose a different name for this alias.
|
||||
|
||||
You cannot use any of the following reserved words: \`${ReservedWords.join('`, `')}\`.`,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('add.ts:33', message, e));
|
||||
return;
|
||||
}
|
||||
|
||||
let errorOut = false;
|
||||
const query: QueryShape[] = await dbClient
|
||||
.query(
|
||||
`SELECT aliasName FROM aliases WHERE guildid = ? AND userid = ? AND aliasName = ?`,
|
||||
guildMode ? [message.guildId, 0n, aliasName.toLowerCase()] : [0n, message.authorId, aliasName.toLowerCase()],
|
||||
)
|
||||
.catch((e0) => {
|
||||
utils.commonLoggers.dbError('add.ts:44', 'query', e0);
|
||||
message
|
||||
.send(generateAliasError('DB Query Failed.', `add-q0-${guildMode ? 't' : 'f'}-${aliasName}-${guildMode ? message.guildId : message.authorId}`))
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('add.ts:47', message, e));
|
||||
errorOut = true;
|
||||
});
|
||||
if (errorOut) return;
|
||||
|
||||
if (!replaceAlias && query.length) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: `Error: \`${aliasName}\` already exists as a ${guildMode ? 'guild' : 'personal'} alias`,
|
||||
description: 'Please choose a different name for this alias.',
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('add.ts:63', message, e));
|
||||
return;
|
||||
} else if (replaceAlias && !query.length) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: `Error: \`${aliasName}\` does not exist as a ${guildMode ? 'guild' : 'personal'} alias`,
|
||||
description: `If you are trying to create a new ${guildMode ? 'guild' : 'personal'} alias, please run the following command:
|
||||
\`${config.prefix}ra ${guildMode ? 'guild ' : ''}add\` followed by the desired alias name and roll string.
|
||||
|
||||
If you are trying to update an existing alias, but forgot the name, please run the following command to view all your ${guildMode ? 'guild ' : ''}aliases:
|
||||
\`${config.prefix}ra ${guildMode ? 'guild ' : ''}list\``,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('add.ts:63', message, e));
|
||||
return;
|
||||
}
|
||||
|
||||
const rawRollStr = argSpaces.join('').trim();
|
||||
const newMsg: DiscordenoMessage | void = await message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: infoColor1,
|
||||
title: 'Please wait, testing your roll string . . .',
|
||||
description: `The following roll string is being tested. Once the verdict of your roll has been determined, this message will be updated.
|
||||
|
||||
\`${rawRollStr}\``,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e) => {
|
||||
utils.commonLoggers.dbError('add.ts:78', 'query', e);
|
||||
errorOut = true;
|
||||
});
|
||||
|
||||
if (errorOut || !newMsg) return;
|
||||
|
||||
const [modifiers, remainingArgs] = getModifiers(argSpaces);
|
||||
const failedRollMsg = `The provided roll string (listed below) encountered an error. Please try this roll outside the roll alias system and resolve the error before trying again.
|
||||
|
||||
\`${rawRollStr}\`${rawRollStr.length > 1_700 ? ' (trimmed to 2,000 characters to fit in the error message)' : ''}`.slice(0, 2_000);
|
||||
|
||||
if (!modifiers.valid) {
|
||||
newMsg
|
||||
.edit({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: 'Roll failed',
|
||||
description: failedRollMsg,
|
||||
fields: [
|
||||
{
|
||||
name: 'Error Details:',
|
||||
value: modifiers.error.message,
|
||||
},
|
||||
],
|
||||
footer: {
|
||||
text: modifiers.error.name,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageEditError('add.ts:116', newMsg, e));
|
||||
return;
|
||||
}
|
||||
|
||||
const rollCmd = remainingArgs.join('');
|
||||
const testCmdConf = rollCmd
|
||||
.toLowerCase()
|
||||
.split(cmdSplitRegex)
|
||||
.filter((x) => x);
|
||||
try {
|
||||
assertPrePostBalance(testCmdConf, false);
|
||||
let openIdx = testCmdConf.indexOf(config.prefix);
|
||||
while (openIdx !== -1) {
|
||||
const closeIdx = getMatchingPostfixIdx(testCmdConf, openIdx, false);
|
||||
const possibleYVars = testCmdConf
|
||||
.slice(openIdx + 1, closeIdx)
|
||||
.join('')
|
||||
.split(/(y\d+(\.\d*)?)/g)
|
||||
.filter((y) => y.startsWith('y'));
|
||||
for (const yVar of possibleYVars) {
|
||||
if (yVar.includes('.')) {
|
||||
newMsg
|
||||
.edit({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: 'Roll failed',
|
||||
description: failedRollMsg,
|
||||
fields: [
|
||||
{
|
||||
name: 'Error Details:',
|
||||
value: `yVars cannot have decimals`,
|
||||
},
|
||||
],
|
||||
footer: {
|
||||
text: 'yVarDecimal',
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageEditError('add.ts:163', newMsg, e));
|
||||
return;
|
||||
}
|
||||
if (!modifiers.yVars.has(yVar)) {
|
||||
modifiers.yVars.set(yVar, Math.ceil(Math.random() * 20));
|
||||
}
|
||||
}
|
||||
openIdx = testCmdConf.indexOf(config.prefix, closeIdx);
|
||||
}
|
||||
} catch (e) {
|
||||
newMsg
|
||||
.edit({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: 'Roll failed',
|
||||
description: failedRollMsg,
|
||||
fields: [
|
||||
{
|
||||
name: 'Error Details:',
|
||||
value: `Failed to find yVars, requested rollStr likely has unbalanced \`${config.prefix}\`/\`${config.postfix}\``,
|
||||
},
|
||||
{
|
||||
name: 'Raw Error:',
|
||||
value: `\`${JSON.stringify(e)}\``,
|
||||
},
|
||||
],
|
||||
footer: {
|
||||
text: 'caughtErrYVarUnbalanced',
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageEditError('add.ts:191', newMsg, e));
|
||||
return;
|
||||
}
|
||||
|
||||
let i = 0;
|
||||
while (i < modifiers.yVars.size) {
|
||||
if (!modifiers.yVars.has(`y${i}`)) {
|
||||
modifiers.yVars.set(`y${i}`, 0);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
const rollStrVerdict = await new Promise<TestResults>((resolve) => {
|
||||
sendRollRequest({
|
||||
apiRoll: false,
|
||||
ddRoll: false,
|
||||
testRoll: true,
|
||||
test: { resolve },
|
||||
rollCmd,
|
||||
modifiers,
|
||||
originalCommand: rawRollStr,
|
||||
});
|
||||
});
|
||||
|
||||
if (rollStrVerdict.error) {
|
||||
const errorFields: EmbedField[] = [
|
||||
{
|
||||
name: 'Error Details:',
|
||||
value: rollStrVerdict.errorMsg,
|
||||
},
|
||||
];
|
||||
if (modifiers.yVars.size) {
|
||||
errorFields.push({
|
||||
name: 'The following YVars were used in testing:',
|
||||
value: modifiers.yVars
|
||||
.entries()
|
||||
.toArray()
|
||||
.sort((a, b) => sortYVars(a[0], b[0]))
|
||||
.map(([yVar, value]) => `\`${yVar}\`: \`${value}\``)
|
||||
.join('\n'),
|
||||
});
|
||||
}
|
||||
newMsg
|
||||
.edit({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: 'Roll failed',
|
||||
description: failedRollMsg,
|
||||
fields: errorFields,
|
||||
footer: {
|
||||
text: rollStrVerdict.errorCode,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageEditError('add.ts:153', newMsg, e));
|
||||
return;
|
||||
}
|
||||
|
||||
if (replaceAlias) {
|
||||
await dbClient
|
||||
.execute('UPDATE aliases SET rollStr = ?, yVarCnt = ? WHERE guildid = ? AND userid = ? AND aliasName = ?', [
|
||||
rawRollStr,
|
||||
modifiers.yVars.size,
|
||||
guildMode ? message.guildId : 0n,
|
||||
guildMode ? 0n : message.authorId,
|
||||
aliasName.toLowerCase(),
|
||||
])
|
||||
.catch((e0) => {
|
||||
utils.commonLoggers.dbError('add.ts:169', 'update', e0);
|
||||
newMsg
|
||||
.edit(generateAliasError('DB Update Failed.', `add-q1-${guildMode ? 't' : 'f'}-${aliasName}-${guildMode ? message.guildId : message.authorId}`))
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('add.ts:170', message, e));
|
||||
errorOut = true;
|
||||
});
|
||||
} else {
|
||||
const currentAliases = await dbClient
|
||||
.query('SELECT aliasName as count FROM aliases WHERE guildid = ? AND userid = ?', guildMode ? [message.guildId, 0n] : [0n, message.authorId])
|
||||
.catch((e0) => {
|
||||
utils.commonLoggers.dbError('add.ts:266', 'get count', e0);
|
||||
newMsg
|
||||
.edit(generateAliasError('DB Query Failed.', `add-q2-${guildMode ? 't' : 'f'}-${guildMode ? message.guildId : message.authorId}`))
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('add.ts:269', message, e));
|
||||
errorOut = true;
|
||||
});
|
||||
if (errorOut) return;
|
||||
|
||||
if (currentAliases.length < guildMode ? config.limits.alias.free.guild : config.limits.alias.free.user) {
|
||||
await dbClient
|
||||
.execute('INSERT INTO aliases(guildid,userid,aliasName,rollStr,yVarCnt,premium) values(?,?,?,?,?,?)', [
|
||||
guildMode ? message.guildId : 0n,
|
||||
guildMode ? 0n : message.authorId,
|
||||
aliasName.toLowerCase(),
|
||||
rawRollStr,
|
||||
modifiers.yVars.size,
|
||||
0,
|
||||
])
|
||||
.catch((e0) => {
|
||||
utils.commonLoggers.dbError('add.ts:169', 'insert into', e0);
|
||||
newMsg
|
||||
.edit(generateAliasError('DB Insert Failed.', `add-q3-${guildMode ? 't' : 'f'}-${aliasName}-${guildMode ? message.guildId : message.authorId}`))
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('add.ts:187', message, e));
|
||||
errorOut = true;
|
||||
});
|
||||
} else {
|
||||
newMsg
|
||||
.edit({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: `Over ${guildMode ? 'guild' : 'personal'} Alias Limit`,
|
||||
description: `Cannot add another alias as this account already has \`${currentAliases.length}\` aliases saved.
|
||||
|
||||
The current limits imposed on the Alias System are \`${config.limits.alias.free.guild}\` guild aliases and \`${config.limits.alias.free.user}\` account aliases.
|
||||
|
||||
If you need this limit raised, please join the [support server](${config.links.supportServer})`,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageEditError('add.ts:302', newMsg, e));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (errorOut) return;
|
||||
|
||||
const yVarString = ' ' + modifiers.yVars.keys().toArray().sort(sortYVars).join(' ');
|
||||
newMsg
|
||||
.edit({
|
||||
embeds: [
|
||||
{
|
||||
color: successColor,
|
||||
title: `Successfully ${replaceAlias ? 'replaced' : 'added'} the ${guildMode ? 'guild' : 'personal'} alias \`${aliasName}\`!`,
|
||||
description: `You can try it out now using the following command:
|
||||
\`${config.prefix}ra ${guildMode ? 'guild ' : ''}${aliasName}${modifiers.yVars.size ? yVarString : ''}\``,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('add.ts:321', message, e));
|
||||
};
|
||||
|
||||
// Using wrappers to limit "magic" booleans
|
||||
export const add = (message: DiscordenoMessage, guildMode: boolean, argSpaces: string[]) => handleAddUpdate(message, guildMode, argSpaces, false);
|
||||
export const update = (message: DiscordenoMessage, guildMode: boolean, argSpaces: string[]) => handleAddUpdate(message, guildMode, argSpaces, true);
|
||||
203
src/commands/aliasCmd/aliasDelete.ts
Normal file
203
src/commands/aliasCmd/aliasDelete.ts
Normal file
@@ -0,0 +1,203 @@
|
||||
import { DiscordenoMessage, hasGuildPermissions } from '@discordeno';
|
||||
|
||||
import config from '~config';
|
||||
|
||||
import dbClient from 'db/client.ts';
|
||||
|
||||
import { generateAliasError } from 'embeds/alias.ts';
|
||||
import { failColor, successColor, warnColor } from 'embeds/colors.ts';
|
||||
|
||||
import utils from 'utils/utils.ts';
|
||||
|
||||
const handleDelete = async (message: DiscordenoMessage, guildMode: boolean, argSpaces: string[], deleteAll: boolean) => {
|
||||
if (guildMode && !(await hasGuildPermissions(message.authorId, message.guildId, ['ADMINISTRATOR']))) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: 'Error: Only Guild Owners and Admins can delete guild aliases',
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('aliasDelete.ts:16', message, e));
|
||||
return;
|
||||
}
|
||||
|
||||
const verificationCode = (guildMode ? message.guildId : message.authorId).toString().slice(-4);
|
||||
const aliasName = (argSpaces.shift() || '').trim();
|
||||
argSpaces.shift();
|
||||
const userEnteredVCode = (argSpaces.shift() || '').trim();
|
||||
let errorOut = false;
|
||||
|
||||
if (!deleteAll) {
|
||||
if (!aliasName) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: 'Error: Please specify one alias to delete',
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('aliasDelete.ts:38', message, e));
|
||||
return;
|
||||
} else if (!userEnteredVCode) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: warnColor,
|
||||
title: `Deletion is permanent, please confirm you want to delete \`${aliasName}\``,
|
||||
description: `Are you sure you want to delete the ${guildMode ? 'guild' : 'personal'} alias \`${aliasName}\`?
|
||||
|
||||
If you are certain you want to delete \`${aliasName}\` from ${guildMode ? 'this guild' : 'your account'}, please run the following command:
|
||||
\`${config.prefix}ra ${guildMode ? 'guild ' : ''}delete ${aliasName} ${verificationCode}\``,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('aliasDelete.ts:54', message, e));
|
||||
return;
|
||||
} else if (userEnteredVCode !== verificationCode) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: 'Error: Incorrect verification code',
|
||||
description: `If you are certain you want to delete \`${aliasName}\` from ${guildMode ? 'this guild' : 'your account'}, please run the following command:
|
||||
\`${config.prefix}ra ${guildMode ? 'guild ' : ''}delete ${aliasName} ${verificationCode}\``,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('aliasDelete.ts:70', message, e));
|
||||
return;
|
||||
} else if (userEnteredVCode === verificationCode) {
|
||||
const deleteResults = await dbClient
|
||||
.execute('DELETE FROM aliases WHERE guildid = ? AND userid = ? AND aliasName = ?', [
|
||||
guildMode ? message.guildId : 0n,
|
||||
guildMode ? 0n : message.authorId,
|
||||
aliasName,
|
||||
])
|
||||
.catch((e) => {
|
||||
utils.commonLoggers.dbError('aliasDelete.ts:76', 'delete from aliases', e);
|
||||
errorOut = true;
|
||||
});
|
||||
if (errorOut || !deleteResults) {
|
||||
message
|
||||
.send(generateAliasError('Delete failed.', `delete-q0-${guildMode ? 't' : 'f'}-${aliasName}-${guildMode ? message.guildId : message.authorId}`))
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('aliasDelete.ts:86', message, e));
|
||||
return;
|
||||
} else if (deleteResults.affectedRows) {
|
||||
message.send({
|
||||
embeds: [
|
||||
{
|
||||
color: successColor,
|
||||
title: 'Alias Deleted Successfully',
|
||||
description: `The ${guildMode ? 'guild' : 'personal'} alias named \`${aliasName}\` was successfully deleted.`,
|
||||
},
|
||||
],
|
||||
});
|
||||
} else {
|
||||
message.send({
|
||||
embeds: [
|
||||
{
|
||||
color: warnColor,
|
||||
title: 'Nothing deleted',
|
||||
description: `Looks like you${guildMode ? "r guild doesn't" : " don't"} have an alias named \`${aliasName}\`.
|
||||
|
||||
Please run \`${config.prefix}ra ${guildMode ? 'guild ' : ''}list\` to view the current aliases for ${guildMode ? 'this guild' : 'your account'}.`,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
message
|
||||
.send(generateAliasError('How are you here?', 'deleteOne-how'))
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('aliasDelete.ts:117', message, e));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// We're in deleteAll mode, so aliasName will carry the user verification code.
|
||||
// Since one wasn't provided, prompt for confirmation
|
||||
if (!aliasName) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: warnColor,
|
||||
title: 'Deletion is permanent, please confirm you want to delete all aliases',
|
||||
description: `Are you sure you want to delete all aliases for ${guildMode ? 'this guild' : 'your account'}?
|
||||
|
||||
If you are certain you want to delete all aliases for ${guildMode ? 'this guild' : 'your account'}, please run the following command:
|
||||
\`${config.prefix}ra ${guildMode ? 'guild ' : ''}delete-all ${verificationCode}\``,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('aliasDelete.ts:137', message, e));
|
||||
return;
|
||||
} else if (aliasName !== verificationCode) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: 'Error: Incorrect verification code',
|
||||
description: `If you are certain you want to delete all aliases for ${guildMode ? 'this guild' : 'your account'}, please run the following command:
|
||||
\`${config.prefix}ra ${guildMode ? 'guild ' : ''}delete-all ${verificationCode}\``,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('aliasDelete.ts:70', message, e));
|
||||
return;
|
||||
} else if (aliasName === verificationCode) {
|
||||
const deleteResults = await dbClient
|
||||
.execute('DELETE FROM aliases WHERE guildid = ? AND userid = ?', [guildMode ? message.guildId : 0n, guildMode ? 0n : message.authorId])
|
||||
.catch((e) => {
|
||||
utils.commonLoggers.dbError('aliasDelete.ts:159', 'delete from aliases', e);
|
||||
errorOut = true;
|
||||
});
|
||||
if (errorOut || !deleteResults) {
|
||||
message
|
||||
.send(generateAliasError('Delete failed.', `delete-q1-${guildMode ? 't' : 'f'}-${guildMode ? message.guildId : message.authorId}`))
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('aliasDelete.ts:165', message, e));
|
||||
return;
|
||||
} else if (deleteResults.affectedRows) {
|
||||
message.send({
|
||||
embeds: [
|
||||
{
|
||||
color: successColor,
|
||||
title: 'All Aliases Deleted Successfully',
|
||||
description: `All ${guildMode ? 'guild' : 'personal'} aliases for ${guildMode ? 'this guild' : 'your account'} were successfully deleted.`,
|
||||
},
|
||||
],
|
||||
});
|
||||
} else {
|
||||
message.send({
|
||||
embeds: [
|
||||
{
|
||||
color: warnColor,
|
||||
title: 'Nothing deleted',
|
||||
description: `Looks like you${guildMode ? "r guild doesn't" : " don't"} have any aliases to delete.
|
||||
|
||||
Please run \`${config.prefix}ra ${guildMode ? 'guild ' : ''}list\` to view the current aliases for ${guildMode ? 'this guild' : 'your account'}.
|
||||
If anything shows up there after running this command, please \`${config.prefix}report\` this to the developer.`,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
message
|
||||
.send(generateAliasError('How are you here?', 'deleteAll-how'))
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('aliasDelete.ts:194', message, e));
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Using wrappers to limit "magic" booleans
|
||||
export const deleteOne = (message: DiscordenoMessage, guildMode: boolean, argSpaces: string[]) => handleDelete(message, guildMode, argSpaces, false);
|
||||
export const deleteAll = (message: DiscordenoMessage, guildMode: boolean, argSpaces: string[]) => handleDelete(message, guildMode, argSpaces, true);
|
||||
81
src/commands/aliasCmd/aliasHelp.ts
Normal file
81
src/commands/aliasCmd/aliasHelp.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { DiscordenoMessage } from '@discordeno';
|
||||
|
||||
import config from '~config';
|
||||
|
||||
import { ReservedWords } from 'commands/aliasCmd/reservedWords.ts';
|
||||
|
||||
import { infoColor1, infoColor2 } from 'embeds/colors.ts';
|
||||
|
||||
export const help = (message: DiscordenoMessage, guildMode: boolean) => {
|
||||
message.send({
|
||||
embeds: [
|
||||
{
|
||||
color: infoColor2,
|
||||
title: `${config.name}'s Roll Alias System Details:`,
|
||||
description: `This system allows you to save any roll string to a short, custom, memorable alias.
|
||||
|
||||
Currently, you may create up to \`${config.limits.alias.free.guild.toLocaleString()}\` per guild and \`${config.limits.alias.free.user.toLocaleString()}\` per user account. This limit may increase or decrease in the future.
|
||||
|
||||
Aliases are case-insensitive (\`tEsT\` is stored as \`test\`, but can still be called as \`tEsT\`), and are not allowed to be named any of the following: \`${
|
||||
ReservedWords.join(
|
||||
'`, `',
|
||||
)
|
||||
}\``,
|
||||
},
|
||||
{
|
||||
color: infoColor1,
|
||||
title: 'Available Alias Commands:',
|
||||
description: `- If a command has an option listed like \`help/h/?\`, this means \`help\`, \`h\`, and \`?\` are all valid options for the command.
|
||||
- \`[alias]\` indicates where you should put the desired alias to add, update, delete, or run.
|
||||
- \`[rollstr...]\` indicates where you should put the roll string for add/ing/updating an alias.
|
||||
- \`[yVars...?]\` indicates where you should put any numeric parameters needed for running the desired alias, separated by spaces. If none are needed, omit this list.
|
||||
|
||||
All commands below are shown using the shorthand version of the Roll Alias command, but \`${config.prefix}rollalias\`, \`${config.prefix}ralias\`, \`${config.prefix}alias\`, and \`${config.prefix}rolla\` also work.
|
||||
|
||||
To view ${guildMode ? '' : 'non-'}guild mode commands, please run \`${config.prefix}ra ${guildMode ? '' : 'guild '}help\``,
|
||||
fields: [
|
||||
{
|
||||
name: `\`${config.prefix}ra ${guildMode ? 'guild ' : ''}help/h/?\``,
|
||||
value: 'This command.',
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `\`${config.prefix}ra ${guildMode ? 'guild ' : ''}add/create/set [alias] [rollstr...]\``,
|
||||
value: `Creates a new alias with the specified roll string. This is saved for use ${guildMode ? 'in only this guild' : 'by your account'}.`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `\`${config.prefix}ra ${guildMode ? 'guild ' : ''}list/list-all\``,
|
||||
value: `Lists all aliases and their number of yVars created ${guildMode ? 'in this guild' : 'by you'}.`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `\`${config.prefix}ra ${guildMode ? 'guild ' : ''}preview/view [alias]\``,
|
||||
value: `Shows the saved roll string for the specified ${guildMode ? 'guild ' : ''}alias.`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `\`${config.prefix}ra ${guildMode ? 'guild ' : ''}update/replace [alias] [rollstr...]\``,
|
||||
value: `Updates the specified alias to the new roll string. This overwrites the alias saved ${guildMode ? 'in this guild' : 'to your account'}.`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `\`${config.prefix}ra ${guildMode ? 'guild ' : ''}delete/remove [alias]\``,
|
||||
value: `Deletes the specified alias from ${guildMode ? 'this guild' : 'your account'}. This is a permanent deletion and cannot be undone.`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `\`${config.prefix}ra ${guildMode ? 'guild ' : ''}delete-all/remove-all\``,
|
||||
value: `Deletes all aliases saved to ${guildMode ? 'this guild' : 'your account'}. This is a permanent deletion and cannot be undone.`,
|
||||
inline: true,
|
||||
},
|
||||
{
|
||||
name: `\`${config.prefix}ra ${guildMode ? 'guild ' : ''}[alias] [yVars...?]\` or \`${config.prefix}ra ${guildMode ? 'guild ' : ''}run/execute [alias] [yVars...?]\``,
|
||||
value: `Runs the specified ${guildMode ? 'guild ' : ''}alias with the provided yVars. yVars are only required if the alias specified requires them.`,
|
||||
inline: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
49
src/commands/aliasCmd/list.ts
Normal file
49
src/commands/aliasCmd/list.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { DiscordenoMessage } from '@discordeno';
|
||||
|
||||
import dbClient from 'db/client.ts';
|
||||
|
||||
import { generateAliasError } from 'embeds/alias.ts';
|
||||
import { successColor } from 'embeds/colors.ts';
|
||||
|
||||
import utils from 'utils/utils.ts';
|
||||
|
||||
interface QueryShape {
|
||||
aliasName: string;
|
||||
yVarCnt: number;
|
||||
}
|
||||
|
||||
export const list = async (message: DiscordenoMessage, guildMode: boolean) => {
|
||||
let errorOut = false;
|
||||
const query: QueryShape[] = await dbClient
|
||||
.query(
|
||||
`SELECT aliasName, yVarCnt FROM aliases WHERE guildid = ? AND userid = ? ORDER BY createdAt ASC`,
|
||||
guildMode ? [message.guildId, 0n] : [0n, message.authorId],
|
||||
)
|
||||
.catch((e0) => {
|
||||
utils.commonLoggers.dbError('list.ts:10', 'query', e0);
|
||||
message
|
||||
.send(generateAliasError('DB Query Failed.', `list-q0-${guildMode ? 't' : 'f'}-${guildMode ? message.guildId : message.authorId}`))
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('list.ts:11', message, e));
|
||||
errorOut = true;
|
||||
});
|
||||
if (errorOut) return;
|
||||
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: successColor,
|
||||
title: `Found ${query.length} alias${query.length === 1 ? '' : 'es'} for ${guildMode ? 'this guild' : 'your account'}:`,
|
||||
description: query.length
|
||||
? `Format shown is \`alias-name\` followed by the number of yVars required for the alias in parenthesis, if there are any required.
|
||||
|
||||
${query.map((a) => `\`${a.aliasName}\`${a.yVarCnt ? ` (${a.yVarCnt})` : ''}`).join(', ')}`
|
||||
: '',
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e0) => {
|
||||
utils.commonLoggers.messageSendError('list.ts:39', message, e0);
|
||||
message.send(generateAliasError('Message Send Failed.', `list-m0-${guildMode ? 't' : 'f'}-${guildMode ? message.guildId : message.authorId}`));
|
||||
});
|
||||
};
|
||||
21
src/commands/aliasCmd/reservedWords.ts
Normal file
21
src/commands/aliasCmd/reservedWords.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
export const ReservedWords = Object.freeze([
|
||||
'guild',
|
||||
'help',
|
||||
'h',
|
||||
'?',
|
||||
'list',
|
||||
'list-all',
|
||||
'add',
|
||||
'create',
|
||||
'set',
|
||||
'update',
|
||||
'replace',
|
||||
'preview',
|
||||
'view',
|
||||
'delete',
|
||||
'remove',
|
||||
'delete-all',
|
||||
'remove-all',
|
||||
'run',
|
||||
'execute',
|
||||
]);
|
||||
121
src/commands/aliasCmd/run.ts
Normal file
121
src/commands/aliasCmd/run.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import { DiscordenoMessage } from '@discordeno';
|
||||
|
||||
import config from '~config';
|
||||
|
||||
import { getModifiers } from 'artigen/dice/getModifiers.ts';
|
||||
|
||||
import { sendRollRequest } from 'artigen/managers/queueManager.ts';
|
||||
|
||||
import { generateRollError, rollingEmbed } from 'artigen/utils/embeds.ts';
|
||||
|
||||
import dbClient from 'db/client.ts';
|
||||
import { queries } from 'db/common.ts';
|
||||
|
||||
import { generateAliasError } from 'embeds/alias.ts';
|
||||
import { failColor } from 'embeds/colors.ts';
|
||||
|
||||
import utils from 'utils/utils.ts';
|
||||
|
||||
interface QueryShape {
|
||||
aliasName: string;
|
||||
yVarCnt: number;
|
||||
rollStr: string;
|
||||
}
|
||||
|
||||
export const run = async (message: DiscordenoMessage, guildMode: boolean, command: string, argSpaces: string[]) => {
|
||||
let errorOut = false;
|
||||
const aliasName = (command === 'run' || command === 'execute' ? argSpaces.shift() || '' : command)?.trim().toLowerCase();
|
||||
const yVars = new Map<string, number>();
|
||||
argSpaces
|
||||
.join('')
|
||||
.trim()
|
||||
.replaceAll('\n', ' ')
|
||||
.split(' ')
|
||||
.filter((x) => x)
|
||||
.forEach((yVar, idx) => yVars.set(`y${idx}`, parseFloat(yVar)));
|
||||
|
||||
let query: QueryShape[] = await dbClient
|
||||
.query(
|
||||
`SELECT aliasName, yVarCnt, rollStr FROM aliases WHERE guildid = ? AND userid = ? AND aliasName = ?`,
|
||||
guildMode ? [message.guildId, 0n, aliasName] : [0n, message.authorId, aliasName],
|
||||
)
|
||||
.catch((e0) => {
|
||||
utils.commonLoggers.dbError('run.ts:30', 'query', e0);
|
||||
message
|
||||
.send(generateAliasError('DB Query Failed.', `run-q0-${guildMode ? 't' : 'f'}-${aliasName}-${guildMode ? message.guildId : message.authorId}`))
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('run.ts:33', message, e));
|
||||
errorOut = true;
|
||||
});
|
||||
if (errorOut) return;
|
||||
|
||||
if (!guildMode && !query.length) {
|
||||
// Didn't find an alias for the user, maybe their doing an implicit guild mode?
|
||||
query = await dbClient
|
||||
.query(`SELECT aliasName, yVarCnt, rollStr FROM aliases WHERE guildid = ? AND userid = ? AND aliasName = ?`, [message.guildId, 0n, aliasName])
|
||||
.catch((e0) => {
|
||||
utils.commonLoggers.dbError('run.ts:43', 'query', e0);
|
||||
message
|
||||
.send(generateAliasError('DB Query Failed.', `run-q1-${guildMode ? 't' : 'f'}-${aliasName}-${guildMode ? message.guildId : message.authorId}`))
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('run.ts:46', message, e));
|
||||
errorOut = true;
|
||||
});
|
||||
if (errorOut) return;
|
||||
}
|
||||
|
||||
const details = query.shift();
|
||||
if (!query.length || !details) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: `No alias named \`${aliasName}\` found${guildMode ? ' ' : ' on your account or '}in this guild`,
|
||||
description: `Please run \`${config.prefix}ra ${guildMode ? 'guild ' : ''}list\` to view the available aliases.`,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('run.ts:63', message, e));
|
||||
return;
|
||||
}
|
||||
|
||||
if (yVars.size < details.yVarCnt) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: 'Not enough yVars provided',
|
||||
description: `The alias \`${aliasName}\` requires \`${details.yVarCnt}\` yVars, but only \`${yVars.size}\` were provided. The roll string for this alias is:
|
||||
\`${details.rollStr}\``.slice(0, 3_000),
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('run.ts:81', message, e));
|
||||
return;
|
||||
}
|
||||
|
||||
const m = await message.reply(rollingEmbed);
|
||||
|
||||
const rollStrArgSpaces = details.rollStr.split(/([ \n]+)/g);
|
||||
const [modifiers, remainingArgs] = getModifiers(rollStrArgSpaces);
|
||||
|
||||
if (!modifiers.valid) {
|
||||
m.edit(generateRollError('Modifiers invalid:', modifiers.error.name, modifiers.error.message)).catch((e) => utils.commonLoggers.messageEditError('run.ts:96', m, e));
|
||||
return;
|
||||
}
|
||||
|
||||
const currDateTime = new Date();
|
||||
dbClient.execute(queries.callIncCnt('roll')).catch((e) => utils.commonLoggers.dbError('run.ts:104', 'call sproc INC_CNT on', e));
|
||||
dbClient.execute(queries.callIncHeatmap(currDateTime)).catch((e) => utils.commonLoggers.dbError('run.ts:105', 'update', e));
|
||||
|
||||
modifiers.yVars = yVars;
|
||||
sendRollRequest({
|
||||
apiRoll: false,
|
||||
ddRoll: true,
|
||||
testRoll: false,
|
||||
dd: { myResponse: m, originalMessage: message },
|
||||
rollCmd: remainingArgs.join(''),
|
||||
modifiers,
|
||||
originalCommand: details.rollStr,
|
||||
});
|
||||
};
|
||||
88
src/commands/aliasCmd/view.ts
Normal file
88
src/commands/aliasCmd/view.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { DiscordenoMessage } from '@discordeno';
|
||||
|
||||
import config from '~config';
|
||||
|
||||
import dbClient from 'db/client.ts';
|
||||
|
||||
import { generateAliasError } from 'embeds/alias.ts';
|
||||
import { failColor, successColor } from 'embeds/colors.ts';
|
||||
|
||||
import utils from 'utils/utils.ts';
|
||||
|
||||
interface QueryShape {
|
||||
aliasName: string;
|
||||
yVarCnt: number;
|
||||
rollStr: string;
|
||||
}
|
||||
|
||||
export const view = async (message: DiscordenoMessage, guildMode: boolean, argSpaces: string[]) => {
|
||||
const aliasName = argSpaces.shift();
|
||||
|
||||
if (!aliasName) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: 'No alias provided.',
|
||||
description: `Please run this command again with an alias to search for, for example
|
||||
|
||||
If you need to see all aliases for ${guildMode ? 'this guild' : 'your account'}, please run \`${config.prefix}ra ${guildMode ? 'guild ' : ''}list\` to see all of ${
|
||||
guildMode ? "this guild's" : 'your'
|
||||
} current aliases.`,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('view.ts:35', message, e));
|
||||
return;
|
||||
}
|
||||
|
||||
let errorOut = false;
|
||||
const query: QueryShape[] = await dbClient
|
||||
.query(
|
||||
`SELECT aliasName, yVarCnt, rollStr FROM aliases WHERE guildid = ? AND userid = ? AND aliasName = ?`,
|
||||
guildMode ? [message.guildId, 0n, aliasName.toLowerCase()] : [0n, message.authorId, aliasName.toLowerCase()],
|
||||
)
|
||||
.catch((e0) => {
|
||||
utils.commonLoggers.dbError('view.ts:46', 'query', e0);
|
||||
message
|
||||
.send(generateAliasError('DB Query Failed.', `view-q0-${guildMode ? 't' : 'f'}-${aliasName}-${guildMode ? message.guildId : message.authorId}`))
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('view.ts:49', message, e));
|
||||
errorOut = true;
|
||||
});
|
||||
if (errorOut) return;
|
||||
|
||||
const details = query[0];
|
||||
|
||||
if (details) {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: successColor,
|
||||
title: `Found the alias \`${aliasName}\` for ${guildMode ? 'this guild' : 'your account'}:`,
|
||||
description: `Y Var Count: \`${details.yVarCnt}\` Alias Name: \`${details.aliasName}\`
|
||||
${details.rollStr}`,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e0) => {
|
||||
utils.commonLoggers.messageSendError('view.ts:69', message, e0);
|
||||
message.send(
|
||||
generateAliasError('Message Send Failed.', `view-m0-${guildMode ? 't' : 'f'}-${aliasName}-${guildMode ? message.guildId : message.authorId}`),
|
||||
);
|
||||
});
|
||||
} else {
|
||||
message
|
||||
.send({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: `\`${aliasName}\` does not exist as a${guildMode ? ' guild alias' : 'n alias on your account'}.`,
|
||||
description: `Did you mean to run \`${config.prefix}ra ${guildMode ? '' : 'guild '}view ${aliasName}\`?`,
|
||||
},
|
||||
],
|
||||
})
|
||||
.catch((e: Error) => utils.commonLoggers.messageSendError('view.ts:85', message, e));
|
||||
}
|
||||
};
|
||||
@@ -19,7 +19,7 @@ const sortGuildByMemberCount = (a: DiscordenoGuild, b: DiscordenoGuild) => {
|
||||
export const auditGuilds = async (message: DiscordenoMessage) => {
|
||||
const cachedGuilds = await cacheHandlers.size('guilds');
|
||||
const guildOwnerCounts = new Map<bigint, number>();
|
||||
const sizeCats = [10000, 5000, 1000, 500, 100, 50, 25, 10, 1];
|
||||
const sizeCats = [10_000, 5_000, 1_000, 500, 100, 50, 25, 10, 1];
|
||||
const guildSizeDist = new Map<number, number>(sizeCats.map((size) => [size, 0]));
|
||||
|
||||
let totalCount = 0;
|
||||
|
||||
@@ -79,6 +79,8 @@ export const roll = async (message: DiscordenoMessage, args: string[], command:
|
||||
|
||||
sendRollRequest({
|
||||
apiRoll: false,
|
||||
ddRoll: true,
|
||||
testRoll: false,
|
||||
dd: { myResponse: m, originalMessage: message },
|
||||
rollCmd,
|
||||
modifiers,
|
||||
|
||||
21
src/embeds/alias.ts
Normal file
21
src/embeds/alias.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { CreateMessage } from '@discordeno';
|
||||
|
||||
import config from '~config';
|
||||
|
||||
import { failColor } from 'embeds/colors.ts';
|
||||
|
||||
export const generateAliasError = (customMessage: string, customId: string): CreateMessage => ({
|
||||
embeds: [
|
||||
{
|
||||
color: failColor,
|
||||
title: 'Something went wrong!',
|
||||
description: `The Alias System has encountered an error:
|
||||
- ${customMessage}
|
||||
|
||||
Please try again. If this continues to happen, please \`${config.prefix}report\` the error code to the developer.`,
|
||||
footer: {
|
||||
text: `Error Code: ${customId}`,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -83,7 +83,7 @@ export const apiRoll = async (query: Map<string, string>, apiUserid: bigint): Pr
|
||||
rollCmd = rollCmd.replace(/%20/g, ' ').trim();
|
||||
|
||||
const rawSimNom = parseInt(query.get('sn') ?? '0');
|
||||
const simNom = rawSimNom || 10000;
|
||||
const simNom = rawSimNom || config.limits.defaultSimulatedNominal;
|
||||
const modifiers: RollModifiers = {
|
||||
noDetails: query.has('nd'),
|
||||
superNoDetails: query.has('snd'),
|
||||
@@ -102,6 +102,7 @@ export const apiRoll = async (query: Map<string, string>, apiUserid: bigint): Pr
|
||||
rollDist: query.has('rd'),
|
||||
numberVariables: query.has('nv') || query.has('vn'),
|
||||
customDiceShapes: new Map<string, number[]>(),
|
||||
yVars: new Map<string, number>(),
|
||||
apiWarn: hideWarn ? '' : apiWarning,
|
||||
valid: true,
|
||||
error: new Error(),
|
||||
@@ -154,13 +155,15 @@ export const apiRoll = async (query: Map<string, string>, apiUserid: bigint): Pr
|
||||
}
|
||||
|
||||
// simulatedNominal cannot be greater than config.limits.simulatedNominal
|
||||
if (modifiers.simulatedNominal > config.limits.simulatedNominal) {
|
||||
return stdResp.BadRequest(`Number of iterations for \`simulatedNominal\` cannot be greater than \`${config.limits.simulatedNominal}\``);
|
||||
if (modifiers.simulatedNominal > config.limits.maxSimulatedNominal) {
|
||||
return stdResp.BadRequest(`Number of iterations for \`simulatedNominal\` cannot be greater than \`${config.limits.maxSimulatedNominal}\``);
|
||||
}
|
||||
|
||||
return new Promise<Response>((resolve) => {
|
||||
sendRollRequest({
|
||||
apiRoll: true,
|
||||
ddRoll: false,
|
||||
testRoll: false,
|
||||
api: { resolve, channelId: BigInt(query.get('channel') || '0'), userId: BigInt(query.get('user') || '') },
|
||||
rollCmd,
|
||||
modifiers,
|
||||
|
||||
@@ -26,7 +26,7 @@ const sendGuildJoinedBatch = () => {
|
||||
|
||||
setInterval(() => {
|
||||
sendGuildJoinedBatch();
|
||||
}, 60 * 1000);
|
||||
}, 60_000);
|
||||
|
||||
export const guildCreateHandler = (guild: DiscordenoGuild) => {
|
||||
log(LT.LOG, `Handling joining guild ${JSON.stringify(guild)}`);
|
||||
|
||||
@@ -135,6 +135,15 @@ export const messageCreateHandler = (message: DiscordenoMessage) => {
|
||||
// Enable or Disable inline rolling
|
||||
commands.toggleInline(message, args);
|
||||
break;
|
||||
case 'rollalias':
|
||||
case 'ralias':
|
||||
case 'alias':
|
||||
case 'rolla':
|
||||
case 'ra':
|
||||
// [[rollalias, [[ralias, [[rolla, or [[ra args
|
||||
// Manage and roll using aliases
|
||||
commands.alias(message, argSpaces);
|
||||
break;
|
||||
case 'roll':
|
||||
case 'r':
|
||||
// [[roll or [[r
|
||||
|
||||
@@ -40,25 +40,25 @@ export const readyHandler = () => {
|
||||
} catch (e) {
|
||||
log(LT.ERROR, `Failed to update status: ${JSON.stringify(e)}`);
|
||||
}
|
||||
}, 30000);
|
||||
}, 30_000);
|
||||
|
||||
// Interval to update bot list stats every 24 hours
|
||||
LOCALMODE ? log(LT.INFO, 'updateListStatistics not running') : setInterval(() => {
|
||||
log(LT.LOG, 'Updating all bot lists statistics');
|
||||
intervals.updateListStatistics(botId, cache.guilds.size + cache.dispatchedGuildIds.size);
|
||||
}, 86400000);
|
||||
}, 86_400_000);
|
||||
|
||||
// Interval to update hourlyRates every hour
|
||||
setInterval(() => {
|
||||
log(LT.LOG, 'Updating all command hourlyRates');
|
||||
intervals.updateHourlyRates();
|
||||
}, 3600000);
|
||||
}, 3_600_000);
|
||||
|
||||
// Interval to update heatmap.png every hour
|
||||
setInterval(() => {
|
||||
log(LT.LOG, 'Updating heatmap.png');
|
||||
intervals.updateHeatmapPng();
|
||||
}, 3600000);
|
||||
}, 3_600_000);
|
||||
|
||||
// setTimeout added to make sure the startup message does not error out
|
||||
setTimeout(() => {
|
||||
@@ -91,5 +91,5 @@ export const readyHandler = () => {
|
||||
},
|
||||
],
|
||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('ready.ts:93', 'Startup', e));
|
||||
}, 1000);
|
||||
}, 1_000);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user