Devil's Scavenging Enhancer

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

cQrQn3B.png


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:

Deleted User - 24028

Guest
Bovenstaand script is privé ingediend, de 6 maanden exclusiviteits periode zijn ondertussen verlopen.

Normaal gezien wordt het script nu publiek beschikbaar gesteld, echter werkt dit script niet zonder een bijhorende server / discord bot. De maker kan/wilt op dit moment deze server / discord bot niet beschikbaar stellen voor het publiek, met als gevolg:

Vanaf heden is dit script illegaal en mag het door niemand meer gebruikt worden!

De officiële gehoste versie zal verwijderd worden, de versie die hier boven te vinden is is illegaal maar wordt publiek beschikbaar gesteld zodat andere scripters er eventueel mee aan de slag kunnen.
 
Bovenaan