Маркер деревень с приказами на карте

JSmith

Новичок
Оценка реакций
2
В общем написал скрипт и требуется одобрение. Написал чтобы видеть на карте из каких деревень идет атака, подкрепы или если приказы помечены как лазы или топоры их тоже чтоб видеть.

Функции:
- на странице входящих приказов, который доступен с премом, сохраняет входящие приказы в локальное хранилище.
- на странице нападающей деревни или игрока, показывает соответствующие приказы из хранилища из этой деревни или игрока.
- на карте помечает нападающие деревни с иконками которые соответствуют сохраненным приказам. иконки выставляются в нижней части деревни, где обычно стоит метка заметок.
- на других страницах, отправляет на страницу входящих приказов.

PS: Скрипт сам удаляет из хранилища сохраненный приказ если посчитает, что время прихода приказа прошло.

Код:
javascript:
var Polymorph = function(methodName, context, newMethod) {
    this.method = context[methodName];

    this.invokeBase = function() { return this.method.apply(context, arguments);
    };
    this.override = function() { context[methodName] = newMethod; return this;
    };
    this.restore = function() { context[methodName] = this.method; return this;
    };
};

String.prototype.removeSubstring = function(string) { return this.replaceAll(string, ""); };
String.prototype.toInt = function() { let int = parseInt(this); return isNaN(int) ? 0 : int; };
String.prototype.toUriParams = function() {
    let query = this.substring((this.indexOf("?") + 1), this.length);
    return Object.fromEntries(query.split("&").map(string => { let param = string.split("="); return [param[0], param[1]]} ));
};

