// ==UserScript==
// @name Небоскреб
// @namespace Игры
// @version 1.9.6.2
// @description Бот для игры Небоскребы
// @match https://nebo.mobi/*
// @icon https://nebo.mobi/images/icons/home.png
// @copyright BaNru (2014-2025)
// @author BaNru
// @tag game bot
// ==/UserScript==
var BOT = {};
BOT.version = '1.9.6.2';
const DOMAIN = 'https://nebo.mobi/';
const DOMAIN_NAME = 'nebo.mobi';
console.log('НебоБот Запущен '+BOT.version);
/* Функции */
function debuglog(){
// console.log(arguments);
}
/**
*
* end_xhr
*
* Последний запрос - выполнение действия и вывод ответа на экран
*
* @param {string} url - страница действия
* @param {string} text - сообщение для вывода на экран
* @param {string} time - вреия ожидания перед действием
* @param {string} ref - реферал, если разрешено в браузере
* @param {function} callback function, необязательный параметр
*
* TODO переписать функцию: заменить аргументы на объект и добавить передачу CLASS в AddTable
*
*/
function end_xhr(url, text, time, ref, callback) {
setTimeout(function(){
let xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
// Раскомментировать строчку, если разрешены рефералы в браузере,
// немного повышает защиту бота
// xhr2.setRequestHeader('Referer', ref);
xhr.onload = function() {
AddTable(text);
debuglog(url, xhr.responseURL);
let parser = new DOMParser();
let document_ = parser.parseFromString(xhr.response, "text/html");
updateBlocks(document_);
};
xhr.onerror = function() {
debuglog(xhr);
};
xhr.send();
if(callback)callback();
}, time);
}
/**
*
* rand_time
* Случайное время
*
* По умолчанию возвращает от 2000 до 5000 (мс);
* Задавать в секундах. Необязательные параметры
* @param {number} min secunds
* @param {number} max secunds
*
* @default min = 2s, max = 5s
*
* @returns {number} random millseconds
*
*/
function rand_time(min, max) {
min = ( min || 2 ) *1000;
max = ( max || 5 ) *1000;
return Math.floor(Math.random() * (max - min + 1)) + min;
}
/* Лифтер */
function liftFN() {
setTimeout(function(){
fetch_promise('lift','.lift', true)
.then(([lift,doc])=>{
let el = document.querySelector('div.vs .flbdy');
lift.appendChild(lift.querySelector(".clb"));
if (lift && lift.getElementsByClassName('tdu')[0]) {
end_xhr(
lift.getElementsByClassName('tdu')[0].href || DOMAIN + lift.getElementsByClassName('tdu')[0].getAttribute('href'),
lift.innerHTML.replace('
',''),
rand_time(1,3),
DOMAIN + 'lift',
liftFN
);
el.innerHTML = '' + lift.innerHTML + '
';
if(!lift.querySelector('.lift .white').classList.contains('nwr')){
document.querySelector('.vs .rs.small').textContent = Number(document.querySelector('.vs .rs.small').textContent) + 1;
}
} else {
let ttime = 3;
AddTable(lift.innerHTML.replace('',''));
let time = doc.querySelector('[id^=time]'),
el = document.querySelector('div.vs .flbdy');
if(time){
ttime = getSecond(getTime(time.innerHTML));
time.title = time.innerHTML;
time.className = "minor small flr";
lift.querySelector('.flr').parentNode.replaceChild(time,lift.querySelector('.flr'));
AddMessTable('Ждем посетителя!','',function(){
timer(ttime, document.getElementById('log_table_2'), false);
});
}
if(el){
el.innerHTML = '' + lift.innerHTML.replace() + '
';
if(time && lift.querySelector('.flr')){
timer(ttime, el.querySelector('[id^=time]'), false);
}
}
setTimeout(function(){
AddMessTable('Развозим дальше','');
liftFN();
}, ttime*1000);
}
})
.catch(err=>{
debuglog(err);
console.error(err);
AddTable('Лифт сломался, но не отчаивайся - мастера уже на месте!');
AddMessTable('Ошибка! Перезапуск через','',function(){
timer([0, 0, 0, 10], document.getElementById('log_table_2'), false);
});
setTimeout(function(){
liftFN();
}, 10000);
})
}, rand_time(3,6));
}
/* Закупаем товар */
function productBuy() {
setTimeout(function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', DOMAIN + 'floors/0/2', true);
// Раскомментировать строчку, если разрешены рефералы в браузере,
// немного повышает защиту бота
// xhr.setRequestHeader('Referer', DOMAIN + 'floors/0/2');
xhr.onload = function() {
var parser = new DOMParser();
var doc = parser.parseFromString(xhr.responseText, "text/html");
var tower = doc.getElementsByClassName('tower')[0];
var links = tower.getElementsByClassName('tdu');
var l = links.length;
var i = 0, golink = "";
var interval = setInterval(function(){
if (links[i]) {
golink = links[i].href || DOMAIN + links[i].getAttribute('href');
if (/nebo\.mobi\/(?:\.\.\/)*floor\//.exec(golink)) {
var xhr2 = new XMLHttpRequest();
xhr2.open('GET', golink, true);
// xhr2.setRequestHeader('Referer', DOMAIN + 'floors/0/2');
xhr2.onload = function() {
productAction(xhr2.responseText, xhr2.responseURL);
};
xhr2.onerror = function() {
debuglog(xhr2);
};
xhr2.send();
}
}
i++;
if (i == l){
clearInterval(interval);
}
}, 3000);
productBuy();
};
xhr.onerror = function() {
debuglog(xhr);
AddTable('Закупка не получилась!');
AddMessTable('Ошибка! Перезапуск через','',function(){
timer([0, 0, 0, 10], document.getElementById('log_table_2'), false);
});
setTimeout(function(){
productBuy();
}, 10000);
};
xhr.send();
}, rand_time(25,30));
}
/* Функция закупки */
function productAction(text,ref){
var parser = new DOMParser();
var doc = parser.parseFromString(text, "text/html");
var prd = doc.getElementsByClassName('prd')[0];
var links = prd.getElementsByClassName('tdu');
var l = links.length;
var i = 0, golink = "";
var intl = setInterval(function(){
if (links[i]) {
golink = links[i].href || DOMAIN + links[i].getAttribute('href');
if (/wicket:interface=:\d+:floorPanel:product[A-Z]:emptyState:action:link::ILinkListener::/.exec(golink)) {
// TODO Сделать вывод закупаемого товара
// Сейчас выводится первый, если в магазине 1 товар на закупку
end_xhr(golink, prd.querySelectorAll('li')[i].innerHTML, 100, ref);
}
}
i++;
if (i == l){
clearInterval(intl);
}
}, 1000);
}
/* Сбор выручки */
function collectRevenue() {
setTimeout(function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', DOMAIN + 'floors/0/5', true);
// xhr.setRequestHeader('Referer', DOMAIN + 'floors/0/5');
xhr.onload = function() {
var parser = new DOMParser();
var doc = parser.parseFromString(xhr.responseText, "text/html");
var tower = doc.getElementsByClassName('tower')[0];
var links = tower.getElementsByClassName('tdu');
var l = links.length;
var i = 0, golink = "";
var interval = setInterval(function(){
if (links[i]) {
golink = links[i].href || DOMAIN + links[i].getAttribute('href');
if (/wicket:interface=:\d+:floors:\d+:floorPanel:state:action::ILinkListener::/.exec(golink)) {
end_xhr(golink, tower.querySelectorAll('li')[i].innerHTML, 100, DOMAIN + 'floors/0/5');
}
}
i++;
if (i == l){
clearInterval(interval);
}
}, 3000);
collectRevenue();
};
xhr.onerror = function() {
debuglog(xhr);
AddTable('Сбор выручки не получился!');
AddMessTable('Ошибка! Перезапуск через','',function(){
timer([0, 0, 0, 10], document.getElementById('log_table_2'), false);
});
setTimeout(function(){
collectRevenue();
}, 10000);
};
xhr.send();
}, rand_time(25,30));
}
/* Выложить товар */
function putProduct() {
setTimeout(function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', DOMAIN + 'floors/0/3', true);
// xhr.setRequestHeader('Referer', DOMAIN + 'floors/0/3');
xhr.onload = function() {
var parser = new DOMParser();
var doc = parser.parseFromString(xhr.responseText, "text/html");
var tower = doc.getElementsByClassName('tower')[0];
var links = tower.getElementsByClassName('tdu');
var l = links.length;
var i = 0, golink = "";
var interval = setInterval(function(){
if (links[i]) {
golink = links[i].href || DOMAIN + links[i].getAttribute('href');
if (/wicket:interface=:\d+:floors:\d+:floorPanel:state:action::ILinkListener::/.exec(golink)) {
end_xhr(golink, tower.querySelectorAll('li')[i].innerHTML, 100, DOMAIN + "floors/0/3");
}
}
i++;
if (i == l){
clearInterval(interval);
}
}, 3000);
putProduct();
};
xhr.onerror = function() {
debuglog(xhr);
AddTable('Выложить товар не получилось!');
AddMessTable('Ошибка! Перезапуск через','',function(){
timer([0, 0, 0, 10], document.getElementById('log_table_2'), false);
});
setTimeout(function(){
putProduct();
}, 10000);
};
xhr.send();
}, rand_time(25,30));
}
/* Выселение жителей */
// TODO не всегда выселяет с первого раза, когда-нибудь найти ошибку и исправить
function humansFN() {
setTimeout(function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', DOMAIN + 'humans', true);
xhr.onload = function() {
var link, lvl, amount,
parser = new DOMParser(),
doc = parser.parseFromString(xhr.responseText, "text/html"),
human = doc.querySelectorAll('.rsd li'),
tl = human.length,
time_ = 0;
for (var i = 0; i < tl; i++) {
link = human[i].querySelector('a'),
lvl = human[i].querySelector('.abstr'),
amount = human[i].querySelector('.amount');
if (link && parseInt(lvl.innerText) < 9 && !amount) {
time_ = rand_time()+time_;
debuglog(link, parseInt(lvl.innerText));
AddTable(''+human[i].innerHTML+'
');
!function(t,l) {
setTimeout(function(){
evict(l);
},t);
}(time_, link.getAttribute('href'));
}
}
};
xhr.onerror = function() {
debuglog(xhr);
};
xhr.send();
humansFN();
}, rand_time(180,300));// Раз в 3-5 минут
}
/* Функция выселения выбранного жителя */
function evict(url) {
setTimeout(function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function() {
var parser = new DOMParser(),
doc = parser.parseFromString(xhr.responseText, "text/html"),
name = doc.querySelector('.wrk strong.stat'),
link = doc.querySelector('a.btnr').getAttribute('href');
end_xhr(link, name.innerText+' выселен(а)', rand_time(), url);
};
xhr.onerror = function() {
debuglog(xhr);
};
xhr.send();
}, rand_time());
}
/* Задания */
function quests(){
setTimeout(function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', DOMAIN + 'quests', true);
xhr.onload = function() {
var parser = new DOMParser(),
doc = parser.parseFromString(xhr.responseText, "text/html"),
link = doc.querySelectorAll('.nfl .btng'),
tl = link.length,
time_ = 0;
for (var i = 0; i < tl; i++) {
time_ = rand_time()+time_;
//TODO не забыть: когда изменю nd_xhr - убрать тут и в других местах оборачивающий DIV
end_xhr(DOMAIN + link[i].getAttribute('href'), ''+link[i].closest('.nfl').innerHTML+'
', time_, DOMAIN + 'quests');
}
};
xhr.onerror = function() {
debuglog(xhr);
};
xhr.send();
quests();
}, rand_time(180,300));// Раз в 3-5 минут
}
/* Задания города */
function questsCity(){
setTimeout(function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', DOMAIN + 'city/quests/', true);
xhr.onload = function() {
var parser = new DOMParser(),
doc = parser.parseFromString(xhr.responseText, "text/html"),
link = doc.querySelector('.nfl .btng[href*="myQuest:getAwarLink"') ||
doc.querySelector('.nfl .btnr[href*="myQuest:getAwarLink"'),
stop = false;
// Если нет ссылок сбора
if(!link){
var setting = JSON.parse(localStorage.getItem('setting_bot_quests')) || {},
easyMoney = localStorage.getItem('setting_bot_easy_money'),
hour = (new Date).getHours(),
links = doc.querySelectorAll('.nfl .btng[href*="freeQuests"');
// Баксы в полночь
if(easyMoney && easyMoney >= 0 && hour >= easyMoney){
setting[0] = 'Легкие деньги';
}
for(var cur in setting){
if(stop)break;
for (var i = 0, l = links.length; i < l; i++) {
if(setting[cur] === links[i].parentNode.parentNode.querySelector('div:nth-child(1) > strong').textContent){
link = links[i];
stop = true;
break;
}
}
}
}
// Сбор задания или выбор нового
if(link){
end_xhr(
DOMAIN + link.getAttribute('href'),
''+link.closest('.nfl').innerHTML+'
',
rand_time(),
DOMAIN + 'city/quests/'
);
}
};
xhr.onerror = function() {
debuglog(xhr);
};
xhr.send();
questsCity();
}, rand_time(180,300));// Раз в 3-5 минут
}
/* Выбор задания города (вывод инпутов) */
function questsCitySelect(){
var elements = document.querySelectorAll('div.nfl > div:nth-child(1) > strong'),
setting = JSON.parse(localStorage.getItem('setting_bot_quests')) || {},
easyMoney = localStorage.getItem('setting_bot_easy_money'),
inputMoney;
// Поле для Легких денег
inputMoney = document.createElement('input');
inputMoney.className = 'easy_money';
inputMoney.type="number";
inputMoney.size='2';
inputMoney.min = '0';
inputMoney.max = '23';
inputMoney.value = easyMoney;
inputMoney.addEventListener('input', function(){
localStorage.setItem('setting_bot_easy_money', parseInt(this.value));
});
for (var i = 0, l = elements.length, input; i < l; i++) {
input = document.createElement('input');
input.addEventListener('input', questsCitySelectChange);
input.className = 'input_bot_quests';
input.type="number";
input.size='2';
input.min = '0';
input.max = '19';
input.value = 0;
input.setAttribute('value', 0);
for(var cur in setting){
if (setting[cur] === elements[i].textContent){
input.value = cur;
input.setAttribute('value', cur);
}
if(elements[i].textContent === 'Легкие деньги'){
elements[i].appendChild(inputMoney);
}
}
elements[i].appendChild(input);
}
}
/* Изменение приоритета заданий города */
function questsCitySelectChange(){
var thisInput = this,
thisInputValue = this.value,
thisText = thisInput.parentNode.textContent,
setting = JSON.parse(localStorage.getItem('setting_bot_quests')) || {},
inputD = document.querySelector('div.nfl > div:nth-child(1) > strong input[value="'+thisInputValue+'"]');
// Удаялем/обнуляем другие значения с таким же приоритетом
if(thisInputValue > 0 && inputD){
inputD.value = 0;
inputD.setAttribute('value', 0);
}
// Удаляем текущее, чтобы записать новое
for(var cur in setting){
if(setting[cur] === thisText){
delete setting[cur];
}
}
// Устанавливаем value, чтобы сработал querySelector на удаление
thisInput.setAttribute('value', thisInputValue);
// Пишем новое значение
if(thisInputValue.length > 0){
setting[thisInputValue] = thisText;
}
// Удаляем пустышки
delete setting[""];
delete setting[0];
// Пишем в localStorage
localStorage.setItem('setting_bot_quests', JSON.stringify(setting));
}
/*
* Инвесторы
*
* @param {String} url, необязательный параметр
* @param {Number} millseconds - время ожидания, необязательный параметр
*
*/
function boss(url,time){
// TODO Сделать ожидание дня
var day = (new Date()).getDay();
url = url || DOMAIN + "boss/";
if(day == 6){
time = time || rand_time();
}
setTimeout(function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function() {
var parser = new DOMParser(),
doc = parser.parseFromString(xhr.responseText, "text/html"),
link = doc.querySelector('.btng[href*="startCombatLink"]'),
time0 = doc.querySelector('.cntr > div > div.amount span'),
time1 = doc.querySelector('.m5 > .cntr.amount .hr + span'),
time2 = doc.querySelector('.cntr span[id^=time]');
// Инициируем запуск переговоров
if(link){
AddTable(''+link.closest('.m5').innerHTML+'
');
setTimeout(function(){
debuglog(link, link.innerHTML);
boss(DOMAIN + link.getAttribute('href'));
},rand_time());
} else {
// Ожидание начала
link = doc.querySelector('.btng[href*="actionLink"]');
if(time0){
boss(DOMAIN + link.getAttribute('href'),parseInt(time0.textContent)*1000);
AddTable(''+time0.closest('.cntr').innerHTML+'
');
}
// Перерыв
else if(time1){
boss(DOMAIN + link.getAttribute('href'),getSecond(('0:'+time1.textContent).split(':'))*1000);
AddTable(''+time1.closest('.m5').innerHTML+'
');
}
// Переговоры уже идут
else if(time2){
boss(DOMAIN + link.getAttribute('href'),parseInt(time2.textContent)*1000);
AddTable(''+time2.closest('.cntr').parentNode.innerHTML+'
');
}
// Скорее всего начало переговоров
else {
if(link){
AddTable(''+link.closest('.cntr').parentNode.innerHTML+'
');
boss(DOMAIN + link.getAttribute('href'),500);
}
// Вероятно ошибка
else{
boss();
}
}
}
};
xhr.onerror = function() {
boss();
debuglog(xhr);
};
xhr.send();
}, time);
}
/* Задания вестибюля */
function lobby(){
setTimeout(function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', DOMAIN + 'lobby', true);
xhr.onload = function() {
var parser = new DOMParser(),
doc = parser.parseFromString(xhr.responseText, "text/html"),
link = doc.querySelector('.btng[href*="questPanel:getAwarLink"]') ||
doc.querySelector('.btng[href*="questPanel:getQuest"]'),
thisText= doc.querySelector('.nfl .admin').textContent,
setting = JSON.parse(localStorage.getItem('setting_bot_lobby')) || {};
if(link && setting[thisText]){
end_xhr(
DOMAIN + link.getAttribute('href'),
''+link.closest('.nfl').innerHTML+'
',
rand_time(),
DOMAIN + 'lobby'
);
}
};
xhr.onerror = function() {
debuglog(xhr);
};
xhr.send();
lobby();
}, rand_time(180,300));// Раз в 3-5 минут
}
/* Инпуты в вестибюле */
function lobbySelect(){
var element = document.querySelector('div.nfl:not(.m5)'),
setting = JSON.parse(localStorage.getItem('setting_bot_lobby')) || {},
input = document.createElement('input');
input.addEventListener('change', function(){
setting[element.querySelector('.admin').textContent] = this.checked;
localStorage.setItem('setting_bot_lobby', JSON.stringify(setting));
});
input.className = 'input_bot_check';
input.type="checkbox";
if (setting[element.querySelector('.admin').textContent]){
input.checked = true;
}
element.insertBefore(input, element.firstChild);
}
/**
* Функция добавления в "логи" форматированного текста
*
* @param {String} text - текст сообщения
* @param {String} className необязательный параметр
*/
function AddTable(text, className = '') {
var d = new Date();
var t = addZero(d.getHours())+':'+addZero(d.getMinutes())+':'+addZero(d.getSeconds());
document.querySelector('#event_table tbody').insertAdjacentHTML('afterbegin',
'| ' + t + ' | ' + text +' |
');
document.querySelectorAll('#event_table tr:nth-child(n+10)').forEach(item=>{item.remove()})
}
/**
* Функция добавления в таблицу Логов
*
* @param {String} firstText текст сообщения
* @param {String} secondText,текст сообщения
* @param {function} callback function, необязательный параметр
*
*/
function AddMessTable(firstText, secondText, callback) {
document.getElementById('log_table_1').innerHTML = firstText;
document.getElementById('log_table_2').innerHTML = secondText;
if(callback)callback();
}
/*
*
* Функция извлечения времени из строки
*
* @param {String} t - время со страницы формата "39 ч 59 мин"
* @returns {Array} [days, hours, minutes, seconds]
*
*/
function getTime(t) {
var d = 0, h = 0, m = 0, s = 0,
parsetime = t.split(/\s/);
if (parsetime[1] == 'д') {
d = Math.round(parsetime[0]);
h = Math.round(parsetime[2]);
}
if (parsetime[1] == 'ч') {
h = Math.round(parsetime[0]);
m = Math.round(parsetime[2]);
}
if (parsetime[1] == 'м') {
m = Math.round(parsetime[0]);
s = Math.round(parsetime[2]);
}
if (parsetime[1] == 'сек') {
s = Math.round(parsetime[0]);
}
return [d, h, m, s];
}
/*
*
* Функция получения секунд из массива времени getTime()
*
* @param {Array} [days, hours, minutes, seconds]
* @returns {Number} seconds
*
*/
function getSecond(t) {
return (((parseInt(t[0])*24+parseInt(t[1]))*60)+parseInt(t[2]))*60+parseInt(t[3]);
}
function firstMess(e) {
if( e != "granted" ) return false;
new Notification("Уведомления и таймер включены.", {
tag : DOMAIN_NAME,
body : "Перезагрузите страницу!",
icon : "http://static."+DOMAIN_NAME+"/images/icons/home.png"
});
}
/*
*
* Функция добавления ведущео нуля у элемента времени,
* если требуется
*
* @param {Number}
* @returns {Number}
*
*/
function addZero(int_) {
if ((int_+"").length == 1){
int_ = "0"+int_;
}
return int_;
}
/**
* Функция создания таймера на месте времени,
* с последующим уведомлением
*
* @param {Array<4>|String|Number} time - время. На входе возможны массив [0,0,0,0], string время в формате игры "29 м 59 сек"
* @param {String} id - элемент
* @param {String} notice - текст уведомления
* @param {Function} callback функция, необязательный параметр
*
*/
function timer(time, id, notice, callback) {
// Проверяем и преобразуем формат фремени
if(Array.isArray(time) && time.length == 4){
time = getSecond(time);
} else if (typeof time === 'string'){
getSecond(getTime(time));
} else {
time = Number(time) || 1;
}
var int_ = setInterval(function () {
var seconds_left_d, seconds_left_h,
days, hours, minutes, seconds, tpmcl, notifyD = {};
time--;
days = parseInt(time / 86400);
seconds_left_d = time % 86400;
hours = parseInt(seconds_left_d / 3600);
seconds_left_h = time % 3600;
minutes = parseInt(seconds_left_h / 60);
seconds = parseInt(time % 60);
id.innerHTML = (days == 0 ? '' : (days + " д, ")) + addZero(hours) + ":"
+ addZero(minutes) + ":" + addZero(seconds);
if(days <= 0 && hours <= 0 && minutes <= 0 && seconds <= 0){
clearInterval(int_);
if(callback)callback();
if (notice) {
tpmcl = id.closest('.flbdy') || false;
if(tpmcl){
notifyD.name = tpmcl?.parentNode.querySelector('.flhdr > span')?.innerText.trim();
notifyD.body = tpmcl?.querySelector('.state')?.innerText.trim();
notifyD.icon = tpmcl?.querySelector('img')?.src;
} else if (id.closest('.flr.small.amount')) {
notifyD.name = id?.parentNode?.parentNode?.querySelector('.lift .ctrl')?.innerText.trim();
notifyD.body = id?.parentNode?.parentNode?.querySelector('.lift .nshd')?.innerText.trim();
notifyD.icon = id?.parentNode?.parentNode?.querySelector('.lift img')?.src;
}
notifyD.name = notifyD.name || 'Неизвестный таймер';
notifyD.body = notifyD.body || 'Какой-то таймер завершился';
notifyD.icon = notifyD.icon || 'http://igrotop.mobi/images/game7.png';
new Notification(notifyD.name, {
tag : DOMAIN_NAME,
body : notifyD.body,
icon : notifyD.icon
});
}
}
}, 1000);
}
/**
* Проверка на менеджера
*
* @param {Function} callback
*
* @returns true or false
*/
function checkingManager(callback) {
var els = document.querySelectorAll('.tdn .buff'),
l = els.length,
chM;
for (var i = 0; i < l; i++) {
if(/Менеджер*/.exec(els[i].innerText)){
chM = els[i].querySelector('span').innerText;
AddMessTable(
'Работает менеджер', chM,
function(){
timer(
getTime(chM.trim()),
document.getElementById('log_table_2'),
false,
callback
);
}
);
timer(
getTime(chM.trim()),
els[i].querySelector('span'),
'Менеджер закончил свою работу!'
);
return true;
}
}
return false;
}
/**
* Открывание дверей
*
* @param {string} url открытия дври
* @param {Function} doors_open порядковый номер двери от 0 до 2
*
*/
function doors(url,doors_open){
if(localStorage.doors_key == undefined || localStorage.doors_key < 1){
AddTable('Нечем открывать двери');
return false;
}
AddMessTable('Лабиринт запущен', '
' + localStorage.doors_key || 0);
setTimeout(function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', url || DOMAIN + 'doors', true);
// Раскомментировать строчку, если разрешены рефералы в браузере,
// немного повышает защиту бота
// xhr.setRequestHeader('Referer', DOMAIN + 'doors');
xhr.onload = function() {
var parser = new DOMParser(),
doc = parser.parseFromString(xhr.responseText, "text/html"),
doorsLinks = doc.querySelectorAll('[href*=":doorLink"]'),
ttime;
localStorage.doors_key -= 1;
AddMessTable('Лабиринт запущен', '
' + localStorage.doors_key || 0);
let html = doc.querySelector('.m5.cntr');
if(doors_open){
AddTable('Открыта '+ (doors_open+1) +' дверь');
}
if(html.querySelector('.doorSel')){
html.querySelector('.doorSel').style.backgroundColor = '#4BF';
}
html.querySelectorAll('span.amount:first-child,.hint,.minor.small, .hr').forEach(e => e.remove());
AddTable(html.innerHTML);
if (doorsLinks && doorsLinks.length === 3) {
let rand_door = Math.floor(Math.random() * (3 - 1 + 1));
doors(doorsLinks[rand_door].href, rand_door);
} else {
setTimeout(function(){
AddMessTable('Надо больше ключей!','');
doors();
}, 5000);
}
};
xhr.onerror = function() {
debuglog(xhr);
AddTable('Дверь оказалась без замка. Надо вызывать медвежатника!');
AddMessTable('Ошибка! Перезапуск через','',function(){
timer([0, 0, 0, 10], document.getElementById('log_table_2'), false);
});
setTimeout(function(){
doors();
}, 10000);
};
xhr.send();
}, rand_time(5,7));
}
/**
*
* Выбор в объекте максимального или минимально значения (value)
*
* @param {*} object
* @returns key object
*
*/
const max = object=>Object.keys(object).reduce((key, v) => object[v] < object[key] ? v : key);
const min = object=>Object.keys(object).reduce((key, v) => object[v] < object[key] ? v : key);
/**
* Обёртка fetch Promise, делает запрос к странице и возвращает карточку(и)
*
* @param {*} url - адрес страницы
* @param {*} returnBlock - класс блока(ов), который надо вернуть
* @param {*} single - выборка массива блоков (по умолчанию) или один блок
*
* @returns Promise arrays documents select node and document
*
*/
function fetch_promise(url,returnBlock,single = false) {
return new Promise((resolve, reject) => {
// url = url.replace(/https?:\/\/nebo.mobi\//,'');
fetch(DOMAIN+url)
.then(response => {
return response.text();
})
.then(text => {
var parser = new DOMParser();
var document_ = parser.parseFromString(text, "text/html");
updateBlocks(document_);
resolve( [single ? document_.querySelector(returnBlock) : document_.querySelectorAll(returnBlock), document_] );
}).catch(err=>{
console.error('Ошибка', err);
reject(err)
});
})
}
// Обновление строки с деньгами
function updateBlocks(doc) {
// Обновление блока с деньгами
let cash = doc.querySelector('.cash');
cash?.querySelector('script')?.remove()
document.querySelector('.cash').innerHTML = cash.innerHTML;
// Обновление блоков с заданиями
let notify = doc.querySelectorAll('.nfl .prgbr');
notify.forEach((element, index) => {
let notify_new = document.querySelectorAll('.nfl .prgbr')[index];
if (notify_new) {
notify_new.closest('.nfl').innerHTML = element.closest('.nfl').innerHTML;
} else if (document.querySelector('.main > .hr')){
document.querySelector('.main > .hr').insertAdjacentHTML('afterend', element.closest('.nfl').outerHTML);
}
})
// Обновление ключей
let curDoors = doc.querySelector('a.link.tdn[href="doors"]');
let doors_page = document.querySelector('a.link.tdn[href="doors"]');
if (curDoors && doors_page){
doors_page.innerHTML = curDoors.innerHTML;
}
}
/**
* Функция квесты (заданий-событий)
*/
function quests_events() {
// Список страниц для срабатывания
var URLS_EVENTS = [
'timebox' // Контракты, событие с 20 по 26 января
]
if (new RegExp(URLS_EVENTS.join('|')).exec(window.location.pathname)) {
fetch_promise(window.location.pathname, 'a.btng[href*="getQuest"],.nfl a.btng', true)
.then(([block, doc]) => {
if (block) {
end_xhr(
block.href,
block.textContent,
rand_time(),
block.href,
quests_events
)
} else {
if (doc.querySelector('.cntr.minor.small [id*="time_"]')) {
let t = getTime(doc.querySelector('.cntr.minor.small [id*="time_"]').textContent);
setTimeout(() => {
AddMessTable(
'Ждём задание',
'',
() => {
timer(
t,
document.getElementById('log_table_2'),
false,
quests_events
);
}
);
}, t);
} else {
setTimeout(() => {
quests_events();
}, 3 * 60 * 1000); // Проверяем раз в 3 мин
}
}
})
.catch(err => {
AddTable('Что-то сломалось! Будем пробовать ещё раз!');
setTimeout(() => {
quests_events();
}, 3000);
console.error(err);
})
}
}
// function replaceCard(original,new_) {
// }
var Datenow = () => parseInt(Date.now()/1000);
/**
* Ферма
*/
const TIMERS = {
'fabric/floor/0/1' : Datenow() + 1,
'fabric/floor/0/2' : Datenow() + 2,
'fabric/floor/0/3' : Datenow() + 3,
'fabric/floor/0/4' : Datenow() + 4,
'fabric/floor/0/5' : Datenow() + 5
};
// parseInt(Date.now() / 1000) - 715
function fabric(url){
url = url || min(TIMERS);
setTimeout(function(){
// ('.fd, .sr, .rc, .fs, .el')
// Добавить в очередь
// ?wicket:interface=:[0-9]{5}:product1:startContainer:startLink::ILinkListener::
// Забрать
// ?wicket:interface=:[0-9]{5}:product1:collectContainer:collectLink::ILinkListener::"
fetch_promise(url,'.flbdy.snow3_.gift_', true)
.then(([block, doc]) =>{
if (!block) {
setTimeout(() => {
fabric();
}, rand_time());
return false;
}
// findFloor
var floor = url.match(/fabric\/floor\/0\/([0-9])/);
if(floor){
floor = floor[1];
}else{
let img = block.querySelector('.flogo');
if(img){
img = img.src.match(/([0-9])\.(?:gif|png)/);
if(img && img[1]){
floor = img[1];
}
}
}
let time = block.querySelector('[id*="time_"]');
if(floor){
let el = document.querySelectorAll('.fd > .flbdy, .sr > .flbdy, .rc > .flbdy, .fs > .flbdy, .el > .flbdy')[floor-1]
el.innerHTML = block.innerHTML;
let time = el.querySelector('[id^=time]');
if(time){
time.title = time.innerHTML;
timer(getTime(time.innerHTML), time,true);
}
}
AddTable(block.innerHTML);
let link = block.querySelector('.tdu')?.getAttribute('href');
if (link && /startContainer/.test(link)) {
fabric(link);
} else if (link && /collectContainer/.test(link)) {
fabric(link);
document.querySelector('.fabricBot').textContent = parseInt(document.querySelector('.fabricBot').textContent)+1;
} else if (time && floor) {
TIMERS['fabric/floor/0/' + floor] = Datenow() + getSecond(getTime(time.textContent));
fabric();
} else if (floor) {
TIMERS['fabric/floor/0/' + floor] = 3;
fabric();
} else {
AddTable('Ошибка. Пробуем ещё раз!!');
setTimeout(() => {
fabric();
}, 3000);
}
// Обновляем количество билетов
if(doc.querySelector('.snow3_ img[src*="ticket"] + span')){
document.querySelector('.snow3_ img[src*="ticket"] + span').textContent = parseInt(doc.querySelector('.snow3_ img[src*="ticket"] + span').textContent);
}
})
.catch(err=>{
AddTable('Что-то сломалось! Будем пробовать ещё раз!');
setTimeout(() => {
fabric(url);
}, 3000);
console.log(err);
})
}, ( TIMERS[url] - Datenow() ) * 1000);
}
/*
* Если скрипт не запускается, то необходимо
* раскомментировать (удалить в начале строки //)
* и закомментировать (добавить в начале строки // или удалить строку)
* строки ниже и в самом конце файла.
*/
//document.addEventListener("DOMContentLoaded", function(){ // Раскомментировать 1 из 2
window.onload = function() { // Закомментировать 1 из 2
/* Создаём таблицу логов */
document.body.insertAdjacentHTML('beforeend',
`
Новогоднее обновление:
- Лифтёр работает теперь на главной.:
- На главной теперь обновляются денежки и задания.
|
|
Спасибо что воспользовались ботом для игры в Небоскрёбы!
Если у вас есть вопросы или пожелания, вы можете их оставить на
странице проекта
|
`);
AddMessTable('Небобот запущен', BOT.version);
if (/\/home/.exec(window.location.pathname)) {
document.querySelector('.main').insertAdjacentHTML('afterbegin',`
`);
checkingManager();
liftFN();
document.querySelector('.vs .rs.small').textContent = 0;
AddTable('Лифтёр скоро приступит к работе.','rc');
} else if (/\/humans/.exec(window.location.pathname)) {
humansFN();
AddTable('Скоро начнётся выселение.','rc');
} else if (/\/quests/.exec(window.location.pathname)) {
quests();
AddTable('Задания скоро начнут собираться.','rc');
} else if (/\/city\/quests*/.exec(window.location.pathname)) {
questsCity();
questsCitySelect();
AddTable('Задания города скоро начнут собираться.','rc');
} else if (/\/floors\/0\/2/.exec(window.location.pathname)) {
if(!checkingManager(productBuy)){
productBuy();
}
AddTable('Закупки скоро начнутся.','rc');
} else if (/\/floors\/0\/3/.exec(window.location.pathname)) {
if(!checkingManager(collectRevenue)){
collectRevenue();
}
AddTable('Раскладывание товара уже скоро.','rc');
} else if (/\/floors\/0\/5/.exec(window.location.pathname)) {
if(!checkingManager(putProduct)){
putProduct();
}
AddTable('Сбор выручки скоро начнётся.','rc');
} else if (/\/boss*/.exec(window.location.pathname)) {
boss();
AddTable('Ожидаем инвесторов.','rc');
} else if (/\/lobby/.exec(window.location.pathname)) {
lobbySelect();
lobby();
AddTable('Ждём задания в вестибюле.','rc');
} else if (/\/doors/.exec(window.location.pathname)) {
document.querySelector('#log_table tr').insertAdjacentHTML('afterend','| Сколько ключей потратить? | GO |
');
document.querySelector('#event_table').style.top = '62px';
document.querySelector('.DoorsRun').addEventListener('click', ()=>{
localStorage.doors_key = document.querySelector('.Doors_Keys_Input').value || 0;
doors();
})
AddTable('Запустите прохождение дверей вручную','rc');
doors();
} else if (/\/fabric/.exec(window.location.pathname)) {
fabric();
AddTable('Автоматизация началась!','rc');
document.querySelector('.cntr.nshd.m5.white').insertAdjacentHTML('beforeend',' Собрано: 0');
// Кнопка "Обучить всех на данной странице" в Жителях Специалистах
} else if (document?.title == 'Мои жители' && document.querySelector('[href*="humanPanel:upgradeLinkPanel"]')) {
document.querySelector('table.rtgh').insertAdjacentHTML('beforebegin', 'Обучить всех на данной странице');
document.querySelector('.upgradeAllHuman').addEventListener('click', async (btn) => {
let timerHuman = 1;
const items = Array.from(document.querySelectorAll('[href*="humanPanel:upgradeLinkPanel"]'));
btn.target.textContent = 'Идёт обучение 0 их ' + items.length;
btn.target.style.cursor = "wait";
let shouldStop = false;
for (const item of items) {
if (shouldStop) break; // Останавливаем, если были проблемы
await new Promise(resolve => setTimeout(
resolve,
timerHuman += rand_time(1,2)
)).then(async () => {
const response = await fetch(item.href);
if (/\/home/.exec(response.url)) {
item.innerHTML = '✘ Не обучили. Обновите страницу и повторите!';
btn.target.style.background = '#b22';
btn.target.textContent = 'Обновите страницу и перезапустите обучение';
btn.target.style.cursor = "";
btn.target.href = '/humans';
shouldStop = true; // Остановка при ошибке
return;
} else {
item.removeAttribute('href');
item.style.textDecoration = 'none!important';
item.innerHTML = '✓ Успешно обучили';
btn.target.textContent = 'Идёт обучение ' + (items.length - document.querySelectorAll('[href*="humanPanel:upgradeLinkPanel"]').length) + ' их ' + items.length;
}
// Дополнительное условие
// if(){shouldStop = true;}
});
}
if (!shouldStop) {
btn.target.textContent = 'Обучение ' + items.length + ' жителей завершено!';
btn.target.style.background = '#061';
}
}, { once: true })
} else {
AddTable(`Бот автоматически запускается на страницах:
Лифт
Сбор выручки
Закупка товара
Выложить товар
Мои жители
Задания города
Задания
Вестибюль
Босс
Лабиринт
Для работы бота эти страницы должны быть постоянно открыты`,'rc');
}
// Заданий-событий
quests_events();
/* Таймеры */
var time = document.querySelectorAll('[id^=time]');
var tl = time.length;
for (var i = 0; i < tl; i++) {
time[i].title = time[i].innerHTML;
timer(getTime(time[i].innerHTML), time[i],true);
}
switch ( Notification.permission.toLowerCase() ) {
case "granted" : break;
case "denied" :
document.body.insertAdjacentHTML('beforeend','У вас запрещены уведомления!');
break;
case "default" :
document.body.insertAdjacentHTML('beforeend','
Включить уведомления');
break;
}
/* Очищаем раз в час */
setInterval(function() {
if(document.querySelectorAll('#event_table tr td')[1].className !== 'clear_log'){
var els = document.querySelectorAll('#event_table tr'),
ell = els.length,
lt = document.getElementById('event_table');
lt.innerHTML = '';
for (var i = 0; i < ell; i++) {
lt.insertAdjacentHTML("beforeEnd",els[i].innerHTML);
if (i > 3) {
break;
}
}
if(ell > 4){
AddTable('Логи очищены!','clear_log');
}
}
console.clear();
}, 3600000);
}; // Закомментировать 2 из 2
//}); // Раскомментировать 2 из 2