Raw Source
marekblomkvist / Aeterna

// ==UserScript==
// @name         Aeterna
// @version      0.2.1
// @description  Extension to Grepolis for Aeterna
// @author       Marek Blomkvist
// @namespace    http://github.com/marekblomkvist
// @downloadURL  https://github.com/MarekBlomkvist/aeterna-userscript/raw/master/aeterna.user.js
// @include      https://*.grepolis.com/game*
// @copyright	 Copyright (C) 2019, by Marek Blomkvist
// @license      MIT
// @updateURL    https://github.com/MarekBlomkvist/aeterna-userscript/raw/master/aeterna.user.js
// @grant        unsafeWindow
// ==/UserScript==

var uw = unsafeWindow || window;
//bbcodes published_report

function Aeterna(info) {

    var AET = {};

    AET.info = info;

    AET.Helper = {
        copyToClipboard: function(str) {
            const el = document.createElement('textarea');
            el.value = str;
            document.body.appendChild(el);
            el.select();
            document.execCommand('copy');
            document.body.removeChild(el);
        },
        insertAfter: function(newNode, referenceNode) {
            referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
        },
        getTown: function(report) {
            let anchor = report.querySelectorAll('.published_report_header .gp_town_link')[1];

            if (!anchor) return false;

            let link = anchor.getAttribute('href').substr(1);

            // link is encoded in base64
            // window.atob provides function to decode
            // window.btoa provides function to encode

            let decoded = JSON.parse(window.atob(link));

            return decoded.id;
        },
        getDate: function(report) {
            const raw = report.querySelector('.reports_date').innerHTML;

            // patternToday: heute um XX:XX:XX
            // patternOther: XX.XX.XX um XX:XX:XX
            const patternToday = /heute um ([0-9]{2}:[0-9]{2}:[0-9]{2})/;
            const patternOther = /([0-9]{2}.[0-9]{2}.[0-9]{2}) um ([0-9]{2}:[0-9]{2}:[0-9]{2})/;

            // pattern of date for input is: YYYY-MM-DDTHH:MM:II
            if (patternToday.test(raw)) {
                // $1: HH:MM:II
                let match = raw.match(patternToday);
                let timezoneOffset = new Date().getTimezoneOffset() / 60;

                let matchSplitted = match[1].split(':');
                let hours = parseInt(matchSplitted[0]) - timezoneOffset;
                let minutes = matchSplitted[1];
                let seconds = matchSplitted[2];


                let today = new Date();
                today.setHours(hours);
                today.setMinutes(minutes);
                today.setSeconds(seconds);


                return today.toISOString().split('.')[0];
            } else {
                // $1: DD.MM.YY
                // $2: HH:MM:II
                let match = raw.match(patternOther);

                let dateSplitted = match[1].split('.');
                let year = '20' + dateSplitted[2];
                let month = dateSplitted[1];
                let day = dateSplitted[0];

                let hhmmii = match[2];

                return `${year}-${month}-${day}T${hhmmii}`;
            }
        },
        getWall: function(report) {

            // if wall not in report return 0
            if (report.querySelector('.report_details') === null) return false;

            const raw = report.querySelector('.report_details').innerHTML;
            const patternWall = /Stadtmauer: ([0-9]{1,2}) \(-([0-9]{1,2})/;

            if (!patternWall.test(raw)) return false;

            let match = raw.match(patternWall);

            let wallBefore = parseInt(match[1]);
            let wallChange = parseInt(match[2]);

            return wallBefore - wallChange;
        },
        getReportID: function(report) {
            if (!report.querySelector('.report_data')) return false;

            const report_data = report.querySelector('.report_data').innerHTML;
            const parsed = JSON.parse(report_data);

            return parsed.report_id;
        },
        getGod: function(reportID) {
            if (reportID === undefined) return false;

            let troops = ReportViewer.dates[reportID].defender_units;

            let zeus = troops.minotaur.before + troops.manticore.before;
            let poseidon = troops.zyklop.before + troops.sea_monster.before;
            let hera = troops.harpy.before + troops.medusa.before;
            let athena = troops.centaur.before + troops.pegasus.before;
            let hades = troops.cerberus.before + troops.fury.before;
            let artemis = troops.griffin.before + troops.calydonian_boar.before;

            if (zeus > 0) return 'Zeus';
            if (poseidon > 0) return 'Poseidon';
            if (hera > 0) return 'Hera';
            if (athena > 0) return 'Athene';
            if (hades > 0) return 'Hades';
            if (artemis > 0) return 'Artemis';
        },
        getStatus: function(wall) {
            if (wall >= 20) return 'LD';
            if (wall > 15) return 'SD/LD';
            if (wall < 16) return 'SD';
        },
        createButton: function(reportID) {
            let button = document.createElement('a');
            button.classList.add('button');
            button.setAttribute('id', `aeterna-${reportID}`);
            button.setAttribute('href', '#');
            button.innerHTML = '<span class="left"><span class="right"><span class="middle">Aeterna</span></span></span><span style="clear:both;"></span>';
            return button;
        }
    };

    AET.Functions = {
        init: function() {
            console.log(`AETERNA v${AET.info.version}`);
            AET.Functions.addListeners();
        },
        addListeners: function() {
            $(document).ajaxComplete((e, xhr, settings) => {
                let url = settings.url.split('?');
                let type = url[0].substr(6) + "/" + url[1].split("&")[1].substr(7);
                //console.log(xhr);
                //console.log(settings);

                var wnd = GPWindowMgr.getFocusedWindow() || false;
                if (wnd) {
                    AET.wndId = wnd.getID();
                    AET.wnd = wnd.getJQElement().find(".gpwindow_content");
                }

                switch(type) {
                    case 'alliance_forum/forum':
                        AET.Functions.checkForReports();
                        break;
                }
            });
        },
        checkForReports: function() {
            let reports = AET.wnd.find('.published_report');

            if(reports.length > 0) {

                for (let i = 0; i < reports.length; i++) {
                    let report = reports[i];

                    let id = report.getAttribute('id');
                    let reportID = AET.Helper.getReportID(report);
                    let town = AET.Helper.getTown(report);
                    let date = AET.Helper.getDate(report);
                    let wall = AET.Helper.getWall(report);
                    let god = AET.Helper.getGod(reportID);
                    let status = AET.Helper.getStatus(wall);

                    if (!reportID || !town || !wall) {
                        console.log('Report not available');
                    } else {
                        let btn = AET.Helper.createButton(reportID);

                        AET.Helper.insertAfter(btn, report.querySelector('.button.simulator.surv'));

                        btn.addEventListener('click', () => {
                            AET.Helper.copyToClipboard(JSON.stringify({
                                town,
                                date,
                                wall,
                                god,
                                status
                            }));
                            console.log('Copied to clipboard');
                        });
                    }
                }
            }
        }
    };

    AET.Functions.init();

}

var info = {
    version: GM.info.script.version
};


function Initializer() {
    if (uw.Game) {
		var script = document.createElement('script');
		script.type = 'text/javascript';
        script.setAttribute('id', 'aeterna');
		script.textContent = `${Aeterna.toString()}\n Aeterna(${JSON.stringify(info)});`;
		document.body.appendChild(script);

	} else {
		setTimeout(function () {
			Initializer();
		}, 100);
	}
}

Initializer();

//console.log(GM.info.script);