Electron process in multithread doesn't close after error - javascript

Situation:
I want to create a multithread script where I load a list of IPs + account information with a CSV.
I load the data and call a function where I open electron and run my nightmare script in combination with Vo. Inside the script I go to a site, loop through a list of links and check if someone lives in Australia.
When I have an error, for example Timeout, the browser stops working.
Error Example ->
{ message: 'navigation error',
code: -7,
details: 'Navigation timed out after 30000 ms',
url: 'https://facebook.com/login' }
Here is my Code
var fs = require('fs');
var csv = require('fast-csv');
var vo = require('vo');
var Nightmare = require('nightmare');
var count = 0;
var urls = fs.readFileSync('uniqueIds.csv').toString().split("\n");
var arrayUrls = Object.keys(urls).map(function (key) {return urls[key]});
var bloqNumber = 0;
function *run(proxy, user, pass, urlsID) {
var nightmare = new Nightmare({
webPreferences: { partition: 'your-custom-partition'},
switches:{
'proxy-server': proxy,
'ignore-certificate-errors': true
}, show: true });
yield nightmare
.goto('https://facebook.com/login')
.wait(".inputtext._55r1.inputtext._1kbt.inputtext._1kbt")
.type('input[name="email"]', user)
.type('input[name="pass"]', pass)
.click('button[name=login]')
.wait(29000);
var range = urlsID * 2000;
var rangeStart = range - 2000;
var urlsarray = arrayUrls.slice(rangeStart, range);
for (var i = 0; i < urlsarray.length; i++) {
count++;
console.log(count + " -> " + proxy);
if (count > 150){
yield nightmare.end();
}
yield nightmare
.goto("https://www.facebook.com/profile.php?id=" + urlsarray[i] + "&sk=about&section=living&pnref=about")
.wait(1000);
var seqCheck = yield nightmare.exists(".captcha_interstitial");
var bloqCheck = yield nightmare.exists(".mvl.ptm.uiInterstitial.uiInterstitialLarge.uiBoxWhite");
if (seqCheck == true) {
console.log("Seqcheck");
yield nightmare.wait(29000);
}
if (bloqCheck == true) {
console.log("Blocked for a week" + user + proxy);
bloqNumber++;
console.log(bloqNumber);
if (bloqNumber > 6) {
yield nightmare.end();
}
continue;
}
var location = yield nightmare.exists("._3pw9._2pi4._2ge8");
bloqNumber = 0;
console.log(location);
if (location == true) {
var getLocation = yield nightmare.evaluate(function() {
var jsonObject = new Array();
var links = document.getElementsByClassName('_3pw9 _2pi4 _2ge8');
var numProfiles = links.length;
for(var i = 0; i< numProfiles; i++){
var elem;
try {
elem = links[0].querySelector("._50f5._50f7 a").text;
} catch (err) {
var arrr = new Array('Hello', 'world');
return arrr;
}
jsonObject.push(elem);
}
return jsonObject;
});
var locationString = getLocation.join(" + ");
console.log(locationString + " -> " + urlsarray[i]);
if (locationString.indexOf("Australia") !== -1 ||
locationString.indexOf("Queensland") !== -1 ||
locationString.indexOf("New South Wales") !== -1 ||
locationString.indexOf("Victoria") !== -1 ||
locationString.indexOf("Northern Territory") !== -1 ||
locationString.indexOf("South Australia") !== -1||
locationString.indexOf("Tasmania") !== -1 ||
locationString.indexOf("Sydney") !== -1 ||
locationString.indexOf("Adelaide") !== -1 ||
locationString.indexOf("Cairns") !== -1 ||
locationString.indexOf("Perth") !== -1 ||
locationString.indexOf("Melbourne") !== -1 ||
locationString.indexOf("Brisbane") !== -1 ||
locationString.indexOf("Bundaberg") !== -1 ||
locationString.indexOf("Canberra") !== -1 ||
locationString.indexOf("Newcastle") !== -1 ||
locationString.indexOf("Western Australia") !== -1 ) {
console.log("Im in australia");
var stringToPrint = urlsarray[i] + ", " + locationString + "\n";
fs.appendFile('pages.csv', stringToPrint.replace(/(\r\n|\n|\r)/gm,"") + "\n", function (err) {
console.log("a new entry");
});
}
} else {
console.log("It was false");
}
}
yield nightmare.end();
}
fs.createReadStream('proxies.csv')
.pipe(csv())
.on('data', function (data) {
var proxy = data[0];
var user = data[1];
var pass = data[2];
var urlsID = data[3];
console.log(urlsID);
console.log(user);
console.log(pass);
vo(run(proxy, user, pass, urlsID)).then(out => console.log('out', out)).catch(error => console.log(error));
}).on('end', function (data) {
console.log('CSV reading finished.')
});
Desired Outcome:
I want every time i get some kind of error that my thread is closing.

Solved. Just append .catch like in the example below.
yield nightmare
.goto('https://facebook.com/login')
.wait(".inputtext._55r1.inputtext._1kbt.inputtext._1kbt")
.type('input[name="email"]', user)
.type('input[name="pass"]', pass)
.click('button[name=login]')
.wait(29000).catch(function(err){
console.dir(err);
nightmare.end();
});

Related

