Split utils functions into set of helper modules
This commit is contained in:
parent
d57d8c4942
commit
dfc7d48fd4
@ -1,11 +1,11 @@
|
||||
import { Scheduler } from '../Scheduler';
|
||||
import { taskError, TryLaterError } from '../Errors';
|
||||
import { grabActiveVillageId } from '../Page/VillageBlock';
|
||||
import { aroundMinutes } from '../utils';
|
||||
import { Args } from '../Queue/Args';
|
||||
import { Task } from '../Queue/TaskProvider';
|
||||
import { VillageStorage } from '../Storage/VillageStorage';
|
||||
import { VillageFactory } from '../VillageFactory';
|
||||
import { aroundMinutes } from '../Helpers/Time';
|
||||
|
||||
const actionMap: { [name: string]: Function | undefined } = {};
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { ActionController, registerAction } from './ActionController';
|
||||
import { GrabError, taskError, TryLaterError } from '../Errors';
|
||||
import { clickBuildButton } from '../Page/BuildingPage/BuildingPage';
|
||||
import { aroundMinutes } from '../utils';
|
||||
import { Args } from '../Queue/Args';
|
||||
import { Task } from '../Queue/TaskProvider';
|
||||
import { aroundMinutes } from '../Helpers/Time';
|
||||
|
||||
@registerAction
|
||||
export class BuildBuildingAction extends ActionController {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { ActionController, registerAction } from './ActionController';
|
||||
import { GrabError, TryLaterError } from '../Errors';
|
||||
import { aroundMinutes } from '../utils';
|
||||
import { Args } from '../Queue/Args';
|
||||
import { Task } from '../Queue/TaskProvider';
|
||||
import { clickCelebrationButton } from '../Page/BuildingPage/GuildHallPage';
|
||||
import { aroundMinutes } from '../Helpers/Time';
|
||||
|
||||
@registerAction
|
||||
export class CelebrationAction extends ActionController {
|
||||
|
@ -2,7 +2,6 @@ import { ActionController, registerAction } from './ActionController';
|
||||
import { FailTaskError, taskError, TryLaterError } from '../Errors';
|
||||
import { Resources } from '../Core/Resources';
|
||||
import { Coordinates } from '../Core/Village';
|
||||
import { aroundMinutes, timestamp } from '../utils';
|
||||
import { Args } from '../Queue/Args';
|
||||
import { Task } from '../Queue/TaskProvider';
|
||||
import { clickSendButton, fillSendResourcesForm } from '../Page/BuildingPage/MarketPage';
|
||||
@ -17,6 +16,7 @@ import {
|
||||
import { ResourceTransferStorage } from '../Storage/ResourceTransferStorage';
|
||||
import { path } from '../Helpers/Path';
|
||||
import { MARKET_ID } from '../Core/Buildings';
|
||||
import { aroundMinutes, timestamp } from '../Helpers/Time';
|
||||
|
||||
@registerAction
|
||||
export class FindSendResourcesPath extends ActionController {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { ActionController, registerAction } from './ActionController';
|
||||
import { GrabError, taskError, TryLaterError } from '../Errors';
|
||||
import { aroundMinutes } from '../utils';
|
||||
import { Args } from '../Queue/Args';
|
||||
import { Task } from '../Queue/TaskProvider';
|
||||
import { clickResearchButton } from '../Page/BuildingPage/ForgePage';
|
||||
import { aroundMinutes } from '../Helpers/Time';
|
||||
|
||||
@registerAction
|
||||
export class ForgeImprovementAction extends ActionController {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { ActionController, registerAction } from './ActionController';
|
||||
import { trimPrefix } from '../utils';
|
||||
import { AbortTaskError } from '../Errors';
|
||||
import { Args } from '../Queue/Args';
|
||||
import { Task } from '../Queue/TaskProvider';
|
||||
import { trimPrefix } from '../Helpers/Convert';
|
||||
|
||||
const CONFIG = [
|
||||
{ level: 0, health: 60 },
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { ActionController, registerAction } from './ActionController';
|
||||
import { taskError, TryLaterError } from '../Errors';
|
||||
import { aroundMinutes, randomInRange } from '../utils';
|
||||
import { Args } from '../Queue/Args';
|
||||
import { Task } from '../Queue/TaskProvider';
|
||||
import {
|
||||
@ -10,6 +9,8 @@ import {
|
||||
} from '../Page/BuildingPage/TrooperPage';
|
||||
import { TrainTroopTask } from '../Task/TrainTroopTask';
|
||||
import { Resources } from '../Core/Resources';
|
||||
import { randomInRange } from '../Helpers/Random';
|
||||
import { aroundMinutes } from '../Helpers/Time';
|
||||
|
||||
@registerAction
|
||||
export class TrainTrooperAction extends ActionController {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { ActionController, registerAction } from './ActionController';
|
||||
import { GrabError, TryLaterError } from '../Errors';
|
||||
import { clickUpgradeButton } from '../Page/BuildingPage/BuildingPage';
|
||||
import { aroundMinutes } from '../utils';
|
||||
import { Args } from '../Queue/Args';
|
||||
import { Task } from '../Queue/TaskProvider';
|
||||
import { aroundMinutes } from '../Helpers/Time';
|
||||
|
||||
@registerAction
|
||||
export class UpgradeBuildingAction extends ActionController {
|
||||
|
@ -2,10 +2,11 @@ import { ActionController, registerAction } from './ActionController';
|
||||
import { ActionError, taskError, TryLaterError } from '../Errors';
|
||||
import { grabResourceSlots } from '../Page/SlotBlock';
|
||||
import { UpgradeBuildingTask } from '../Task/UpgradeBuildingTask';
|
||||
import { aroundMinutes, getNumber } from '../utils';
|
||||
import { Args } from '../Queue/Args';
|
||||
import { Task } from '../Queue/TaskProvider';
|
||||
import { ResourceSlot } from '../Core/Slot';
|
||||
import { getNumber } from '../Helpers/Convert';
|
||||
import { aroundMinutes } from '../Helpers/Time';
|
||||
|
||||
@registerAction
|
||||
export class UpgradeResourceToLevel extends ActionController {
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { notify, parseLocation, timestamp, uniqId, waitForLoad } from './utils';
|
||||
import { Scheduler } from './Scheduler';
|
||||
import { BuildingPageController } from './Page/BuildingPageController';
|
||||
import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask';
|
||||
@ -21,6 +20,9 @@ import { Task } from './Queue/TaskProvider';
|
||||
import { Action } from './Queue/ActionQueue';
|
||||
import { createStore } from './DashboardView/Store';
|
||||
import { VillageFactory } from './VillageFactory';
|
||||
import { uniqId } from './Helpers/Identity';
|
||||
import { timestamp } from './Helpers/Time';
|
||||
import { notify, parseLocation, waitForLoad } from './Helpers/Browser';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
|
@ -13,8 +13,8 @@
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import * as dateFormat from 'dateformat';
|
||||
import { Mutations } from './Store';
|
||||
import { formatDate } from '../Helpers/Format';
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
@ -30,8 +30,7 @@ export default {
|
||||
};
|
||||
},
|
||||
formatDate(ts) {
|
||||
const d = new Date(ts * 1000);
|
||||
return dateFormat(d, 'HH:MM:ss');
|
||||
return formatDate(ts);
|
||||
},
|
||||
close() {
|
||||
this.$store.commit(Mutations.hideLogs);
|
||||
|
@ -1,9 +1,10 @@
|
||||
import Vuex from 'vuex';
|
||||
import { VillageSettings, VillageSettingsDefaults } from '../Core/Village';
|
||||
import { getNumber, notify } from '../utils';
|
||||
import { VillageStorage } from '../Storage/VillageStorage';
|
||||
import { VillageFactory } from '../VillageFactory';
|
||||
import { StorageContainer } from '../Storage/StorageContainer';
|
||||
import { getNumber } from '../Helpers/Convert';
|
||||
import { notify } from '../Helpers/Browser';
|
||||
|
||||
export enum Mutations {
|
||||
showLogs = 'showLogs',
|
||||
|
@ -42,7 +42,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as dateFormat from 'dateformat';
|
||||
import { formatDate } from '../Helpers/Format';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@ -61,8 +61,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
formatDate(ts) {
|
||||
const d = new Date(ts * 1000);
|
||||
return dateFormat(d, 'HH:MM:ss');
|
||||
return formatDate(ts);
|
||||
},
|
||||
isThisVillageTask(task) {
|
||||
const taskVillageId = (task.args || {}).villageId;
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { markPage, sleepMicro, timestamp, waitForLoad } from './utils';
|
||||
import {
|
||||
AbortTaskError,
|
||||
ActionError,
|
||||
@ -18,6 +17,8 @@ import { Action } from './Queue/ActionQueue';
|
||||
import { Task } from './Queue/TaskProvider';
|
||||
import { createTaskHandler } from './Task/TaskMap';
|
||||
import { VillageFactory } from './VillageFactory';
|
||||
import { sleepMicro, timestamp } from './Helpers/Time';
|
||||
import { markPage, waitForLoad } from './Helpers/Browser';
|
||||
|
||||
export interface ExecutionSettings {
|
||||
pauseTs: number;
|
||||
|
@ -3,7 +3,7 @@ import { getBuildingPageAttributes, isForgePage } from '../Page/PageDetector';
|
||||
import { ContractType } from '../Core/Contract';
|
||||
import { grabImprovementContracts, grabRemainingSeconds } from '../Page/BuildingPage/ForgePage';
|
||||
import { ProductionQueue } from '../Core/ProductionQueue';
|
||||
import { timestamp } from '../utils';
|
||||
import { timestamp } from '../Helpers/Time';
|
||||
|
||||
export class ForgePageGrabber extends Grabber {
|
||||
grab(): void {
|
||||
|
@ -2,7 +2,7 @@ import { Grabber } from './Grabber';
|
||||
import { isGuildHallPage } from '../Page/PageDetector';
|
||||
import { grabRemainingSeconds } from '../Page/BuildingPage/GuildHallPage';
|
||||
import { ProductionQueue } from '../Core/ProductionQueue';
|
||||
import { timestamp } from '../utils';
|
||||
import { timestamp } from '../Helpers/Time';
|
||||
|
||||
export class GuildHallPageGrabber extends Grabber {
|
||||
grab(): void {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Grabber } from './Grabber';
|
||||
import { parseLocation } from '../utils';
|
||||
import { grabBuildingSlots } from '../Page/SlotBlock';
|
||||
import { parseLocation } from '../Helpers/Browser';
|
||||
|
||||
export class VillageBuildingsPageGrabber extends Grabber {
|
||||
grab(): void {
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { Grabber } from './Grabber';
|
||||
import { grabBuildingQueueInfo, grabResourcesPerformance } from '../Page/VillageBlock';
|
||||
import { parseLocation, timestamp } from '../utils';
|
||||
import { GrabError } from '../Errors';
|
||||
import { ProductionQueue } from '../Core/ProductionQueue';
|
||||
import { grabResourceSlots } from '../Page/SlotBlock';
|
||||
import { BuildingQueueInfo } from '../Core/BuildingQueueInfo';
|
||||
import { timestamp } from '../Helpers/Time';
|
||||
import { parseLocation } from '../Helpers/Browser';
|
||||
|
||||
export class VillageOverviewPageGrabber extends Grabber {
|
||||
grab(): void {
|
||||
|
31
src/Helpers/Browser.ts
Normal file
31
src/Helpers/Browser.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import * as URLParse from 'url-parse';
|
||||
|
||||
export async function waitForLoad() {
|
||||
return new Promise(resolve => jQuery(resolve));
|
||||
}
|
||||
|
||||
export function parseLocation(location?: string | undefined) {
|
||||
return new URLParse(location || window.location.href, true);
|
||||
}
|
||||
|
||||
export function notify(msg: string): void {
|
||||
const n = new Notification(msg);
|
||||
setTimeout(() => n && n.close(), 4000);
|
||||
}
|
||||
|
||||
export function markPage(text: string, version: string) {
|
||||
jQuery('body').append(
|
||||
'<div style="' +
|
||||
'position: absolute; ' +
|
||||
'top: 0; left: 0; ' +
|
||||
'background-color: white; ' +
|
||||
'font-size: 24px; ' +
|
||||
'z-index: 9999; ' +
|
||||
'padding: 8px 6px; ' +
|
||||
'color: black">' +
|
||||
text +
|
||||
' ' +
|
||||
version +
|
||||
'</div>'
|
||||
);
|
||||
}
|
5
src/Helpers/Collection.ts
Normal file
5
src/Helpers/Collection.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import * as _ from 'underscore';
|
||||
|
||||
export function first<T>(items: ReadonlyArray<T>): T | undefined {
|
||||
return _.first(items);
|
||||
}
|
30
src/Helpers/Convert.ts
Normal file
30
src/Helpers/Convert.ts
Normal file
@ -0,0 +1,30 @@
|
||||
export function trimPrefix(text: string, prefix: string): string {
|
||||
return text.startsWith(prefix) ? text.substr(prefix.length) : text;
|
||||
}
|
||||
|
||||
export function elClassId(classes: string | undefined, prefix: string): number | undefined {
|
||||
if (classes === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
let result: number | undefined = undefined;
|
||||
classes.split(/\s/).forEach(part => {
|
||||
const match = part.match(new RegExp(prefix + '(\\d+)'));
|
||||
if (match) {
|
||||
result = toNumber(match[1]);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
export function toNumber(value: any): number | undefined {
|
||||
const normalized = String(value)
|
||||
.replace('\u2212', '\u002d') // minus to hyphen-minus
|
||||
.replace(/[^0-9\u002d]/g, '');
|
||||
const converted = Number(normalized);
|
||||
return isNaN(converted) ? undefined : converted;
|
||||
}
|
||||
|
||||
export function getNumber(value: any, def: number = 0): number {
|
||||
const converted = toNumber(value);
|
||||
return converted === undefined ? def : converted;
|
||||
}
|
6
src/Helpers/Format.ts
Normal file
6
src/Helpers/Format.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import * as dateFormat from 'dateformat';
|
||||
|
||||
export function formatDate(ts: number, format: string = 'HH:MM:ss') {
|
||||
const d = new Date(ts * 1000);
|
||||
return dateFormat(d, format);
|
||||
}
|
15
src/Helpers/Identity.ts
Normal file
15
src/Helpers/Identity.ts
Normal file
@ -0,0 +1,15 @@
|
||||
const ALPHABET = 'abcdefghijklmnopqrstuvwxyz1234567890';
|
||||
const ALPHABET_LENGTH = ALPHABET.length - 1;
|
||||
|
||||
function generateId(count: number): string {
|
||||
let str = '';
|
||||
for (let i = 0; i < count; ++i) {
|
||||
let symbolIndex = Math.floor(Math.random() * ALPHABET_LENGTH);
|
||||
str += ALPHABET[symbolIndex];
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
export function uniqId(prefix: string = 'id'): string {
|
||||
return prefix + generateId(6);
|
||||
}
|
10
src/Helpers/Random.ts
Normal file
10
src/Helpers/Random.ts
Normal file
@ -0,0 +1,10 @@
|
||||
export function randomInRange(from: number, to: number): number {
|
||||
const delta = to - from;
|
||||
const variation = Math.random() * delta;
|
||||
return Math.floor(from + variation);
|
||||
}
|
||||
|
||||
export function around(value: number, koeff: number): number {
|
||||
const delta = Math.floor(value * koeff);
|
||||
return randomInRange(value - delta, value + delta);
|
||||
}
|
19
src/Helpers/Time.ts
Normal file
19
src/Helpers/Time.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { around, randomInRange } from './Random';
|
||||
|
||||
export function sleep(ms: number) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export async function sleepMicro() {
|
||||
const timeInMs = randomInRange(1500, 2500);
|
||||
return await sleep(timeInMs);
|
||||
}
|
||||
|
||||
export function timestamp(): number {
|
||||
return Math.floor(Date.now() / 1000);
|
||||
}
|
||||
|
||||
export function aroundMinutes(minutes: number) {
|
||||
const seconds = minutes * 60;
|
||||
return around(seconds, 0.1);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { timestamp } from './utils';
|
||||
import { timestamp } from './Helpers/Time';
|
||||
|
||||
export interface Logger {
|
||||
info(...args: any[]): void;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { parseLocation } from './utils';
|
||||
import { parseLocation } from './Helpers/Browser';
|
||||
|
||||
export enum ManagementMode {
|
||||
Blank = 'blank',
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { GrabError } from '../../Errors';
|
||||
import { getNumber, trimPrefix, uniqId } from '../../utils';
|
||||
import { Resources } from '../../Core/Resources';
|
||||
import { getNumber, trimPrefix } from '../../Helpers/Convert';
|
||||
import { uniqId } from '../../Helpers/Identity';
|
||||
|
||||
export function clickBuildButton(typeId: number) {
|
||||
const section = jQuery(`#contract_building${typeId}`);
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { elClassId, getNumber, uniqId } from '../../utils';
|
||||
import { Resources } from '../../Core/Resources';
|
||||
import { grabResourcesFromList } from './BuildingPage';
|
||||
import { GrabError } from '../../Errors';
|
||||
import { elClassId, getNumber } from '../../Helpers/Convert';
|
||||
import { uniqId } from '../../Helpers/Identity';
|
||||
|
||||
interface ResearchClickHandler {
|
||||
(resources: Resources, unitId: number): void;
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { getNumber, uniqId } from '../../utils';
|
||||
import { Resources } from '../../Core/Resources';
|
||||
import { grabResourcesFromList } from './BuildingPage';
|
||||
import { GrabError } from '../../Errors';
|
||||
import { getNumber } from '../../Helpers/Convert';
|
||||
import { uniqId } from '../../Helpers/Identity';
|
||||
|
||||
interface CelebrationClickHandler {
|
||||
(resources: Resources, id: number): void;
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { getNumber, uniqId } from '../../utils';
|
||||
import { Resources, ResourcesInterface } from '../../Core/Resources';
|
||||
import { Coordinates } from '../../Core/Village';
|
||||
import { IncomingMerchant, MerchantsInfo } from '../../Core/Market';
|
||||
import { grabResourcesFromList } from './BuildingPage';
|
||||
import { getNumber } from '../../Helpers/Convert';
|
||||
import { uniqId } from '../../Helpers/Identity';
|
||||
|
||||
interface SendResourcesClickHandler {
|
||||
(resources: Resources, crd: Coordinates): void;
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Resources } from '../../Core/Resources';
|
||||
import { GrabError } from '../../Errors';
|
||||
import { elClassId, getNumber, uniqId } from '../../utils';
|
||||
import { grabResourcesFromList } from './BuildingPage';
|
||||
import { elClassId, getNumber } from '../../Helpers/Convert';
|
||||
import { uniqId } from '../../Helpers/Identity';
|
||||
|
||||
export function createTrainTroopButtons(
|
||||
onClickHandler: (troopId: number, resources: Resources, count: number) => void
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { notify } from '../utils';
|
||||
import { UpgradeBuildingTask } from '../Task/UpgradeBuildingTask';
|
||||
import { Scheduler } from '../Scheduler';
|
||||
import { TrainTroopTask } from '../Task/TrainTroopTask';
|
||||
@ -23,6 +22,7 @@ import { ForgeImprovementTask } from '../Task/ForgeImprovementTask';
|
||||
import { createCelebrationButtons } from './BuildingPage/GuildHallPage';
|
||||
import { CelebrationTask } from '../Task/CelebrationTask';
|
||||
import { VillageController } from '../VillageController';
|
||||
import { notify } from '../Helpers/Browser';
|
||||
|
||||
export class BuildingPageController {
|
||||
private scheduler: Scheduler;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { GrabError } from '../Errors';
|
||||
import { getNumber } from '../utils';
|
||||
import { ResourceMapping, ResourceType } from '../Core/ResourceType';
|
||||
import { HeroAllResources, HeroAttributes, HeroResourceType } from '../Core/Hero';
|
||||
import { getNumber } from '../Helpers/Convert';
|
||||
|
||||
export function grabHeroAttributes(): HeroAttributes {
|
||||
const healthElement = jQuery('#attributes .attribute.health .powervalue .value');
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { elClassId, getNumber, parseLocation } from '../utils';
|
||||
import { FORGE_ID, GUILD_HALL_ID, MARKET_ID } from '../Core/Buildings';
|
||||
import { elClassId, getNumber } from '../Helpers/Convert';
|
||||
import { parseLocation } from '../Helpers/Browser';
|
||||
|
||||
export interface BuildingPageAttributes {
|
||||
buildTypeId: number;
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { GrabError } from '../Errors';
|
||||
import { getNumber } from '../utils';
|
||||
import { Resources } from '../Core/Resources';
|
||||
import { ResourceType } from '../Core/ResourceType';
|
||||
import { ResourceStorage } from '../Core/ResourceStorage';
|
||||
import { getNumber } from '../Helpers/Convert';
|
||||
|
||||
export function grabVillageResources(): Resources {
|
||||
const lumber = grabResource(ResourceType.Lumber);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { elClassId, getNumber } from '../utils';
|
||||
import { numberToResourceType } from '../Core/ResourceType';
|
||||
import { BuildingSlot, ResourceSlot } from '../Core/Slot';
|
||||
import { elClassId, getNumber } from '../Helpers/Convert';
|
||||
|
||||
interface SlotElement {
|
||||
el: HTMLElement;
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { GrabError } from '../Errors';
|
||||
import { getNumber, parseLocation } from '../utils';
|
||||
import { Resources } from '../Core/Resources';
|
||||
import { Coordinates, Village, VillageList } from '../Core/Village';
|
||||
import { BuildingQueueInfo } from '../Core/BuildingQueueInfo';
|
||||
import { getNumber } from '../Helpers/Convert';
|
||||
import { parseLocation } from '../Helpers/Browser';
|
||||
|
||||
function getVillageListItems() {
|
||||
const $elements = jQuery('#sidebarBoxVillagelist ul li a');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Args } from './Args';
|
||||
import { uniqId } from '../utils';
|
||||
import { ResourcesInterface } from '../Core/Resources';
|
||||
import { ProductionQueue } from '../Core/ProductionQueue';
|
||||
import { getProductionQueue } from '../Task/TaskMap';
|
||||
import { uniqId } from '../Helpers/Identity';
|
||||
|
||||
export type TaskId = string;
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { around, timestamp } from './utils';
|
||||
import { TaskQueue } from './Queue/TaskQueue';
|
||||
import { BalanceHeroResourcesTask } from './Task/BalanceHeroResourcesTask';
|
||||
import { Logger } from './Logger';
|
||||
@ -12,6 +11,8 @@ import { VillageRepositoryInterface } from './VillageRepository';
|
||||
import { VillageFactory } from './VillageFactory';
|
||||
import { RunVillageProductionTask } from './Task/RunVillageProductionTask';
|
||||
import { isProductionTask } from './Task/TaskMap';
|
||||
import { around } from './Helpers/Random';
|
||||
import { timestamp } from './Helpers/Time';
|
||||
|
||||
interface NextExecution {
|
||||
task?: Task;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as dateFormat from 'dateformat';
|
||||
import { formatDate } from './Helpers/Format';
|
||||
|
||||
const KEY_FORMAT = 'yyyy-mm-dd-HH';
|
||||
const KEEP_RECORD_COUNT = 24;
|
||||
@ -23,7 +23,7 @@ export class Statistics {
|
||||
|
||||
incrementAction(ts: number): void {
|
||||
const stat = this.storage.getActionStatistics();
|
||||
const key = dateFormat(ts * 1000, KEY_FORMAT);
|
||||
const key = formatDate(ts, KEY_FORMAT);
|
||||
stat[key] = (stat[key] || 0) + 1;
|
||||
this.trimStatistics(stat);
|
||||
this.storage.setActionStatistics(stat);
|
||||
|
@ -4,7 +4,6 @@ import { ResourceStorage } from '../Core/ResourceStorage';
|
||||
import { IncomingMerchant, MerchantsInfo } from '../Core/Market';
|
||||
import { VillageSettings, VillageSettingsDefaults } from '../Core/Village';
|
||||
import { ProductionQueue } from '../Core/ProductionQueue';
|
||||
import { getNumber } from '../utils';
|
||||
import { Task, uniqTaskId } from '../Queue/TaskProvider';
|
||||
import {
|
||||
BuildingSlot,
|
||||
@ -12,6 +11,7 @@ import {
|
||||
ResourceSlot,
|
||||
ResourceSlotDefaults,
|
||||
} from '../Core/Slot';
|
||||
import { getNumber } from '../Helpers/Convert';
|
||||
|
||||
const RESOURCES_KEY = 'resources';
|
||||
const CAPACITY_KEY = 'capacity';
|
||||
|
@ -1,14 +1,9 @@
|
||||
import { uniqId } from './utils';
|
||||
import * as dateFormat from 'dateformat';
|
||||
import { ImmutableTaskList } from './Queue/TaskProvider';
|
||||
import { uniqId } from './Helpers/Identity';
|
||||
import { formatDate } from './Helpers/Format';
|
||||
|
||||
const ID = uniqId();
|
||||
|
||||
function formatDate(ts: number) {
|
||||
const d = new Date(ts * 1000);
|
||||
return dateFormat(d, 'HH:MM:ss');
|
||||
}
|
||||
|
||||
export class TaskQueueRenderer {
|
||||
render(tasks: ImmutableTaskList) {
|
||||
const ul = jQuery('<ul></ul>')
|
||||
|
@ -9,7 +9,7 @@ import { ReceiveResourcesMode } from './Core/Village';
|
||||
import { ResourceType } from './Core/ResourceType';
|
||||
import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask';
|
||||
import { GARNER_ID, WAREHOUSE_ID } from './Core/Buildings';
|
||||
import { first } from './utils';
|
||||
import { first } from './Helpers/Collection';
|
||||
|
||||
export class VillageController {
|
||||
private readonly villageId: number;
|
||||
|
@ -6,10 +6,10 @@ import { VillageRepositoryInterface } from './VillageRepository';
|
||||
import { VillageNotFound } from './Errors';
|
||||
import { OrderedProductionQueues, ProductionQueue } from './Core/ProductionQueue';
|
||||
import { isInQueue, TaskCore, TaskId } from './Queue/TaskProvider';
|
||||
import { timestamp } from './utils';
|
||||
import { VillageTaskCollection } from './VillageTaskCollection';
|
||||
import { TrainTroopTask } from './Task/TrainTroopTask';
|
||||
import { Args } from './Queue/Args';
|
||||
import { timestamp } from './Helpers/Time';
|
||||
|
||||
export interface TaskState {
|
||||
id: TaskId;
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { VillageStorage } from './Storage/VillageStorage';
|
||||
import { Task, TaskId, uniqTaskId, withResources, withTime } from './Queue/TaskProvider';
|
||||
import { Args } from './Queue/Args';
|
||||
import { timestamp } from './utils';
|
||||
import { Resources } from './Core/Resources';
|
||||
import { ContractAttributes, ContractType } from './Core/Contract';
|
||||
import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask';
|
||||
import { ForgeImprovementTask } from './Task/ForgeImprovementTask';
|
||||
import { isProductionTask } from './Task/TaskMap';
|
||||
import { timestamp } from './Helpers/Time';
|
||||
|
||||
export class VillageTaskCollection {
|
||||
private readonly storage: VillageStorage;
|
||||
|
112
src/utils.ts
112
src/utils.ts
@ -1,112 +0,0 @@
|
||||
import * as URLParse from 'url-parse';
|
||||
import * as _ from 'underscore';
|
||||
|
||||
export function sleep(ms: number) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export function randomInRange(from: number, to: number): number {
|
||||
const delta = to - from;
|
||||
const variation = Math.random() * delta;
|
||||
return Math.floor(from + variation);
|
||||
}
|
||||
|
||||
export function around(value: number, koeff: number): number {
|
||||
const delta = Math.floor(value * koeff);
|
||||
return randomInRange(value - delta, value + delta);
|
||||
}
|
||||
|
||||
export async function sleepMicro() {
|
||||
const timeInMs = randomInRange(1500, 2500);
|
||||
return await sleep(timeInMs);
|
||||
}
|
||||
|
||||
export function aroundMinutes(minutes: number) {
|
||||
const seconds = minutes * 60;
|
||||
return around(seconds, 0.1);
|
||||
}
|
||||
|
||||
export async function waitForLoad() {
|
||||
return new Promise(resolve => jQuery(resolve));
|
||||
}
|
||||
|
||||
const ALPHABET = 'abcdefghijklmnopqrstuvwxyz1234567890';
|
||||
const ALPHABET_LENGTH = ALPHABET.length - 1;
|
||||
|
||||
function generateId(count: number): string {
|
||||
let str = '';
|
||||
for (let i = 0; i < count; ++i) {
|
||||
let symbolIndex = Math.floor(Math.random() * ALPHABET_LENGTH);
|
||||
str += ALPHABET[symbolIndex];
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
export function uniqId(prefix: string = 'id'): string {
|
||||
return prefix + generateId(6);
|
||||
}
|
||||
|
||||
export function timestamp(): number {
|
||||
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 elClassId(classes: string | undefined, prefix: string): number | undefined {
|
||||
if (classes === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
let result: number | undefined = undefined;
|
||||
classes.split(/\s/).forEach(part => {
|
||||
const match = part.match(new RegExp(prefix + '(\\d+)'));
|
||||
if (match) {
|
||||
result = toNumber(match[1]);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
export function toNumber(value: any): number | undefined {
|
||||
const normalized = String(value)
|
||||
.replace('\u2212', '\u002d') // minus to hyphen-minus
|
||||
.replace(/[^0-9\u002d]/g, '');
|
||||
const converted = Number(normalized);
|
||||
return isNaN(converted) ? undefined : converted;
|
||||
}
|
||||
|
||||
export function getNumber(value: any, def: number = 0): number {
|
||||
const converted = toNumber(value);
|
||||
return converted === undefined ? def : converted;
|
||||
}
|
||||
|
||||
export function parseLocation(location?: string | undefined) {
|
||||
return new URLParse(location || window.location.href, true);
|
||||
}
|
||||
|
||||
export function notify(msg: string): void {
|
||||
const n = new Notification(msg);
|
||||
setTimeout(() => n && n.close(), 4000);
|
||||
}
|
||||
|
||||
export function markPage(text: string, version: string) {
|
||||
jQuery('body').append(
|
||||
'<div style="' +
|
||||
'position: absolute; ' +
|
||||
'top: 0; left: 0; ' +
|
||||
'background-color: white; ' +
|
||||
'font-size: 24px; ' +
|
||||
'z-index: 9999; ' +
|
||||
'padding: 8px 6px; ' +
|
||||
'color: black">' +
|
||||
text +
|
||||
' ' +
|
||||
version +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
|
||||
export function first<T>(items: ReadonlyArray<T>): T | undefined {
|
||||
return _.first(items);
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { it, describe } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { elClassId, getNumber } from '../src/utils';
|
||||
import { elClassId, getNumber } from '../../src/Helpers/Convert';
|
||||
|
||||
describe('Utils', function() {
|
||||
describe('getNumber', function() {
|
Loading…
Reference in New Issue
Block a user