- Reactiescore
- 304
Voegt een extra tabel op de pagina massa roven toe, die laat zien hoeveel elke pagina aan het roven is

Code:
// ==UserScript==
// @name Devil's Scavenging Enhancer
// @description Scavenging Enhancer
// @author Devilicious#9733 (discord)
// @version 1.0
// @grant none
// @ticket t14258460/t14429659
// @gekeurd op 29/09/2020
// @include https://*.tribalwars.nl*&screen=place*&mode=scavenge_mass*
// ==/UserScript==
if (window.location.href.indexOf(`screen=place&mode=scavenge_mass`) < 0) {
window.location.assign(`${game_data.link_base_pure}place&mode=scavenge_mass`);
}
const isMobile = game_data.device.match(/iphone|android|blackberry/ig);
if (typeof window.twLib === 'undefined') {
window.twLib = {
queues: null,
init: function () {
if (this.queues === null) {
this.queues = this.queueLib.createQueues(5);
}
},
queueLib: {
maxAttempts: 3,
Item: function (action, arg, promise = null) {
this.action = action;
this.arguments = arg;
this.promise = promise;
this.attempts = 0;
},
Queue: function () {
this.list = [];
this.working = false;
this.length = 0;
this.doNext = function () {
let item = this.dequeue();
let self = this;
if (item.action === 'openWindow') {
window.open(...item.arguments).addEventListener('DOMContentLoaded', function () {
self.start();
});
} else {
$[item.action](...item.arguments).done(function () {
item.promise.resolve.apply(null, arguments);
self.start();
}).fail(function () {
item.attempts += 1;
if (item.attempts < twLib.queueLib.maxAttempts) {
self.enqueue(item, true);
} else {
item.promise.reject.apply(null, arguments);
}
self.start();
});
}
};
this.start = function () {
if (this.length) {
this.working = true;
this.doNext();
} else {
this.working = false;
}
};
this.dequeue = function () {
this.length -= 1;
return this.list.shift();
};
this.enqueue = function (item, front = false) {
(front) ? this.list.unshift(item) : this.list.push(item);
this.length += 1;
if (!this.working) {
this.start();
}
};
},
createQueues: function (amount) {
let arr = [];
for (let i = 0; i < amount; i++) {
arr[i] = new twLib.queueLib.Queue();
}
return arr;
},
addItem: function (item) {
let leastBusyQueue = twLib.queues.map(q => q.length).reduce((next, curr) => (curr < next) ? curr : next, 0);
twLib.queues[leastBusyQueue].enqueue(item);
},
orchestrator: function (type, arg) {
let promise = $.Deferred();
let item = new twLib.queueLib.Item(type, arg, promise);
twLib.queueLib.addItem(item);
return promise;
}
},
ajax: function () {
return twLib.queueLib.orchestrator('ajax', arguments);
},
get: function () {
return twLib.queueLib.orchestrator('get', arguments);
},
post: function () {
return twLib.queueLib.orchestrator('post', arguments);
},
openWindow: function () {
let item = new twLib.queueLib.Item('openWindow', arguments);
twLib.queueLib.addItem(item);
}
};
twLib.init();
}
class Resource {
constructor(wood, stone, iron) {
return {'wood': wood, 'stone': stone, 'iron': iron, 'total': wood + stone + iron}
}
}
class ScavengingPage {
totalWood = 0;
totalStone = 0;
totalIron = 0;
constructor(page) {
this.data = page;
this.processHaulStats();
}
processHaulStats() {
Object.values(this.data).map((row, _) => this.processHaulRow(row));
}
processHaulRow(row) {
const wood = Object.values(row.options).reduce((a, option) => a + option.scavenging_squad?.loot_res.wood || 0, 0);
const stone = Object.values(row.options).reduce((a, option) => a + option.scavenging_squad?.loot_res.stone || 0, 0);
const iron = Object.values(row.options).reduce((a, option) => a + option.scavenging_squad?.loot_res.iron || 0, 0);
this.totalWood += wood;
this.totalStone += stone;
this.totalIron += iron;
return new Resource(wood, stone, iron);
}
get rows() {
return Object.values(this.data).map((row, _) => this.mapRow(row));
}
mapRow(row) {
return {
'player_id': row.player_id,
'village': row.village_name,
'return_times': Object.values(row.options).map((option, _) => {
return {'category': option.base_id, "return_time": option.scavenging_squad?.return_time}
})
}
}
get totalHaul() {
return new Resource(this.totalWood, this.totalStone, this.totalIron);
}
htmlRow(index) {
return `<tr><td>Pagina ${index + 1}</td><td style="text-align: center">${Format.number(this.totalWood)}</td><td style="text-align: center">${Format.number(this.totalStone)}</td><td style="text-align: center">${Format.number(this.totalIron)}</td></tr>`;
}
}
async function getScavengingPageData() {
const currentPage = [`${game_data.link_base_pure}place&mode=scavenge_mass&page=${parseInt($('#scavenge_mass_screen').prevAll('table').find('strong').text().match(/\d+/g).pop()) - 1 || 0}`];
const select = $('.paged-nav-item:last').next('select').find('option:not(:selected)');
let scavengingData = [];
let allOtherPages = $('.paged-nav-item').map((index, el) => $(el).attr('href')).get();
if (isMobile || select.length > 0) {
allOtherPages = select.map((_, el) => $(el).val()).get();
}
(await getScavengingPageDataFor(currentPage.concat(allOtherPages))).forEach((data, _) => scavengingData.push(data));
return scavengingData;
}
async function getScavengingPageDataFor(pages) {
let data = [];
$('.options-container').after(`<div id="scav-enhancer-progress-bar" class="progress-bar live-progress-bar progress-bar-alive"><div></div><span class="label"></span></div>`);
const progressBar = $('#scav-enhancer-progress-bar');
UI.InitProgressBars();
UI.updateProgressBar(progressBar, 0, pages.length);
for (const [index, page] of pages.entries()) {
UI.updateProgressBar(progressBar, index + 1, pages.length);
data.push(await getDataFromUrl(page));
}
return data;
}
async function getDataFromUrl(url) {
return new Promise((resolve, reject) => {
twLib.get({
url: url,
dataType: 'html',
success: function (html) {
resolve(new ScavengingPage(JSON.parse(`[${$(html).find('script:contains("ScavengeMassScreen")').html().match(/{.*:{.*:.*}}/g)[2]}]`)));
}, error: function (error) {
reject(error);
}
})
});
}
function getHtmlTable(pages) {
return `<div class="scavenging-enhancement-container"><table style="width: 100%" class="vis scavenging-enhancement-table">
<thead>
<tr>
<th>Totale Buit</th>
<th style="text-align: center"><span class="icon header wood"/></th>
<th style="text-align: center"><span class="icon header stone"/></th>
<th style="text-align: center"><span class="icon header iron"/></th>
</tr>
</thead>
<tbody>
${Object.values(pages).map((page, index) => page.htmlRow(index)).join('')}
<tr>
<th>Totaal (<span style="color: ${isMobile ? 'white' : 'darkgreen'}">+${Format.number(Object.values(pages).reduce((t, page) => t + page.totalHaul.total || 0, 0))}</span>)</th>
<th style="text-align: center">${Format.number(Object.values(pages).reduce((w, page) => w + page.totalHaul.wood || 0, 0))}</th>
<th style="text-align: center">${Format.number(Object.values(pages).reduce((s, page) => s + page.totalHaul.stone || 0, 0))}</th>
<th style="text-align: center">${Format.number(Object.values(pages).reduce((i, page) => i + page.totalHaul.iron || 0, 0))}</th>
</tr>
</tbody>
</table></div>`;
}
getScavengingPageData().then(async (data) => {
$('.buttons-container')
.prepend('<a class="btn btn-default save-scavenging-run">Sync To Discord</a>')
.before(getHtmlTable(data));
$('.save-scavenging-run').click(() => {
const mergedData = [].concat.apply([], data.map((page, _) => page.rows));
const totalLoot = Object.values(data).reduce((t, page) => t + page.totalHaul.total || 0, 0);
$.ajax({
url: `url`,
async: false,
type: 'POST',
crossDomain: true,
dataType: "json",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
'totalLoot': totalLoot,
'data': mergedData
})
});
});
});
Laatst bewerkt door een moderator: