From 295d87be6993d603f336623f6babacf7e119e9b7 Mon Sep 17 00:00:00 2001 From: XP Date: Mon, 26 Aug 2024 12:42:51 -0700 Subject: [PATCH 1/2] Sim circuit breaker for PLD issue and fix styling of sim config --- packages/common-ui/styles/common.less | 26 ++++++++++++++++---------- packages/core/src/sims/cycle_sim.ts | 21 +++++++++++++++++---- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/packages/common-ui/styles/common.less b/packages/common-ui/styles/common.less index 89f5a032..18cf153c 100644 --- a/packages/common-ui/styles/common.less +++ b/packages/common-ui/styles/common.less @@ -1580,7 +1580,22 @@ add-sim-dialog { padding: 10px; display: flex; flex-direction: column; - align-items: center; + align-items: stretch; + width: max-content; + max-width: calc(100% - 10px); + margin-left: auto; + margin-right: auto; + + > .named-section { + .named-section-standard; + width: 100%; + + max-width: unset; + + label[for='cycle-total-time'] { + margin-right: 10px; + } + } > * { margin-top: 10px; @@ -3205,15 +3220,6 @@ gear-set-issues-modal { .top-level-widget; } -#sim-config-area-inner > .named-section { - .named-section-standard; - width: 100%; - - label[for='cycle-total-time'] { - margin-right: 10px; - } -} - .top-level-widget { border-radius: 10px; .shadow-big; diff --git a/packages/core/src/sims/cycle_sim.ts b/packages/core/src/sims/cycle_sim.ts index 1acf4692..a9553dee 100644 --- a/packages/core/src/sims/cycle_sim.ts +++ b/packages/core/src/sims/cycle_sim.ts @@ -417,6 +417,13 @@ export class CycleProcessor { private readonly comboTrackerMap: Map; private readonly aaAbility: AutoAttack; + /** + * Tracks the number of actions used so that it can trip a circuit breaker if stuck in an infinite loop. + * + * @private + */ + private _rowCount = 0; + constructor(private settings: MultiCycleSettings) { // TODO: set enforcement mode this.cdTracker = new CooldownTracker(() => this.currentTime); @@ -473,7 +480,7 @@ export class CycleProcessor { } const activeBuffs = this.getActiveBuffsData(startTime); - const matchingActiveBuffIdx = activeBuffs.findIndex(b => b.buff.statusId == buff.statusId); + const matchingActiveBuffIdx = activeBuffs.findIndex(b => b.buff.statusId == buff.statusId); if (matchingActiveBuffIdx != -1) { activeBuffs[matchingActiveBuffIdx].end = startTime; activeBuffs[matchingActiveBuffIdx].forceEnd = true; @@ -667,6 +674,9 @@ export class CycleProcessor { * @param time The time of the record. Current time will be used if not specified. */ addSpecialRow(message: string, time?: number) { + if (this._rowCount++ > 10_000) { + throw Error("Used too many special rows"); + } this.allRecords.push({ usedAt: time ?? this.currentTime, label: message, @@ -892,7 +902,7 @@ export class CycleProcessor { } // Counter that makes this fail on purpose if buggy sim rotation code gets into an infinite loop - _counter: number = 0; + _canUseCdCount: number = 0; /** * Determines whether or not a GCD plus zero or more oGCDs can be used without violating cooldowns and @@ -905,8 +915,8 @@ export class CycleProcessor { * @param ogcds */ canUseCooldowns(gcd: GcdAbility, ogcds: OgcdAbility[]): 'yes' | 'no' | 'not-enough-time' { - if (this._counter++ > 10000) { - if (this._counter > 10005) { + if (this._canUseCdCount++ > 10000) { + if (this._canUseCdCount > 10005) { throw Error("loop") } } @@ -1059,6 +1069,9 @@ export class CycleProcessor { private combatStarting: boolean = false; protected addAbilityUse(usedAbility: AbilityUseRecordUnf) { + if (this._rowCount++ > 10_000) { + throw Error("Used too many actions"); + } this.allRecords.push(usedAbility); // If this is a pre-pull ability, we can offset by the hardcast time and/or application delay if (!this.combatStarted && usedAbility.ability.potency !== null) { From 98382af0d7c9247abbf43d4b677cd35829a3411c Mon Sep 17 00:00:00 2001 From: XP Date: Mon, 26 Aug 2024 12:44:54 -0700 Subject: [PATCH 2/2] Clamp allowed duration for sim --- .../scripts/sims/components/cycle_settings_components.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/frontend/src/scripts/sims/components/cycle_settings_components.ts b/packages/frontend/src/scripts/sims/components/cycle_settings_components.ts index 39b99b6c..75d01c12 100644 --- a/packages/frontend/src/scripts/sims/components/cycle_settings_components.ts +++ b/packages/frontend/src/scripts/sims/components/cycle_settings_components.ts @@ -1,10 +1,10 @@ import {CycleSettings} from "@xivgear/core/sims/cycle_settings"; import { + clampValues, FieldBoundCheckBox, FieldBoundFloatField, labeledCheckbox, - labelFor, - nonNegative + labelFor } from "@xivgear/common-ui/components/util"; import {NamedSection} from "../../components/section"; @@ -12,7 +12,8 @@ export function cycleSettingsGui(cycleSettings: CycleSettings) { const out = new NamedSection('Cycle Settings'); const timeField = new FieldBoundFloatField(cycleSettings, 'totalTime', { inputMode: 'number', - postValidators: [nonNegative] + // 1 hour of sim time should be enough for any application + postValidators: [clampValues(0, 60 * 60)], }); timeField.id = 'cycle-total-time'; const label = labelFor('Total Time:', timeField);