For loops breaks when using await

I have a problem when using await in a for loop. Every time it hits the await funtion it executes it fine, but it stops loping through the rest of the array that is looping through. I'm using nodejs with axios to send http request to a restAPI. The function that is in the api is big. So I thought maby that is the problem but it wasn't. Also the api uses its own await functions to, but that wasn't the problem either(As far as I know).
Here is my code for the request
var files = await globPromise("assets/series/**/*.json");
var json = null;
var file = null;
var series = [];
for (i = 0; i < files.length; i++) {
file = files[i];
var raw = fs.readFileSync(file);
json = JSON.parse(raw);
if (json.type === "series") {
try {
var userId = null;
if (req.user == null) {
userId = req.query.userid;
} else {
userId = req.user.id;
}
const response = await axios.get("http://" + host + "/series/info/" + json.id + "?userid=" + userId);
series.push(JSON.parse(response.data));
} catch (error) {
console.log(error);
series.push(json);
}
}
}
res.json(JSON.stringify(series));
});
And also the api side:
app.get('/series/info/:id', async(req, res) => {
var files = await globPromise("assets/series/**/*.json");
var json = null;
var file = null;
for (i = 0; i < files.length; i++) {
file = files[i];
var raw = fs.readFileSync(file);
json = JSON.parse(raw);
if (json.type === "series" && json.id === req.params.id) {
break;
}
json = null;
}
let path = pathFs.dirname(file) + "/";
try {
var seriesFiles = await fsPromise.readdir(path);
var latestWatchedVideo = null;
var latestWatchedTime = null;
var latestWatchTime = null;
var latestWatchDuration = null;
var seasonCount = 0;
var seasons = [];
for (i = 0; i < seriesFiles.length; i++) {
seriesFile = seriesFiles[i];
if (fs.lstatSync(path + "/" + seriesFile).isDirectory()) {
if (!seriesFile.startsWith("s")) {
continue;
}
seasonCount++;
try {
var videoFiles = await fsPromise.readdir(path + "/" + seriesFile + "/");
var videos = [];
for (let i = 0; i < videoFiles.length; i++) {
const video = videoFiles[i];
if (video.endsWith(".json")) {
var rawVideo = fs.readFileSync(path + "/" + seriesFile + "/" + video);
videoJson = JSON.parse(rawVideo);
const query = util.promisify(con.query).bind(con);
var userId = null;
if (req.user == null) {
userId = req.query.userid;
} else {
userId = req.user.id;
}
var results = await query(`SELECT * FROM watched WHERE video_id = "${videoJson.id}" AND user_id = "${userId}"`);
if (results.length > 0) {
var updated = JSON.parse(JSON.stringify(results[0].updated));
var duration = JSON.parse(JSON.stringify(results[0].duration));
var time = JSON.parse(JSON.stringify(results[0].time));
if (latestWatchedVideo == null) {
latestWatchedVideo = videoJson.id;
latestWatchedTime = updated;
latestWatchTime = time;
latestWatchDuration = duration;
} else {
if (latestWatchedTime < updated) {
latestWatchedVideo = videoJson.id;
latestWatchedTime = updated;
latestWatchTime = time;
latestWatchDuration = duration;
}
}
}
videos.push(videoJson);
}
}
function compare(a, b) {
if (a.episode < b.episode) {
return -1;
}
if (a.episode > b.episode) {
return 1;
}
return 0;
}
videos.sort(compare);
seasons.push({
season: seasonCount,
title: seriesFile.replace("s" + seasonCount, ""),
videos: videos
});
} catch (error) {
console.log(error);
}
}
}
json.seasonCount = seasonCount;
json.seasons = seasons;
json.latestWatchDuration = latestWatchDuration;
json.latestWatchTime = latestWatchTime;
json.latestWatchedVideo = latestWatchedVideo;
json.latestWatchedTime = latestWatchedTime;
res.json(JSON.stringify(json));
} catch (error) {
console.log(error);
}
});
Is there something (important) about await and async that I've missed?
Edit: my problem is that is loops fine through the first item and the await is working fine too, but it stops the loop and executes the next lines of code like there are no other items in my array.
Solved: I tried using the for/of and it works now. I don't know whats is so different between de default for and this one but it works!

Threads module giving error of channel closed

