From 473e3572e3bbc9fbc1d2c621ee85793ce29b9909 Mon Sep 17 00:00:00 2001
From: Anton Vakhrushev <anwinged@ya.ru>
Date: Thu, 2 Apr 2020 10:57:21 +0300
Subject: [PATCH] Add ability to check building queue

---
 .../CheckBuildingRemainingTimeAction.ts       | 21 ++++++
 ...ourceFieldsAction.ts => GoToPageAction.ts} |  6 +-
 src/Action/StoreRemainingBuildTimeAction.ts   | 15 -----
 src/GameState.ts                              |  1 +
 src/Scheduler.ts                              | 67 +++++++++----------
 src/Task/UpgradeBuildingTask.ts               |  4 ++
 src/utils.ts                                  |  4 +-
 7 files changed, 62 insertions(+), 56 deletions(-)
 create mode 100644 src/Action/CheckBuildingRemainingTimeAction.ts
 rename src/Action/{GoToResourceFieldsAction.ts => GoToPageAction.ts} (54%)
 delete mode 100644 src/Action/StoreRemainingBuildTimeAction.ts
 create mode 100644 src/GameState.ts

diff --git a/src/Action/CheckBuildingRemainingTimeAction.ts b/src/Action/CheckBuildingRemainingTimeAction.ts
new file mode 100644
index 0000000..d2decff
--- /dev/null
+++ b/src/Action/CheckBuildingRemainingTimeAction.ts
@@ -0,0 +1,21 @@
+import ActionController from './ActionController';
+import { Args } from '../Common';
+import { Task } from '../Storage/TaskQueue';
+import { TryLaterError } from '../Errors';
+
+export default class CheckBuildingRemainingTimeAction extends ActionController {
+    static NAME = 'check_building_remaining_time';
+
+    async run(args: Args, task: Task): Promise<any> {
+        const timer = jQuery('.buildDuration .timer');
+        if (timer.length === 1) {
+            const remainingSeconds = Number(timer.attr('value'));
+            if (remainingSeconds > 0) {
+                throw new TryLaterError(
+                    remainingSeconds + 1,
+                    'Building queue is full'
+                );
+            }
+        }
+    }
+}
diff --git a/src/Action/GoToResourceFieldsAction.ts b/src/Action/GoToPageAction.ts
similarity index 54%
rename from src/Action/GoToResourceFieldsAction.ts
rename to src/Action/GoToPageAction.ts
index f12c9ad..844d310 100644
--- a/src/Action/GoToResourceFieldsAction.ts
+++ b/src/Action/GoToPageAction.ts
@@ -2,9 +2,9 @@ import ActionController from './ActionController';
 import { Args } from '../Common';
 import { Task } from '../Storage/TaskQueue';
 
