mirror of
https://github.com/LightZirconite/Microsoft-Rewards-Bot.git
synced 2026-01-11 09:46:16 +00:00
feat: add job state reset functionality and improve user prompts
This commit is contained in:
@@ -21,7 +21,7 @@
|
|||||||
"parallel": false,
|
"parallel": false,
|
||||||
"runOnZeroPoints": false,
|
"runOnZeroPoints": false,
|
||||||
"clusters": 1,
|
"clusters": 1,
|
||||||
"passesPerRun": 1
|
"passesPerRun": 1 // Number of times to run through all accounts (set to 3 to run 3 times even if already completed)
|
||||||
},
|
},
|
||||||
"jobState": {
|
"jobState": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
|||||||
60
src/index.ts
60
src/index.ts
@@ -4,6 +4,7 @@ import type { Page } from 'playwright'
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { spawn } from 'child_process'
|
import { spawn } from 'child_process'
|
||||||
|
import { createInterface } from 'readline'
|
||||||
|
|
||||||
import Browser from './browser/Browser'
|
import Browser from './browser/Browser'
|
||||||
import BrowserFunc from './browser/BrowserFunc'
|
import BrowserFunc from './browser/BrowserFunc'
|
||||||
@@ -169,6 +170,43 @@ export class MicrosoftRewardsBot {
|
|||||||
return value === '1' || lower === 'true' || lower === 'yes'
|
return value === '1' || lower === 'true' || lower === 'yes'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async promptResetJobState(): Promise<boolean> {
|
||||||
|
// Skip prompt in non-interactive environments (Docker, CI, scheduled tasks)
|
||||||
|
if (!process.stdin.isTTY) {
|
||||||
|
log('main','TASK','Non-interactive environment detected - keeping job state', 'warn')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const rl = createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout
|
||||||
|
})
|
||||||
|
|
||||||
|
return new Promise<boolean>((resolve) => {
|
||||||
|
rl.question('\n⚠️ Reset job state and run all accounts again? (y/N): ', (answer) => {
|
||||||
|
rl.close()
|
||||||
|
const trimmed = answer.trim().toLowerCase()
|
||||||
|
resolve(trimmed === 'y' || trimmed === 'yes')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private resetAllJobStates(): void {
|
||||||
|
if (!this.accountJobState) return
|
||||||
|
|
||||||
|
const jobStateDir = this.accountJobState.getJobStateDir()
|
||||||
|
if (!fs.existsSync(jobStateDir)) return
|
||||||
|
|
||||||
|
const files = fs.readdirSync(jobStateDir).filter(f => f.endsWith('.json'))
|
||||||
|
for (const file of files) {
|
||||||
|
try {
|
||||||
|
fs.unlinkSync(path.join(jobStateDir, file))
|
||||||
|
} catch {
|
||||||
|
// Ignore errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async run() {
|
async run() {
|
||||||
this.printBanner()
|
this.printBanner()
|
||||||
log('main', 'MAIN', `Bot started with ${this.config.clusters} clusters`)
|
log('main', 'MAIN', `Bot started with ${this.config.clusters} clusters`)
|
||||||
@@ -479,6 +517,22 @@ export class MicrosoftRewardsBot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async runTasks(accounts: Account[]) {
|
private async runTasks(accounts: Account[]) {
|
||||||
|
// Check if all accounts are already completed and prompt user
|
||||||
|
const accountDayKey = this.utils.getFormattedDate()
|
||||||
|
const allCompleted = accounts.every(acc => this.shouldSkipAccount(acc.email, accountDayKey))
|
||||||
|
|
||||||
|
if (allCompleted && accounts.length > 0) {
|
||||||
|
log('main','TASK',`All accounts already completed on ${accountDayKey}`, 'warn', 'yellow')
|
||||||
|
const shouldReset = await this.promptResetJobState()
|
||||||
|
if (shouldReset) {
|
||||||
|
this.resetAllJobStates()
|
||||||
|
log('main','TASK','Job state reset - proceeding with all accounts', 'log', 'green')
|
||||||
|
} else {
|
||||||
|
log('main','TASK','Keeping existing job state - exiting', 'log')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const account of accounts) {
|
for (const account of accounts) {
|
||||||
// If a global standby is active due to security/banned, stop processing further accounts
|
// If a global standby is active due to security/banned, stop processing further accounts
|
||||||
if (this.globalStandby.active) {
|
if (this.globalStandby.active) {
|
||||||
@@ -490,9 +544,9 @@ export class MicrosoftRewardsBot {
|
|||||||
log('main','TASK',`Stopping remaining accounts due to ban on ${this.bannedTriggered.email}: ${this.bannedTriggered.reason}`,'warn')
|
log('main','TASK',`Stopping remaining accounts due to ban on ${this.bannedTriggered.email}: ${this.bannedTriggered.reason}`,'warn')
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
const accountDayKey = this.utils.getFormattedDate()
|
const currentDayKey = this.utils.getFormattedDate()
|
||||||
if (this.shouldSkipAccount(account.email, accountDayKey)) {
|
if (this.shouldSkipAccount(account.email, currentDayKey)) {
|
||||||
log('main','TASK',`Skipping account ${account.email}: already completed on ${accountDayKey} (job-state resume)`, 'warn')
|
log('main','TASK',`Skipping account ${account.email}: already completed on ${currentDayKey} (job-state resume)`, 'warn')
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Reset compromised state per account
|
// Reset compromised state per account
|
||||||
|
|||||||
@@ -99,6 +99,10 @@ export class JobState {
|
|||||||
this.save(email, st)
|
this.save(email, st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getJobStateDir(): string {
|
||||||
|
return this.baseDir
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default JobState
|
export default JobState
|
||||||
|
|||||||
Reference in New Issue
Block a user