From 24ceb04307e24bf19ef876c896254bc2a95b5a41 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Sun, 19 Apr 2020 11:53:18 +0300 Subject: [PATCH] Optimize postpone error handler --- src/Action/ActionController.ts | 16 ++++++++- src/Action/BuildBuildingAction.ts | 9 +++-- .../CheckBuildingRemainingTimeAction.ts | 11 ++---- src/Action/UpgradeBuildingAction.ts | 10 +++--- src/Errors.ts | 14 -------- src/Executor.ts | 8 +---- src/Scheduler.ts | 36 ++++++++++--------- 7 files changed, 49 insertions(+), 55 deletions(-) diff --git a/src/Action/ActionController.ts b/src/Action/ActionController.ts index 9aca21e..824f34f 100644 --- a/src/Action/ActionController.ts +++ b/src/Action/ActionController.ts @@ -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'); + } + } } diff --git a/src/Action/BuildBuildingAction.ts b/src/Action/BuildBuildingAction.ts index 4212cd6..a14d9ea 100644 --- a/src/Action/BuildBuildingAction.ts +++ b/src/Action/BuildBuildingAction.ts @@ -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 { + 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; } diff --git a/src/Action/CheckBuildingRemainingTimeAction.ts b/src/Action/CheckBuildingRemainingTimeAction.ts index 7059e09..5d458c1 100644 --- a/src/Action/CheckBuildingRemainingTimeAction.ts +++ b/src/Action/CheckBuildingRemainingTimeAction.ts @@ -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 { 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'); } } diff --git a/src/Action/UpgradeBuildingAction.ts b/src/Action/UpgradeBuildingAction.ts index acca62e..226b0e9 100644 --- a/src/Action/UpgradeBuildingAction.ts +++ b/src/Action/UpgradeBuildingAction.ts @@ -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 { - 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; } diff --git a/src/Errors.ts b/src/Errors.ts index 0d79334..f7c1e0b 100644 --- a/src/Errors.ts +++ b/src/Errors.ts @@ -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); - } -} diff --git a/src/Executor.ts b/src/Executor.ts index 123a134..1ec7fdf 100644 --- a/src/Executor.ts +++ b/src/Executor.ts @@ -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; diff --git a/src/Scheduler.ts b/src/Scheduler.ts index e91d5d3..ff155e4 100644 --- a/src/Scheduler.ts +++ b/src/Scheduler.ts @@ -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) - ); - } - - postponeBuildingsInVillage(villageId: number, seconds: number) { - this.taskQueue.modify( - t => isBuildingTask(t.name) && sameVillage(villageId, t.args), - t => withTime(t, timestamp() + seconds) - ); + postponeTask(taskId: TaskId, seconds: number) { + const task = this.taskQueue.seeItems().find(t => t.id === taskId); + if (!task) { + return; + } + if (isBuildingTask(task.name) && task.args.villageId) { + this.taskQueue.modify( + 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 {