Add hero adventures task
This commit is contained in:
parent
711c8a414b
commit
4b1e7cb676
14
src/Action/ClickButtonAction.ts
Normal file
14
src/Action/ClickButtonAction.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import ActionController from './ActionController';
|
||||||
|
import { Args } from '../Common';
|
||||||
|
import { Task } from '../Storage/TaskQueue';
|
||||||
|
|
||||||
|
export default class ClickButtonAction extends ActionController {
|
||||||
|
static NAME = 'click_button';
|
||||||
|
async run(args: Args, task: Task): Promise<any> {
|
||||||
|
const el = jQuery(args.selector);
|
||||||
|
if (el.length === 1) {
|
||||||
|
console.log('CLICK BUTTON', el);
|
||||||
|
el.trigger('click');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
src/Action/CompleteTaskAction.ts
Normal file
17
src/Action/CompleteTaskAction.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import ActionController 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;
|
||||||
|
}
|
||||||
|
async run(args: Args, task: Task): Promise<any> {
|
||||||
|
this.scheduler.completeTask(task.id);
|
||||||
|
}
|
||||||
|
}
|
35
src/Action/GrabHeroAttributesAction.ts
Normal file
35
src/Action/GrabHeroAttributesAction.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import ActionController 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(args: Args, task: Task): Promise<any> {
|
||||||
|
const healthElement = jQuery(
|
||||||
|
'#attributes .attribute.health .powervalue .value'
|
||||||
|
);
|
||||||
|
if (healthElement.length !== 1) {
|
||||||
|
throw new ActionError(task.id, 'Health dom element not found');
|
||||||
|
}
|
||||||
|
const text = healthElement.text();
|
||||||
|
let normalized = text.replace(/[^0-9]/g, '');
|
||||||
|
const value = Number(normalized);
|
||||||
|
if (isNaN(value)) {
|
||||||
|
throw new ActionError(
|
||||||
|
task.id,
|
||||||
|
`Health value "${text}" (${normalized}) couldn't be converted to number`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state.set('hero', { health: value });
|
||||||
|
}
|
||||||
|
}
|
71
src/Action/SendOnAdventureAction.ts
Normal file
71
src/Action/SendOnAdventureAction.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import ActionController from './ActionController';
|
||||||
|
import { Args } from '../Common';
|
||||||
|
import { Task } from '../Storage/TaskQueue';
|
||||||
|
import { GameState } from '../Storage/GameState';
|
||||||
|
import { trimPrefix } from '../utils';
|
||||||
|
import { AbortTaskError } from '../Errors';
|
||||||
|
|
||||||
|
const HARD = 0;
|
||||||
|
const NORMAL = 3;
|
||||||
|
|
||||||
|
interface Adventure {
|
||||||
|
el: HTMLElement;
|
||||||
|
level: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class SendOnAdventureAction extends ActionController {
|
||||||
|
static NAME = 'send_on_adventure';
|
||||||
|
private state: GameState;
|
||||||
|
|
||||||
|
constructor(state: GameState) {
|
||||||
|
super();
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(args: Args, task: Task): Promise<any> {
|
||||||
|
const adventures = this.findAdventures();
|
||||||
|
|
||||||
|
console.log('ADVENTURES', adventures);
|
||||||
|
|
||||||
|
adventures.sort((x, y) => x.level - y.level);
|
||||||
|
|
||||||
|
const easiest = adventures.shift();
|
||||||
|
const hero = this.state.get('hero') || {};
|
||||||
|
|
||||||
|
console.log('EASIEST', easiest);
|
||||||
|
console.log('HERO', hero);
|
||||||
|
|
||||||
|
if (easiest && hero.health) {
|
||||||
|
if (easiest.level === NORMAL && hero.health >= 30) {
|
||||||
|
return jQuery(easiest.el)
|
||||||
|
.find('td.goTo .gotoAdventure')
|
||||||
|
.trigger('click');
|
||||||
|
}
|
||||||
|
if (easiest.level === HARD && hero.health >= 50) {
|
||||||
|
return jQuery(easiest.el)
|
||||||
|
.find('td.goTo .gotoAdventure')
|
||||||
|
.trigger('click');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new AbortTaskError(task.id, 'No suitable adventure');
|
||||||
|
}
|
||||||
|
|
||||||
|
private findAdventures(): Array<Adventure> {
|
||||||
|
const adventures: Array<Adventure> = [];
|
||||||
|
|
||||||
|
jQuery('tr[id^=adventure]').each((index, el) => {
|
||||||
|
const imgClass =
|
||||||
|
jQuery(el)
|
||||||
|
.find('.difficulty img')
|
||||||
|
.attr('class')
|
||||||
|
?.toString() || '';
|
||||||
|
const level = Number(trimPrefix(imgClass, 'adventureDifficulty'));
|
||||||
|
if (!isNaN(level)) {
|
||||||
|
adventures.push({ el, level: level });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return adventures;
|
||||||
|
}
|
||||||
|
}
|
@ -6,23 +6,15 @@ import { Task } from '../Storage/TaskQueue';
|
|||||||
|
|
||||||
export default class UpgradeBuildingAction extends ActionController {
|
export default class UpgradeBuildingAction extends ActionController {
|
||||||
static NAME = 'upgrade_building';
|
static NAME = 'upgrade_building';
|
||||||
private scheduler: Scheduler;
|
|
||||||
|
|
||||||
constructor(scheduler: Scheduler) {
|
|
||||||
super();
|
|
||||||
this.scheduler = scheduler;
|
|
||||||
}
|
|
||||||
|
|
||||||
async run(args: Args, task: Task): Promise<any> {
|
async run(args: Args, task: Task): Promise<any> {
|
||||||
const btn = jQuery(
|
const btn = jQuery(
|
||||||
'.upgradeButtonsContainer .section1 button.green.build'
|
'.upgradeButtonsContainer .section1 button.green.build'
|
||||||
);
|
);
|
||||||
if (btn.length === 1) {
|
|
||||||
this.scheduler.completeTask(task.id);
|
if (btn.length !== 1) {
|
||||||
btn.trigger('click');
|
|
||||||
} else {
|
|
||||||
throw new TryLaterError(5 * 60, 'No upgrade button, try later');
|
throw new TryLaterError(5 * 60, 'No upgrade button, try later');
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
btn.trigger('click');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import * as URLParse from 'url-parse';
|
import * as URLParse from 'url-parse';
|
||||||
import { markPage, uniqId, waitForLoad } from './utils';
|
import { markPage, trimPrefix, uniqId, waitForLoad } from './utils';
|
||||||
import Scheduler from './Scheduler';
|
import Scheduler from './Scheduler';
|
||||||
import UpgradeBuildingTask from './Task/UpgradeBuildingTask';
|
import UpgradeBuildingTask from './Task/UpgradeBuildingTask';
|
||||||
import { Command } from './Common';
|
import { Command } from './Common';
|
||||||
|
@ -1,5 +1,23 @@
|
|||||||
import { TaskId } from './Storage/TaskQueue';
|
import { TaskId } from './Storage/TaskQueue';
|
||||||
|
|
||||||
|
export class ActionError extends Error {
|
||||||
|
readonly id: TaskId;
|
||||||
|
constructor(id: TaskId, msg: string = '') {
|
||||||
|
super(msg);
|
||||||
|
this.id = id;
|
||||||
|
Object.setPrototypeOf(this, ActionError.prototype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AbortTaskError extends Error {
|
||||||
|
readonly id: TaskId;
|
||||||
|
constructor(id: TaskId, msg: string = '') {
|
||||||
|
super(msg);
|
||||||
|
this.id = id;
|
||||||
|
Object.setPrototypeOf(this, AbortTaskError.prototype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class TryLaterError extends Error {
|
export class TryLaterError extends Error {
|
||||||
readonly seconds: number;
|
readonly seconds: number;
|
||||||
readonly id: TaskId;
|
readonly id: TaskId;
|
||||||
@ -18,6 +36,6 @@ export class BuildingQueueFullError extends Error {
|
|||||||
super(msg);
|
super(msg);
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.seconds = seconds;
|
this.seconds = seconds;
|
||||||
Object.setPrototypeOf(this, TryLaterError.prototype);
|
Object.setPrototypeOf(this, BuildingQueueFullError.prototype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
export default class GameState {}
|
|
@ -1,7 +1,11 @@
|
|||||||
import { markPage, sleepShort, timestamp } from './utils';
|
import { markPage, sleepShort, timestamp } from './utils';
|
||||||
import UpgradeBuildingTask from './Task/UpgradeBuildingTask';
|
import UpgradeBuildingTask from './Task/UpgradeBuildingTask';
|
||||||
import UpgradeBuildingAction from './Action/UpgradeBuildingAction';
|
import UpgradeBuildingAction from './Action/UpgradeBuildingAction';
|
||||||
import { BuildingQueueFullError, TryLaterError } from './Errors';
|
import {
|
||||||
|
AbortTaskError,
|
||||||
|
BuildingQueueFullError,
|
||||||
|
TryLaterError,
|
||||||
|
} from './Errors';
|
||||||
import { TaskQueue, TaskList, Task, TaskId } from './Storage/TaskQueue';
|
import { TaskQueue, TaskList, Task, TaskId } from './Storage/TaskQueue';
|
||||||
import ActionQueue from './Storage/ActionQueue';
|
import ActionQueue from './Storage/ActionQueue';
|
||||||
import { Args, Command } from './Common';
|
import { Args, Command } from './Common';
|
||||||
@ -10,16 +14,24 @@ import ActionController from './Action/ActionController';
|
|||||||
import TaskController from './Task/TaskController';
|
import TaskController from './Task/TaskController';
|
||||||
import GoToPageAction from './Action/GoToPageAction';
|
import GoToPageAction from './Action/GoToPageAction';
|
||||||
import CheckBuildingRemainingTimeAction from './Action/CheckBuildingRemainingTimeAction';
|
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 {
|
export default class Scheduler {
|
||||||
private readonly version: string;
|
private readonly version: string;
|
||||||
private taskQueue: TaskQueue;
|
private taskQueue: TaskQueue;
|
||||||
private actionQueue: ActionQueue;
|
private actionQueue: ActionQueue;
|
||||||
|
private gameState: GameState;
|
||||||
|
|
||||||
constructor(version: string) {
|
constructor(version: string) {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.taskQueue = new TaskQueue();
|
this.taskQueue = new TaskQueue();
|
||||||
this.actionQueue = new ActionQueue();
|
this.actionQueue = new ActionQueue();
|
||||||
|
this.gameState = new GameState();
|
||||||
}
|
}
|
||||||
|
|
||||||
async run() {
|
async run() {
|
||||||
@ -27,7 +39,10 @@ export default class Scheduler {
|
|||||||
markPage('Executor', this.version);
|
markPage('Executor', this.version);
|
||||||
|
|
||||||
this.renderTaskQueue();
|
this.renderTaskQueue();
|
||||||
setInterval(() => this.renderTaskQueue(), 5000);
|
setInterval(() => this.renderTaskQueue(), 5 * 1000);
|
||||||
|
|
||||||
|
this.scheduleHeroAdventure();
|
||||||
|
setInterval(() => this.scheduleHeroAdventure(), 3600 * 1000);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
await this.doLoopStep();
|
await this.doLoopStep();
|
||||||
@ -39,6 +54,15 @@ export default class Scheduler {
|
|||||||
new TaskQueueRenderer().render(this.taskQueue.seeItems());
|
new TaskQueueRenderer().render(this.taskQueue.seeItems());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private scheduleHeroAdventure() {
|
||||||
|
if (!this.taskQueue.hasNamed(SendOnAdventureTask.NAME)) {
|
||||||
|
this.taskQueue.push(
|
||||||
|
new Command(SendOnAdventureTask.NAME, {}),
|
||||||
|
timestamp()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async doLoopStep() {
|
private async doLoopStep() {
|
||||||
await sleepShort();
|
await sleepShort();
|
||||||
const currentTs = timestamp();
|
const currentTs = timestamp();
|
||||||
@ -51,7 +75,7 @@ export default class Scheduler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const actionCommand = this.popActionCommand();
|
const actionCommand = this.actionQueue.pop();
|
||||||
|
|
||||||
this.log('CURRENT TASK', taskCommand);
|
this.log('CURRENT TASK', taskCommand);
|
||||||
this.log('CURRENT ACTION', actionCommand);
|
this.log('CURRENT ACTION', actionCommand);
|
||||||
@ -67,7 +91,7 @@ export default class Scheduler {
|
|||||||
|
|
||||||
private async processTaskCommand(task: Task) {
|
private async processTaskCommand(task: Task) {
|
||||||
const taskController = this.createTaskControllerByName(task.cmd.name);
|
const taskController = this.createTaskControllerByName(task.cmd.name);
|
||||||
this.log('PROCESS TASK CONTROLLER', taskController, task);
|
this.log('PROCESS TASK', task.cmd.name, task, taskController);
|
||||||
if (taskController) {
|
if (taskController) {
|
||||||
taskController.run(task);
|
taskController.run(task);
|
||||||
}
|
}
|
||||||
@ -75,7 +99,7 @@ export default class Scheduler {
|
|||||||
|
|
||||||
private async processActionCommand(cmd: Command, task: Task) {
|
private async processActionCommand(cmd: Command, task: Task) {
|
||||||
const actionController = this.createActionControllerByName(cmd.name);
|
const actionController = this.createActionControllerByName(cmd.name);
|
||||||
this.log('PROCESS ACTION CONTROLLER', cmd.name, actionController);
|
this.log('PROCESS ACTION', cmd.name, actionController);
|
||||||
if (actionController) {
|
if (actionController) {
|
||||||
await this.runAction(actionController, cmd.args, task);
|
await this.runAction(actionController, cmd.args, task);
|
||||||
}
|
}
|
||||||
@ -104,31 +128,37 @@ export default class Scheduler {
|
|||||||
switch (taskName) {
|
switch (taskName) {
|
||||||
case UpgradeBuildingTask.NAME:
|
case UpgradeBuildingTask.NAME:
|
||||||
return new UpgradeBuildingTask(this);
|
return new UpgradeBuildingTask(this);
|
||||||
|
case SendOnAdventureTask.NAME:
|
||||||
|
return new SendOnAdventureTask(this);
|
||||||
}
|
}
|
||||||
this.logError('TASK NOT FOUND', taskName);
|
this.logError('TASK NOT FOUND', taskName);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private popActionCommand(): Command | undefined {
|
|
||||||
const actionItem = this.actionQueue.pop();
|
|
||||||
if (actionItem === undefined) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return actionItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
private createActionControllerByName(
|
private createActionControllerByName(
|
||||||
actonName: string
|
actonName: string
|
||||||
): ActionController | undefined {
|
): ActionController | undefined {
|
||||||
if (actonName === UpgradeBuildingAction.NAME) {
|
|
||||||
return new UpgradeBuildingAction(this);
|
|
||||||
}
|
|
||||||
if (actonName === GoToPageAction.NAME) {
|
if (actonName === GoToPageAction.NAME) {
|
||||||
return new GoToPageAction();
|
return new GoToPageAction();
|
||||||
}
|
}
|
||||||
|
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) {
|
if (actonName === CheckBuildingRemainingTimeAction.NAME) {
|
||||||
return new CheckBuildingRemainingTimeAction();
|
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);
|
this.logError('ACTION NOT FOUND', actonName);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@ -138,14 +168,17 @@ export default class Scheduler {
|
|||||||
await action.run(args, task);
|
await action.run(args, task);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('ACTION ABORTED', e.message);
|
console.warn('ACTION ABORTED', e.message);
|
||||||
|
this.actionQueue.clear();
|
||||||
|
if (e instanceof AbortTaskError) {
|
||||||
|
console.warn('ABORT TASK', e.id);
|
||||||
|
this.completeTask(e.id);
|
||||||
|
}
|
||||||
if (e instanceof TryLaterError) {
|
if (e instanceof TryLaterError) {
|
||||||
console.warn('TRY', task.id, 'AFTER', e.seconds);
|
console.warn('TRY', task.id, 'AFTER', e.seconds);
|
||||||
this.actionQueue.clear();
|
|
||||||
this.taskQueue.postpone(task.id, timestamp() + e.seconds);
|
this.taskQueue.postpone(task.id, timestamp() + e.seconds);
|
||||||
}
|
}
|
||||||
if (e instanceof BuildingQueueFullError) {
|
if (e instanceof BuildingQueueFullError) {
|
||||||
console.warn('BUILDING QUEUE FULL, TRY ALL AFTER', e.seconds);
|
console.warn('BUILDING QUEUE FULL, TRY ALL AFTER', e.seconds);
|
||||||
this.actionQueue.clear();
|
|
||||||
this.taskQueue.modify(
|
this.taskQueue.modify(
|
||||||
t => t.cmd.name === UpgradeBuildingTask.NAME,
|
t => t.cmd.name === UpgradeBuildingTask.NAME,
|
||||||
t => t.withTime(timestamp() + e.seconds)
|
t => t.withTime(timestamp() + e.seconds)
|
||||||
|
34
src/Storage/GameState.ts
Normal file
34
src/Storage/GameState.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
const NAMESPACE = 'game_state:v1';
|
||||||
|
|
||||||
|
function join(x: string, y: string) {
|
||||||
|
return x.replace(/[:]+$/g, '') + ':' + y.replace(/^[:]+/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GameState {
|
||||||
|
get(key: string): any {
|
||||||
|
this.log('GET', key);
|
||||||
|
try {
|
||||||
|
const serialized = localStorage.getItem(join(NAMESPACE, key));
|
||||||
|
return JSON.parse(serialized || 'null');
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof SyntaxError) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
has(key: string): boolean {
|
||||||
|
return localStorage.getItem(join(NAMESPACE, key)) === null;
|
||||||
|
}
|
||||||
|
|
||||||
|
set(key: string, value: any) {
|
||||||
|
let serialized = JSON.stringify(value);
|
||||||
|
this.log('SET', key, serialized);
|
||||||
|
localStorage.setItem(join(NAMESPACE, key), serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
private log(...args) {
|
||||||
|
console.log('GAME STATE:', ...args);
|
||||||
|
}
|
||||||
|
}
|
@ -49,6 +49,15 @@ export class TaskQueue {
|
|||||||
return readyItems[0];
|
return readyItems[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
has(predicate: (t: Task) => boolean): boolean {
|
||||||
|
const [matched, _] = this.split(predicate);
|
||||||
|
return matched.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasNamed(name: string): boolean {
|
||||||
|
return this.has(t => t.cmd.name === name);
|
||||||
|
}
|
||||||
|
|
||||||
modify(predicate: (t: Task) => boolean, modifier: (t: Task) => Task) {
|
modify(predicate: (t: Task) => boolean, modifier: (t: Task) => Task) {
|
||||||
const [matched, other] = this.split(predicate);
|
const [matched, other] = this.split(predicate);
|
||||||
const modified = matched.map(modifier);
|
const modified = matched.map(modifier);
|
||||||
|
41
src/Task/SendOnAdventureTask.ts
Normal file
41
src/Task/SendOnAdventureTask.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
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';
|
||||||
|
|
||||||
|
export default class SendOnAdventureTask extends TaskController {
|
||||||
|
static NAME = 'send_on_adventure';
|
||||||
|
private scheduler: Scheduler;
|
||||||
|
|
||||||
|
constructor(scheduler: Scheduler) {
|
||||||
|
super();
|
||||||
|
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, {
|
||||||
|
...args,
|
||||||
|
path: '/hero.php?t=3',
|
||||||
|
}),
|
||||||
|
new Command(SendOnAdventureAction.NAME, args),
|
||||||
|
new Command(ClickButtonAction.NAME, {
|
||||||
|
...args,
|
||||||
|
selector: '.adventureSendButton button',
|
||||||
|
}),
|
||||||
|
new Command(CompleteTaskAction.NAME, args),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import { Task } from '../Storage/TaskQueue';
|
import { Task } from '../Storage/TaskQueue';
|
||||||
|
|
||||||
export default abstract class TaskController {
|
export default abstract class TaskController {
|
||||||
|
abstract name(): string;
|
||||||
abstract run(task: Task);
|
abstract run(task: Task);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import { Task } from '../Storage/TaskQueue';
|
|||||||
import TaskController from './TaskController';
|
import TaskController from './TaskController';
|
||||||
import GoToPageAction from '../Action/GoToPageAction';
|
import GoToPageAction from '../Action/GoToPageAction';
|
||||||
import CheckBuildingRemainingTimeAction from '../Action/CheckBuildingRemainingTimeAction';
|
import CheckBuildingRemainingTimeAction from '../Action/CheckBuildingRemainingTimeAction';
|
||||||
|
import CompleteTaskAction from '../Action/CompleteTaskAction';
|
||||||
|
|
||||||
export default class UpgradeBuildingTask extends TaskController {
|
export default class UpgradeBuildingTask extends TaskController {
|
||||||
static NAME = 'upgrade_building';
|
static NAME = 'upgrade_building';
|
||||||
@ -15,6 +16,10 @@ export default class UpgradeBuildingTask extends TaskController {
|
|||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name(): string {
|
||||||
|
return UpgradeBuildingTask.NAME;
|
||||||
|
}
|
||||||
|
|
||||||
run(task: Task) {
|
run(task: Task) {
|
||||||
console.log('RUN', UpgradeBuildingTask.NAME, 'with', task);
|
console.log('RUN', UpgradeBuildingTask.NAME, 'with', task);
|
||||||
const args: Args = { ...task.cmd.args, taskId: task.id };
|
const args: Args = { ...task.cmd.args, taskId: task.id };
|
||||||
@ -26,6 +31,7 @@ export default class UpgradeBuildingTask extends TaskController {
|
|||||||
path: '/build.php?id=' + args.id,
|
path: '/build.php?id=' + args.id,
|
||||||
}),
|
}),
|
||||||
new Command(UpgradeBuildingAction.NAME, args),
|
new Command(UpgradeBuildingAction.NAME, args),
|
||||||
|
new Command(CompleteTaskAction.NAME, args),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,10 @@ export function timestamp(): number {
|
|||||||
return Math.floor(Date.now() / 1000);
|
return Math.floor(Date.now() / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function trimPrefix(text: string, prefix: string): string {
|
||||||
|
return text.startsWith(prefix) ? text.substr(prefix.length) : text;
|
||||||
|
}
|
||||||
|
|
||||||
export function markPage(text: string, version: string) {
|
export function markPage(text: string, version: string) {
|
||||||
jQuery('body').append(
|
jQuery('body').append(
|
||||||
'<div style="' +
|
'<div style="' +
|
||||||
|
Loading…
Reference in New Issue
Block a user