Skriptit / miniweppis.js

JavaScript-käyttäjäskripti miniweppis.js muuttaa weppis.com -videochatin ääriminimalistiseksi perustekstichatiksi. YouTube-yhteydet (jukebox), WebRTC-yhteydet (chattaajien ääni ja video) sekä WebGL (koristeet) estyvät kokonaan, mutta vain weppis.com -sivua käyttäessä. Hyvä vaihtoehto esimerkiksi puhelimen käyttäjälle, joka haluaa chattailla tutun porukan kanssa pidemmän aikaa ja on puhelimen akun varassa. Skripti ajetaan esimerkiksi ScriptCatilla (suositus), Tampermonkeylla, Violentmonkeylla tai Wildmonkeylla.

Huom! Tämä on ensimmäinen, pitkälti testaamaton versio ja omannee ainakin seuraavanlaisia ongelmia:

• Skripti ei välttämättä toimi kaikilla käyttäjäskriptinhallintalisäosilla. Violentmonkeyn kanssa on ongelmia, mutta ScriptCat vaikuttaisi toimivan täydellisesti.

• Skripti on asetettu estämään weppis.com -chatin kaikki "punatekstiset" virheilmoitukset, koska WebRTC:n esto aiheuttaa niitä suhteellisen paljon ja ne olisivat lähinnä häiriöksi. Joskus tämä voi tarkoittaa sitä, ettet näe myöskään sellaisia virheilmoituksia jotka muut näkevät, ja tämä voi aiheuttaa hämmennystä, mutta en näe tätä vaarallisena. Jos haluat virheilmoitukset päälle, muuta skriptistä merkkijonot .msg.system.error vaikkapa muotoon .pier.naur.lol (tällaista .pier.naur.lol -luokkaa ei ole käytössä, joten tällöin ne eivät tee mitään) tai pyydä minulta versiota, jossa ne on poistettu ja julkaisen sen esim. täällä.

• Toisten tavalliset tekstiviestit kyllä näkyvät, mutta tietyt erikoisviestit eivät välttämättä näy tai antavat ilmoitusta, jonka mukaan "viestin liitetiedosto on vanhentunut". Tämä liittynee WebGL:n estoon. En itsekään tunne vielä kovin hyvin weppis.comin chatin toimintoja, joten en ole perehtynyt tarkemmin siihen, minkälaiset viestit eivät näy, mutta olletenkin niissä on jonkinlainen liitetiedosto tai tietyn tyyppinen hyperlinkki.

• Yleinen-huoneeseen automaattinen liittyminen ei toimi, vaan sinun tulee klikata hiirellä Yleinen-huonetta huonelistasta itse.

• Huoneen käyttäjälista ei lataudu heti liittyessäsi, vaan näyttää tyhjää. Havaintojeni mukaan se päivittyy silloin, kun joku toinen käyttäjä liittyy tai poistuu. Jos olet klikannut itsesi Yleinen-huoneeseen, viestiesi tulisi kuitenkin näkyä huoneeseen, vaikka et vielä näekään käyttäjälistaa.

Yleisluontoinen neuvo käyttäjäskriptejä koskien: käyttäjäskriptit varsinkin satunnaisemmasta lähteestä voivat sisältää haittakoodia, joten kannattaa copypastettaa ne tekoälylle tai parille ja kysyä, löytävätkö ne haittakoodia seasta.

// ==UserScript==
// @name         miniweppis.js
// @description  Muuttaa weppis.com -videochatin pelkäksi tekstichatiksi, "virransäästötila"
// @version      1.0
// @match        https://weppis.com/*
// @run-at       document-start
// @grant        none
// ==/UserScript==