var MC = {
    Repository: {
        name:  "__MC_Commands",
        load() { return JSON.parse(localStorage[this.name] ?? "{}"); },
        save(data) { localStorage[this.name] = JSON.stringify(data); }
    },
    Common: {
        getServerTime() {
            let serverTime = document.querySelector("#serverTime").textContent.split(":");
            let serverDate = document.querySelector("#serverDate").textContent.split("/");
            return new Date(serverDate[2], serverDate[1] - 1, serverDate[0], serverTime[0], serverTime[1], serverTime[2]).getTime();
        },
        getCoordinates(string) {
            let matches = string.match(/(.*?)\((\d+)\|(\d+)\)\sK(\d+)/);
            let coordinates = { x: matches[2].toInt(), y: matches[3].toInt() };
            coordinates.string = coordinates.x + "|" + coordinates.y;
            return coordinates;
        },
        formatMs(ms) {
            let totalSeconds = ms / 1000;
            let hours = parseInt(totalSeconds / 3600);
            let minutes = parseInt( totalSeconds / 60 ) % 60;
            let seconds = totalSeconds % 60;
            hours = hours > 9 ? hours : '0' + hours;
            minutes = minutes > 9 ? minutes : '0' + minutes;
            seconds = seconds > 9 ? seconds : '0' + seconds;
            return hours + ":" + minutes + ":" + seconds;
        },
        dateToString(ms) {
            let format = {
                day: 'numeric',
                month: 'numeric',
                year: 'numeric',
                hour: 'numeric',
                minute: 'numeric',
                second: 'numeric'
            };
            return new Date(ms).toLocaleString('ru', format);
        }
    },
    Incomings: {
        parseVillage(column) {
            let a = column.querySelector("a");
            let id = parseInt(a.getAttribute("href").toUriParams().id);
            id = isNaN(id) ? a.getAttribute("href").toUriParams().village : id;
            let name = a.textContent.substring(0, a.textContent.length - 14);
            return { id: id, name: name, coordinates: MC.Common.getCoordinates(a.textContent.removeSubstring(name)) };
        },
        parseOrigin(columns) {
            let a = columns[3].querySelector("a");
            let id = parseInt(a.getAttribute("href").toUriParams().id);
            let name = a.textContent.trim();
            return { id: id, name: name, village: this.parseVillage(columns[2]) };
        },
        parseTarget(columns) {
            let id = game_data.player.id;
            let name = game_data.player.name;
            return { id: id, name: name, village: this.parseVillage(columns[1]) }
        },
        parseIcons(colum) {
            let sources = [];
            colum.querySelectorAll("img").forEach(img => sources.push(img.getAttribute("src")));
            return sources;
        },
        parseArrivalTime(colum) {
            let array = colum.textContent.split(":").map(string => string.toInt());
            let arriveIn = (array[0] * 3600 * 1000) + (array[1] * 60 * 1000) + (array[2] * 1000);
            return MC.Common.getServerTime() + arriveIn;
        },

        getIncomingCommads() {
            let commands = {};
            document.querySelector("#incomings_table").querySelectorAll("tr.nowrap").forEach(function(row) {
                let columns = row.querySelectorAll("td");
                let id = columns[0].querySelector(".quickedit").getAttribute("data-id").toInt();
                commands[id] = {
                    name: columns[0].querySelector(".quickedit-label").textContent.trim(),
                    origin: this.parseOrigin(columns),
                    target: this.parseTarget(columns),
                    arrivalTime: this.parseArrivalTime(columns[6]),
                    icons: this.parseIcons(columns[0])
                };
            }.bind(this));
            return commands;
        },

        execute() {
            let commands = this.getIncomingCommads();
            MC.Repository.save(commands);
            UI.SuccessMessage("Команды успешно занесены в базу", 1000);
        }
    },

    Map: {
        displayForVillage(village, x, y) {
            let villageId = parseInt(village.id);
            let commands = MC.Repository.load();
            let commandsCount = 0;
            Object.keys(commands).forEach(id => {
                let command = commands[id];
                if(command.origin.village.id == villageId) commandsCount++;
            });
            
            let html = `
                <tr>
                    <td><b>Вх.Приказов:</b></td>
                    <td>` + commandsCount + `</td>
                </tr>`;
            let element = document.querySelector("#info_points_row");
            if(element) element.outerHTML = element.outerHTML + html;
        },

        updateVillageIcons() {
            let commands = MC.Repository.load();
            Object.keys(commands).forEach(function(id) {
                let command = commands[id];
                if(MC.Common.getServerTime() >= command.arrivalTime) {
                    commands[id] = undefined;
                    return;
                }

                if(!TWMap.villageIcons[command.origin.village.id]) {
                    TWMap.villageIcons[command.origin.village.id] = {};
                }

                let icons = TWMap.villageIcons[command.origin.village.id];
                let iconsArray = Object.keys(icons).map(id => icons[id].img);
                let i = iconsArray.length;

                command.icons.forEach(function(icon) {
                    if(!iconsArray.includes(icon)) icons[++i] = { img: icon }; }
                );
            }.bind(this));
            TWMap.reload();
        },

        initHandlers() {
            let displayForVillage = new Polymorph("displayForVillage", TWMap.popup, function(village, x, y) {
                displayForVillage.invokeBase(village, x, y);
                this.displayForVillage(village, x, y);
            }.bind(this)).override();

            let onDragEnd = new Polymorph("onDragEnd", TWMap.mapHandler, function(e, a) {
                onDragEnd.invokeBase(e, a);
                this.updateVillageIcons();
            }.bind(this)).override();
        },

        execute() {
            this.updateVillageIcons();
            this.initHandlers();
        }
    },

    InfoVillage: {
        execute() {
            let commands = MC.Repository.load();
            let originId = parseInt(document.location.search.toUriParams().id);
            let rows = "";
            let count = 0;
            Object.keys(commands).forEach(id => {
                let command = commands[id];
                if(MC.Common.getServerTime() >= command.arrivalTime) {
                    commands[id] = undefined;
                    return;
                }

                if(command.origin.village.id != originId) return;

                let icons = command.icons.map(icon => { return `<span style="margin: 0px 2px;"><img alt="" src="`+ icon +`"></span>` }).join("");
                let commandUrl = TribalWars.buildURL("", {screen: "info_command", id: id, type: "other"});
                let targetUrl = TribalWars.buildURL("", {screen: "info_village", id: command.target.village.id});
                rows += `
                    <tr>
                        <td>` + icons + `<a href="` + commandUrl + `">` + command.name + `</a></td>
                        <td>` + MC.Common.dateToString(command.arrivalTime) + `</td>
                        <td><a href="` + targetUrl + `">` + command.target.village.name + `</a></td>
                    </tr>`;
                count++;
            });

            if(count == 0) { UI.ErrorMessage("Нет входящих приказов", 1000); return; }

            let html = `
                <table id="mc_village_commands" class="vis" style="width:100%; margin-bottom: 20px;">
                    <tbody>
                        <tr>
                            <th>Приказы (` + count + `)</th><th>Прибытие</th><th>В деревню</th>
                        </tr>` + rows + ` </tbody>
                </table>`;

            let existing = document.querySelector("#mc_village_commands");
            if(existing) { existing.outerHTML = ""; }


            let element = document.querySelector("#content_value h2");
            element.outerHTML = element.outerHTML + html;
        }
    },

    InfoPlayer: {
        execute() {
            let commands = MC.Repository.load();
            let originId = parseInt(document.location.search.toUriParams().id);
            let rows = "";
            let count = 0;
            Object.keys(commands).forEach(id => {
                let command = commands[id];
                if(MC.Common.getServerTime() >= command.arrivalTime) {
                    commands[id] = undefined;
                    return;
                }

                if(command.origin.id != originId) return;

                let icons = command.icons.map(icon => { return `<span style="margin: 0px 2px;"><img alt="" src="`+ icon +`"></span>` }).join("");
                let commandUrl = TribalWars.buildURL("", {screen: "info_command", id: id, type: "other"});
                let targetUrl = TribalWars.buildURL("", {screen: "info_village", id: command.target.village.id});
                rows += `
                    <tr>
                        <td>` + icons + `<a href="` + commandUrl + `">` + command.name + `</a></td>
                        <td>` + MC.Common.dateToString(command.arrivalTime) + `</td>
                        <td><a href="` + targetUrl + `">` + command.target.village.name + `</a></td>
                    </tr>`;
                count++;
            });

            if(count == 0) { UI.ErrorMessage("Нет входящих приказов", 1000); return; }

            let html = `
                <table id="mc_player_commands" class="vis" style="width:100%; margin-bottom: 20px;">
                    <tbody>
                        <tr>
                            <th>Приказы (` + count + `)</th><th>Прибытие</th><th>В деревню</th>
                        </tr>` + rows + ` </tbody>
                </table>`;

            let existing = document.querySelector("#mc_player_commands");
            if(existing) { existing.outerHTML = ""; }


            let element = document.querySelector("#content_value h2");
            element.outerHTML = element.outerHTML + html;
        }
    },

    execute() {
        params = document.location.search.toUriParams();
        if(params.screen == "overview_villages" && params.mode == "incomings") {
            this.Incomings.execute();
        } else if(params.screen == "map") {
            this.Map.execute();
        } else if(params.screen == "info_village" && params.id) {
            this.InfoVillage.execute();
        } else if(params.screen == "info_player" && params.id) {
            this.InfoPlayer.execute();
        } else {
            UI.ErrorMessage("Скрипт не работает на этой странице", 1000);
            document.location.href = TribalWars.buildURL("", { screen: "overview_villages", mode: "incomings" })
        }
    }
};

MC.execute();


1675737536364.jpeg
 
Верх