Roll20 Boilerplate v2

Use this before other scripts

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         Roll20 Boilerplate v2
// @namespace    http://statonions.com
// @version      0.2.4
// @description  Use this before other scripts
// @author       Justice Noon
// @match        https://app.roll20.net/editor/
// @include      https://app.roll20.net/assets/*
// @run-at       document-start
// @grant        GM_webRequest
// @webRequest   {"selector": {"include":"*/assets/app.js?*","exclude":"*/assets/app.js?n*"}, "action": "cancel" }
//Changelog: Rollback VTTES detection because it doesn't work on chrome unpacked (sometimes) depending on load order. Exposed variable is now just d20 everywhere. VTTES already exposes it. Activating VTTES or this script should do the same thing for scripts relying on window.d20
// ==/UserScript==

(function() {
    'use strict';
    var readyScript = '';

    GM_webRequest([{"selector": {"include":"*/assets/app.js?*","exclude":"*/assets/app.js?n*"}, "action": "cancel" }], function(info, message, details) {
        console.log(info, message, details);
    });
    var oReq = new XMLHttpRequest();
    oReq.addEventListener("load", function() {
		readyScript = this.responseText.replace('getPointer,degreesToRadians;', 'getPointer,degreesToRadians;window.d20=d20;');
    });
    oReq.open("GET", "https://app.roll20.net/assets/app.js?n" + Date.now());
    oReq.send();

    const observer = new MutationObserver(mutations => {
        mutations.forEach(({ addedNodes }) => {
            addedNodes.forEach(node => {
                if(node.nodeType === 1 && node.tagName === 'SCRIPT') {
                    const src = node.src || '';
                    //Load modified app when it would have loaded normally
                    if(src.indexOf('assets/app.js') > -1) {
                        window.eval(readyScript);
                        node.type = 'javascript/blocked';
                        node.parentElement.removeChild(node);
                        observer.disconnect();
                    }
                }
            })
        })
    })

    observer.observe(document.documentElement, {
        childList: true,
        subtree: true
    })
})();