diff --git a/src/Action/SendResourcesAction.ts b/src/Action/SendResourcesAction.ts index f414f49..a0fd71e 100644 --- a/src/Action/SendResourcesAction.ts +++ b/src/Action/SendResourcesAction.ts @@ -11,7 +11,7 @@ import { VillageState } from '../State/VillageState'; import { Args } from '../Queue/Args'; import { Task } from '../Queue/TaskProvider'; -function err(msg): never { +function err(msg: string): never { throw new ActionError(msg); } @@ -101,7 +101,7 @@ export class SendResourcesAction extends ActionController { return missing; } - private getResourcesForTransfer(recipientVillageId): Resources { + private getResourcesForTransfer(recipientVillageId: number): Resources { const senderResources = this.getSenderAvailableResources(); const recipientNeeds = this.getRecipientRequirements(recipientVillageId); const prepared = senderResources.min(recipientNeeds); diff --git a/src/Container.ts b/src/Container.ts index 85b66d0..981cb4a 100644 --- a/src/Container.ts +++ b/src/Container.ts @@ -13,7 +13,7 @@ export class Container { this.version = version; } - private _scheduler; + private _scheduler: Scheduler | undefined; get scheduler(): Scheduler { this._scheduler = @@ -27,7 +27,7 @@ export class Container { return this._scheduler; } - private _executor; + private _executor: Executor | undefined; get executor(): Executor { this._executor = @@ -38,7 +38,7 @@ export class Container { return this._executor; } - private _controlPanel; + private _controlPanel: ControlPanel | undefined; get controlPanel(): ControlPanel { this._controlPanel = diff --git a/src/ControlPanel.ts b/src/ControlPanel.ts index 7dcecd4..dadb996 100644 --- a/src/ControlPanel.ts +++ b/src/ControlPanel.ts @@ -15,12 +15,13 @@ import { ResourcesToLevel } from './Task/ResourcesToLevel'; import { ConsoleLogger, Logger } from './Logger'; import { VillageState } from './State/VillageState'; import { Resources } from './Core/Resources'; -import { Village } from './Core/Village'; +import { Coordinates, Village } from './Core/Village'; import { calcGatheringTimings } from './Core/GatheringTimings'; import { DataStorage } from './DataStorage'; import { getBuildingPageAttributes, isBuildingPage } from './Page/PageDetectors'; import { debounce } from 'debounce'; import { ExecutionState } from './State/ExecutionState'; +import { ResourceStorage } from './Core/ResourceStorage'; interface QuickAction { label: string; @@ -42,7 +43,7 @@ export class ControlPanel { await waitForLoad(); const p = parseLocation(); - this.logger.log('PARSED LOCATION', p); + this.logger.info('PARSED LOCATION', p); const villageId = grabActiveVillageId(); @@ -51,7 +52,7 @@ export class ControlPanel { const executionState = new ExecutionState(); - const state = { + const state: any = { name: 'Dashboard', version: this.version, activeVillage: {}, @@ -125,7 +126,7 @@ export class ControlPanel { this.createControlPanel(state); } - private createControlPanel(state) { + private createControlPanel(state: any) { const appId = `app-${uniqId()}`; jQuery('body').prepend(`
`); new Vue({ @@ -135,7 +136,7 @@ export class ControlPanel { }); } - private createDepositsQuickActions(villageId) { + private createDepositsQuickActions(villageId: number) { const deposits = grabResourceDeposits(); if (deposits.length === 0) { return []; @@ -162,25 +163,25 @@ export class ControlPanel { } class VillageController { - public readonly id; - public readonly name; - public readonly crd; - public readonly active; - public readonly lumber; - public readonly clay; - public readonly iron; - public readonly crop; - public readonly resources; - public readonly performance; + public readonly id: number; + public readonly name: string; + public readonly crd: Coordinates; + public readonly active: boolean; + public readonly lumber: number; + public readonly clay: number; + public readonly iron: number; + public readonly crop: number; + public readonly resources: Resources; + public readonly performance: Resources; public readonly requiredResources: Resources; public readonly requiredBalance: Resources; public readonly totalRequiredResources: Resources; public readonly totalRequiredBalance: Resources; public readonly incomingResources: Resources; - public readonly storage; - public readonly warehouse; - public readonly granary; - public readonly buildRemainingSeconds; + public readonly storage: ResourceStorage; + public readonly warehouse: number; + public readonly granary: number; + public readonly buildRemainingSeconds: number; constructor(village: Village, state: VillageState, scheduler: Scheduler) { const resources = state.getResources(); diff --git a/src/DataStorage.ts b/src/DataStorage.ts index 584cd68..6aad0bc 100644 --- a/src/DataStorage.ts +++ b/src/DataStorage.ts @@ -64,7 +64,7 @@ export class DataStorage { const fullKey = join(NAMESPACE, this.name, key); try { const serialized = storage.getItem(fullKey); - this.logger.log('GET', fullKey, serialized); + this.logger.info('GET', fullKey, serialized); return JSON.parse(serialized || 'null'); } catch (e) { if (e instanceof SyntaxError) { @@ -97,7 +97,7 @@ export class DataStorage { set(key: string, value: any) { const fullKey = join(NAMESPACE, this.name, key); let serialized = JSON.stringify(value); - this.logger.log('SET', fullKey, serialized); + this.logger.info('SET', fullKey, serialized); storage.setItem(fullKey, serialized); } } diff --git a/src/Executor.ts b/src/Executor.ts index 7831c7c..ddda5ac 100644 --- a/src/Executor.ts +++ b/src/Executor.ts @@ -72,14 +72,14 @@ export class Executor { // текущего таска нет, очищаем очередь действий по таску if (!task) { - this.logger.log('NO ACTIVE TASK'); + this.logger.info('NO ACTIVE TASK'); this.scheduler.clearActions(); return; } const actionCommand = this.scheduler.nextAction(); - this.logger.log('CURRENT JOB', 'TASK', task, 'ACTION', actionCommand); + this.logger.info('CURRENT JOB', 'TASK', task, 'ACTION', actionCommand); this.runGrabbers(); @@ -98,7 +98,7 @@ export class Executor { private async processActionCommand(cmd: Action, task: Task) { const actionHandler = createActionHandler(cmd.name, this.scheduler); - this.logger.log('PROCESS ACTION', cmd.name, actionHandler); + this.logger.info('PROCESS ACTION', cmd.name, actionHandler); if (cmd.args.taskId !== task.id) { throw new ActionError(`Action task id ${cmd.args.taskId} not equal current task id ${task.id}`); } @@ -112,7 +112,7 @@ export class Executor { private async processTaskCommand(task: Task) { const taskHandler = createTaskHandler(task.name, this.scheduler); - this.logger.log('PROCESS TASK', task.name, task, taskHandler); + this.logger.info('PROCESS TASK', task.name, task, taskHandler); if (taskHandler) { await taskHandler.run(task); } else { @@ -147,7 +147,7 @@ export class Executor { private runGrabbers() { try { - this.logger.log('Rug grabbers'); + this.logger.info('Rug grabbers'); this.grabbers.grab(); } catch (e) { this.logger.warn('Grabbers fails with', e.message); diff --git a/src/Logger.ts b/src/Logger.ts index 66c76b8..19a66ff 100644 --- a/src/Logger.ts +++ b/src/Logger.ts @@ -1,31 +1,31 @@ -export abstract class Logger { - abstract log(...args): void; - abstract warn(...args): void; - abstract error(...args): void; +export interface Logger { + info(...args: any[]): void; + warn(...args: any[]): void; + error(...args: any[]): void; } -export class NullLogger extends Logger { - log(...args): void {} - warn(...args): void {} - error(...args): void {} +export class NullLogger implements Logger { + info(...args: any[]): void {} + warn(...args: any[]): void {} + error(...args: any[]): void {} } -export class ConsoleLogger extends Logger { +export class ConsoleLogger implements Logger { private readonly name: string; + constructor(name: string) { - super(); this.name = name.toUpperCase(); } - log(...args): void { + info(...args: any[]): void { console.log(this.name + ':', ...args); } - warn(...args): void { + warn(...args: any[]): void { console.warn(this.name + ':', ...args); } - error(...args): void { + error(...args: any[]): void { console.error(this.name + ':', ...args); } } diff --git a/src/Page/BuildingPage.ts b/src/Page/BuildingPage.ts index 829723d..0b39ce1 100644 --- a/src/Page/BuildingPage.ts +++ b/src/Page/BuildingPage.ts @@ -60,12 +60,12 @@ export function createUpgradeButton(onClickHandler: (resources: Resources) => vo }); } -function grabResourcesFromList($els) { - const getText = n => +function grabResourcesFromList($els: JQuery) { + const getText = (n: number) => jQuery($els.get(n)) .find('.value') .text(); - const grab = n => getNumber(getText(n)); + const grab = (n: number) => getNumber(getText(n)); return new Resources(grab(0), grab(1), grab(2), grab(3)); } @@ -120,7 +120,9 @@ export function createSendResourcesButton( x1000 `); - const createHandler = (handler, scale) => evt => { + const createHandler = (handler: (resources: Resources, crd: Coordinates, scale: number) => void, scale: number) => ( + evt: JQuery.Event + ) => { evt.preventDefault(); const sendSelect = jQuery('#send_select'); const resources = new Resources( diff --git a/src/Page/BuildingPageController.ts b/src/Page/BuildingPageController.ts index 26084e2..afa37a3 100644 --- a/src/Page/BuildingPageController.ts +++ b/src/Page/BuildingPageController.ts @@ -3,7 +3,7 @@ import { UpgradeBuildingTask } from '../Task/UpgradeBuildingTask'; import { Scheduler } from '../Scheduler'; import { TrainTroopTask } from '../Task/TrainTroopTask'; import { grabActiveVillageId } from './VillageBlock'; -import { ConsoleLogger } from '../Logger'; +import { ConsoleLogger, Logger } from '../Logger'; import { createBuildButton, createSendResourcesButton, @@ -21,7 +21,7 @@ import { BuildingPageAttributes, isMarketSendResourcesPage } from './PageDetecto export class BuildingPageController { private scheduler: Scheduler; private readonly attributes: BuildingPageAttributes; - private readonly logger; + private readonly logger: Logger; constructor(scheduler: Scheduler, attributes: BuildingPageAttributes) { this.scheduler = scheduler; @@ -31,7 +31,7 @@ export class BuildingPageController { run() { const { buildTypeId, sheetId } = this.attributes; - this.logger.log('BUILD PAGE DETECTED', 'ID', this.attributes.buildId, this.attributes); + this.logger.info('BUILD PAGE DETECTED', 'ID', this.attributes.buildId, this.attributes); if (buildTypeId) { createUpgradeButton(res => this.onScheduleUpgradeBuilding(res)); diff --git a/src/Page/VillageBlock.ts b/src/Page/VillageBlock.ts index 9a6fdb3..2996afa 100644 --- a/src/Page/VillageBlock.ts +++ b/src/Page/VillageBlock.ts @@ -35,7 +35,7 @@ export function grabActiveVillageId(): number { return grabActiveVillage()?.id || 0; } -function grabVillageInfo($el): Village { +function grabVillageInfo($el: JQuery): Village { const href = $el.attr('href'); const parsedHref = parseLocation(href || ''); const id = getNumber(parsedHref.query.newdid); diff --git a/src/Queue/DataStorageTaskProvider.ts b/src/Queue/DataStorageTaskProvider.ts index 244ff9b..1a2e0e3 100644 --- a/src/Queue/DataStorageTaskProvider.ts +++ b/src/Queue/DataStorageTaskProvider.ts @@ -1,5 +1,5 @@ import { DataStorage } from '../DataStorage'; -import {Task, TaskList, TaskProvider, uniqTaskId} from './TaskProvider'; +import { Task, TaskList, TaskProvider, uniqTaskId } from './TaskProvider'; const NAMESPACE = 'tasks:v1'; const QUEUE_NAME = 'queue'; diff --git a/src/Queue/TaskQueue.ts b/src/Queue/TaskQueue.ts index 48eaac0..fbfcdaf 100644 --- a/src/Queue/TaskQueue.ts +++ b/src/Queue/TaskQueue.ts @@ -14,7 +14,7 @@ export class TaskQueue { push(name: string, args: Args, ts: number): Task { const id = uniqTaskId(); const task = new Task(id, ts, name, args); - this.logger.log('PUSH TASK', id, ts, name, args); + this.logger.info('PUSH TASK', id, ts, name, args); let items = this.getItems(); items.push(task); this.flushItems(items); diff --git a/src/Scheduler.ts b/src/Scheduler.ts index 94551ce..f454fa2 100644 --- a/src/Scheduler.ts +++ b/src/Scheduler.ts @@ -56,7 +56,7 @@ export class Scheduler { } scheduleTask(name: string, args: Args, ts?: number | undefined): void { - this.logger.log('PUSH TASK', name, args, ts); + this.logger.info('PUSH TASK', name, args, ts); let insertedTs = calculateInsertTime(this.taskQueue.seeItems(), name, args, ts); this.taskQueue.push(name, args, insertedTs); if (args.villageId) { @@ -83,9 +83,9 @@ export class Scheduler { } const villageId = task.args.villageId; - const modifyTime = t => withTime(t, timestamp() + seconds); - const buildPred = t => sameVillage(villageId, t.args) && isBuildingTask(t.name); - const trainPred = t => sameVillage(villageId, t.args) && isTrainTroopTask(t.name); + const modifyTime = (t: Task) => withTime(t, timestamp() + seconds); + const buildPred = (t: Task) => sameVillage(villageId, t.args) && isBuildingTask(t.name); + const trainPred = (t: Task) => sameVillage(villageId, t.args) && isTrainTroopTask(t.name); if (isBuildingTask(task.name) && villageId) { this.taskQueue.modify(buildPred, modifyTime); @@ -115,7 +115,7 @@ export class Scheduler { this.actionQueue.clear(); } - getVillageRequiredResources(villageId): Resources { + getVillageRequiredResources(villageId: number): Resources { const tasks = this.taskQueue .seeItems() .filter(t => sameVillage(villageId, t.args) && t.args.resources && t.name !== SendResourcesTask.name); @@ -123,10 +123,10 @@ export class Scheduler { if (first && first.args.resources) { return Resources.fromObject(first.args.resources); } - return new Resources(0, 0, 0, 0); + return Resources.zero(); } - getTotalVillageRequiredResources(villageId): Resources { + getTotalVillageRequiredResources(villageId: number): Resources { const tasks = this.taskQueue .seeItems() .filter(t => sameVillage(villageId, t.args) && t.args.resources && t.name !== SendResourcesTask.name); @@ -135,8 +135,8 @@ export class Scheduler { private reorderVillageTasks(villageId: number) { const tasks = this.taskQueue.seeItems(); - const trainPred = t => isTrainTroopTask(t.name) && sameVillage(villageId, t.args); - const buildPred = t => isBuildingTask(t.name) && sameVillage(villageId, t.args); + const trainPred = (t: Task) => isTrainTroopTask(t.name) && sameVillage(villageId, t.args); + const buildPred = (t: Task) => isBuildingTask(t.name) && sameVillage(villageId, t.args); const lastTrainTaskTs = lastTaskTime(tasks, trainPred); if (lastTrainTaskTs) { this.taskQueue.modify(buildPred, t => withTime(t, lastTrainTaskTs + 1)); @@ -196,7 +196,8 @@ function calculateInsertTime(tasks: ImmutableTaskList, name: string, args: Args, if (villageId && !insertedTs) { for (let taskTypePred of TASK_TYPE_PREDICATES) { - const sameVillageAndTypePred = t => taskTypePred(name) && t.args.villageId === villageId && t.name === name; + const sameVillageAndTypePred = (t: Task) => + taskTypePred(name) && t.args.villageId === villageId && t.name === name; insertedTs = lastTaskTime(tasks, sameVillageAndTypePred); if (insertedTs) { insertedTs += 1; diff --git a/src/index.js b/src/index.js index b6dcd24..4cbd0be 100644 --- a/src/index.js +++ b/src/index.js @@ -6,18 +6,18 @@ import { Container } from './Container'; function main() { const logger = new ConsoleLogger('Travian'); - logger.log('TRAVIAN AUTOMATION', TxtVersion); + logger.info('TRAVIAN AUTOMATION', TxtVersion); const container = new Container(TxtVersion); const modeDetector = new ModeDetector(); if (modeDetector.isAuto()) { modeDetector.setAuto(); - logger.log('AUTO MANAGEMENT ON'); + logger.info('AUTO MANAGEMENT ON'); const executor = container.executor; executor.run(); } else { - logger.log('NORMAL MODE'); + logger.info('NORMAL MODE'); const controlPanel = container.controlPanel; controlPanel.run(); } diff --git a/tsconfig.json b/tsconfig.json index 1982446..06a3f3d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,7 @@ "isolatedModules": true, "module": "commonjs", "outDir": "./dist", + "noImplicitAny": true, "strictNullChecks": true, "strictPropertyInitialization": true, "target": "es2018",