Add "no implicit any" option and types

This commit is contained in:
Anton Vakhrushev 2020-05-01 13:29:52 +03:00
parent 418655ebff
commit e091a2170d
14 changed files with 72 additions and 67 deletions

View File

@ -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);

View File

@ -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 =

View File

@ -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(`<div id="${appId}"></div>`);
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();

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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(
<a id="${id1000}" href="#">x1000</a>
</div>`);
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(

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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();
}

View File

@ -5,6 +5,7 @@
"isolatedModules": true,
"module": "commonjs",
"outDir": "./dist",
"noImplicitAny": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"target": "es2018",