Greasy Fork 还支持 简体中文。

Atlantis GameData hyperlinks

Add hyperlinks to GameData

Från och med 2021-03-23. Se den senaste versionen.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Atlantis GameData hyperlinks
// @namespace    http://atlantis-pbem.com/data
// @version      0.004
// @description  Add hyperlinks to GameData
// @author       Anton
// @match        http://atlantis-pbem.com/data
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    if (typeof GM_addStyle !== 'function') {
        GM_addStyle = function (aCss) {
            'use strict';
            let head = document.getElementsByTagName('head')[0];
            if (head) {
                let style = document.createElement('style');
                style.setAttribute('type', 'text/css');
                style.textContent = aCss;
                head.appendChild(style);
                return style;
            }
            return null;
        };
    }

GM_addStyle(`
.gameDataMenu {
  position: fixed;
  right: 0;
  top: 100px;
  width: 350px;
  border-top: 1px solid #CCC;
  border-left: 1px solid #CCC;
  border-bottom: 1px solid #CCC;
  border-top-left-radius: 8px;
  border-bottom-left-radius: 8px;
  padding: 8px;
}
.gameDataLink, pre > a.mainlink {
  position: relative;
  top: -80px;
}
#skills-ph, #items-ph, #objects-ph {
  padding-left: 8px;
  font-size: 70%;
}
#filtr {
  margin-left: 8px;
  padding: 1px;
  border: 1px solid #CCC;
}
`);

    let body = document.querySelector('body');
    let container = document.querySelector('pre');
    let data = container.innerHTML;
    let dataLines = data.split(/\r?\n/);

    let skillReportLine = dataLines.indexOf("Skill reports:");
    let itemReportLine = dataLines.indexOf("Item reports:");
    let objectReportLine = dataLines.indexOf("Object reports:");

    let controlPanel = document.createElement('div');
    controlPanel.className = 'gameDataMenu';
    controlPanel.innerHTML = `
<div><label for="filtr">Search: </label><input id="filtr" type="text"></div>
<a href="#skills">Skills</a>
<div id="skills-ph"></div>
<a href="#items">Items</a>
<div id="items-ph"></div>
<a href="#objects">Objects</a>
<div id="objects-ph"></div>
`;
    body.append(controlPanel);

    let skillsArray = [];
    let itemsArray = [];
    let objectsArray = [];
    let skillsDescription = {};
    let itemsDescription = {};
    let objectsDescription = {};
    let skillsDesc = {};
    let itemsDesc = {};
    let objectsDesc = {};

    let addToArray = (arr, key, item) => {
        if (arr != '' && key != '') {
            if (!arr[key]) arr[key] = [];
            if (arr[key].indexOf(item) == -1) arr[key].push(item);
        }
    };

    let analyzePart = (s, run, prevSkill, prevItem, prevObject) => {
        let parts = s.match(/(.*)(\[(.{3,4})\])(.*)/);
        if (parts && parts.length > 0) {
            let skillAddon = (skillsArray.indexOf(parts[3] + '1') != -1) ? '1' : '';
            addToArray(skillsDescription, prevSkill, parts[3] + skillAddon);
            addToArray(itemsDescription, prevItem, parts[3]);
            addToArray(objectsDescription, prevObject, parts[3]);
            return analyzePart(parts[1], run, prevSkill, prevItem, prevObject) +
                '<a href="#' + parts[3] + skillAddon + '">' + parts[2] + '</a>' + analyzePart(parts[4], run, prevSkill, prevItem, prevObject);
        }
        return s;
    };

    let clearName = (s) => {
        return s.replace(' ', '_').replace("'", '');
    };

    for (let run = 0; run < 2; run++) {
        let prevLine = '';
        let prevSkill = '';
        let prevItem = '';
        let prevObject = '';
        for (let i = 0; i < dataLines.length; i++) {
            let str = dataLines[i];
            // mining [MINI] 3: A unit with this skill may PRODUCE mithril [MITH] at
            let searchForName = str.match(/(\S.*)(\[(.{3,4})\].(\d)):(.*)/);
            if (searchForName && searchForName.length > 0 && prevLine.trim() == '') {
                let firstPart = searchForName[1]; // mining
                let linkText = searchForName[2]; // [MINI] 3
                let name = searchForName[3]; // MINI
                let level = parseInt(searchForName[4]); // 3
                let lastPart = searchForName[5]; // A unit with this skill may PRODUCE mithril [MITH] at
                let linkName = name + level;
                prevSkill = name + '1';
                prevItem = '';
                prevObject = '';
                if (skillsArray.indexOf(linkName) == -1) {
                    skillsArray.push(linkName);
                    lastPart = analyzePart(lastPart, run, prevSkill, prevItem, prevObject);
                    dataLines[i] = firstPart + '<a class="mainlink" name="' + linkName + '"></a>' + linkText + ':' + lastPart;
                }
            } else {
                // winged horse [WING], weight 50, walking capacity 20, riding capacity
                searchForName = str.match(/(\S.*)(\[(.{3,4})\])[,\.](.*)/);
                if (searchForName && searchForName.length > 0 && prevLine.trim() == '') {
                    let firstPart = searchForName[1]; // winged horse
                    let linkText = searchForName[2]; // [WING]
                    let name = searchForName[3]; // WING
                    let lastPart = searchForName[4]; // weight 50, walking capacity 20, riding capacity
                    let linkName = name;
                    prevSkill = '';
                    prevItem = name;
                    prevObject = '';
                    if (itemsArray.indexOf(linkName) == -1) {
                        itemsArray.push(linkName);
                        lastPart = analyzePart(lastPart, run, prevSkill, prevItem, prevObject);
                        dataLines[i] = firstPart + '<a class="mainlink" name="' + linkName + '"></a>' + linkText + ',' + lastPart;
                    }
                } else {
                    // Magician's Tower: This is a building. Monsters can potentially lair in
                    searchForName = str.match(/^(.+):(.+)/);
                    if (searchForName && searchForName.length > 0 && prevLine.trim() == '' && run == 0) {
                        let name = searchForName[1]; // Magician's Tower
                        let lastPart = searchForName[2]; // This is a building. Monsters can potentially lair in
                        let linkName = clearName(name);
                        prevSkill = '';
                        prevItem = '';
                        prevObject = name;
                        if (objectsArray.indexOf(linkName) == -1) {
                            objectsArray.push(linkName);
                            lastPart = analyzePart(lastPart, run, prevSkill, prevItem, prevObject);
                            dataLines[i] = '<a class="mainlink" name="' + linkName + '"></a>' + name + ':' + lastPart;
                        }
                    } else {
                        if (run == 1) dataLines[i] = analyzePart(str, run, prevSkill, prevItem, prevObject);
                    }
                }
            }
            if (str.trim() == '') {
                prevSkill = '';
                prevItem = '';
            } else if (prevSkill != '' && run == 0) {
                if (!skillsDesc[prevSkill]) skillsDesc[prevSkill] = str.trim().toUpperCase();
                else skillsDesc[prevSkill] += ' ' + str.trim().toUpperCase();
            } else if (prevItem != '' && run == 0) {
                if (!itemsDesc[prevItem]) itemsDesc[prevItem] = str.trim().toUpperCase();
                else itemsDesc[prevItem] += ' ' + str.trim().toUpperCase();
            } else if (prevObject != '' && run == 0) {
                if (!objectsDesc[prevObject]) objectsDesc[prevObject] = str.trim().toUpperCase();
                else objectsDesc[prevObject] += ' ' + str.trim().toUpperCase();
            }
            prevLine = str;
        }
    }

    dataLines[skillReportLine] = '<a name="skills" class="gameDataLink"></a>Skill reports:';
    dataLines[itemReportLine] = '<a name="items" class="gameDataLink"></a>Item reports:';
    dataLines[objectReportLine] = '<a name="objects" class="gameDataLink"></a>Object reports:';

    container.innerHTML = dataLines.join("\n");

    let skillHasObject = (skil, filterValue) => {
        let found = skillsDescription[skil] && !!(skillsDescription[skil].find(o => o.indexOf(filterValue) != -1));
        let foundInDesc = skillsDesc[skil] && skillsDesc[skil].indexOf(filterValue) != -1;
        return found || foundInDesc;
    };

    let objectHasSkill = (ob, filterValue) => {
        let found = itemsDescription[ob] && !!(itemsDescription[ob].find(o => o.indexOf(filterValue) != -1));
        let foundInDesc = itemsDesc[ob] && itemsDesc[ob].indexOf(filterValue) != -1;
        return found || foundInDesc;
    };

    let objectHasDescription = (ob, filterValue) => {
        let foundInDesc = objectsDesc[ob] && objectsDesc[ob].indexOf(filterValue) != -1;
        return foundInDesc;
    };

    let skillsPH = document.querySelector('#skills-ph');
    let itemsPH = document.querySelector('#items-ph');
    let objectsPH = document.querySelector('#objects-ph');

    let updateLists = (filterValue) => {
        skillsPH.innerHTML = skillsArray
            .filter(e => e[e.length - 1] == 1)
            .filter(e => e.indexOf(filterValue) != -1 || skillHasObject(e, filterValue))
            .map(e => e.substr(0, e.length - 1))
            .map(e => '<a href="#' + e + '1">' + e + '</a>')
            .join(', ');

        itemsPH.innerHTML = itemsArray
            .filter(e => e.indexOf(filterValue) != -1 || objectHasSkill(e, filterValue))
            .map(e => '<a href="#' + e + '">' + e + '</a>')
            .join(', ');

        if (filterValue.trim() == '') objectsPH.innerHTML = '';
        else {
            objectsPH.innerHTML = objectsArray
                .filter(e => objectHasDescription(e, filterValue))
                .map(e => '<a href="#' + clearName(e) + '">' + e + '</a>')
                .join(', ');
            }
    }

    updateLists('');

    let inp = document.querySelector('#filtr');
    inp.onkeyup = (e) => {
        updateLists(String(inp.value).toUpperCase());
    };

    console.log('Atlantis GameData hyperlinks: hello!');
})();