Refactor hero resource balance action

This commit is contained in:
Anton Vakhrushev 2020-04-19 10:38:48 +03:00
parent a6cc1b5383
commit 84ac56d052
42 changed files with 182 additions and 76 deletions

View File

@ -1,6 +1,6 @@
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { DataStorage } from '../Storage/DataStorage';
import { Args } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { DataStorage } from '../DataStorage';
import { Scheduler } from '../Scheduler';
const actionMap: { [name: string]: Function | undefined } = {};

View File

@ -1,15 +1,24 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { grabResources, grabResourceStorage } from '../Page/ResourcesBlock';
import { changeHeroResource, grabCurrentHeroResource } from '../Page/HeroPage';
import { HeroAllResources, Resources } from '../Game';
import { grabActiveVillageId } from '../Page/VillageBlock';
import { HeroState } from '../State/HeroState';
@registerAction
export class BalanceHeroResourcesAction extends ActionController {
async run(args: Args, task: Task): Promise<any> {
const resources = this.getRequirements();
const activeVillageId = grabActiveVillageId();
const heroVillageId = new HeroState().getVillageId();
if (heroVillageId === undefined || activeVillageId !== heroVillageId) {
changeHeroResource(HeroAllResources);
return;
}
const resources = this.getRequirements(heroVillageId);
const resourcesAsList = resources.asList();
const currentType = grabCurrentHeroResource();
@ -17,8 +26,11 @@ export class BalanceHeroResourcesAction extends ActionController {
const sorted = resourcesAsList.sort((x, y) => y.value - x.value);
const maxRequirement = sorted[0];
const minRequirement = sorted[sorted.length - 1];
const delta = maxRequirement.value - minRequirement.value;
const eps = maxRequirement.value / 10;
const delta = Math.abs(maxRequirement.value - minRequirement.value);
const eps = Math.abs(maxRequirement.value / 10);
console.log('REQUIREMENTS', sorted);
console.log('REQUIREMENTS', maxRequirement, minRequirement, delta, eps);
const resType = delta > eps ? maxRequirement.type : HeroAllResources;
if (resType !== currentType) {
@ -26,11 +38,12 @@ export class BalanceHeroResourcesAction extends ActionController {
}
}
private getRequirements() {
private getRequirements(heroVillageId) {
const resources = grabResources();
const requiredResources = this.scheduler.getVillageRequiredResources(heroVillageId);
const villageId = grabActiveVillageId();
const requiredResources = this.scheduler.getVillageRequiredResources(villageId);
console.log('RESOURCES', resources);
console.log('REQUIRED', requiredResources);
if (requiredResources) {
return new Resources(

View File

@ -1,7 +1,7 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Args } from '../Command';
import { ActionError, GrabError, TryLaterError } from '../Errors';
import { Task } from '../Storage/TaskQueue';
import { Task } from '../Queue/TaskQueue';
import { clickBuildButton } from '../Page/BuildingPage';
@registerAction

View File

@ -1,6 +1,6 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { PostponeAllBuildingsError, GrabError } from '../Errors';
import { grabActiveVillageId, grabBuildingQueueInfo } from '../Page/VillageBlock';
import { BuildingQueueInfo } from '../Game';

View File

@ -1,6 +1,6 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args } from '../Command';
import { Task } from '../Queue/TaskQueue';
@registerAction
export class ClickButtonAction extends ActionController {

View File

@ -1,6 +1,6 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args } from '../Command';
import { Task } from '../Queue/TaskQueue';
@registerAction
export class CompleteTaskAction extends ActionController {

View File

@ -1,6 +1,6 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { grabVillageList } from '../Page/VillageBlock';
import { grabHeroVillage } from '../Page/HeroPage';
import { path } from '../utils';

View File

@ -1,6 +1,6 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args } from '../Command';
import { Task } from '../Queue/TaskQueue';
@registerAction
export class GoToPageAction extends ActionController {

View File

@ -1,6 +1,6 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { ActionError } from '../Errors';
import { getNumber } from '../utils';

View File

@ -1,6 +1,6 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { trimPrefix } from '../utils';
import { AbortTaskError } from '../Errors';

View File

@ -1,7 +1,7 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { StateGrabberManager } from '../State/StateGrabberManager';
import { Args } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { StateGrabberManager } from '../Grabber/StateGrabberManager';
@registerAction
export class StoreVillageState extends ActionController {

View File

@ -1,7 +1,7 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Args } from '../Command';
import { ActionError, TryLaterError } from '../Errors';
import { Task } from '../Storage/TaskQueue';
import { Task } from '../Queue/TaskQueue';
import { getNumber, toNumber } from '../utils';
@registerAction

View File

@ -1,6 +1,6 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { grabContractResources } from '../Page/BuildingPage';
@registerAction

View File

@ -1,7 +1,7 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Args } from '../Command';
import { ActionError, GrabError, PostponeAllBuildingsError } from '../Errors';
import { Task } from '../Storage/TaskQueue';
import { Task } from '../Queue/TaskQueue';
import { clickUpgradeButton } from '../Page/BuildingPage';
@registerAction

View File

@ -1,7 +1,7 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Args } from '../Command';
import { ActionError, GrabError, TryLaterError } from '../Errors';
import { Task } from '../Storage/TaskQueue';
import { Task } from '../Queue/TaskQueue';
import { clickUpgradeButton } from '../Page/BuildingPage';
import { grabResourceDeposits } from '../Page/SlotBlock';
import { UpgradeBuildingTask } from '../Task/UpgradeBuildingTask';

View File

@ -1,5 +1,5 @@
import { ResourcesInterface } from './Game';
import { TaskId } from './Storage/TaskQueue';
import { TaskId } from './Queue/TaskQueue';
export interface Args {
villageId?: number;

View File

@ -14,7 +14,7 @@ import DashboardApp from './DashboardView/Dashboard.vue';
import { ResourcesToLevel } from './Task/ResourcesToLevel';
import { ConsoleLogger, Logger } from './Logger';
import { VillageState } from './State/VillageState';
import { StateGrabberManager } from './State/StateGrabberManager';
import { StateGrabberManager } from './Grabber/StateGrabberManager';
interface QuickAction {
label: string;

View File

@ -1,4 +1,4 @@
import { ConsoleLogger, Logger, NullLogger } from '../Logger';
import { ConsoleLogger, Logger, NullLogger } from './Logger';
const NAMESPACE = 'travian:v1';

View File

@ -1,4 +1,4 @@
import { TaskId } from './Storage/TaskQueue';
import { TaskId } from './Queue/TaskQueue';
export class GrabError extends Error {
constructor(msg: string = '') {

View File

@ -1,12 +1,12 @@
import { markPage, sleepMicro, timestamp, waitForLoad } from './utils';
import { AbortTaskError, ActionError, PostponeAllBuildingsError, TryLaterError } from './Errors';
import { Task } from './Storage/TaskQueue';
import { Command } from './Common';
import { Task } from './Queue/TaskQueue';
import { Command } from './Command';
import { TaskQueueRenderer } from './TaskQueueRenderer';
import { createAction } from './Action/ActionController';
import { createTask } from './Task/TaskController';
import { ConsoleLogger, Logger } from './Logger';
import { StateGrabberManager } from './State/StateGrabberManager';
import { StateGrabberManager } from './Grabber/StateGrabberManager';
import { Scheduler } from './Scheduler';
export class Executor {

View File

@ -108,6 +108,13 @@ export class BuildingQueueInfo {
}
}
export class HeroAttributes {
readonly health: number;
constructor(health: number) {
this.health = health;
}
}
export type HeroAllResourcesType = 'all';
export const HeroAllResources: HeroAllResourcesType = 'all';

View File

@ -0,0 +1,44 @@
import { StateGrabber } from './StateGrabber';
import {
grabActiveVillageId,
grabBuildingQueueInfo,
grabResourcesPerformance,
grabVillageList,
} from '../Page/VillageBlock';
import { VillageState } from '../State/VillageState';
import { parseLocation } from '../utils';
import { GrabError } from '../Errors';
import { BuildingQueueInfo } from '../Game';
import { HeroState } from '../State/HeroState';
import { grabHeroAttributes, grabHeroVillage } from '../Page/HeroPage';
export class HeroPageGrabber extends StateGrabber {
grab(): void {
const p = parseLocation();
if (p.pathname !== '/hero.php') {
return;
}
const state = new HeroState();
state.storeAttributes(grabHeroAttributes());
const villageId = this.getHeroVillageId();
if (villageId) {
state.storeVillageId(villageId);
}
}
private getHeroVillageId(): number | undefined {
const villages = grabVillageList();
const heroVillage = grabHeroVillage();
for (let village of villages) {
if (village.name === heroVillage) {
return village.id;
}
}
return undefined;
}
}

View File

@ -1,7 +1,7 @@
import { StateGrabber } from './StateGrabber';
import { grabActiveVillageId } from '../Page/VillageBlock';
import { grabResources, grabResourceStorage } from '../Page/ResourcesBlock';
import { VillageState } from './VillageState';
import { VillageState } from '../State/VillageState';
export class ResourceGrabber extends StateGrabber {
grab(): void {

View File

@ -1,6 +1,7 @@
import { StateGrabber } from './StateGrabber';
import { ResourceGrabber } from './ResourceGrabber';
import { VillageOverviewPageGrabber } from './VillageOverviewPageGrabber';
import { HeroPageGrabber } from './HeroPageGrabber';
export class StateGrabberManager {
private readonly grabbers: Array<StateGrabber> = [];
@ -9,6 +10,7 @@ export class StateGrabberManager {
this.grabbers = [];
this.grabbers.push(new ResourceGrabber());
this.grabbers.push(new VillageOverviewPageGrabber());
this.grabbers.push(new HeroPageGrabber());
}
grab() {

View File

@ -1,6 +1,6 @@
import { StateGrabber } from './StateGrabber';
import { grabActiveVillageId, grabBuildingQueueInfo, grabResourcesPerformance } from '../Page/VillageBlock';
import { VillageState } from './VillageState';
import { VillageState } from '../State/VillageState';
import { parseLocation } from '../utils';
import { GrabError } from '../Errors';
import { BuildingQueueInfo } from '../Game';

View File

@ -1,5 +1,15 @@
import { GrabError } from '../Errors';
import { HeroAllResources, HeroResourceType, ResourceMapping, ResourceType } from '../Game';
import { ActionError, GrabError } from '../Errors';
import { HeroAllResources, HeroAttributes, HeroResourceType, ResourceMapping, ResourceType } from '../Game';
import { getNumber } from '../utils';
export function grabHeroAttributes(): HeroAttributes {
const healthElement = jQuery('#attributes .attribute.health .powervalue .value');
if (healthElement.length !== 1) {
throw new GrabError('Health dom element not found');
}
return new HeroAttributes(getNumber(healthElement.text()));
}
export function grabCurrentHeroResource(): HeroResourceType {
for (let mp of ResourceMapping) {
@ -44,7 +54,7 @@ function heroResourceTypeToNumber(type: HeroResourceType): number {
export function grabHeroVillage(): string | undefined {
const status = jQuery('.heroStatusMessage').text();
const hrefText = jQuery('.heroStatusMessage a').text();
if (status.includes('в родной деревне')) {
if (status.toLowerCase().includes('в родной деревне')) {
return hrefText || undefined;
} else {
return undefined;

View File

@ -1,6 +1,6 @@
import { Command } from '../Common';
import { Command } from '../Command';
import { ConsoleLogger, Logger } from '../Logger';
import { DataStorage } from './DataStorage';
import { DataStorage } from '../DataStorage';
const NAMESPACE = 'actions.v1';
const QUEUE_NAME = 'queue';

View File

@ -1,7 +1,7 @@
import { Args } from '../Common';
import { Args } from '../Command';
import { uniqId } from '../utils';
import { ConsoleLogger, Logger } from '../Logger';
import { DataStorage } from './DataStorage';
import { DataStorage } from '../DataStorage';
const NAMESPACE = 'tasks:v1';
const QUEUE_NAME = 'queue';

View File

@ -1,13 +1,13 @@
import { timestamp } from './utils';
import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask';
import { Task, TaskId, TaskList, TaskQueue } from './Storage/TaskQueue';
import { Args, Command } from './Common';
import { Task, TaskId, TaskList, TaskQueue } from './Queue/TaskQueue';
import { Args, Command } from './Command';
import { SendOnAdventureTask } from './Task/SendOnAdventureTask';
import { BalanceHeroResourcesTask } from './Task/BalanceHeroResourcesTask';
import { ConsoleLogger, Logger } from './Logger';
import { BuildBuildingTask } from './Task/BuildBuildingTask';
import { GrabVillageState } from './Task/GrabVillageState';
import { ActionQueue } from './Storage/ActionQueue';
import { ActionQueue } from './Queue/ActionQueue';
import { Resources, ResourcesInterface } from './Game';
import { UpdateResourceContracts } from './Task/UpdateResourceContracts';

30
src/State/HeroState.ts Normal file
View File

@ -0,0 +1,30 @@
import { DataStorage } from '../DataStorage';
import { HeroAttributes } from '../Game';
const VILLAGE_ID_KEY = 'village_id';
const ATTRIBUTES_KEY = 'attr';
export class HeroState {
private storage: DataStorage;
constructor() {
this.storage = new DataStorage('hero.v1');
}
storeVillageId(villageId: number) {
this.storage.set(VILLAGE_ID_KEY, villageId);
}
getVillageId(): number | undefined {
return (this.storage.get(VILLAGE_ID_KEY) as number) || undefined;
}
storeAttributes(attributes: HeroAttributes) {
this.storage.set(ATTRIBUTES_KEY, attributes);
}
getAttributes(): HeroAttributes {
let plain = this.storage.get(ATTRIBUTES_KEY);
let res = new HeroAttributes(0);
return Object.assign(res, plain) as HeroAttributes;
}
}

View File

@ -1,4 +1,4 @@
import { DataStorage } from '../Storage/DataStorage';
import { DataStorage } from '../DataStorage';
import { BuildingQueueInfo, Resources, ResourceStorage } from '../Game';
const RESOURCES_KEY = 'res';

View File

@ -1,5 +1,5 @@
import { Args, Command } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args, Command } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { TaskController, registerTask } from './TaskController';
import { GoToPageAction } from '../Action/GoToPageAction';
import { CompleteTaskAction } from '../Action/CompleteTaskAction';

View File

@ -1,10 +1,10 @@
import { Args, Command } from '../Common';
import { Args, Command } from '../Command';
import { BuildBuildingAction } from '../Action/BuildBuildingAction';
import { CheckBuildingRemainingTimeAction } from '../Action/CheckBuildingRemainingTimeAction';
import { CompleteTaskAction } from '../Action/CompleteTaskAction';
import { GoToPageAction } from '../Action/GoToPageAction';
import { path } from '../utils';
import { Task } from '../Storage/TaskQueue';
import { Task } from '../Queue/TaskQueue';
import { TaskController, registerTask } from './TaskController';
@registerTask

View File

@ -1,8 +1,8 @@
import { Args, Command } from '../Common';
import { Args, Command } from '../Command';
import { CompleteTaskAction } from '../Action/CompleteTaskAction';
import { GoToPageAction } from '../Action/GoToPageAction';
import { path } from '../utils';
import { Task } from '../Storage/TaskQueue';
import { Task } from '../Queue/TaskQueue';
import { TaskController, registerTask } from './TaskController';
import { grabVillageList } from '../Page/VillageBlock';
import { StoreVillageState } from '../Action/StoreVillageState';

View File

@ -1,5 +1,5 @@
import { Args, Command } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args, Command } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { TaskController, registerTask } from './TaskController';
import { GoToPageAction } from '../Action/GoToPageAction';
import { CompleteTaskAction } from '../Action/CompleteTaskAction';

View File

@ -1,5 +1,5 @@
import { Args, Command } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args, Command } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { TaskController, registerTask } from './TaskController';
import { GoToPageAction } from '../Action/GoToPageAction';
import { GrabHeroAttributesAction } from '../Action/GrabHeroAttributesAction';

View File

@ -1,4 +1,4 @@
import { Task } from '../Storage/TaskQueue';
import { Task } from '../Queue/TaskQueue';
import { Scheduler } from '../Scheduler';
const taskMap: { [name: string]: Function | undefined } = {};

View File

@ -1,5 +1,5 @@
import { Args, Command } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args, Command } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { TaskController, registerTask } from './TaskController';
import { GoToPageAction } from '../Action/GoToPageAction';
import { CompleteTaskAction } from '../Action/CompleteTaskAction';

View File

@ -1,5 +1,5 @@
import { Args, Command } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args, Command } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { TaskController, registerTask } from './TaskController';
import { GoToPageAction } from '../Action/GoToPageAction';
import { path } from '../utils';

View File

@ -1,6 +1,6 @@
import { UpgradeBuildingAction } from '../Action/UpgradeBuildingAction';
import { Args, Command } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { Args, Command } from '../Command';
import { Task } from '../Queue/TaskQueue';
import { TaskController, registerTask } from './TaskController';
import { GoToPageAction } from '../Action/GoToPageAction';
import { CheckBuildingRemainingTimeAction } from '../Action/CheckBuildingRemainingTimeAction';

View File

@ -1,4 +1,4 @@
import { TaskList } from './Storage/TaskQueue';
import { TaskList } from './Queue/TaskQueue';
import { uniqId } from './utils';
import * as dateFormat from 'dateformat';