Add task for building upgrade

This commit is contained in:
Anton Vakhrushev 2020-03-29 12:27:42 +03:00
parent 5c69dd6a90
commit b525ff0e27
13 changed files with 217 additions and 44 deletions

45
package-lock.json generated
View File

@ -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": {

View File

@ -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"
}

View File

@ -1,3 +1,3 @@
export default abstract class Action {
abstract async run();
abstract async run(args);
}

View File

@ -0,0 +1,10 @@
import Action from './Action';
export default class GoToBuildingAction extends Action {
static NAME = 'go_to_building';
async run(args): Promise<any> {
window.location.assign('/build.php?id=' + args.id);
return null;
}
}

View File

@ -0,0 +1,17 @@
import Action from './Action';
export default class UpgradeBuildingAction extends Action {
static NAME = 'upgrade_building';
async run(args): Promise<any> {
const btn = jQuery(
'.upgradeButtonsContainer .section1 button.green.build'
);
if (btn.length === 1) {
btn.trigger('click');
} else {
console.log('NO UPGRADE BUTTON');
}
return null;
}
}

40
src/Dashboard.ts Normal file
View File

@ -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(
'<div style="position: absolute; top: 0; left: 0; background-color: white">Dashboard</div>'
);
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(
`<div style="padding: 8px"><a id="${id}" href="#">В очередь</a></div>`
);
jQuery(`#${id}`).on('click', () => {
const queueItem = new QueueItem(UpgradeBuildingTask.NAME, {
id: p.query['id'],
});
this.scheduler.pushTask(queueItem);
return false;
});
}
}
}

View File

@ -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<QueueItem>)
: [];
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));
}
}

View File

@ -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);
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) {
// do task
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);
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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/**/*"