Compare commits
No commits in common. "master" and "V4.1.1" have entirely different histories.
|
@ -1,4 +1,4 @@
|
|||
# The Artificer - A Dice Rolling Discord Bot | V4.1.2 - 2025/08/06
|
||||
# The Artificer - A Dice Rolling Discord Bot | V4.1.1 - 2025/08/05
|
||||
[](https://sonarcloud.io/summary/new_code?id=TheArtificer)
|
||||
[](https://sonarcloud.io/summary/new_code?id=TheArtificer) [](https://sonarcloud.io/summary/new_code?id=TheArtificer) [](https://sonarcloud.io/summary/new_code?id=TheArtificer) [](https://sonarcloud.io/summary/new_code?id=TheArtificer) [](https://sonarcloud.io/summary/new_code?id=TheArtificer) [](https://sonarcloud.io/summary/new_code?id=TheArtificer)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export const config = {
|
||||
name: 'The Artificer', // Name of the bot
|
||||
maxFileSize: 8_388_290, // Max file size bot can send
|
||||
version: '4.1.2', // Version of the bot
|
||||
version: '4.1.1', // Version of the bot
|
||||
token: 'the_bot_token', // Discord API Token for this bot
|
||||
localtoken: 'local_testing_token', // Discord API Token for a secondary OPTIONAL testing bot, THIS MUST BE DIFFERENT FROM "token"
|
||||
prefix: '[[', // Prefix for all commands
|
||||
|
@ -16,7 +16,7 @@ export const config = {
|
|||
guild: 1_000, // Allows guilds to have 1000 aliased rolls for free
|
||||
},
|
||||
},
|
||||
maxLoops: 2_000_000, // Determines how long the bot will attempt a roll, number of loops before it kills a roll. Increase this at your own risk.
|
||||
maxLoops: 1_000_000, // Determines how long the bot will attempt a roll, number of loops before it kills a roll. Increase this at your own risk.
|
||||
maxWorkers: 16, // Maximum number of worker threads to spawn at once (Set this to less than the number of threads your CPU has, Artificer will eat it all if too many rolls happen at once)
|
||||
workerTimeout: 300_000, // Maximum time before the bot kills a worker thread in ms
|
||||
defaultSimulatedNominal: 10_000, // Default number of loops to run for simulating a nominal
|
||||
|
|
|
@ -23,7 +23,6 @@ export interface SolvedRoll {
|
|||
line1: string;
|
||||
line2: string;
|
||||
line3: string;
|
||||
footer: string;
|
||||
counts: CountDetails;
|
||||
rollDistributions: RollDistributionMap;
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@ import { tokenizeCmd } from 'artigen/cmdTokenizer.ts';
|
|||
|
||||
import { Modifiers } from 'artigen/dice/getModifiers.ts';
|
||||
|
||||
import { getLoopCount, loopCountCheck } from 'artigen/managers/loopManager.ts';
|
||||
import { loopCountCheck } from 'artigen/managers/loopManager.ts';
|
||||
import { QueuedRoll } from 'artigen/managers/manager.d.ts';
|
||||
|
||||
import { reduceCountDetails } from 'artigen/utils/counter.ts';
|
||||
import { cmdSplitRegex, escapeCharacters, withYVarsDash } from 'artigen/utils/escape.ts';
|
||||
import { loggingEnabled, showLoopCountDebug } from 'artigen/utils/logFlag.ts';
|
||||
import { loggingEnabled } from 'artigen/utils/logFlag.ts';
|
||||
import { assertPrePostBalance } from 'artigen/utils/parenBalance.ts';
|
||||
import { reduceRollDistMaps } from 'artigen/utils/rollDist.ts';
|
||||
import { compareTotalRolls, compareTotalRollsReverse, sortYVars } from 'artigen/utils/sortFuncs.ts';
|
||||
|
@ -26,7 +26,6 @@ export const runCmd = (rollRequest: QueuedRoll): SolvedRoll => {
|
|||
line1: '',
|
||||
line2: '',
|
||||
line3: '',
|
||||
footer: '',
|
||||
counts: {
|
||||
total: 0,
|
||||
successful: 0,
|
||||
|
@ -110,7 +109,7 @@ export const runCmd = (rollRequest: QueuedRoll): SolvedRoll => {
|
|||
if (rollRequest.modifiers.simulatedNominal) line2 += `Iterations performed per roll: \`${rollRequest.modifiers.simulatedNominal.toLocaleString()}\`\n`;
|
||||
|
||||
// Reduce counts to a single object
|
||||
if (rollRequest.modifiers.count) returnMsg.counts = reduceCountDetails(tempCountDetails);
|
||||
returnMsg.counts = reduceCountDetails(tempCountDetails);
|
||||
|
||||
// If a regular nominal and roll looks somewhat complex, alert user simulatedNominal exists
|
||||
if (rollRequest.modifiers.nominalRoll && tempReturnData.filter((data) => data.isComplex).length) {
|
||||
|
@ -121,7 +120,7 @@ export const runCmd = (rollRequest: QueuedRoll): SolvedRoll => {
|
|||
const line2Space = rollRequest.modifiers.noSpaces ? '' : ' ';
|
||||
// Fill out all of the details and results now
|
||||
tempReturnData.forEach((e, i) => {
|
||||
loopCountCheck('artigen.ts - tempReturnData');
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `Parsing roll ${rollRequest.rollCmd} | Making return text ${JSON.stringify(e)}`);
|
||||
let preFormat = '';
|
||||
|
@ -170,7 +169,7 @@ export const runCmd = (rollRequest: QueuedRoll): SolvedRoll => {
|
|||
returnMsg.line3 = line3;
|
||||
|
||||
// Reduce rollDist maps into a single map
|
||||
if (rollRequest.modifiers.rollDist) returnMsg.rollDistributions = reduceRollDistMaps(tempRollDists);
|
||||
returnMsg.rollDistributions = reduceRollDistMaps(tempRollDists);
|
||||
} catch (e) {
|
||||
// Fill in the return block
|
||||
const solverError = e as Error;
|
||||
|
@ -179,7 +178,5 @@ export const runCmd = (rollRequest: QueuedRoll): SolvedRoll => {
|
|||
[returnMsg.errorCode, returnMsg.errorMsg] = translateError(solverError);
|
||||
}
|
||||
|
||||
if (showLoopCountDebug) returnMsg.footer = `Loop Count: ${getLoopCount()}`;
|
||||
|
||||
return returnMsg;
|
||||
};
|
||||
|
|
|
@ -32,7 +32,7 @@ export const tokenizeCmd = (
|
|||
|
||||
// Wrapped commands still exist, unwrap them
|
||||
while (cmd.includes(config.prefix)) {
|
||||
loopCountCheck('cmdTokenizer.ts - while cmd includes prefix');
|
||||
loopCountCheck();
|
||||
|
||||
const openIdx = cmd.indexOf(config.prefix);
|
||||
const closeIdx = getMatchingPostfixIdx(cmd, openIdx);
|
||||
|
@ -49,7 +49,7 @@ export const tokenizeCmd = (
|
|||
|
||||
const simulatedData: ReturnData[] = [];
|
||||
for (let i = 0; i < simulatedLoopCount; i++) {
|
||||
loopCountCheck(`cmdTokenizer.ts - simulate nominal loop #${i}`);
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `In simLoop:${i} "${currentCmd}" of ${JSON.stringify(cmd)}`);
|
||||
|
||||
|
@ -78,7 +78,7 @@ export const tokenizeCmd = (
|
|||
loggingEnabled && log(LT.LOG, `ConfirmCrit on ${JSON.stringify(currentCmd)}`);
|
||||
let done = false;
|
||||
while (!done) {
|
||||
loopCountCheck('cmdTokenizer.ts - confirming crit');
|
||||
loopCountCheck();
|
||||
|
||||
// Keep running the same roll again until its not successful
|
||||
const [ccTempData, ccTempCounts, ccTempDists] = tokenizeCmd(
|
||||
|
@ -194,7 +194,7 @@ export const tokenizeCmd = (
|
|||
const tempInitConf = data.initConfig.split(internalGrpWrapRegex).filter((x) => x);
|
||||
loggingEnabled && log(LT.LOG, `Split solved math into tempInitConf ${JSON.stringify(tempInitConf)}`);
|
||||
while (tempInitConf.includes(openInternalGrp)) {
|
||||
loopCountCheck('cmdTokenizer.ts - handling internal group result merging');
|
||||
loopCountCheck();
|
||||
|
||||
const openIdx = tempInitConf.indexOf(openInternalGrp);
|
||||
const closeIdx = getMatchingInternalGrpIdx(tempInitConf, openIdx);
|
||||
|
@ -214,7 +214,7 @@ export const tokenizeCmd = (
|
|||
.filter((x) => x);
|
||||
loggingEnabled && log(LT.LOG, `Split tempInitConfig into initConf ${JSON.stringify(initConf)}`);
|
||||
while (initConf.includes(openInternal)) {
|
||||
loopCountCheck('cmdTokenizer.ts - handling internal nested roll result merging');
|
||||
loopCountCheck();
|
||||
|
||||
const openIdx = initConf.indexOf(openInternal);
|
||||
const closeIdx = getMatchingInternalIdx(initConf, openIdx);
|
||||
|
|
|
@ -80,7 +80,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
|
|||
for (let i = 0; i < rollConf.dieCount; i++) {
|
||||
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Initial rolling ${i} of ${JSON.stringify(rollConf)}`);
|
||||
// If loopCount gets too high, stop trying to calculate infinity
|
||||
loopCountCheck('executeRoll.ts - handling initial rolling');
|
||||
loopCountCheck();
|
||||
|
||||
// Copy the template to fill out for this iteration
|
||||
const rolling = getTemplateRoll();
|
||||
|
@ -104,7 +104,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
|
|||
for (let i = 0; i < rollSet.length; i++) {
|
||||
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Handling rerolling and exploding ${JSON.stringify(rollSet[i])}`);
|
||||
// If loopCount gets too high, stop trying to calculate infinity
|
||||
loopCountCheck('executeRoll.ts - handling rerolling and exploding');
|
||||
loopCountCheck();
|
||||
|
||||
// This big boolean statement first checks if reroll is on, if the roll is within the reroll range, and finally if ro is ON, make sure we haven't already rerolled the roll
|
||||
if (rollConf.reroll.on && rollConf.reroll.nums.includes(rollSet[i].roll) && (!rollConf.reroll.once || !rollSet[i ? i - 1 : i].rerolled)) {
|
||||
|
@ -117,7 +117,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
|
|||
if (modifiers.maxRoll && !minMaxOverride) {
|
||||
// If maximizeRoll is on and we've entered the reroll code, dieSize is not allowed, determine the next best option and always return that
|
||||
mmMaxLoop: for (let m = rollConf.dieSize - 1; m > 0; m--) {
|
||||
loopCountCheck('executeRoll.ts - maximizeRoll');
|
||||
loopCountCheck();
|
||||
|
||||
if (!rollConf.reroll.nums.includes(m)) {
|
||||
minMaxOverride = m;
|
||||
|
@ -127,7 +127,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
|
|||
} else if (modifiers.minRoll && !minMaxOverride) {
|
||||
// If minimizeRoll is on and we've entered the reroll code, 1 is not allowed, determine the next best option and always return that
|
||||
mmMinLoop: for (let m = rollConf.dPercent.on ? 1 : 2; m <= rollConf.dieSize; m++) {
|
||||
loopCountCheck('executeRoll.ts - minimizeRoll');
|
||||
loopCountCheck();
|
||||
|
||||
if (!rollConf.reroll.nums.includes(m)) {
|
||||
minMaxOverride = m;
|
||||
|
@ -181,7 +181,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
|
|||
for (const penRoll of rollSet) {
|
||||
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Handling penetrating explosions ${JSON.stringify(penRoll)}`);
|
||||
// If loopCount gets too high, stop trying to calculate infinity
|
||||
loopCountCheck('executeRoll.ts - penetrating explosion');
|
||||
loopCountCheck();
|
||||
|
||||
// If the die was from an explosion, decrement it by one
|
||||
if (penRoll.exploding) {
|
||||
|
@ -195,7 +195,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
|
|||
for (let i = 0; i < rollSet.length; i++) {
|
||||
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Handling compounding explosions ${JSON.stringify(rollSet[i])}`);
|
||||
// If loopCount gets too high, stop trying to calculate infinity
|
||||
loopCountCheck('executeRoll.ts - compounding explosion');
|
||||
loopCountCheck();
|
||||
|
||||
// Compound the exploding rolls, including the exploding flag and
|
||||
if (rollSet[i].exploding) {
|
||||
|
@ -215,7 +215,8 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
|
|||
let rerollCount = 0;
|
||||
if (rollConf.reroll.on) {
|
||||
for (let j = 0; j < rollSet.length; j++) {
|
||||
loopCountCheck('executeRoll.ts - count rerolls');
|
||||
// If loopCount gets too high, stop trying to calculate infinity
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Setting originalIdx on ${JSON.stringify(rollSet[j])}`);
|
||||
rollSet[j].origIdx = j;
|
||||
|
@ -264,7 +265,8 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
|
|||
// Now its time to drop all dice needed
|
||||
let i = 0;
|
||||
while (dropCount > 0 && i < rollSet.length) {
|
||||
loopCountCheck('executeRoll.ts - dropping/keeping');
|
||||
// If loopCount gets too high, stop trying to calculate infinity
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Dropping dice ${dropCount} ${JSON.stringify(rollSet[i])}`);
|
||||
// Skip all rolls that were rerolled
|
||||
|
@ -288,7 +290,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
|
|||
|
||||
// Drop all dice that are not a part of the max
|
||||
for (const ovaRoll of rollSet) {
|
||||
loopCountCheck('executeRoll.ts - OVA');
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled &&
|
||||
log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | checking if this roll should be dropped ${ovaRoll.roll} | to keep: ${maxRoll}`);
|
||||
|
@ -309,7 +311,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
|
|||
const labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
let labelIdx = 0;
|
||||
const rollLabels: Array<string> = rollVals.map((count) => {
|
||||
loopCountCheck('executeRoll.ts - matching');
|
||||
loopCountCheck();
|
||||
|
||||
if (labelIdx >= labels.length) {
|
||||
throw new Error(`TooManyLabels_${labels.length}`);
|
||||
|
@ -325,7 +327,7 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed
|
|||
|
||||
// Apply labels
|
||||
for (const roll of rollSet) {
|
||||
loopCountCheck('executeRoll.ts - labeling matches');
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | trying to add a label to ${JSON.stringify(roll)}`);
|
||||
if (rollLabels[roll.roll - 1]) {
|
||||
|
|
|
@ -20,7 +20,7 @@ export const formatRoll = (executedRoll: ExecutedRoll, modifiers: RollModifiers)
|
|||
// Loop thru all parts of the roll to document everything that was done to create the total roll
|
||||
loggingEnabled && log(LT.LOG, `Formatting roll ${JSON.stringify(executedRoll)}`);
|
||||
executedRoll.rollSet.forEach((e) => {
|
||||
loopCountCheck('generateFormattedRoll.ts - formatting executed roll');
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `At ${JSON.stringify(e)}`);
|
||||
let preFormat = '';
|
||||
|
|
|
@ -14,7 +14,7 @@ export const getGroupConf = (groupStr: string, rawStr: string): GroupConf => {
|
|||
|
||||
let biggest = parseInt(numberMatches.length ? numberMatches[0] : '1');
|
||||
for (const num of numberMatches) {
|
||||
loopCountCheck('getGroupConf.ts - finding biggest number for die size');
|
||||
loopCountCheck();
|
||||
|
||||
const curNum = parseInt(num);
|
||||
loggingEnabled && log(LT.LOG, `Finding biggest number to use as die size, ${curNum} ${biggest}`);
|
||||
|
@ -37,7 +37,7 @@ export const getGroupConf = (groupStr: string, rawStr: string): GroupConf => {
|
|||
let maxFail: number | null = null;
|
||||
|
||||
while (groupSplit.length) {
|
||||
loopCountCheck('getGroupConf.ts - parsing groupConf');
|
||||
loopCountCheck();
|
||||
|
||||
const option = groupSplit.shift() ?? '';
|
||||
const value = parseInt(groupSplit.shift() ?? '');
|
||||
|
|
|
@ -126,7 +126,7 @@ export const getRollConf = (rollStr: string, customTypes: CustomDiceShapes = new
|
|||
const difficulty = parseInt(tempDifficulty.slice(0, afterDifficultyIdx) || '10');
|
||||
|
||||
for (let i = difficulty; i <= rollConf.dieSize; i++) {
|
||||
loopCountCheck('getRollConf.ts - setting cwod difficulty');
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling cwod ${rollStr} | Parsing difficulty ${i}`);
|
||||
rollConf.success.range.push(i);
|
||||
|
@ -216,7 +216,7 @@ export const getRollConf = (rollStr: string, customTypes: CustomDiceShapes = new
|
|||
|
||||
// Loop until all remaining args are parsed
|
||||
while (remains.length > 0) {
|
||||
loopCountCheck('getRollConf.ts - parsing rollConf');
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Parsing remains ${remains}`);
|
||||
// Find the next number in the remains to be able to cut out the rule name
|
||||
|
@ -232,7 +232,7 @@ export const getRollConf = (rollStr: string, customTypes: CustomDiceShapes = new
|
|||
let noNumberAfter = false;
|
||||
if (!(Object.values(DiceOptions) as string[]).includes(tempSep)) {
|
||||
NumberlessDiceOptions.some((opt) => {
|
||||
loopCountCheck('getRollConf.ts - parsing numberlessDiceOptions');
|
||||
loopCountCheck();
|
||||
loggingEnabled && log(LT.LOG, `In NumberlessDiceOptions ${opt} ${tempSep.startsWith(opt) && tempSep !== opt}`);
|
||||
if (tempSep.startsWith(opt) && tempSep !== opt) {
|
||||
afterSepIdx = opt.length;
|
||||
|
|
|
@ -30,7 +30,7 @@ export const handleGroup = (
|
|||
|
||||
// Nested groups still exist, unwrap them
|
||||
while (groupParts.includes('{')) {
|
||||
loopCountCheck('groupHandler.ts - handling nested groups');
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `Handling Nested Groups | Current cmd: ${JSON.stringify(groupParts)}`);
|
||||
|
||||
|
@ -72,7 +72,7 @@ export const handleGroup = (
|
|||
const groupResults: ReturnData[] = [];
|
||||
|
||||
for (const part of commaParts) {
|
||||
loopCountCheck('groupHandler.ts - solving commaParts');
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `Solving commaPart: ${part}`);
|
||||
const [tempData, tempCounts, tempDists] = tokenizeMath(part, modifiers, previousResults, prevGrpReturnData);
|
||||
|
@ -131,7 +131,7 @@ export const handleGroup = (
|
|||
|
||||
let i = 0;
|
||||
while (dropCount > 0 && i < groupResults.length) {
|
||||
loopCountCheck('groupHandler.ts - handling group drop/keep');
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `Handling group dropping | Dropping ${dropCount}`);
|
||||
|
||||
|
@ -148,7 +148,7 @@ export const handleGroup = (
|
|||
let failCnt = 0;
|
||||
if (groupConf.success.on || groupConf.fail.on) {
|
||||
groupResults.forEach((rd, idx) => {
|
||||
loopCountCheck('groupHandler.ts - handling group success/fail');
|
||||
loopCountCheck();
|
||||
|
||||
if (!resultFlags[idx].dropped) {
|
||||
if (
|
||||
|
@ -265,7 +265,7 @@ export const handleGroup = (
|
|||
const initConf = retData.initConfig.split(internalGrpWrapRegex).filter((x) => x);
|
||||
loggingEnabled && log(LT.LOG, `Split retData into initConf ${JSON.stringify(initConf)}`);
|
||||
while (initConf.includes(openInternalGrp)) {
|
||||
loopCountCheck('groupHandler.ts - handling merging nested groups up');
|
||||
loopCountCheck();
|
||||
|
||||
const openIdx = initConf.indexOf(openInternalGrp);
|
||||
const closeIdx = getMatchingInternalGrpIdx(initConf, openIdx);
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import { closeLog, initLog } from '@Log4Deno';
|
||||
|
||||
import { runCmd } from 'artigen/artigen.ts';
|
||||
import { SolvedRoll } from 'artigen/artigen.d.ts';
|
||||
|
||||
import { QueuedRoll } from 'artigen/managers/manager.d.ts';
|
||||
|
||||
import { loggingEnabled, loopLoggingEnabled } from 'artigen/utils/logFlag.ts';
|
||||
import { loggingEnabled } from 'artigen/utils/logFlag.ts';
|
||||
|
||||
if (loggingEnabled || loopLoggingEnabled) initLog('logs/worker', loggingEnabled || loopLoggingEnabled);
|
||||
loggingEnabled && initLog('logs/worker', loggingEnabled);
|
||||
|
||||
// Extend the BigInt prototype to support JSON.stringify
|
||||
interface BigIntX extends BigInt {
|
||||
|
@ -24,14 +23,13 @@ self.postMessage('ready');
|
|||
// Handle the roll
|
||||
self.onmessage = async (e: MessageEvent<QueuedRoll>) => {
|
||||
const payload = e.data;
|
||||
const returnMsg: SolvedRoll = runCmd(payload) || {
|
||||
const returnMsg = runCmd(payload) || {
|
||||
error: true,
|
||||
errorCode: 'EmptyMessage',
|
||||
errorMsg: 'Error: Empty message',
|
||||
line1: '',
|
||||
line2: '',
|
||||
line3: '',
|
||||
footer: '',
|
||||
counts: {
|
||||
total: 0,
|
||||
successful: 0,
|
||||
|
@ -39,12 +37,9 @@ self.onmessage = async (e: MessageEvent<QueuedRoll>) => {
|
|||
rerolled: 0,
|
||||
dropped: 0,
|
||||
exploded: 0,
|
||||
success: 0,
|
||||
fail: 0,
|
||||
matches: new Map<string, number>(),
|
||||
},
|
||||
};
|
||||
self.postMessage(returnMsg);
|
||||
if (loggingEnabled || loopLoggingEnabled) await closeLog();
|
||||
loggingEnabled && (await closeLog());
|
||||
self.close();
|
||||
};
|
||||
|
|
|
@ -278,7 +278,7 @@ Please click on "<@${botId}> *Click to see attachment*" above this message to se
|
|||
details: returnMsg.line3,
|
||||
},
|
||||
counts: rollRequest.modifiers.count ? returnMsg.counts : null,
|
||||
rollDistributions: rollRequest.modifiers.rollDist ? returnMsg.rollDistributions.entries().toArray() : null,
|
||||
rollDistributions: returnMsg.rollDistributions.entries().toArray(),
|
||||
},
|
||||
}),
|
||||
{
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
import { log, LogTypes as LT } from '@Log4Deno';
|
||||
|
||||
import config from '~config';
|
||||
|
||||
import { loopLoggingEnabled } from 'artigen/utils/logFlag.ts';
|
||||
|
||||
let loopCount = 0;
|
||||
|
||||
// Will ensure if maxLoops is 10, 10 loops will be allowed, 11 will not.
|
||||
export const loopCountCheck = (location = 'unset'): void => {
|
||||
export const loopCountCheck = (): void => {
|
||||
loopCount++;
|
||||
loopLoggingEnabled && log(LT.LOG, `Loop #${loopCount} at "${location}"`);
|
||||
if (loopCount > config.limits.maxLoops) {
|
||||
throw new Error('MaxLoopsExceeded');
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ export const mathSolver = (conf: MathConf[], wrapDetails = false): SolvedStep =>
|
|||
|
||||
// Evaluate all parenthesis
|
||||
while (conf.includes('(')) {
|
||||
loopCountCheck('mathSolver.ts - evaluating parens');
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `Evaluating roll ${JSON.stringify(conf)} | Looking for (`);
|
||||
// Get first open parenthesis
|
||||
|
@ -75,7 +75,7 @@ export const mathSolver = (conf: MathConf[], wrapDetails = false): SolvedStep =>
|
|||
// Start at index 1 as there will never be implicit multiplication before the first element
|
||||
loggingEnabled && log(LT.LOG, `Checking for missing implicit multiplication ${JSON.stringify(conf)}`);
|
||||
for (let i = 1; i < conf.length; i++) {
|
||||
loopCountCheck('mathSolver.ts - checking for implicit multiplication');
|
||||
loopCountCheck();
|
||||
|
||||
const prevConfAsStr = <string> conf[i - 1];
|
||||
const curConfAsStr = <string> conf[i];
|
||||
|
@ -94,15 +94,14 @@ export const mathSolver = (conf: MathConf[], wrapDetails = false): SolvedStep =>
|
|||
['+', '-'],
|
||||
];
|
||||
allCurOps.forEach((curOps) => {
|
||||
// No loopCountCheck here since its finite/will always be 3 loops
|
||||
loggingEnabled && log(LT.LOG, `Cur Ops ${JSON.stringify(curOps)}`);
|
||||
loggingEnabled && log(LT.LOG, `Evaluating roll ${JSON.stringify(conf)} | Evaluating ${JSON.stringify(curOps)}`);
|
||||
// Iterate thru all operators/operands in the conf
|
||||
for (let i = 0; i < conf.length; i++) {
|
||||
loggingEnabled && log(LT.LOG, `Checking ${JSON.stringify(conf[i])}`);
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `Evaluating roll ${JSON.stringify(conf)} | Evaluating ${JSON.stringify(curOps)} | Checking ${JSON.stringify(conf[i])}`);
|
||||
// Check if the current index is in the active tier of operators
|
||||
if (curOps.includes(conf[i].toString())) {
|
||||
loggingEnabled && log(LT.LOG, `Evaluating roll ${JSON.stringify(conf)} as ${JSON.stringify(conf[i])} is in curOps`);
|
||||
loopCountCheck('mathSolver.ts - evaluating roll');
|
||||
// Grab the operands from before and after the operator
|
||||
const operand1 = conf[i - 1];
|
||||
const operand2 = conf[i + 1];
|
||||
|
|
|
@ -45,11 +45,11 @@ export const tokenizeMath = (
|
|||
loggingEnabled && log(LT.LOG, `Split roll into mathConf ${JSON.stringify(mathConf)}`);
|
||||
|
||||
// Verify balanced parens before doing anything
|
||||
if (mathConf.includes('(') || mathConf.includes(')')) assertParenBalance(mathConf);
|
||||
assertParenBalance(mathConf);
|
||||
|
||||
// Evaluate all rolls into stepSolve format and all numbers into floats
|
||||
for (let i = 0; i < mathConf.length; i++) {
|
||||
loopCountCheck('mathTokenizer.ts - parsing all tokens into MathConf');
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `Parsing roll ${JSON.stringify(cmd)} | Evaluating rolls into math-able items ${JSON.stringify(mathConf[i])}`);
|
||||
|
||||
|
@ -201,7 +201,7 @@ export const tokenizeMath = (
|
|||
const formattedRoll = formatRoll(executedRoll, modifiers);
|
||||
mathConf[i] = formattedRoll.solvedStep;
|
||||
countDetails.push(formattedRoll.countDetails);
|
||||
if (modifiers.rollDist) rollDists.push(formattedRoll.rollDistributions);
|
||||
rollDists.push(formattedRoll.rollDistributions);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,7 +272,7 @@ export const tokenizeMath = (
|
|||
|
||||
let i = 0;
|
||||
while (dropCount > 0 && i < allRollSets.length) {
|
||||
loopCountCheck('mathTokenizer.ts - handling group dropping');
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `Handling group dropping | Dropping ${dropCount}, looking at ${JSON.stringify(allRollSets[i])}`);
|
||||
|
||||
|
@ -293,7 +293,7 @@ export const tokenizeMath = (
|
|||
// Handle marking new successes/fails
|
||||
if (groupConf.success.on || groupConf.fail.on) {
|
||||
allRollSets.forEach((rs) => {
|
||||
loopCountCheck('mathTokenizer.ts - handling group success/fails');
|
||||
loopCountCheck();
|
||||
|
||||
if (!rs.dropped && !rs.rerolled) {
|
||||
if (groupConf.success.on && groupConf.success.range.includes(rs.roll)) {
|
||||
|
@ -318,7 +318,7 @@ export const tokenizeMath = (
|
|||
const formattedRoll = formatRoll(executedRoll, modifiers);
|
||||
mathConf[rollGroupIdx] = formattedRoll.solvedStep;
|
||||
countDetails.push(formattedRoll.countDetails);
|
||||
if (modifiers.rollDist) rollDists.push(formattedRoll.rollDistributions);
|
||||
rollDists.push(formattedRoll.rollDistributions);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ export const rollCounter = (rollSet: RollSet[]): CountDetails => {
|
|||
};
|
||||
|
||||
rollSet.forEach((roll) => {
|
||||
loopCountCheck('counter.ts - summing RollSet into CountDetails');
|
||||
loopCountCheck();
|
||||
countDetails.total++;
|
||||
if (roll.critHit) countDetails.successful++;
|
||||
if (roll.critFail) countDetails.failed++;
|
||||
|
@ -34,9 +34,9 @@ export const rollCounter = (rollSet: RollSet[]): CountDetails => {
|
|||
export const reduceCountDetails = (counts: CountDetails[]): CountDetails =>
|
||||
counts.reduce(
|
||||
(acc, cur) => {
|
||||
loopCountCheck('counter.ts - merging array of CountDetails down to single CountDetail');
|
||||
loopCountCheck();
|
||||
cur.matches.forEach((cnt, label) => {
|
||||
loopCountCheck('counter.ts - merging matches');
|
||||
loopCountCheck();
|
||||
acc.matches.set(label, (acc.matches.get(label) ?? 0) + cnt);
|
||||
});
|
||||
return {
|
||||
|
|
|
@ -259,17 +259,13 @@ export const generateRollEmbed = (
|
|||
|
||||
// Embed desc limit is 4096
|
||||
// Discord only formats 200 items per message
|
||||
const fullSize = fullDesc.length + returnDetails.footer.length;
|
||||
if (fullSize < 4_000 && formattingCount <= 200) {
|
||||
if (fullDesc.length < 4_000 && formattingCount <= 200) {
|
||||
// Response is valid size
|
||||
return {
|
||||
charCount: fullSize,
|
||||
charCount: fullDesc.length,
|
||||
embed: {
|
||||
color: infoColor2,
|
||||
description: fullDesc,
|
||||
footer: {
|
||||
text: returnDetails.footer,
|
||||
},
|
||||
},
|
||||
hasAttachment: false,
|
||||
};
|
||||
|
|
|
@ -11,14 +11,12 @@ import { loggingEnabled } from 'artigen/utils/logFlag.ts';
|
|||
export const escapeCharacters = (str: string, esc: string): string => {
|
||||
// Loop thru each esc char one at a time
|
||||
for (const e of esc) {
|
||||
loggingEnabled && log(LT.LOG, `Escaping character ${e} | ${str}, ${esc}`);
|
||||
if (str.includes(e)) {
|
||||
loopCountCheck(`escape.ts - escaping character ${e}`);
|
||||
loopCountCheck();
|
||||
|
||||
// Create a new regex to look for that char that needs replaced and escape it
|
||||
const tempRgx = new RegExp(`[${e}]`, 'g');
|
||||
str = str.replace(tempRgx, `\\${e}`);
|
||||
}
|
||||
loggingEnabled && log(LT.LOG, `Escaping character ${e} | ${str}, ${esc}`);
|
||||
// Create a new regex to look for that char that needs replaced and escape it
|
||||
const tempRgx = new RegExp(`[${e}]`, 'g');
|
||||
str = str.replace(tempRgx, `\\${e}`);
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
export const loggingEnabled = false;
|
||||
export const loopLoggingEnabled = false;
|
||||
export const showLoopCountDebug = false;
|
||||
|
|
|
@ -22,8 +22,7 @@ const checkBalance = (
|
|||
|
||||
// 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++) {
|
||||
countLoops &&
|
||||
loopCountCheck(`parenBalance.ts - ${getMatching ? 'Looking for matching' : 'Checking'} ${openStr}/${closeStr}${getMatching ? '' : ' balance'}`);
|
||||
countLoops && loopCountCheck();
|
||||
loggingEnabled &&
|
||||
log(
|
||||
LT.LOG,
|
||||
|
|
|
@ -14,7 +14,7 @@ export const addToRange = (tSep: string, range: Array<number>, tNum: number) =>
|
|||
|
||||
const internalAddMultipleToRange = (tSep: string, range: Array<number>, start: number, end: number) => {
|
||||
for (let i = start; i <= end; i++) {
|
||||
loopCountCheck(`rangeAdder.ts - ${tSep} range adder`);
|
||||
loopCountCheck();
|
||||
addToRange(tSep, range, i);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ export const createRollDistMap = (rollSet: RollSet[]): RollDistributionMap => {
|
|||
const rollDistMap = new Map<string, number[]>();
|
||||
|
||||
rollSet.forEach((roll) => {
|
||||
loopCountCheck('rollDist.ts - convert RollSet into RollDist');
|
||||
loopCountCheck();
|
||||
const tempArr: number[] = rollDistMap.get(rollDistKey(roll.type, roll.size)) ?? new Array<number>(roll.type === 'fate' ? roll.size + 2 : roll.size).fill(0);
|
||||
tempArr[roll.type === 'fate' ? roll.roll + 1 : roll.roll - 1]++;
|
||||
rollDistMap.set(rollDistKey(roll.type, roll.size), tempArr);
|
||||
|
@ -22,17 +22,17 @@ export const createRollDistMap = (rollSet: RollSet[]): RollDistributionMap => {
|
|||
// Collapses an array of RollDistMaps into a single RollDistMap
|
||||
export const reduceRollDistMaps = (rollDistArr: RollDistributionMap[]): RollDistributionMap =>
|
||||
rollDistArr.reduce((acc, cur) => {
|
||||
loopCountCheck('rollDist.ts - merge array of RollDists into single RollDist');
|
||||
loopCountCheck();
|
||||
|
||||
cur
|
||||
.entries()
|
||||
.toArray()
|
||||
.forEach(([key, value]) => {
|
||||
loopCountCheck('rollDist.ts - doing the merge on each item of current');
|
||||
loopCountCheck();
|
||||
|
||||
const tempArr = acc.get(key) ?? new Array<number>(value.length).fill(0);
|
||||
for (let i = 0; i < tempArr.length; i++) {
|
||||
loopCountCheck('rollDist.ts - doing the merge');
|
||||
loopCountCheck();
|
||||
tempArr[i] += value[i];
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ export const generateRollVals = (rollConf: RollConf, rollSet: RollSet[], rollStr
|
|||
|
||||
// Count up all rolls
|
||||
for (const ovaRoll of rollSet) {
|
||||
loopCountCheck('rollValCounter.ts - counting roll vals');
|
||||
loopCountCheck();
|
||||
|
||||
loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | incrementing rollVals for ${JSON.stringify(ovaRoll)}`);
|
||||
if (!ovaRoll.dropped && !ovaRoll.rerolled) {
|
||||
|
|
Loading…
Reference in New Issue