diff --git a/src/Action/ActionController.ts b/src/Action/ActionController.ts index c1724da..4242ae6 100644 --- a/src/Action/ActionController.ts +++ b/src/Action/ActionController.ts @@ -1,6 +1,35 @@ import { Args } from '../Common'; import { Task } from '../Storage/TaskQueue'; +import { GameState } from '../Storage/GameState'; +import Scheduler from '../Scheduler'; -export default abstract class ActionController { - abstract async run(args: Args, task: Task); +const actionMap: { [name: string]: Function | undefined } = {}; + +export function registerAction(constructor: Function) { + console.log('REGISTER ACTION', constructor.name); + actionMap[constructor.name] = constructor; +} + +export function createAction( + name: string, + state: GameState, + scheduler: Scheduler +): ActionController | undefined { + const storedFunction = actionMap[name]; + if (storedFunction === undefined) { + return undefined; + } + const constructor = (storedFunction as unknown) as typeof ActionController; + return new constructor(state, scheduler); +} + +export class ActionController { + protected state: GameState; + protected scheduler: Scheduler; + constructor(state: GameState, scheduler: Scheduler) { + this.state = state; + this.scheduler = scheduler; + } + + async run(args: Args, task: Task) {} } diff --git a/src/Action/CheckBuildingRemainingTimeAction.ts b/src/Action/CheckBuildingRemainingTimeAction.ts index 5035607..b33d376 100644 --- a/src/Action/CheckBuildingRemainingTimeAction.ts +++ b/src/Action/CheckBuildingRemainingTimeAction.ts @@ -1,11 +1,10 @@ -import ActionController from './ActionController'; +import { ActionController, registerAction } from './ActionController'; import { Args } from '../Common'; import { Task } from '../Storage/TaskQueue'; import { BuildingQueueFullError } from '../Errors'; -export default class CheckBuildingRemainingTimeAction extends ActionController { - static NAME = 'check_building_remaining_time'; - +@registerAction +export class CheckBuildingRemainingTimeAction extends ActionController { async run(args: Args, task: Task): Promise { const timer = jQuery('.buildDuration .timer'); if (timer.length === 1) { diff --git a/src/Action/ClickButtonAction.ts b/src/Action/ClickButtonAction.ts index 974f6bd..3459a71 100644 --- a/src/Action/ClickButtonAction.ts +++ b/src/Action/ClickButtonAction.ts @@ -1,9 +1,9 @@ -import ActionController from './ActionController'; +import { ActionController, registerAction } from './ActionController'; import { Args } from '../Common'; import { Task } from '../Storage/TaskQueue'; -export default class ClickButtonAction extends ActionController { - static NAME = 'click_button'; +@registerAction +export class ClickButtonAction extends ActionController { async run(args: Args, task: Task): Promise { const el = jQuery(args.selector); if (el.length === 1) { diff --git a/src/Action/CompleteTaskAction.ts b/src/Action/CompleteTaskAction.ts index 59a0dd5..06234bf 100644 --- a/src/Action/CompleteTaskAction.ts +++ b/src/Action/CompleteTaskAction.ts @@ -1,16 +1,9 @@ -import ActionController from './ActionController'; +import { ActionController, registerAction } from './ActionController'; import { Args } from '../Common'; import { Task } from '../Storage/TaskQueue'; -import Scheduler from '../Scheduler'; -export default class CompleteTaskAction extends ActionController { - static NAME = 'complete_task'; - private scheduler: Scheduler; - - constructor(scheduler: Scheduler) { - super(); - this.scheduler = scheduler; - } +@registerAction +export class CompleteTaskAction extends ActionController { async run(args: Args, task: Task): Promise { this.scheduler.completeTask(task.id); } diff --git a/src/Action/GoToPageAction.ts b/src/Action/GoToPageAction.ts index 844d310..f910e86 100644 --- a/src/Action/GoToPageAction.ts +++ b/src/Action/GoToPageAction.ts @@ -1,9 +1,9 @@ -import ActionController from './ActionController'; +import { ActionController, registerAction } from './ActionController'; import { Args } from '../Common'; import { Task } from '../Storage/TaskQueue'; -export default class GoToPageAction extends ActionController { - static NAME = 'go_to_page'; +@registerAction +export class GoToPageAction extends ActionController { async run(args: Args, task: Task): Promise { window.location.assign(args.path); } diff --git a/src/Action/GrabHeroAttributesAction.ts b/src/Action/GrabHeroAttributesAction.ts index 9ebca22..42ab785 100644 --- a/src/Action/GrabHeroAttributesAction.ts +++ b/src/Action/GrabHeroAttributesAction.ts @@ -1,18 +1,10 @@ -import ActionController from './ActionController'; +import { ActionController, registerAction } from './ActionController'; import { Args } from '../Common'; import { Task } from '../Storage/TaskQueue'; import { ActionError } from '../Errors'; -import { GameState } from '../Storage/GameState'; - -export default class GrabHeroAttributesAction extends ActionController { - static NAME = 'grab_hero_attributes'; - private state: GameState; - - constructor(state: GameState) { - super(); - this.state = state; - } +@registerAction +export class GrabHeroAttributesAction extends ActionController { async run(args: Args, task: Task): Promise { const healthElement = jQuery( '#attributes .attribute.health .powervalue .value' diff --git a/src/Action/SendOnAdventureAction.ts b/src/Action/SendOnAdventureAction.ts index d3b8351..9bd2013 100644 --- a/src/Action/SendOnAdventureAction.ts +++ b/src/Action/SendOnAdventureAction.ts @@ -1,7 +1,6 @@ -import ActionController from './ActionController'; +import { ActionController, registerAction } from './ActionController'; import { Args } from '../Common'; import { Task } from '../Storage/TaskQueue'; -import { GameState } from '../Storage/GameState'; import { trimPrefix } from '../utils'; import { AbortTaskError } from '../Errors'; @@ -13,15 +12,8 @@ interface Adventure { level: number; } -export default class SendOnAdventureAction extends ActionController { - static NAME = 'send_on_adventure'; - private state: GameState; - - constructor(state: GameState) { - super(); - this.state = state; - } - +@registerAction +export class SendOnAdventureAction extends ActionController { async run(args: Args, task: Task): Promise { const adventures = this.findAdventures(); diff --git a/src/Action/UpgradeBuildingAction.ts b/src/Action/UpgradeBuildingAction.ts index 89b2b1a..8eaff5c 100644 --- a/src/Action/UpgradeBuildingAction.ts +++ b/src/Action/UpgradeBuildingAction.ts @@ -1,11 +1,10 @@ -import ActionController from './ActionController'; +import { ActionController, registerAction } from './ActionController'; import { Args } from '../Common'; import { TryLaterError } from '../Errors'; -import Scheduler from '../Scheduler'; import { Task } from '../Storage/TaskQueue'; -export default class UpgradeBuildingAction extends ActionController { - static NAME = 'upgrade_building'; +@registerAction +export class UpgradeBuildingAction extends ActionController { async run(args: Args, task: Task): Promise { const btn = jQuery( '.upgradeButtonsContainer .section1 button.green.build' diff --git a/src/Scheduler.ts b/src/Scheduler.ts index 8921060..edf6564 100644 --- a/src/Scheduler.ts +++ b/src/Scheduler.ts @@ -1,25 +1,18 @@ import { markPage, sleepShort, timestamp } from './utils'; import UpgradeBuildingTask from './Task/UpgradeBuildingTask'; -import UpgradeBuildingAction from './Action/UpgradeBuildingAction'; import { AbortTaskError, BuildingQueueFullError, TryLaterError, } from './Errors'; -import { TaskQueue, TaskList, Task, TaskId } from './Storage/TaskQueue'; +import { Task, TaskId, TaskList, TaskQueue } from './Storage/TaskQueue'; import ActionQueue from './Storage/ActionQueue'; import { Args, Command } from './Common'; import TaskQueueRenderer from './TaskQueueRenderer'; -import ActionController from './Action/ActionController'; +import { ActionController, createAction } from './Action/ActionController'; import TaskController from './Task/TaskController'; -import GoToPageAction from './Action/GoToPageAction'; -import CheckBuildingRemainingTimeAction from './Action/CheckBuildingRemainingTimeAction'; import SendOnAdventureTask from './Task/SendOnAdventureTask'; -import GrabHeroAttributesAction from './Action/GrabHeroAttributesAction'; import { GameState } from './Storage/GameState'; -import CompleteTaskAction from './Action/CompleteTaskAction'; -import SendOnAdventureAction from './Action/SendOnAdventureAction'; -import ClickButtonAction from './Action/ClickButtonAction'; export default class Scheduler { private readonly version: string; @@ -91,7 +84,12 @@ export default class Scheduler { private async processTaskCommand(task: Task) { const taskController = this.createTaskControllerByName(task.cmd.name); - this.log('PROCESS TASK', task.cmd.name, task, taskController); + this.log( + 'PROCESS TASK', + taskController?.constructor.name, + task, + taskController + ); if (taskController) { taskController.run(task); } @@ -99,7 +97,11 @@ export default class Scheduler { private async processActionCommand(cmd: Command, task: Task) { const actionController = this.createActionControllerByName(cmd.name); - this.log('PROCESS ACTION', cmd.name, actionController); + this.log( + 'PROCESS ACTION', + actionController?.constructor.name, + actionController + ); if (actionController) { await this.runAction(actionController, cmd.args, task); } @@ -136,31 +138,14 @@ export default class Scheduler { } private createActionControllerByName( - actonName: string + actionName: string ): ActionController | undefined { - if (actonName === GoToPageAction.NAME) { - return new GoToPageAction(); + const action = createAction(actionName, this.gameState, this); + if (!action) { + this.logError('ACTION NOT FOUND', actionName); + return undefined; } - if (actonName === ClickButtonAction.NAME) { - return new ClickButtonAction(); - } - if (actonName === CompleteTaskAction.NAME) { - return new CompleteTaskAction(this); - } - if (actonName === UpgradeBuildingAction.NAME) { - return new UpgradeBuildingAction(); - } - if (actonName === CheckBuildingRemainingTimeAction.NAME) { - return new CheckBuildingRemainingTimeAction(); - } - if (actonName === GrabHeroAttributesAction.NAME) { - return new GrabHeroAttributesAction(this.gameState); - } - if (actonName === SendOnAdventureAction.NAME) { - return new SendOnAdventureAction(this.gameState); - } - this.logError('ACTION NOT FOUND', actonName); - return undefined; + return action; } private async runAction(action: ActionController, args: Args, task: Task) { diff --git a/src/Task/SendOnAdventureTask.ts b/src/Task/SendOnAdventureTask.ts index 3c821c8..e03a49e 100644 --- a/src/Task/SendOnAdventureTask.ts +++ b/src/Task/SendOnAdventureTask.ts @@ -2,11 +2,11 @@ import Scheduler from '../Scheduler'; import { Args, Command } from '../Common'; import { Task } from '../Storage/TaskQueue'; import TaskController from './TaskController'; -import GoToPageAction from '../Action/GoToPageAction'; -import GrabHeroAttributesAction from '../Action/GrabHeroAttributesAction'; -import CompleteTaskAction from '../Action/CompleteTaskAction'; -import SendOnAdventureAction from '../Action/SendOnAdventureAction'; -import ClickButtonAction from '../Action/ClickButtonAction'; +import { GoToPageAction } from '../Action/GoToPageAction'; +import { GrabHeroAttributesAction } from '../Action/GrabHeroAttributesAction'; +import { CompleteTaskAction } from '../Action/CompleteTaskAction'; +import { SendOnAdventureAction } from '../Action/SendOnAdventureAction'; +import { ClickButtonAction } from '../Action/ClickButtonAction'; export default class SendOnAdventureTask extends TaskController { static NAME = 'send_on_adventure'; @@ -17,25 +17,21 @@ export default class SendOnAdventureTask extends TaskController { this.scheduler = scheduler; } - name(): string { - return SendOnAdventureTask.NAME; - } - run(task: Task) { const args: Args = { ...task.cmd.args, taskId: task.id }; this.scheduler.scheduleActions([ - new Command(GoToPageAction.NAME, { ...args, path: 'hero.php' }), - new Command(GrabHeroAttributesAction.NAME, args), - new Command(GoToPageAction.NAME, { + new Command(GoToPageAction.name, { ...args, path: 'hero.php' }), + new Command(GrabHeroAttributesAction.name, args), + new Command(GoToPageAction.name, { ...args, path: '/hero.php?t=3', }), - new Command(SendOnAdventureAction.NAME, args), - new Command(ClickButtonAction.NAME, { + new Command(SendOnAdventureAction.name, args), + new Command(ClickButtonAction.name, { ...args, selector: '.adventureSendButton button', }), - new Command(CompleteTaskAction.NAME, args), + new Command(CompleteTaskAction.name, args), ]); } } diff --git a/src/Task/TaskController.ts b/src/Task/TaskController.ts index dbb7fe3..55a8dd3 100644 --- a/src/Task/TaskController.ts +++ b/src/Task/TaskController.ts @@ -1,6 +1,5 @@ import { Task } from '../Storage/TaskQueue'; export default abstract class TaskController { - abstract name(): string; abstract run(task: Task); } diff --git a/src/Task/UpgradeBuildingTask.ts b/src/Task/UpgradeBuildingTask.ts index d9fcd25..2824753 100644 --- a/src/Task/UpgradeBuildingTask.ts +++ b/src/Task/UpgradeBuildingTask.ts @@ -1,11 +1,11 @@ import Scheduler from '../Scheduler'; -import UpgradeBuildingAction from '../Action/UpgradeBuildingAction'; +import { UpgradeBuildingAction } from '../Action/UpgradeBuildingAction'; import { Args, Command } from '../Common'; import { Task } from '../Storage/TaskQueue'; import TaskController from './TaskController'; -import GoToPageAction from '../Action/GoToPageAction'; -import CheckBuildingRemainingTimeAction from '../Action/CheckBuildingRemainingTimeAction'; -import CompleteTaskAction from '../Action/CompleteTaskAction'; +import { GoToPageAction } from '../Action/GoToPageAction'; +import { CheckBuildingRemainingTimeAction } from '../Action/CheckBuildingRemainingTimeAction'; +import { CompleteTaskAction } from '../Action/CompleteTaskAction'; export default class UpgradeBuildingTask extends TaskController { static NAME = 'upgrade_building'; @@ -16,22 +16,18 @@ export default class UpgradeBuildingTask extends TaskController { this.scheduler = scheduler; } - name(): string { - return UpgradeBuildingTask.NAME; - } - run(task: Task) { console.log('RUN', UpgradeBuildingTask.NAME, 'with', task); const args: Args = { ...task.cmd.args, taskId: task.id }; this.scheduler.scheduleActions([ - new Command(GoToPageAction.NAME, { ...args, path: '/dorf1.php' }), - new Command(CheckBuildingRemainingTimeAction.NAME, args), - new Command(GoToPageAction.NAME, { + new Command(GoToPageAction.name, { ...args, path: '/dorf1.php' }), + new Command(CheckBuildingRemainingTimeAction.name, args), + new Command(GoToPageAction.name, { ...args, path: '/build.php?id=' + args.id, }), - new Command(UpgradeBuildingAction.NAME, args), - new Command(CompleteTaskAction.NAME, args), + new Command(UpgradeBuildingAction.name, args), + new Command(CompleteTaskAction.name, args), ]); } } diff --git a/tsconfig.json b/tsconfig.json index cb28352..b1e4339 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "allowJs": true, + "experimentalDecorators": true, "isolatedModules": true, "module": "commonjs", "outDir": "./dist",