Greasy Fork

Greasy Fork is available in English.

Popmundo chat

Adds instant public chat boxes to locales, cities, social clubs and the community page

当前为 2021-08-26 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Popmundo chat
// @name:tr      Popmundo Sohbet
// @namespace    bheuv.dev
// @version      1.2.3
// @description  Adds instant public chat boxes to locales, cities, social clubs and the community page
// @description:tr Mekanlara, şehirlere, sosyal kulüplere ve hoş geldiniz sayfasına anlık sohbet edebileceğiniz odalar ekler.
// @author       Ian Parsons (105997)
// @match        https://*.popmundo.com/*
// @icon         https://www.google.com/s2/favicons?domain=popmundo.com
// @run-at       document-end
// @noframes
// ==/UserScript==

const version = '1.2';
const hostOrigin = "https://botmundo.bheuv.dev:3005";

(function() {
    'use strict';

    let parseCharacterData = function() {
        // This must be done to make the authenticated character known to the script
        try {
            if (window.location.href.indexOf('/ChooseCharacter') !== -1) {
                // The select character page discloses the character ids
                let content = document.getElementById('ppm-content');
                let buttons = content.querySelectorAll('input[type="submit"]');
                let characterMap = [];
    
                for (let i = 0, len = buttons.length; i < len; i++) {
                    let id = buttons[i].parentNode.parentNode.querySelector("div.idHolder").innerText;
                    let name = buttons[i].parentNode.parentNode.querySelector("h2 a").innerText;
                    characterMap[i] = id + ':' + name;
                }
    
                // Store the data for use on other pages
                window.localStorage.setItem('characterMap', characterMap.join(','));
            } else {
                let characterMap = window.localStorage.getItem('characterMap');
    
                if (! characterMap) {
                    // Character map is not available; cannot run the script
                    throw new Error("Character map is unavailable!");
                }
                
                // Charactermap will now be an array of characters with format [id:name]
                characterMap = characterMap.split(',');

                const dropdown = document.querySelector('#character-tools-character select');
                const options = dropdown.querySelectorAll('option');

                const names = [];
                const ids = [];

                // Split character map into a list of names and ids to make searching in the next step easier
                characterMap.forEach((character) => {
                    const [id, name] = character.split(':');
                    names.push(name);
                    ids.push(id);
                });

                // Attempt to match each option in the dropdown menu to a name from the list of names and set the ID that matches that name's index
                for (let i = 0, len = options.length; i < len; i++) {
                    const option = options[i];
                    const index = names.indexOf(option.innerText);
                    
                    if (index !== -1) {
                        option.dataset.id = ids[index];
                    }
                }
    
                // Now find the authenticated character's id and attach it as data to the document body
                let selectedOption = dropdown.querySelector('option[selected]');
                let selectedValue = selectedOption.dataset.id;
    
                if (selectedValue) {
                    document.body.dataset.character_name = selectedOption.innerText;
                    document.body.dataset.character_id = selectedValue;
                } else {
                    throw "Failed to parse character data from character select box!";
                }
            }
        } catch (e) {
            console.log("CharacterMap could not be found/built: " + e);
            console.log(e);
        }
    }

    if (! document.querySelector('body').dataset.character_id) {
        parseCharacterData();
    }

    if (! document.querySelector('body').dataset.character_id) {
        // Fallback method
        if (document.location.href.endsWith('.popmundo.com/World/Popmundo.aspx/Character')) {
            const characterName = document.querySelector('div.charPresBox h2').innerText;
            const characterIdentifier = document.querySelector('.idHolder').innerText;

            window.localStorage.setItem('character_name', characterName);
            window.localStorage.setItem('character_id', characterIdentifier);
        }

        if (window.localStorage.getItem('character_id')) {
            document.body.dataset.character_id = window.localStorage.getItem('character_id');
            document.body.dataset.character_name = window.localStorage.getItem('character_name');
        }
    }
    
    const characterName = document.body.dataset.character_name;
    const characterIdentifier = document.body.dataset.character_id;

    const addStyle = function(style) {
        const styleEl = document.createElement('style');
        styleEl.textContent = style;
        document.head.append(styleEl);
    }
    
    // Resize property doesn't work on iframes in firefox - this is a workaround
    addStyle(`
        .resizer { 
            display:flex;
            margin:0;
            padding:0;
            resize:vertical;
            overflow:hidden 
        } 
        .resizer > .resized {
             flex-grow:1;
             margin:0;
             padding:0;
             border:0
        }
    `);

    const createChatBox = function(resourceType, resourceIdentifier, characterIdentifier, characterName, mountCallback, chatTitle)
    {
        if (!chatTitle) {
            chatTitle = 'Botmundo Chat';
        }

        const wrapper = document.createElement('div');
        wrapper.classList.add('box');
        wrapper.innerHTML = `<h2>${chatTitle}</h2>`;
        
        const resizer = document.createElement('div');
        resizer.classList.add('resizer');
        resizer.style.height = '400px';
        resizer.style.minHeight = '400px';

        const chatbox = document.createElement('iframe');
        chatbox.src = hostOrigin + '/chat.html';
        chatbox.style.border = '0';
        chatbox.style.width = '100%';
        chatbox.classList.add('resized');

        resizer.appendChild(chatbox);
        wrapper.appendChild(resizer);

        mountCallback(wrapper);

        const style = getComputedStyle(chatbox);

        chatbox.addEventListener('load', function() {
            

            this.contentWindow.postMessage({
                message: 'connect',
                character: {
                    identifier: characterIdentifier,
                    name: characterName
                },
                resource: {
                    identifier: resourceIdentifier,
                    type: resourceType
                },
                style: {
                    background: style.backgroundColor,
                    color: style.color
                },
                script: {
                    version: version
                }
            }, hostOrigin);
        });
        
        return wrapper;
    }

    if (/Locale\/[0-9]+$/.test(document.location.href)) {
        // Locale page
        const localeIdentifier = parseInt(document.querySelector('.idHolder').innerText);
        createChatBox(
            'locale', 
            localeIdentifier, 
            characterIdentifier, 
            characterName, 
            (el) => { 
                document.querySelector("#ppm-content h1").insertAdjacentElement('afterend', el);
            },
            document.title.split(' - ')[1] + ' Chat'
        );
    }
    else if (document.location.href.endsWith('/World/Popmundo.aspx')) {
        // Community news / Welcome page
        createChatBox(
            'community', 
            0, 
            characterIdentifier, 
            characterName, 
            (el) => { 
                document.querySelector("#ctl00_cphLeftColumn_ctl00_divDefaultGreeting").insertAdjacentElement('afterend', el); 
            },
            'Global Chat'
        );
    } else if (document.querySelector("#ctl00_cphLeftColumn_ctl00_pnlCalendar")) {
        // City page
        const cityIdentifier = document.querySelector("#ctl00_cphRightColumn_ctl01_ddlCities").value;
        createChatBox(
            'city', 
            cityIdentifier, 
            characterIdentifier, 
            characterName, 
            (el) => {
                document.querySelector("#ppm-content h1").insertAdjacentElement('afterend', el)
            },
            document.title.split(' - ')[1] + ' Chat'
        );
    } else if (/SocialClub\/[0-9]+$/.test(document.location.href)) {
        // Social club
        const clubIdentifier = document.querySelector(".idHolder").innerText;

        createChatBox(
            'club', 
            clubIdentifier, 
            characterIdentifier, 
            characterName, 
            (el) => {
                document.querySelector("#ppm-content h1").insertAdjacentElement('afterend', el)
            },
            document.querySelector("#ppm-content h1").innerText + ' Chat'
        );
    }
})();