Optimize postpone error handler
This commit is contained in:
		| @@ -1,7 +1,9 @@ | ||||
| import { Args } from '../Command'; | ||||
| import { Task } from '../Queue/TaskQueue'; | ||||
| import { DataStorage } from '../DataStorage'; | ||||
| import { Scheduler } from '../Scheduler'; | ||||
| import { ActionError, TryLaterError } from '../Errors'; | ||||
| import { grabActiveVillageId } from '../Page/VillageBlock'; | ||||
| import { aroundMinutes } from '../utils'; | ||||
|  | ||||
| const actionMap: { [name: string]: Function | undefined } = {}; | ||||
|  | ||||
| @@ -25,4 +27,16 @@ export class ActionController { | ||||
|     } | ||||
|  | ||||
|     async run(args: Args, task: Task) {} | ||||
|  | ||||
|     ensureSameVillage(args: Args, task: Task) { | ||||
|         let villageId = args.villageId; | ||||
|         if (villageId === undefined) { | ||||
|             throw new ActionError(task.id, 'Undefined village id'); | ||||
|         } | ||||
|  | ||||
|         const activeVillageId = grabActiveVillageId(); | ||||
|         if (villageId !== activeVillageId) { | ||||
|             throw new TryLaterError(task.id, aroundMinutes(1), 'Not same village'); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -3,20 +3,23 @@ import { Args } from '../Command'; | ||||
| import { ActionError, GrabError, TryLaterError } from '../Errors'; | ||||
| import { Task } from '../Queue/TaskQueue'; | ||||
| import { clickBuildButton } from '../Page/BuildingPage'; | ||||
| import { aroundMinutes } from '../utils'; | ||||
|  | ||||
| @registerAction | ||||
| export class BuildBuildingAction extends ActionController { | ||||
|     async run(args: Args, task: Task): Promise<any> { | ||||
|         this.ensureSameVillage(args, task); | ||||
|  | ||||
|         const buildTypeId = args.buildTypeId; | ||||
|         if (!buildTypeId) { | ||||
|             throw new ActionError(task.id, 'Unknown build type id'); | ||||
|         if (buildTypeId === undefined) { | ||||
|             throw new ActionError(task.id, 'Undefined build type id'); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             clickBuildButton(buildTypeId); | ||||
|         } catch (e) { | ||||
|             if (e instanceof GrabError) { | ||||
|                 throw new TryLaterError(task.id, 15 * 60, 'No build button, try later'); | ||||
|                 throw new TryLaterError(task.id, aroundMinutes(5), 'No upgrade button, try later'); | ||||
|             } | ||||
|             throw e; | ||||
|         } | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| import { ActionController, registerAction } from './ActionController'; | ||||
| import { Args } from '../Command'; | ||||
| import { Task } from '../Queue/TaskQueue'; | ||||
| import { PostponeAllBuildingsError, GrabError } from '../Errors'; | ||||
| import { grabActiveVillageId, grabBuildingQueueInfo } from '../Page/VillageBlock'; | ||||
| import { GrabError, TryLaterError } from '../Errors'; | ||||
| import { grabBuildingQueueInfo } from '../Page/VillageBlock'; | ||||
| import { BuildingQueueInfo } from '../Game'; | ||||
|  | ||||
| @registerAction | ||||
| @@ -10,12 +10,7 @@ export class CheckBuildingRemainingTimeAction extends ActionController { | ||||
|     async run(args: Args, task: Task): Promise<any> { | ||||
|         const info = this.grabBuildingQueueInfoOrDefault(); | ||||
|         if (info.seconds > 0) { | ||||
|             throw new PostponeAllBuildingsError( | ||||
|                 task.id, | ||||
|                 grabActiveVillageId(), | ||||
|                 info.seconds + 1, | ||||
|                 'Building queue is full' | ||||
|             ); | ||||
|             throw new TryLaterError(task.id, info.seconds + 1, 'Building queue is full'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,22 +1,20 @@ | ||||
| import { ActionController, registerAction } from './ActionController'; | ||||
| import { Args } from '../Command'; | ||||
| import { ActionError, GrabError, PostponeAllBuildingsError } from '../Errors'; | ||||
| import { GrabError, TryLaterError } from '../Errors'; | ||||
| import { Task } from '../Queue/TaskQueue'; | ||||
| import { clickUpgradeButton } from '../Page/BuildingPage'; | ||||
| import { aroundMinutes } from '../utils'; | ||||
|  | ||||
| @registerAction | ||||
| export class UpgradeBuildingAction extends ActionController { | ||||
|     async run(args: Args, task: Task): Promise<any> { | ||||
|         let villageId = args.villageId; | ||||
|         if (villageId === undefined) { | ||||
|             throw new ActionError(task.id, 'No village id'); | ||||
|         } | ||||
|         this.ensureSameVillage(args, task); | ||||
|  | ||||
|         try { | ||||
|             clickUpgradeButton(); | ||||
|         } catch (e) { | ||||
|             if (e instanceof GrabError) { | ||||
|                 throw new PostponeAllBuildingsError(task.id, villageId, 15 * 60, 'No upgrade button, try later'); | ||||
|                 throw new TryLaterError(task.id, aroundMinutes(5), 'No upgrade button, try later'); | ||||
|             } | ||||
|             throw e; | ||||
|         } | ||||
|   | ||||
| @@ -36,17 +36,3 @@ export class TryLaterError extends Error { | ||||
|         Object.setPrototypeOf(this, TryLaterError.prototype); | ||||
|     } | ||||
| } | ||||
|  | ||||
| export class PostponeAllBuildingsError extends Error { | ||||
|     readonly seconds: number; | ||||
|     readonly villageId: number; | ||||
|     readonly taskId: TaskId; | ||||
|  | ||||
|     constructor(taskId: TaskId, villageId: number, seconds: number, msg: string = '') { | ||||
|         super(msg); | ||||
|         this.villageId = villageId; | ||||
|         this.taskId = taskId; | ||||
|         this.seconds = seconds; | ||||
|         Object.setPrototypeOf(this, PostponeAllBuildingsError.prototype); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { markPage, sleepMicro, timestamp, waitForLoad } from './utils'; | ||||
| import { AbortTaskError, ActionError, PostponeAllBuildingsError, TryLaterError } from './Errors'; | ||||
| import { AbortTaskError, ActionError, TryLaterError } from './Errors'; | ||||
| import { Task } from './Queue/TaskQueue'; | ||||
| import { Command } from './Command'; | ||||
| import { TaskQueueRenderer } from './TaskQueueRenderer'; | ||||
| @@ -108,12 +108,6 @@ export class Executor { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (err instanceof PostponeAllBuildingsError) { | ||||
|             this.logger.warn('BUILDING QUEUE FULL, TRY ALL AFTER', err.seconds); | ||||
|             this.scheduler.postponeBuildingsInVillage(err.villageId, err.seconds); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (err instanceof ActionError) { | ||||
|             this.logger.warn('ACTION ABORTED', err.message); | ||||
|             return; | ||||
|   | ||||
| @@ -73,28 +73,32 @@ export class Scheduler { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     completeTask(id: TaskId) { | ||||
|         this.taskQueue.remove(id); | ||||
|     completeTask(taskId: TaskId) { | ||||
|         this.taskQueue.remove(taskId); | ||||
|         this.actionQueue.clear(); | ||||
|     } | ||||
|  | ||||
|     removeTask(id: TaskId) { | ||||
|         this.taskQueue.remove(id); | ||||
|     removeTask(taskId: TaskId) { | ||||
|         this.taskQueue.remove(taskId); | ||||
|         this.actionQueue.clear(); | ||||
|     } | ||||
|  | ||||
|     postponeTask(id: TaskId, deltaTs: number) { | ||||
|         this.taskQueue.modify( | ||||
|             t => t.id === id, | ||||
|             t => withTime(t, timestamp() + deltaTs) | ||||
|         ); | ||||
|     postponeTask(taskId: TaskId, seconds: number) { | ||||
|         const task = this.taskQueue.seeItems().find(t => t.id === taskId); | ||||
|         if (!task) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|     postponeBuildingsInVillage(villageId: number, seconds: number) { | ||||
|         if (isBuildingTask(task.name) && task.args.villageId) { | ||||
|             this.taskQueue.modify( | ||||
|             t => isBuildingTask(t.name) && sameVillage(villageId, t.args), | ||||
|                 t => sameVillage(task.args.villageId, t.args), | ||||
|                 t => withTime(t, timestamp() + seconds) | ||||
|             ); | ||||
|         } else { | ||||
|             this.taskQueue.modify( | ||||
|                 t => t.id === taskId, | ||||
|                 t => withTime(t, timestamp() + seconds) | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     updateResources(taskId: TaskId, resources: Resources): void { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user