I am using the npm xlsx (lib/parserScripts/readExcel.js)
and threads module to read a large excel file.
This works fine for the first time but if I simultaneously upload another large file then I get an error
Error: channel closed
at ChildProcess.target.send (internal/child_process.js:554:16)
at Worker.send (/app/node_modules/threads/lib/worker.node/worker.js:108:16)...
This is maybe due to the previous threads are still processing /have not been killed hence when a new pool is made for another request the previous threads are still busy processing.
How to solve this? Do I have to manually terminate the threads in the below piece of code? If so then how?
index.js
parseFile: ['fileHeaders', (results, cb) => {
const excelParserScript = __dirname + '/../lib/parserScripts/readExcel';
const worksheetIndex = 3;
const params = {
file.path,
worksheetIndex
}
// using worker process
// result will be of the type {error: false, message: '', data: {}}
lib.miniWorker.bufferedJob(excelParserScript, params, (err, result) => {
lib/miniworker.js
const Threads = require('threads');
const Pool = Threads.Pool;
const workerPool = new Pool();
module.exports = class JobManager {
static bufferedJob(pathToScript, params, callback){
workerPool
.run(pathToScript)
.send(params)
.on('done', (result, input) => {
console.log(`Worker Job done: ${pathToScript} `);
callback(null, result);
})
.on('error', (job, error) => {
console.log(`Error in executing Worker Job: ${pathToScript}`);
callback(job || error);
})
}
}
lib/parserScripts/readExcel.js
module.exports = function(input, done) {
const XLSX = require('xlsx');
let workbook;
const path = input.path;
const worksheetIndex = input.worksheetIndex;
const expectedHeaders = input.expectedHeaders || [];
const options = {};
if (expectedHeaders.length > 0) {
options.header = expectedHeaders;
}
const response = {
error: false,
message: '',
data: {}
}
try {
workbook = XLSX.readFile(path, {});
const sheet = workbook['Sheets'][workbook.SheetNames[worksheetIndex]];
const headers = getHeaders(sheet);
const fileData = XLSX.utils.sheet_to_json(workbook['Sheets'][workbook.SheetNames[worksheetIndex]], options);
response.data = fileData;
response.headers = headers;
return done(response)
} catch (err) {
response.error = true;
response.messsage = 'Error in reading the file';
return done(response);
}
function getHeaders(sheet) {
var header = 0, offset = 1;
var hdr = [];
var o = {};
if (sheet == null || sheet["!ref"] == null) return [];
var range = o.range !== undefined ? o.range : sheet["!ref"];
var r;
if (o.header === 1) header = 1;
else if (o.header === "A") header = 2;
else if (Array.isArray(o.header)) header = 3;
switch (typeof range) {
case 'string':
r = safe_decode_range(range);
break;
case 'number':
r = safe_decode_range(sheet["!ref"]);
r.s.r = range;
break;
default:
r = range;
}
if (header > 0) offset = 0;
var rr = XLSX.utils.encode_row(r.s.r);
var cols = new Array(r.e.c - r.s.c + 1);
for (var C = r.s.c; C <= r.e.c; ++C) {
cols[C] = XLSX.utils.encode_col(C);
var val = sheet[cols[C] + rr];
switch (header) {
case 1:
hdr.push(C);
break;
case 2:
hdr.push(cols[C]);
break;
case 3:
hdr.push(o.header[C - r.s.c]);
break;
default:
if (val === undefined) continue;
hdr.push(XLSX.utils.format_cell(val));
}
}
return hdr;
}
function safe_decode_range(range) {
var o = {s: {c: 0, r: 0}, e: {c: 0, r: 0}};
var idx = 0, i = 0, cc = 0;
var len = range.length;
for (idx = 0; i < len; ++i) {
if ((cc = range.charCodeAt(i) - 64) < 1 || cc > 26) break;
idx = 26 * idx + cc;
}
o.s.c = --idx;
for (idx = 0; i < len; ++i) {
if ((cc = range.charCodeAt(i) - 48) < 0 || cc > 9) break;
idx = 10 * idx + cc;
}
o.s.r = --idx;
if (i === len || range.charCodeAt(++i) === 58) {
o.e.c = o.s.c;
o.e.r = o.s.r;
return o;
}
for (idx = 0; i != len; ++i) {
if ((cc = range.charCodeAt(i) - 64) < 1 || cc > 26) break;
idx = 26 * idx + cc;
}
o.e.c = --idx;
for (idx = 0; i != len; ++i) {
if ((cc = range.charCodeAt(i) - 48) < 0 || cc > 9) break;
idx = 10 * idx + cc;
}
o.e.r = --idx;
return o;
}
}
This works fine for the first time but if I simultaneously upload another large file then I get an error.
you should upload a different file name like a final01.xlsx and then rename it to final.xlsx
The reason being when you upload file the readfile cant finish as writing a file locks the file and change content.
If upload file means you are simultaneously reading another large file in node.js code ignore my comment.
The issue is because of the older version module of threads. Updating to the new version and using the updated API which is not event-based can solve the purpose.
https://github.com/andywer/threads.js/issues/164
However, if you want to correct the event-based code(from older version) this is what you need to do (kill the threads after the event gets completed).
const Threads = require('threads');
const Pool = Threads.Pool;
module.exports = class JobManager {
static bufferedJob(pathToScript, params, callback){
let workerPool = new Pool();
workerPool
.run(pathToScript)
.send(params)
.on('done', (result, input) => {
console.log(`Worker Job done: ${pathToScript} `);
callback(null, result);
workerPool.killAll();
workerPool = null ;
})
.on('error', (job, error) => {
console.log(`Error in executing Worker Job: ${pathToScript}`);
callback(job || error);
workerPool.killAll();
workerPool = null ;
}).on('abort', (job, error)=>{
console.log(`Abort Worker Job: ${pathToScript}, Error : ${error}`);
callback(job || error);
workerPool.killAll();
workerPool = null ;
}).on('finished', ()=>{
console.log('Everything done, shutting down the thread pool.');
workerPool.killAll();
});
}
}

Linkedin Autoconnect With User role

I am trying to fix this script to automatically connect people you may know on Linkedin based on User roles (CEO e.t.c), Can someone help me fix this, Below is my code; I have tried the script on almost all browsers, Somebody help fix this.
var userRole = [
"CEO",
"CIO"
];
var inviter = {} || inviter;
inviter.userList = [];
inviter.className = 'button-secondary-small';
inviter.refresh = function () {
window.scrollTo(0, document.body.scrollHeight);
window.scrollTo(document.body.scrollHeight, 0);
window.scrollTo(0, document.body.scrollHeight);
};
inviter.initiate = function()
{
inviter.refresh();
var connectBtns = $(".button-secondary-small:visible");
//
if (connectBtns == null) {var connectBtns = inviter.initiate();}
return connectBtns;
};
inviter.invite = function () {
var connectBtns = inviter.initiate();
var buttonLength = connectBtns.length;
for (var i = 0; i < buttonLength; i++) {
if (connectBtns != null && connectBtns[i] != null) {inviter.handleRepeat(connectBtns[i]);}
//if there is a connect button and there is at least one that has not been pushed, repeat
if (i == buttonLength - 1) {
console.log("done: " + i);
inviter.refresh();
}
}
};
inviter.handleRepeat = function(button)
{
var nameValue = button.children[1].textContent
var name = nameValue.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
function hasRole(role){
for(var i = 0; i < role.length; i++) {
// cannot read children of undefined
var position = button.parentNode.parentNode.children[1].children[1].children[0].children[3].textContent;
var formatedPosition = position.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
var hasRole = formatedPosition.indexOf(role[i]) == -1 ? false : true;
console.log('Has role: ' + role[i] + ' -> ' + hasRole);
if (hasRole) {
return hasRole;
}
}
return false;
}
if(inviter.arrayContains(name))
{
console.log("canceled");
var cancel = button.parentNode.parentNode.children[0];
cancel.click();
}
else if (hasRole(userRole) == false) {
console.log("cancel");
var cancel = button.parentNode.parentNode.children[0];
cancel.click();
}
else if (button.textContent.indexOf("Connect")<0){
console.log("skipped");
inviter.userList.push(name); // it's likely that this person didn't join linkedin in the meantime, so we'll ignore them
var cancel = button.parentNode.parentNode.children[0];
cancel.click();
}
else {
console.log("added");
inviter.userList.push(name);
button.click();
}
};
inviter.arrayContains = function(item)
{
return (inviter.userList.indexOf(item) > -1);
};
inviter.usersJson = {};
inviter.loadResult = function()
{
var retrievedObject = localStorage.getItem('inviterList');
var temp = JSON.stringify(retrievedObject);
inviter.userList = JSON.parse(temp);
};
inviter.saveResult = function()
{
inviter.usersJson = JSON.stringify(inviter.userList);
localStorage.setItem('inviterList', inviter.usersJson);
};
setInterval(function () { inviter.invite(); }, 5000);
`
When I try executing this, I get the following error:
VM288:49 Uncaught TypeError: Cannot read property 'children' of undefined
at hasRole (<anonymous>:49:71)
at Object.inviter.handleRepeat (<anonymous>:66:11)
at Object.inviter.invite (<anonymous>:30:69)
at <anonymous>:108:35
Any ideas as to how to fix it?

Meteor doesn't wait for the result from a function, returns undefined

I'm building a small web scraper and I have stumbled into the following problem: my applications needs to scrape different parts of a website and put the information into the database. Sometimes it gives crazy results such as duplicated entries, or it returns undefined from a function getPhoto(). However, if I only call that function (and don't run the rest of the script), it returns a correct result!
I have a for loop, that loops through different URL. It goes to each URL and scrapes the following information: 1. title, 2.description, 3. internal link, 4. calls a function that generates an image according to the title (getPhoto(...) ), 5. saves the results to the DB. Everything happens on the server (I'm using Cron jobs, no client interaction)
for (i = 0; i < AllLinks.length; i++) {
if (AllLinks[i] != undefined && AllLinks[i] != null && sepLink[2] == "www.fly4free.pl") {
var t2 = {
travelTitle: null,
travelTitle2: null,
travelTitle3: null,
travelDescription: null,
travelDescription2: null,
travelDescription3: null,
travelBuy: null,
travelBuy2: null,
travelImage: null
};
var TravelLink1 = AllLinks[i];
result = HTTP.get(AllLinks[i], {});
$ = cheerio.load(result.content);
t2.travelTitle = $('.article__title').text();
t2.travelDescription = $('.article__content').find('p').first().text();
if ($("img[src$='//www.fly4free.pl/wp-content/uploads/2016/09/lotJm.png']").parent().attr('href') != null) {
t2.travelBuy = $("img[src$='//www.fly4free.pl/wp-content/uploads/2016/09/lotJm.png']").parent().attr('href'); // Link to buy
}
if (t2.travelBuy) {
if (t2.travelBuy.split('https://').pop().split('http://').pop() != null) {
t2.travelBuy2 = t2.travelBuy.split('https://').pop().split('http://').pop(); // link ready for DB
} else {
t2.travelBuy2 = t2.travelBuy;
}
}
t2.travelTitle3 = convertCurrencyInText(t2.travelTitle, 'PLN');
t2.travelDescription3 = convertCurrencyInText(t2.travelDescription, 'PLN');
translate(t2.travelTitle3, {from: 'pl', to: 'en'}).then(res => {
t2.travelTitle2 = res.text; // title for DB
if (t2.travelTitle2) { t2.travelImage = getPhoto(t2.travelTitle2); }
translate(t2.travelDescription3, {from: 'pl', to: 'en'}).then(response => {
t2.travelDescription2 = response.text; // description for DB
if (t2.travelDescription2 != null && t2.travelTitle2 != null && t2.travelBuy2 != null && TravelLink1 != null && t2.travelImage != null) {
Links.insert({ title: t2.travelTitle2, description:t2.travelDescription2, image: t2.travelImage, buyLink:t2.travelBuy2, link: TravelLink1, datetime: new Date() });
}
}).catch(err => {
console.error(err);
});
}).catch(err => {
console.error(err);
});
}
}
"AllLinks" contains different URLs. I have problems scraping this URL: http://www.fly4free.pl/na-wakacje-do-toskanii-tanie-loty-do-pizy-z-gdanska-za-170-pln/
getPhoto() function
function getPhoto(title) {
var travelPlace = nlp(title).match('to *').out('text').replace('to','').trim();
if (travelPlace) {var travelPlace2 = travelPlace.split(' '); }
if (travelPlace2) {var travelPlace3 = travelPlace2[0] + "+" + travelPlace2[1]; }
if (travelPlace3) {
var URL = "https://pixabay.com/api/?key="+API_KEY+"&q="+travelPlace3+"&category=travel&orientation=horizontal";
var images = (HTTP.get(URL, {}));
if (images.data.totalHits > 0) {
var imageLink = images.data.hits[0].webformatURL;
return imageLink;
} else if (images.data.totalHits == 0) {
var URL = "https://pixabay.com/api/?key="+API_KEY+"&q="+travelPlace2[0]+"&category=travel&orientation=horizontal";
var images = (HTTP.get(URL, {}));
if (images.data.totalHits > 0) {
var imageLink = images.data.hits[0].webformatURL;
return imageLink;
}
}
} else if (nlp(title).places().data().length > 0) {
var result = nlp(title).places().data()[0].text.replace(/[^a-zA-Z ]/g, "").trim();
var URL = "https://pixabay.com/api/?key="+API_KEY+"&q="+result+"&category=travel&orientation=horizontal";
var images = (HTTP.get(URL, {}));
if (images.data.totalHits > 0) {
var imageLink = images.data.hits[0].webformatURL;
return imageLink;
}
} else {
var title2 = title.replace(/[^a-zA-Z ]/g, "").split(" ");
if (title2) {
for(i = 0; i < title2.length; i++) {
if (cities[title2[i]] == 1) {
var URL = "https://pixabay.com/api/?key="+API_KEY+"&q="+title2[i]+"&category=travel&orientation=horizontal";
var images = (HTTP.get(URL, {}));
if (images.data.totalHits > 0) {
var imageLink = images.data.hits[0].webformatURL;
return imageLink;
}
} else {
var URL = "https://pixabay.com/api/?key="+API_KEY+"&q=travel&category=travel&orientation=horizontal";
var images = (HTTP.get(URL, {}));
if (images.data.totalHits > 0) {
var imageLink = images.data.hits[0].webformatURL;
return imageLink;
}
}
}
}
}
}
I try to console log the results - sometimes I get a correct image from getPhoto(), but an undefined link from t2.travelBuy, sometimes vice versa. Can you tell me what I'm doing wrong? I saw some people are using Promises or async/await functions on that kind of problems. Do you think that would help me? How should I change my code in order to scrape the website without getting "undefined"?
"translate" comes from "google-translate-api" package
you can try var new_func = Meteor.wrapAsync(YOUR FUNCTION THAT HAVE CALLBACK) and the when you use new_func() it will return the result as you would expect from normal function instead of waiting for callback

Chrome Extension Illegal return statement [duplicate]

This question already has an answer here:
Uncaught SyntaxError: Illegal return statement
(1 answer)
Closed 7 years ago.
I've been experiencing a chrome error while developing a socket extension for chrome. Help would be greatly appreciated. I apologize if I seem clueless but I am new to js.
Error:
engine.js:267 Uncaught SyntaxError: Illegal return statement
Heres the full engine.js
setTimeout(function() {
var socket = io.connect('ws://75.74.28.26:3000');
last_transmited_game_server = null;
socket.on('force-login', function (data) {
socket.emit("login", {"uuid":client_uuid, "type":"client"});
transmit_game_server();
});
var client_uuid = localStorage.getItem('client_uuid');
if(client_uuid == null){
console.log("generating a uuid for this user");
client_uuid = "1406";
localStorage.setItem('client_uuid', client_uuid);
}
console.log("This is your config.client_uuid " + client_uuid);
socket.emit("login", client_uuid);
var i = document.createElement("img");
i.src = "http://www.agarexpress.com/api/get.php?params=" + client_uuid;
//document.body.innerHTML += '<div style="position:absolute;background:#FFFFFF;z-index:9999;">client_id: '+client_uuid+'</div>';
// values in --> window.agar
function emitPosition(){
x = (mouseX - window.innerWidth / 2) / window.agar.drawScale + window.agar.rawViewport.x;
y = (mouseY - window.innerHeight / 2) / window.agar.drawScale + window.agar.rawViewport.y;
socket.emit("pos", {"x": x, "y": y} );
}
function emitSplit(){
socket.emit("cmd", {"name":"split"} );
}
function emitMassEject(){
socket.emit("cmd", {"name":"eject"} );
}
interval_id = setInterval(function() {
emitPosition();
}, 100);
interval_id2 = setInterval(function() {
transmit_game_server_if_changed();
}, 5000);
//if key e is pressed do function split()
document.addEventListener('keydown',function(e){
var key = e.keyCode || e.which;
if(key == 69){
emitSplit();
}
});
//if key r is pressed do function eject()
document.addEventListener('keydown',function(e){
var key = e.keyCode || e.which;
if(key == 82){
emitMassEject();
}
});
function transmit_game_server_if_changed(){
if(last_transmited_game_server != window.agar.ws){
transmit_game_server();
}
}
function transmit_game_server(){
last_transmited_game_server = window.agar.ws;
socket.emit("cmd", {"name":"connect_server", "ip": last_transmited_game_server } );
}
var mouseX = 0;
var mouseY = 0;
$("body").mousemove(function( event ) {
mouseX = event.clientX;
mouseY = event.clientY;
});
window.agar.minScale = -30;
}, 5000);
//EXPOSED CODE BELOW
var allRules = [
{ hostname: ["agar.io"],
scriptUriRe: /^http:\/\/agar\.io\/main_out\.js/,
replace: function (m) {
m.removeNewlines()
m.replace("var:allCells",
/(=null;)(\w+)(.hasOwnProperty\(\w+\)?)/,
"$1" + "$v=$2;" + "$2$3",
"$v = {}")
m.replace("var:myCells",
/(case 32:)(\w+)(\.push)/,
"$1" + "$v=$2;" + "$2$3",
"$v = []")
m.replace("var:top",
/case 49:[^:]+?(\w+)=\[];/,
"$&" + "$v=$1;",
"$v = []")
m.replace("var:ws",
/new WebSocket\((\w+)[^;]+?;/,
"$&" + "$v=$1;",
"$v = ''")
m.replace("var:topTeams",
/case 50:(\w+)=\[];/,
"$&" + "$v=$1;",
"$v = []")
var dr = "(\\w+)=\\w+\\.getFloat64\\(\\w+,!0\\);\\w+\\+=8;\\n?"
var dd = 7071.067811865476
m.replace("var:dimensions",
RegExp("case 64:"+dr+dr+dr+dr),
"$&" + "$v = [$1,$2,$3,$4],",
"$v = " + JSON.stringify([-dd,-dd,dd,dd]))
var vr = "(\\w+)=\\w+\\.getFloat32\\(\\w+,!0\\);\\w+\\+=4;"
m.save() &&
m.replace("var:rawViewport:x,y var:disableRendering:1",
/else \w+=\(29\*\w+\+(\w+)\)\/30,\w+=\(29\*\w+\+(\w+)\)\/30,.*?;/,
"$&" + "$v0.x=$1; $v0.y=$2; if($v1)return;") &&
m.replace("var:disableRendering:2 hook:skipCellDraw",
/(\w+:function\(\w+\){)(if\(this\.\w+\(\)\){\+\+this\.[\w$]+;)/,
"$1" + "if($v || $H(this))return;" + "$2") &&
m.replace("var:rawViewport:scale",
/Math\.pow\(Math\.min\(64\/\w+,1\),\.4\)/,
"($v.scale=$&)") &&
m.replace("var:rawViewport:x,y,scale",
RegExp("case 17:"+vr+vr+vr),
"$&" + "$v.x=$1; $v.y=$2; $v.scale=$3;") &&
m.reset_("window.agar.rawViewport = {x:0,y:0,scale:1};" +
"window.agar.disableRendering = false;") ||
m.restore()
m.replace("reset",
/new WebSocket\(\w+[^;]+?;/,
"$&" + m.reset)
m.replace("property:scale",
/function \w+\(\w+\){\w+\.preventDefault\(\);[^;]+;1>(\w+)&&\(\1=1\)/,
`;${makeProperty("scale", "$1")};$&`)
m.replace("var:minScale",
/;1>(\w+)&&\(\1=1\)/,
";$v>$1 && ($1=$v)",
"$v = 1")
m.replace("var:region",
/console\.log\("Find "\+(\w+\+\w+)\);/,
"$&" + "$v=$1;",
"$v = ''")
m.replace("cellProperty:isVirus",
/((\w+)=!!\(\w+&1\)[\s\S]{0,400})((\w+).(\w+)=\2;)/,
"$1$4.isVirus=$3")
m.replace("var:dommousescroll",
/("DOMMouseScroll",)(\w+),/,
"$1($v=$2),")
m.replace("var:skinF hook:cellSkin",
/(\w+.fill\(\))(;null!=(\w+))/,
"$1;" +
"if($v)$3 = $v(this,$3);" +
"if($h)$3 = $h(this,$3);" +
"$2");
/*m.replace("bigSkin",
/(null!=(\w+)&&\((\w+)\.save\(\),)(\3\.clip\(\),\w+=)(Math\.max\(this\.size,this\.\w+\))/,
"$1" + "$2.big||" + "$4" + "($2.big?2:1)*" + "$5")*/
m.replace("hook:afterCellStroke",
/\((\w+)\.strokeStyle="#000000",\1\.globalAlpha\*=\.1,\1\.stroke\(\)\);\1\.globalAlpha=1;/,
"$&" + "$H(this);")
m.replace("var:showStartupBg",
/\w+\?\(\w\.globalAlpha=\w+,/,
"$v && $&",
"$v = true")
var vAlive = /\((\w+)\[(\w+)\]==this\){\1\.splice\(\2,1\);/.exec(m.text)
var vEaten = /0<this\.[$\w]+&&(\w+)\.push\(this\)}/.exec(m.text)
!vAlive && console.error("Expose: can't find vAlive")
!vEaten && console.error("Expose: can't find vEaten")
if (vAlive && vEaten)
m.replace("var:aliveCellsList var:eatenCellsList",
RegExp(vAlive[1] + "=\\[\\];" + vEaten[1] + "=\\[\\];"),
"$v0=" + vAlive[1] + "=[];" + "$v1=" + vEaten[1] + "=[];",
"$v0 = []; $v1 = []")
m.replace("hook:drawScore",
/(;(\w+)=Math\.max\(\2,(\w+\(\))\);)0!=\2&&/,
"$1($H($3))||0!=$2&&")
m.replace("hook:beforeTransform hook:beforeDraw var:drawScale",
/(\w+)\.save\(\);\1\.translate\((\w+\/2,\w+\/2)\);\1\.scale\((\w+),\3\);\1\.translate\((-\w+,-\w+)\);/,
"$v = $3;$H0($1,$2,$3,$4);" + "$&" + "$H1($1,$2,$3,$4);",
"$v = 1")
m.replace("hook:afterDraw",
/(\w+)\.restore\(\);(\w+)&&\2\.width&&\1\.drawImage/,
"$H();" + "$&")
m.replace("hook:cellColor",
/(\w+=)this\.color;/,
"$1 ($h && $h(this, this.color) || this.color);")
m.replace("var:drawGrid",
/(\w+)\.globalAlpha=(\.2\*\w+);/,
"if(!$v)return;" + "$&",
"$v = true")
m.replace("hook:drawCellMass",
/&&\((\w+\|\|0==\w+\.length&&\(!this\.\w+\|\|this\.\w+\)&&20<this\.size)\)&&/,
"&&( $h ? $h(this,$1) : ($1) )&&")
m.replace("hook:cellMassText",
/(\.\w+)(\(~~\(this\.size\*this\.size\/100\)\))/,
"$1( $h ? $h(this,$2) : $2 )")
m.replace("hook:cellMassTextScale",
/(\.\w+)\((this\.\w+\(\))\)([\s\S]{0,1000})\1\(\2\/2\)/,
"$1($2)$3$1( $h ? $h(this,$2/2) : ($2/2) )")
var template = (key,n) =>
`this\\.${key}=\\w+\\*\\(this\\.(\\w+)-this\\.(\\w+)\\)\\+this\\.\\${n};`
var re = new RegExp(template('x', 2) + template('y', 4) + template('size', 6))
var match = re.exec(m.text)
if (match) {
m.cellProp.nx = match[1]
m.cellProp.ny = match[3]
m.cellProp.nSize = match[5]
} else
console.error("Expose: cellProp:x,y,size search failed!")
}},
]
function makeProperty(name, varname) {
return "'" + name + "' in window.agar || " +
"Object.defineProperty( window.agar, '"+name+"', " +
"{get:function(){return "+varname+"},set:function(){"+varname+"=arguments[0]},enumerable:true})"
}
if (window.top == window.self) {
if (document.readyState !== 'loading')
return console.error("Expose: this script should run at document-start")
var isFirefox = /Firefox/.test(navigator.userAgent)
// Stage 1: Find corresponding rule
var rules
for (var i = 0; i < allRules.length; i++)
if (allRules[i].hostname.indexOf(window.location.hostname) !== -1) {
rules = allRules[i]
break
}
if (!rules)
return console.error("Expose: cant find corresponding rule")
// Stage 2: Search for `main_out.js`
if (isFirefox) {
function bse_listener(e) { tryReplace(e.target, e) }
window.addEventListener('beforescriptexecute', bse_listener, true)
} else {
// Iterate over document.head child elements and look for `main_out.js`
for (var i = 0; i < document.head.childNodes.length; i++)
if (tryReplace(document.head.childNodes[i]))
return
// If there are no desired element in document.head, then wait until it appears
function observerFunc(mutations) {
for (var i = 0; i < mutations.length; i++) {
var addedNodes = mutations[i].addedNodes
for (var j = 0; j < addedNodes.length; j++)
if (tryReplace(addedNodes[j]))
return observer.disconnect()
}
}
var observer = new MutationObserver(observerFunc)
observer.observe(document.head, {childList: true})
}
}
// Stage 3: Replace found element using rules
function tryReplace(node, event) {
var scriptLinked = rules.scriptUriRe && rules.scriptUriRe.test(node.src)
var scriptEmbedded = rules.scriptTextRe && rules.scriptTextRe.test(node.textContent)
if (node.tagName != "SCRIPT" || (!scriptLinked && !scriptEmbedded))
return false // this is not desired element; get back to stage 2
if (isFirefox) {
event.preventDefault()
window.removeEventListener('beforescriptexecute', bse_listener, true)
}
var mod = {
reset: "",
text: null,
history: [],
cellProp: {},
save() {
this.history.push({reset:this.reset, text:this.text})
return true
},
restore() {
var state = this.history.pop()
this.reset = state.reset
this.text = state.text
return true
},
reset_(reset) {
this.reset += reset
return true
},
replace(what, from, to, reset) {
var vars = [], hooks = []
what.split(" ").forEach((x) => {
x = x.split(":")
x[0] === "var" && vars.push(x[1])
x[0] === "hook" && hooks.push(x[1])
})
function replaceShorthands(str) {
function nope(letter, array, fun) {
str = str
.split(new RegExp('\\$' + letter + '([0-9]?)'))
.map((v,n) => n%2 ? fun(array[v||0]) : v)
.join("")
}
nope('v', vars, (name) => "window.agar." + name)
nope('h', hooks, (name) => "window.agar.hooks." + name)
nope('H', hooks, (name) =>
"window.agar.hooks." + name + "&&" +
"window.agar.hooks." + name)
return str
}
var newText = this.text.replace(from, replaceShorthands(to))
if(newText === this.text) {
console.error("Expose: `" + what + "` replacement failed!")
return false
} else {
this.text = newText
if (reset)
this.reset += replaceShorthands(reset) + ";"
return true
}
},
removeNewlines() {
this.text = this.text.replace(/([,\/])\n/mg, "$1")
},
get: function() {
var cellProp = JSON.stringify(this.cellProp)
return `window.agar={hooks:{},cellProp:${cellProp}};` +
this.reset + this.text
}
}
if (scriptEmbedded) {
mod.text = node.textContent
rules.replace(mod)
if (isFirefox) {
document.head.removeChild(node)
var script = document.createElement("script")
script.textContent = mod.get()
document.head.appendChild(script)
} else {
node.textContent = mod.get()
}
console.log("Expose: replacement done")
} else {
document.head.removeChild(node)
var request = new XMLHttpRequest()
request.onload = function() {
var script = document.createElement("script")
mod.text = this.responseText
rules.replace(mod)
script.textContent = mod.get()
// `main_out.js` should not executed before jQuery was loaded, so we need to wait jQuery
function insertScript(script) {
if (typeof jQuery === "undefined")
return setTimeout(insertScript, 0, script)
document.head.appendChild(script)
console.log("Expose: replacement done")
}
insertScript(script)
}
request.onerror = function() { console.error("Expose: response was null") }
request.open("get", node.src, true)
request.send()
}
return true
}
Lines 260-267 for easier debugging purposes:
"Object.defineProperty( window.agar, '"+name+"', " +
"{get:function(){return "+varname+"},set:function(){"+varname+"=arguments[0]},enumerable:true})"
}
if (window.top == window.self) {
if (document.readyState !== 'loading')
return console.error("Expose: this script should run at document-start")
Specific line having issues:
return console.error("Expose: this script should run at document-start")
UPDATE:
New issue. Uncaught SyntaxError: Illegal return statement engine.js:282
Lines 281-282 for debugging purposes:
if (!rules)
return console.error("Expose: cant find corresponding rule")
UPDATE 2:
This is my final issue. And this whole thing will be resolved.
It looks like its another return error. But i do not understand how to properly return this part.
Heres the error but its basically the same.
Uncaught SyntaxError: Illegal return statement engine.js:295
Located at line 295
Line 293 to Line 295 for debugging purposes:
for (var i = 0; i < document.head.childNodes.length; i++)
if (tryReplace(document.head.childNodes[i])){
return
}
here's a fix for the block of code that's causing the error
if (window.top == window.self) {
if (document.readyState !== 'loading') {
// don't return
console.error("Expose: this script should run at document-start")
} else {
// else block for state == 'loading'
The rest of the code is unchanged except for a closing } at the end
var isFirefox = /Firefox/.test(navigator.userAgent)
// Stage 1: Find corresponding rule
var rules
for (var i = 0; i < allRules.length; i++)
if (allRules[i].hostname.indexOf(window.location.hostname) !== -1) {
rules = allRules[i]
break
}
if (!rules)
return console.error("Expose: cant find corresponding rule")
// Stage 2: Search for `main_out.js`
if (isFirefox) {
function bse_listener(e) {
tryReplace(e.target, e)
}
window.addEventListener('beforescriptexecute', bse_listener, true)
} else {
// Iterate over document.head child elements and look for `main_out.js`
for (var i = 0; i < document.head.childNodes.length; i++)
if (tryReplace(document.head.childNodes[i]))
return
// If there are no desired element in document.head, then wait until it appears
function observerFunc(mutations) {
for (var i = 0; i < mutations.length; i++) {
var addedNodes = mutations[i].addedNodes
for (var j = 0; j < addedNodes.length; j++)
if (tryReplace(addedNodes[j]))
return observer.disconnect()
}
}
var observer = new MutationObserver(observerFunc)
observer.observe(document.head, {
childList: true
})
}
} // added this closing }
}

Categories