diff --git a/package-lock.json b/package-lock.json index f6b78f5..edd961a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -330,6 +330,15 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/jquery": { + "version": "3.3.34", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.34.tgz", + "integrity": "sha512-lW9vsVL53Xu/Nj4gi2hNmHGc4u3KKghjqTkAlO0kF5GIOPxbqqnQpgqJBzmn3yXLrPqHb6cmNJ6URnS23Vtvbg==", + "dev": true, + "requires": { + "@types/sizzle": "*" + } + }, "@types/mocha": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", @@ -342,12 +351,24 @@ "integrity": "sha512-uzaaDXey/NI2l7kU+xCgWu852Dh/zmf6ZKApc0YQEQpY4DaiZFmLN29E6SLHJfSedj3iNWAndSwfSBpEDadJfg==", "dev": true }, + "@types/sizzle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", + "dev": true + }, "@types/url-parse": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/@types/url-parse/-/url-parse-1.4.3.tgz", "integrity": "sha512-4kHAkbV/OfW2kb5BLVUuUMoumB3CP8rHqlw48aHvFy5tf9ER0AfOonBlX29l/DD68G70DmyhRlSYfQPSYpC5Vw==", "dev": true }, + "@types/uuid": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-7.0.2.tgz", + "integrity": "sha512-8Ly3zIPTnT0/8RCU6Kg/G3uTICf9sRwYOpUzSIM3503tLIKcnJPRuinHhXngJUy2MntrEf6dlpOHXJju90Qh5w==", + "dev": true + }, "@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -3262,6 +3283,12 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3360,6 +3387,12 @@ "istanbul-lib-report": "^3.0.0" } }, + "jquery": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", + "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -4243,6 +4276,12 @@ "ansi-regex": "^5.0.0" } }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -5833,9 +5872,9 @@ "dev": true }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.2.tgz", + "integrity": "sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw==", "dev": true }, "v8-compile-cache": { diff --git a/package.json b/package.json index ea9f6bc..02d83fd 100644 --- a/package.json +++ b/package.json @@ -22,10 +22,13 @@ }, "devDependencies": { "@types/chai": "^4.2.11", + "@types/jquery": "^3.3.34", "@types/mocha": "^7.0.2", "@types/node": "^13.9.4", "@types/url-parse": "^1.4.3", + "@types/uuid": "^7.0.2", "chai": "^4.2.0", + "jquery": "^3.4.1", "mocha": "^7.1.1", "mocha-junit-reporter": "^1.23.3", "nyc": "^15.0.0", @@ -34,6 +37,7 @@ "ts-node": "^8.8.1", "typescript": "^3.8.3", "url-parse": "^1.4.7", + "uuid": "^7.0.2", "webpack": "^4.42.1", "webpack-cli": "^3.3.11" } diff --git a/src/Action/Action.ts b/src/Action/Action.ts index 03ec84c..7966315 100644 --- a/src/Action/Action.ts +++ b/src/Action/Action.ts @@ -1,3 +1,3 @@ export default abstract class Action { - abstract async run(); + abstract async run(args); } diff --git a/src/Action/GoToBuildingAction.ts b/src/Action/GoToBuildingAction.ts new file mode 100644 index 0000000..83e6a86 --- /dev/null +++ b/src/Action/GoToBuildingAction.ts @@ -0,0 +1,10 @@ +import Action from './Action'; + +export default class GoToBuildingAction extends Action { + static NAME = 'go_to_building'; + + async run(args): Promise { + window.location.assign('/build.php?id=' + args.id); + return null; + } +} diff --git a/src/Action/UpgradeBuildingAction.ts b/src/Action/UpgradeBuildingAction.ts new file mode 100644 index 0000000..6ce2ca4 --- /dev/null +++ b/src/Action/UpgradeBuildingAction.ts @@ -0,0 +1,17 @@ +import Action from './Action'; + +export default class UpgradeBuildingAction extends Action { + static NAME = 'upgrade_building'; + + async run(args): Promise { + const btn = jQuery( + '.upgradeButtonsContainer .section1 button.green.build' + ); + if (btn.length === 1) { + btn.trigger('click'); + } else { + console.log('NO UPGRADE BUTTON'); + } + return null; + } +} diff --git a/src/Dashboard.ts b/src/Dashboard.ts new file mode 100644 index 0000000..30d35f9 --- /dev/null +++ b/src/Dashboard.ts @@ -0,0 +1,40 @@ +import * as URLParse from 'url-parse'; +import { sleep } from './utils'; +import { v4 as uuid } from 'uuid'; +import { QueueItem } from './Queue'; +import Scheduler from './Scheduler'; +import UpgradeBuildingTask from './Task/UpgradeBuildingTask'; + +export default class Dashboard { + private scheduler: Scheduler; + + constructor(scheduler: Scheduler) { + this.scheduler = scheduler; + } + + async run() { + jQuery('body').append( + '
Dashboard
' + ); + + const p = new URLParse(window.location.href, true); + console.log('PARSED LOCATION', p); + + await sleep(5000); + + if (p.pathname === '/build.php') { + console.log('BUILD PAGE DETECTED'); + const id = uuid(); + jQuery('.upgradeButtonsContainer .section1').append( + `
В очередь
` + ); + jQuery(`#${id}`).on('click', () => { + const queueItem = new QueueItem(UpgradeBuildingTask.NAME, { + id: p.query['id'], + }); + this.scheduler.pushTask(queueItem); + return false; + }); + } + } +} diff --git a/src/Queue.ts b/src/Queue.ts index 701c031..8931db3 100644 --- a/src/Queue.ts +++ b/src/Queue.ts @@ -27,7 +27,7 @@ export class Queue { } const first = items.shift(); - localStorage.setItem(this.name, JSON.stringify(items)); + this.flush(items); if (first === undefined) { return null; @@ -41,7 +41,12 @@ export class Queue { const items = serialized ? (JSON.parse(serialized) as Array) : []; - const first = items.push(item); + items.push(item); + this.flush(items); + } + + private flush(items) { + console.log('SET NEW QUEUE', this.name, items); localStorage.setItem(this.name, JSON.stringify(items)); } } diff --git a/src/Scheduler.ts b/src/Scheduler.ts index b7bebb8..4c37e86 100644 --- a/src/Scheduler.ts +++ b/src/Scheduler.ts @@ -1,6 +1,8 @@ -import { sleep } from './utils'; -import { Queue } from './Queue'; -import GoToMainAction from './Action/GoToMainAction'; +import { sleepLong } from './utils'; +import { Queue, QueueItem } from './Queue'; +import UpgradeBuildingTask from './Task/UpgradeBuildingTask'; +import GoToBuildingAction from './Action/GoToBuildingAction'; +import UpgradeBuildingAction from './Action/UpgradeBuildingAction'; const ACTION_QUEUE = 'action_queue'; const TASK_QUEUE = 'task_queue'; @@ -16,39 +18,76 @@ export default class Scheduler { async run() { while (true) { - const action = this.popAction(); - console.log('POP ACTION', action); - if (action !== null) { - await action.run(); + await sleepLong(); + const actionItem = this.popAction(); + this.log('POP ACTION ITEM', actionItem); + if (actionItem !== null) { + const action = this.createAction(actionItem); + this.log('POP ACTION', action); + if (action) { + await action.run(actionItem.args); + } } else { - const task = this.popTask(); - console.log('POP TASK', task); - if (task !== null) { - // do task + const taskItem = this.popTask(); + this.log('POP TASK ITEM', taskItem); + if (taskItem !== null) { + const task = this.createTask(taskItem); + this.log('POP TASK', task); + if (task !== null) { + task.run(taskItem.args); + } } } - const waitTime = Math.random() * 5000; - console.log('WAIT', waitTime); - await sleep(waitTime); } } + pushTask(task: QueueItem): void { + this.log('PUSH TASK', task); + this.taskQueue.push(task); + } + + pushAction(action: QueueItem): void { + this.log('PUSH ACTION', action); + this.actionQueue.push(action); + } + private popTask() { - const item = this.taskQueue.pop(); - if (item === null) { + const taskItem = this.taskQueue.pop(); + if (taskItem === null) { return null; } + return taskItem; + } + + private createTask(taskItem: QueueItem) { + switch (taskItem.name) { + case UpgradeBuildingTask.NAME: + return new UpgradeBuildingTask(this); + } + this.log('UNKNOWN TASK', taskItem.name); return null; } private popAction() { - const item = this.actionQueue.pop(); - if (item === null) { + const actionItem = this.actionQueue.pop(); + if (actionItem === null) { return null; } - if (item.name === 'go_to_main') { - return new GoToMainAction(); + this.log('UNKNOWN ACTION', actionItem.name); + return actionItem; + } + + private createAction(actionItem: QueueItem) { + if (actionItem.name === GoToBuildingAction.NAME) { + return new GoToBuildingAction(); + } + if (actionItem.name === UpgradeBuildingAction.NAME) { + return new UpgradeBuildingAction(); } return null; } + + private log(...args) { + console.log('SCHEDULER', ...args); + } } diff --git a/src/Task/UpgradeBuildingTask.ts b/src/Task/UpgradeBuildingTask.ts new file mode 100644 index 0000000..98da2e7 --- /dev/null +++ b/src/Task/UpgradeBuildingTask.ts @@ -0,0 +1,21 @@ +import Scheduler from '../Scheduler'; +import GoToBuildingAction from '../Action/GoToBuildingAction'; +import UpgradeBuildingAction from '../Action/UpgradeBuildingAction'; +import { QueueItem } from '../Queue'; + +export default class UpgradeBuildingTask { + static NAME = 'upgrade_building'; + private scheduler: Scheduler; + + constructor(scheduler: Scheduler) { + this.scheduler = scheduler; + } + + run(args) { + console.log('RUN', UpgradeBuildingTask.NAME, 'with', args); + this.scheduler.pushAction(new QueueItem(GoToBuildingAction.NAME, args)); + this.scheduler.pushAction( + new QueueItem(UpgradeBuildingAction.NAME, args) + ); + } +} diff --git a/src/index.ts b/src/index.ts index 31d89c4..5885e82 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ import ModeDetector from './ModeDetector'; import Scheduler from './Scheduler'; +import Dashboard from './Dashboard'; const md = new ModeDetector(); if (md.isAuto()) { @@ -9,4 +10,6 @@ if (md.isAuto()) { scheduler.run(); } else { console.log('NORMAL MODE'); + const dashboard = new Dashboard(new Scheduler()); + dashboard.run(); } diff --git a/src/utils.ts b/src/utils.ts index f457501..a93b75c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,15 @@ -function sleep(ms: number) { +export function sleep(ms: number) { return new Promise(resolve => setTimeout(resolve, ms)); } -export { sleep }; +export async function sleepShort() { + let ms = 2000 + Math.random() * 10000; + console.log('SLEEp SHORT', Math.round(ms)); + return await sleep(ms); +} + +export async function sleepLong() { + let ms = 10000 + Math.random() * 10000; + console.log('SLEEP LONG', Math.round(ms)); + return await sleep(ms); +} diff --git a/travian.user.js b/travian.user.js deleted file mode 100644 index 8290465..0000000 --- a/travian.user.js +++ /dev/null @@ -1,15 +0,0 @@ -// ==UserScript== -// @name New Userscript -// @namespace http://tampermonkey.net/ -// @version 0.1 -// @description try to take over the world! -// @author You -// @match http://*/* -// @grant none -// ==/UserScript== - -(function() { - 'use strict'; - - // Your code here... -})(); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index e7ea427..47c7786 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,7 @@ "target": "es5", "module": "commonjs", "strictNullChecks": true, - "types": ["node", "url-parse", "mocha", "chai"] + "types": ["node", "url-parse", "jquery", "uuid", "mocha", "chai"] }, "include": [ "./src/**/*"