Change artigen to take rollRequest to use originalCommand as the raw text, then use remaining args after getModifiers eats mods

This commit is contained in:
Ean Milligan 2025-05-05 18:19:39 -04:00
parent 2fe2c5f296
commit b169ee8632
5 changed files with 65 additions and 53 deletions

View File

@ -3,7 +3,7 @@ import { log, LogTypes as LT } from '@Log4Deno';
import { SolvedRoll } from 'artigen/artigen.d.ts';
import { tokenizeCmd } from 'artigen/cmdTokenizer.ts';
import { RollModifiers } from 'artigen/dice/dice.d.ts';
import { QueuedRoll } from 'artigen/managers/manager.d.ts';
import { cmdSplitRegex, escapeCharacters } from 'artigen/utils/escape.ts';
import { loggingEnabled } from 'artigen/utils/logFlag.ts';
@ -11,9 +11,9 @@ import { assertPrePostBalance } from 'artigen/utils/parenBalance.ts';
import { compareTotalRolls, compareTotalRollsReverse } from 'artigen/utils/sortFuncs.ts';
import { translateError } from 'artigen/utils/translateError.ts';
// runCmd(fullCmd, modifiers)
// runCmd handles converting fullCmd into a computer readable format for processing, and finally executes the solving
export const runCmd = (fullCmd: string, modifiers: RollModifiers): SolvedRoll => {
// runCmd(rollRequest)
// runCmd handles converting rollRequest into a computer readable format for processing, and finally executes the solving
export const runCmd = (rollRequest: QueuedRoll): SolvedRoll => {
const returnMsg: SolvedRoll = {
error: false,
errorCode: '',
@ -34,22 +34,19 @@ export const runCmd = (fullCmd: string, modifiers: RollModifiers): SolvedRoll =>
// Whole processor lives in a try-catch to catch artigen's intentional error conditions
try {
// filter removes all null/empty strings since we don't care about them
const sepCmds = fullCmd.split(cmdSplitRegex).filter((x) => x);
const sepCmds = rollRequest.rollCmd.split(cmdSplitRegex).filter((x) => x);
loggingEnabled && log(LT.LOG, `Split cmd into parts ${JSON.stringify(sepCmds)}`);
// Verify prefix/postfix balance
assertPrePostBalance(sepCmds);
// Send the split roll into the command tokenizer to get raw response data
const [tempReturnData, tempCountDetails] = tokenizeCmd(sepCmds, modifiers, true);
const [tempReturnData, tempCountDetails] = tokenizeCmd(sepCmds, rollRequest.modifiers, true);
loggingEnabled && log(LT.LOG, `Return data is back ${JSON.stringify(tempReturnData)}`);
// Remove any floating spaces from fullCmd
fullCmd = fullCmd.trim();
// Escape any | and ` chars in fullCmd to prevent spoilers and code blocks from acting up
fullCmd = escapeCharacters(fullCmd, '|');
fullCmd = fullCmd.replace(/`/g, '');
// Remove any floating spaces from originalCommand
// Escape any | and ` chars in originalCommand to prevent spoilers and code blocks from acting up
const rawCmd = escapeCharacters(rollRequest.originalCommand.trim(), '|').replace(/`/g, '');
let line1 = '';
let line2 = '';
@ -60,26 +57,26 @@ export const runCmd = (fullCmd: string, modifiers: RollModifiers): SolvedRoll =>
line2 = resultStr;
// If a theoretical roll is requested, mark the output as such, else use default formatting
if (modifiers.maxRoll || modifiers.minRoll || modifiers.nominalRoll) {
if (rollRequest.modifiers.maxRoll || rollRequest.modifiers.minRoll || rollRequest.modifiers.nominalRoll) {
const theoreticalTexts = ['Maximum', 'Minimum', 'Nominal'];
const theoreticalBools = [modifiers.maxRoll, modifiers.minRoll, modifiers.nominalRoll];
const theoreticalBools = [rollRequest.modifiers.maxRoll, rollRequest.modifiers.minRoll, rollRequest.modifiers.nominalRoll];
const theoreticalText = theoreticalTexts[theoreticalBools.indexOf(true)];
line1 = ` requested the Theoretical ${theoreticalText} of:\n\`${fullCmd}\``;
line1 = ` requested the Theoretical ${theoreticalText} of:\n\`${rawCmd}\``;
line2 = `Theoretical ${theoreticalText} ${resultStr}`;
} else if (modifiers.order === 'a') {
line1 = ` requested the following rolls to be ordered from least to greatest:\n\`${fullCmd}\``;
} else if (rollRequest.modifiers.order === 'a') {
line1 = ` requested the following rolls to be ordered from least to greatest:\n\`${rawCmd}\``;
tempReturnData.sort(compareTotalRolls);
} else if (modifiers.order === 'd') {
line1 = ` requested the following rolls to be ordered from greatest to least:\n\`${fullCmd}\``;
} else if (rollRequest.modifiers.order === 'd') {
line1 = ` requested the following rolls to be ordered from greatest to least:\n\`${rawCmd}\``;
tempReturnData.sort(compareTotalRollsReverse);
} else {
line1 = ` rolled:\n\`${fullCmd}\``;
line1 = ` rolled:\n\`${rawCmd}\``;
}
// Fill out all of the details and results now
tempReturnData.forEach((e) => {
loggingEnabled && log(LT.LOG, `Parsing roll ${fullCmd} | Making return text ${JSON.stringify(e)}`);
loggingEnabled && log(LT.LOG, `Parsing roll ${rollRequest.rollCmd} | Making return text ${JSON.stringify(e)}`);
let preFormat = '';
let postFormat = '';
@ -94,21 +91,21 @@ export const runCmd = (fullCmd: string, modifiers: RollModifiers): SolvedRoll =>
}
// Populate line2 (the results) and line3 (the details) with their data
if (modifiers.order === '') {
line2 += `${e.rollPreFormat ? escapeCharacters(e.rollPreFormat, '|*_~`') : ' '}${preFormat}${modifiers.commaTotals ? e.rollTotal.toLocaleString() : e.rollTotal}${postFormat}${
if (rollRequest.modifiers.order === '') {
line2 += `${e.rollPreFormat ? escapeCharacters(e.rollPreFormat, '|*_~`') : ' '}${preFormat}${rollRequest.modifiers.commaTotals ? e.rollTotal.toLocaleString() : e.rollTotal}${postFormat}${
e.rollPostFormat ? escapeCharacters(e.rollPostFormat, '|*_~`') : ''
}`;
} else {
// If order is on, turn rolls into csv without formatting
line2 += `${preFormat}${modifiers.commaTotals ? e.rollTotal.toLocaleString() : e.rollTotal}${postFormat}, `;
line2 += `${preFormat}${rollRequest.modifiers.commaTotals ? e.rollTotal.toLocaleString() : e.rollTotal}${postFormat}, `;
}
const rollDetails = modifiers.noDetails ? ' = ' : ` = ${e.rollDetails} = `;
line3 += `\`${e.initConfig}\`${rollDetails}${preFormat}${modifiers.commaTotals ? e.rollTotal.toLocaleString() : e.rollTotal}${postFormat}\n`;
const rollDetails = rollRequest.modifiers.noDetails ? ' = ' : ` = ${e.rollDetails} = `;
line3 += `\`${e.initConfig}\`${rollDetails}${preFormat}${rollRequest.modifiers.commaTotals ? e.rollTotal.toLocaleString() : e.rollTotal}${postFormat}\n`;
});
// If order is on, remove trailing ", "
if (modifiers.order !== '') {
if (rollRequest.modifiers.order !== '') {
line2 = line2.substring(0, line2.length - 2);
}
@ -139,7 +136,7 @@ export const runCmd = (fullCmd: string, modifiers: RollModifiers): SolvedRoll =>
} catch (e) {
// Fill in the return block
const solverError = e as Error;
loggingEnabled && log(LT.ERROR, `Error hit: ${solverError.message} | ${fullCmd}`);
loggingEnabled && log(LT.ERROR, `Error hit: ${solverError.message} | ${rollRequest.rollCmd}`);
returnMsg.error = true;
[returnMsg.errorCode, returnMsg.errorMsg] = translateError(solverError);
}

View File

@ -2,7 +2,22 @@ import { log, LogTypes as LT } from '@Log4Deno';
import { RollModifiers } from 'artigen/dice/dice.d.ts';
export const getModifiers = (args: string[]): RollModifiers => {
export const Modifiers = Object.freeze({
Count: '-c',
NoDetails: '-nd',
SuperNoDetails: '-snd',
HideRaw: '-hr',
Spoiler: '-s',
Max: '-max',
MaxShorthand: '-m',
Min: '-min',
Nominal: '-n',
GM: '-gm',
Order: '-o',
CommaTotals: '-ct',
});
export const getModifiers = (args: string[]): [RollModifiers, string[]] => {
const modifiers: RollModifiers = {
noDetails: false,
superNoDetails: false,
@ -26,32 +41,32 @@ export const getModifiers = (args: string[]): RollModifiers => {
log(LT.LOG, `Checking ${args.join(' ')} for command modifiers ${i}`);
let defaultCase = false;
switch (args[i].toLowerCase()) {
case '-c':
case Modifiers.Count:
modifiers.count = true;
break;
case '-nd':
case Modifiers.NoDetails:
modifiers.noDetails = true;
break;
case '-snd':
case Modifiers.SuperNoDetails:
modifiers.superNoDetails = true;
break;
case '-hr':
case Modifiers.HideRaw:
modifiers.hideRaw = true;
break;
case '-s':
case Modifiers.Spoiler:
modifiers.spoiler = '||';
break;
case '-max':
case '-m':
case Modifiers.Max:
case Modifiers.MaxShorthand:
modifiers.maxRoll = true;
break;
case '-min':
case Modifiers.Min:
modifiers.minRoll = true;
break;
case '-n':
case Modifiers.Nominal:
modifiers.nominalRoll = true;
break;
case '-gm':
case Modifiers.GM:
modifiers.gmRoll = true;
// -gm is a little more complex, as we must get all of the GMs that need to be DMd
@ -65,10 +80,10 @@ export const getModifiers = (args: string[]): RollModifiers => {
// If -gm is on and none were found, throw an error
modifiers.error.name = 'NoGMsFound';
modifiers.error.message = 'Must specify at least one GM by @mentioning them';
return modifiers;
return [modifiers, args];
}
break;
case '-o':
case Modifiers.Order:
// Shift the -o out of the array so the next item is the direction
args.splice(i, 1);
@ -76,12 +91,12 @@ export const getModifiers = (args: string[]): RollModifiers => {
// If -o is on and asc or desc was not specified, error out
modifiers.error.name = 'NoOrderFound';
modifiers.error.message = 'Must specify `a` or `d` to order the rolls ascending or descending';
return modifiers;
return [modifiers, args];
}
modifiers.order = args[i].toLowerCase()[0];
break;
case '-ct':
case Modifiers.CommaTotals:
modifiers.commaTotals = true;
break;
default:
@ -100,9 +115,9 @@ export const getModifiers = (args: string[]): RollModifiers => {
if ([modifiers.maxRoll, modifiers.minRoll, modifiers.nominalRoll].filter((b) => b).length > 1) {
modifiers.error.name = 'MaxAndNominal';
modifiers.error.message = 'Can only use one of the following at a time:\n`maximize`, `minimize`, `nominal`';
return modifiers;
return [modifiers, args];
}
modifiers.valid = true;
return modifiers;
return [modifiers, args];
};

View File

@ -1,6 +1,9 @@
import { closeLog, initLog } from '@Log4Deno';
import { runCmd } from 'artigen/artigen.ts';
import { QueuedRoll } from 'artigen/managers/manager.d.ts';
import { loggingEnabled } from 'artigen/utils/logFlag.ts';
loggingEnabled && initLog('logs/worker', loggingEnabled);
@ -9,9 +12,9 @@ loggingEnabled && initLog('logs/worker', loggingEnabled);
self.postMessage('ready');
// Handle the roll
self.onmessage = async (e) => {
self.onmessage = async (e: MessageEvent<QueuedRoll>) => {
const payload = e.data;
const returnMsg = runCmd(payload.rollCmd, payload.modifiers) || {
const returnMsg = runCmd(payload) || {
error: true,
errorCode: 'EmptyMessage',
errorMsg: 'Error: Empty message',

View File

@ -6,8 +6,5 @@ import { loggingEnabled } from 'artigen/utils/logFlag.ts';
export const onWorkerReady = (rollWorker: Worker, rollRequest: QueuedRoll) => {
loggingEnabled && log(LT.LOG, `Sending roll to worker: ${rollRequest.rollCmd}, ${JSON.stringify(rollRequest.modifiers)}`);
rollWorker.postMessage({
rollCmd: rollRequest.rollCmd,
modifiers: rollRequest.modifiers,
});
rollWorker.postMessage(rollRequest);
};

View File

@ -45,7 +45,7 @@ export const roll = async (message: DiscordenoMessage, args: string[], command:
const m = await message.reply(rollingEmbed);
// Get modifiers from command
const modifiers = getModifiers(args);
const [modifiers, remainingArgs] = getModifiers(args);
// Return early if the modifiers were invalid
if (!modifiers.valid) {
@ -60,7 +60,7 @@ export const roll = async (message: DiscordenoMessage, args: string[], command:
return;
}
let rollCmd = message.content.startsWith(`${config.prefix}r`) ? args.join(' ') : message.content;
let rollCmd = message.content.startsWith(`${config.prefix}r`) ? remainingArgs.join(' ') : `${config.prefix}${command} ${remainingArgs.join(' ')}`;
// Try to ensure the roll is wrapped
if (!rollCmd.includes(config.prefix)) {