feat: support configurable random delays between auto steps
- 合并 PR #44 的核心改动:新增 Auto 步间随机延迟配置,并在后台执行前应用该随机等待\n- 本地补充修复:无\n- 影响范围:background auto orchestration、sidepanel auto settings、README、tests
This commit is contained in:
@@ -192,6 +192,19 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<span class="data-label">步间随机</span>
|
||||
<div class="data-inline auto-delay-inline">
|
||||
<div class="auto-delay-controls">
|
||||
<input type="number" id="input-auto-step-delay-min-seconds" class="data-input auto-delay-input" value="12" min="0"
|
||||
max="600" step="1" title="自动运行每一步执行前的最小随机等待秒数" />
|
||||
<span class="data-unit">~</span>
|
||||
<input type="number" id="input-auto-step-delay-max-seconds" class="data-input auto-delay-input" value="18" min="0"
|
||||
max="600" step="1" title="自动运行每一步执行前的最大随机等待秒数" />
|
||||
<span class="data-unit">秒</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<span class="data-label">OAuth</span>
|
||||
<span id="display-oauth-url" class="data-value mono truncate">等待中...</span>
|
||||
|
||||
@@ -85,6 +85,8 @@ const inputRunCount = document.getElementById('input-run-count');
|
||||
const inputAutoSkipFailures = document.getElementById('input-auto-skip-failures');
|
||||
const inputAutoDelayEnabled = document.getElementById('input-auto-delay-enabled');
|
||||
const inputAutoDelayMinutes = document.getElementById('input-auto-delay-minutes');
|
||||
const inputAutoStepDelayMinSeconds = document.getElementById('input-auto-step-delay-min-seconds');
|
||||
const inputAutoStepDelayMaxSeconds = document.getElementById('input-auto-step-delay-max-seconds');
|
||||
const autoStartModal = document.getElementById('auto-start-modal');
|
||||
const autoStartTitle = autoStartModal?.querySelector('.modal-title');
|
||||
const autoStartMessage = document.getElementById('auto-start-message');
|
||||
@@ -108,6 +110,10 @@ const SKIPPABLE_STEPS = new Set([1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||
const AUTO_DELAY_MIN_MINUTES = 1;
|
||||
const AUTO_DELAY_MAX_MINUTES = 1440;
|
||||
const AUTO_DELAY_DEFAULT_MINUTES = 30;
|
||||
const AUTO_STEP_DELAY_MIN_SECONDS = 0;
|
||||
const AUTO_STEP_DELAY_MAX_SECONDS = 600;
|
||||
const AUTO_STEP_DELAY_DEFAULT_MIN_SECONDS = 12;
|
||||
const AUTO_STEP_DELAY_DEFAULT_MAX_SECONDS = 18;
|
||||
const DEFAULT_LOCAL_CPA_STEP9_MODE = 'submit';
|
||||
|
||||
let latestState = null;
|
||||
@@ -447,6 +453,23 @@ function normalizeAutoDelayMinutes(value) {
|
||||
return Math.min(AUTO_DELAY_MAX_MINUTES, Math.max(AUTO_DELAY_MIN_MINUTES, Math.floor(numeric)));
|
||||
}
|
||||
|
||||
function normalizeAutoStepDelaySeconds(value, fallback = AUTO_STEP_DELAY_DEFAULT_MIN_SECONDS) {
|
||||
const numeric = Number(value);
|
||||
if (!Number.isFinite(numeric)) {
|
||||
return fallback;
|
||||
}
|
||||
return Math.min(AUTO_STEP_DELAY_MAX_SECONDS, Math.max(AUTO_STEP_DELAY_MIN_SECONDS, Math.floor(numeric)));
|
||||
}
|
||||
|
||||
function normalizeAutoStepDelayRange(minValue, maxValue) {
|
||||
const minSeconds = normalizeAutoStepDelaySeconds(minValue, AUTO_STEP_DELAY_DEFAULT_MIN_SECONDS);
|
||||
const maxSeconds = Math.max(
|
||||
minSeconds,
|
||||
normalizeAutoStepDelaySeconds(maxValue, AUTO_STEP_DELAY_DEFAULT_MAX_SECONDS)
|
||||
);
|
||||
return { minSeconds, maxSeconds };
|
||||
}
|
||||
|
||||
function updateAutoDelayInputState() {
|
||||
const scheduled = isAutoRunScheduledPhase();
|
||||
inputAutoDelayEnabled.disabled = scheduled;
|
||||
@@ -598,6 +621,10 @@ function collectSettingsPayload() {
|
||||
const selectedCloudflareDomain = normalizeCloudflareDomainValue(
|
||||
!cloudflareDomainEditMode ? selectCfDomain.value : activeDomain
|
||||
) || activeDomain;
|
||||
const autoStepDelayRange = normalizeAutoStepDelayRange(
|
||||
inputAutoStepDelayMinSeconds.value,
|
||||
inputAutoStepDelayMaxSeconds.value
|
||||
);
|
||||
return {
|
||||
panelMode: selectPanelMode.value,
|
||||
vpsUrl: inputVpsUrl.value.trim(),
|
||||
@@ -617,6 +644,8 @@ function collectSettingsPayload() {
|
||||
autoRunSkipFailures: inputAutoSkipFailures.checked,
|
||||
autoRunDelayEnabled: inputAutoDelayEnabled.checked,
|
||||
autoRunDelayMinutes: normalizeAutoDelayMinutes(inputAutoDelayMinutes.value),
|
||||
autoStepRandomDelayMinSeconds: autoStepDelayRange.minSeconds,
|
||||
autoStepRandomDelayMaxSeconds: autoStepDelayRange.maxSeconds,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -858,6 +887,12 @@ function applySettingsState(state) {
|
||||
inputAutoSkipFailures.checked = Boolean(state?.autoRunSkipFailures);
|
||||
inputAutoDelayEnabled.checked = Boolean(state?.autoRunDelayEnabled);
|
||||
inputAutoDelayMinutes.value = String(normalizeAutoDelayMinutes(state?.autoRunDelayMinutes));
|
||||
const autoStepDelayRange = normalizeAutoStepDelayRange(
|
||||
state?.autoStepRandomDelayMinSeconds,
|
||||
state?.autoStepRandomDelayMaxSeconds
|
||||
);
|
||||
inputAutoStepDelayMinSeconds.value = String(autoStepDelayRange.minSeconds);
|
||||
inputAutoStepDelayMaxSeconds.value = String(autoStepDelayRange.maxSeconds);
|
||||
if (state?.autoRunTotalRuns) {
|
||||
inputRunCount.value = String(state.autoRunTotalRuns);
|
||||
}
|
||||
@@ -2380,6 +2415,33 @@ inputAutoDelayMinutes.addEventListener('blur', () => {
|
||||
saveSettings({ silent: true }).catch(() => { });
|
||||
});
|
||||
|
||||
function syncAutoStepDelayInputs() {
|
||||
const range = normalizeAutoStepDelayRange(
|
||||
inputAutoStepDelayMinSeconds.value,
|
||||
inputAutoStepDelayMaxSeconds.value
|
||||
);
|
||||
inputAutoStepDelayMinSeconds.value = String(range.minSeconds);
|
||||
inputAutoStepDelayMaxSeconds.value = String(range.maxSeconds);
|
||||
}
|
||||
|
||||
inputAutoStepDelayMinSeconds.addEventListener('input', () => {
|
||||
markSettingsDirty(true);
|
||||
scheduleSettingsAutoSave();
|
||||
});
|
||||
inputAutoStepDelayMinSeconds.addEventListener('blur', () => {
|
||||
syncAutoStepDelayInputs();
|
||||
saveSettings({ silent: true }).catch(() => { });
|
||||
});
|
||||
|
||||
inputAutoStepDelayMaxSeconds.addEventListener('input', () => {
|
||||
markSettingsDirty(true);
|
||||
scheduleSettingsAutoSave();
|
||||
});
|
||||
inputAutoStepDelayMaxSeconds.addEventListener('blur', () => {
|
||||
syncAutoStepDelayInputs();
|
||||
saveSettings({ silent: true }).catch(() => { });
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// Listen for Background broadcasts
|
||||
// ============================================================
|
||||
@@ -2477,6 +2539,14 @@ chrome.runtime.onMessage.addListener((message) => {
|
||||
if (message.payload.autoRunDelayMinutes !== undefined) {
|
||||
inputAutoDelayMinutes.value = String(normalizeAutoDelayMinutes(message.payload.autoRunDelayMinutes));
|
||||
}
|
||||
if (message.payload.autoStepRandomDelayMinSeconds !== undefined || message.payload.autoStepRandomDelayMaxSeconds !== undefined) {
|
||||
const autoStepDelayRange = normalizeAutoStepDelayRange(
|
||||
message.payload.autoStepRandomDelayMinSeconds ?? inputAutoStepDelayMinSeconds.value,
|
||||
message.payload.autoStepRandomDelayMaxSeconds ?? inputAutoStepDelayMaxSeconds.value
|
||||
);
|
||||
inputAutoStepDelayMinSeconds.value = String(autoStepDelayRange.minSeconds);
|
||||
inputAutoStepDelayMaxSeconds.value = String(autoStepDelayRange.maxSeconds);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user