-export default class GoToResourceFieldsAction extends ActionController {
-    static NAME = 'go_to_resource_fields';
+export default class GoToPageAction extends ActionController {
+    static NAME = 'go_to_page';
     async run(args: Args, task: Task): Promise<any> {
-        window.location.assign('/dorf1.php');
+        window.location.assign(args.path);
     }
 }
diff --git a/src/Action/StoreRemainingBuildTimeAction.ts b/src/Action/StoreRemainingBuildTimeAction.ts
deleted file mode 100644
index be876bc..0000000
--- a/src/Action/StoreRemainingBuildTimeAction.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import ActionController from './ActionController';
-import { Args } from '../Common';
-import { Task } from '../Storage/TaskQueue';
-
-export default class StoreRemainingBuildTimeAction extends ActionController {
-    static NAME = 'store_remaining_build_time';
-
-    async run(args: Args, task: Task): Promise<any> {
-        const timer = jQuery('.buildDuration .timer');
-        // if (timer.length === 1) {
-        //     const remainingSeconds = +timer.val();
-        // }
-        return null;
-    }
-}
diff --git a/src/GameState.ts b/src/GameState.ts
new file mode 100644
index 0000000..65205ac
--- /dev/null
+++ b/src/GameState.ts
@@ -0,0 +1 @@
+export default class GameState {}
diff --git a/src/Scheduler.ts b/src/Scheduler.ts
index a02e670..64602ae 100644
--- a/src/Scheduler.ts
+++ b/src/Scheduler.ts
@@ -1,4 +1,4 @@
-import { markPage, sleepLong, sleepShort, timestamp } from './utils';
+import { markPage, sleepShort, timestamp } from './utils';
 import UpgradeBuildingTask from './Task/UpgradeBuildingTask';
 import GoToBuildingAction from './Action/GoToBuildingAction';
 import UpgradeBuildingAction from './Action/UpgradeBuildingAction';
@@ -9,41 +9,38 @@ import { Args, Command } from './Common';
 import TaskQueueRenderer from './TaskQueueRenderer';
 import ActionController from './Action/ActionController';
 import TaskController from './Task/TaskController';
-
-enum SleepType {
-    Long,
-    Short,
-}
+import GoToPageAction from './Action/GoToPageAction';
+import CheckBuildingRemainingTimeAction from './Action/CheckBuildingRemainingTimeAction';
 
 export default class Scheduler {
     private readonly version: string;
     private taskQueue: TaskQueue;
     private actionQueue: ActionQueue;
-    private sleepType: SleepType;
 
     constructor(version: string) {
         this.version = version;
         this.taskQueue = new TaskQueue();
         this.actionQueue = new ActionQueue();
-        this.sleepType = SleepType.Short;
     }
 
     async run() {
         await sleepShort();
         markPage('Executor', this.version);
 
-        setInterval(() => {
-            this.log('RENDER TASK QUEUE');
-            new TaskQueueRenderer().render(this.taskQueue.seeItems());
-        }, 1000);
+        setInterval(() => this.renderTaskQueue(), 5000);
 
         while (true) {
             await this.doLoopStep();
         }
     }
 
+    private renderTaskQueue() {
+        this.log('RENDER TASK QUEUE');
+        new TaskQueueRenderer().render(this.taskQueue.seeItems());
+    }
+
     private async doLoopStep() {
-        await this.sleep();
+        await sleepShort();
         const currentTs = timestamp();
         const taskCommand = this.taskQueue.get(currentTs);
 
@@ -68,33 +65,22 @@ export default class Scheduler {
         }
     }
 
+    private async processTaskCommand(task: Task) {
+        const taskController = this.createTaskControllerByName(task.cmd.name);
+        this.log('PROCESS TASK CONTROLLER', taskController, task);
+        if (taskController) {
+            taskController.run(task);
+        }
+    }
+
     private async processActionCommand(cmd: Command, task: Task) {
         const actionController = this.createActionControllerByName(cmd.name);
-        this.log('PROCESS ACTION CTR', actionController);
+        this.log('PROCESS ACTION CONTROLLER', cmd.name, actionController);
         if (actionController) {
             await this.runAction(actionController, cmd.args, task);
         }
     }
 
-    private async processTaskCommand(task: Task) {
-        const taskController = this.createTaskControllerByName(task.cmd.name);
-        this.log('PROCESS TASK CTR', taskController, task);
-        taskController?.run(task);
-    }
-
-    private async sleep() {
-        if (this.sleepType === SleepType.Long) {
-            await sleepLong();
-        } else {
-            await sleepShort();
-        }
-        this.sleepType = SleepType.Short;
-    }
-
-    private nextSleepLong() {
-        this.sleepType = SleepType.Long;
-    }
-
     getTaskItems(): TaskList {
         return this.taskQueue.seeItems();
     }
@@ -119,7 +105,7 @@ export default class Scheduler {
             case UpgradeBuildingTask.NAME:
                 return new UpgradeBuildingTask(this);
         }
-        this.log('UNKNOWN TASK', taskName);
+        this.logError('TASK NOT FOUND', taskName);
         return undefined;
     }
 
@@ -128,7 +114,6 @@ export default class Scheduler {
         if (actionItem === undefined) {
             return undefined;
         }
-        this.log('UNKNOWN ACTION', actionItem.name);
         return actionItem;
     }
 
@@ -141,6 +126,13 @@ export default class Scheduler {
         if (actonName === UpgradeBuildingAction.NAME) {
             return new UpgradeBuildingAction(this);
         }
+        if (actonName === GoToPageAction.NAME) {
+            return new GoToPageAction();
+        }
+        if (actonName === CheckBuildingRemainingTimeAction.NAME) {
+            return new CheckBuildingRemainingTimeAction();
+        }
+        this.logError('ACTION NOT FOUND', actonName);
         return undefined;
     }
 
@@ -153,7 +145,6 @@ export default class Scheduler {
                 console.warn('TRY', task.id, 'AFTER', e.seconds);
                 this.actionQueue.clear();
                 this.taskQueue.postpone(task.id, timestamp() + e.seconds);
-                this.nextSleepLong();
             }
         }
     }
@@ -161,4 +152,8 @@ export default class Scheduler {
     private log(...args) {
         console.log('SCHEDULER:', ...args);
     }
+
+    private logError(...args) {
+        console.error(...args);
+    }
 }
diff --git a/src/Task/UpgradeBuildingTask.ts b/src/Task/UpgradeBuildingTask.ts
index 7ec9468..44673f4 100644
--- a/src/Task/UpgradeBuildingTask.ts
+++ b/src/Task/UpgradeBuildingTask.ts
@@ -4,6 +4,8 @@ import UpgradeBuildingAction from '../Action/UpgradeBuildingAction';
 import { Command } from '../Common';
 import { Task } from '../Storage/TaskQueue';
 import TaskController from './TaskController';
+import GoToPageAction from '../Action/GoToPageAction';
+import CheckBuildingRemainingTimeAction from '../Action/CheckBuildingRemainingTimeAction';
 
 export default class UpgradeBuildingTask extends TaskController {
     static NAME = 'upgrade_building';
@@ -18,6 +20,8 @@ export default class UpgradeBuildingTask extends TaskController {
         console.log('RUN', UpgradeBuildingTask.NAME, 'with', task);
         const 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(GoToBuildingAction.NAME, args),
             new Command(UpgradeBuildingAction.NAME, args),
         ]);
diff --git a/src/utils.ts b/src/utils.ts
index 8e00531..f08d7e2 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -8,13 +8,13 @@ export function sleep(ms: number) {
 
 export async function sleepShort() {
     let ms = 3000 + Math.random() * 1000;
-    console.log('SLEEP SHORT', Math.round(ms));
+    console.log('SLEEP SHORT', Math.round(ms / 1000));
     return await sleep(ms);
 }
 
 export async function sleepLong() {
     let ms = 120_000 + Math.random() * 300_000;
-    console.log('SLEEP LONG', Math.round(ms));
+    console.log('SLEEP LONG', Math.round(ms / 1000));
     return await sleep(ms);
 }