(function() {
    'use strict';



// ================================================
// WebRTC:n (kamera/mikrofoniyhteydet) esto, ALKU
// ================================================
    try {
        const blockWebRTC = () => {
            throw new Error('WebRTC on estetty tällä sivulla.');
        };

        if (window.RTCPeerConnection) window.RTCPeerConnection = blockWebRTC;
        if (window.webkitRTCPeerConnection) window.webkitRTCPeerConnection = blockWebRTC;
        if (window.mozRTCPeerConnection) window.mozRTCPeerConnection = blockWebRTC;
        if (window.RTCDataChannel) window.RTCDataChannel = blockWebRTC;

        if (navigator.mediaDevices) {
            navigator.mediaDevices.getUserMedia = () => Promise.reject(new Error('getUserMedia estetty'));
        }
    } catch (e) {
        console.warn('WebRTC-esto epäonnistui', e);
    }
// ================================================
// WebRTC:n (kamera/mikrofoniyhteydet) esto, LOPPU
// ================================================



// ================================================
// YouTube-yhteyksien esto, ALKU
// ================================================
    try {
        const isYouTube = (url) => {
            try {
                const u = new URL(url, location.href);
                return /(^|\.)youtube\.com$|(^|\.)youtu\.be$|(^|\.)ytimg\.com$|(^|\.)googlevideo\.com$/.test(u.hostname);
            } catch (e) {
                return false;
            }
        };

        const origFetch = window.fetch;
        window.fetch = function(input, init) {
            const url = typeof input === 'string' ? input : input.url;
            if (isYouTube(url)) {
                return Promise.reject(new Error('YouTube estetty weppis.comissa'));
            }
            return origFetch.apply(this, arguments);
        };

        const origOpen = XMLHttpRequest.prototype.open;
        XMLHttpRequest.prototype.open = function(method, url, ...rest) {
            if (isYouTube(url)) {
                throw new Error('YouTube estetty weppis.comissa');
            }
            return origOpen.call(this, method, url, ...rest);
        };

        const blockIfYouTube = (el) => {
            const src = el.src || el.getAttribute('src');
            if (src && isYouTube(src)) {
                el.remove();
            }
        };

        const observer = new MutationObserver((mutations) => {
            for (const m of mutations) {
                for (const node of m.addedNodes) {
                    if (node.nodeType === 1) {
                        if (['IFRAME', 'IMG', 'SCRIPT'].includes(node.tagName)) {
                            blockIfYouTube(node);
                        }
                        node.querySelectorAll?.('iframe, img, script').forEach(blockIfYouTube);
                    }
                }
            }
        });

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

        document.addEventListener('DOMContentLoaded', () => {
            document.querySelectorAll('iframe, img, script').forEach(blockIfYouTube);
        });
    } catch (e) {
        console.warn('YouTube-esto epäonnistui', e);
    }
// ================================================
// YouTube-yhteyksien esto, LOPPU
// ================================================



// ================================================
// WebGL:n (turhat krumeluurit) esto, ALKU
// ================================================
    try {
        const origGetContext = HTMLCanvasElement.prototype.getContext;
        HTMLCanvasElement.prototype.getContext = function(type, ...rest) {
            if (type === 'webgl' || type === 'experimental-webgl' || type === 'webgl2') {
                return null;
            }
            return origGetContext.call(this, type, ...rest);
        };

        if (typeof OffscreenCanvas !== 'undefined') {
            const origOffscreenGetContext = OffscreenCanvas.prototype.getContext;
            OffscreenCanvas.prototype.getContext = function(type, ...rest) {
                if (type === 'webgl' || type === 'experimental-webgl' || type === 'webgl2') {
                    return null;
                }
                return origOffscreenGetContext.call(this, type, ...rest);
            };
        }
    } catch (e) {
        console.warn('WebGL-esto epäonnistui', e);
    }
// ================================================
// WebGL:n (turhat krumeluurit) esto, LOPPU
// ================================================



// ================================================
// Turhien osioiden poisto/piilotus, ALKU
// ================================================
    try {
        const style = document.createElement('style');
        style.textContent = `.jukebox { display: none !important; } 
        .new-messages { display: none !important; } 
        .media-controls { display: none !important; } 
        .msg.system.error { display: none !important; }`;
        (document.head || document.documentElement).appendChild(style);

        const removeTurhuus = () => {
            document.querySelectorAll('.jukebox').forEach(el => el.remove());
            document.querySelectorAll('.media-controls').forEach(el => el.remove());
            document.querySelectorAll('.new-messages').forEach(el => el.remove());
            document.querySelectorAll('.msg.system.error').forEach(el => el.remove());
        };

        removeTurhuus();

        const turhuusObserver = new MutationObserver(() => {
            removeTurhuus();
        });

        turhuusObserver.observe(document.documentElement, {
            childList: true,
            subtree: true
        });
    } catch (e) {
        console.warn('Turhuuksien piilotus epäonnistui', e);
    }
// ================================================
// Turhien osioiden poisto/piilotus, LOPPU
// ================================================



})();