RainbowDDB

Ajoute un contour autour des messages signalés. La couleur change selon qui a effectué l'alerte ou si l'alerte a été traitée.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

Advertisement:

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

Advertisement:

// ==UserScript==
// @name         RainbowDDB
// @namespace    CrazyJeux/Daring-Do
// @author       CrazyJeux/Daring-Do / H264
// @match        https://www.jeuxvideo.com/recherche/forums/0-*
// @match        https://www.jeuxvideo.com/forums/0-*
// @match        https://www.jeuxvideo.com/forums/42-*
// @match        https://www.jeuxvideo.com/forums/1-*
// @description  Ajoute un contour autour des messages signalés. La couleur change selon qui a effectué l'alerte ou si l'alerte a été traitée.
// @version      56.7.0
// @grant        none
// ==/UserScript==

const DISABLE_ALERT = false; //Switch on 'true' to disable all alerts on request.


//Rainbow DDB CSS (CSS utilisé pour resiter au mutation du DOM REACT)
const RainbowDDBCSS = document.createElement('style');
RainbowDDBCSS.id = 'RainbowDDBCSS';
RainbowDDBCSS.textContent = `
#rainbow-ddb-btn {
    border-radius: 0.45rem;
    width: 95%;
    display: block;
    margin: 0 auto 20px;
}`;
// RainbowDDBCSS.textContent += (Le contenu est ensuite ajouté à la feuille css via ID dans les functions)
document.head.appendChild(RainbowDDBCSS);
//Rainbow DDB CSS


async function getPayload(doc) {
    const payloadRaw = [...doc.scripts].map(s => s.textContent.match(/jvc\.\w*Payload\s*=\s*["']([^"']+)["']/)).find(Boolean)?.[1];
    if (!payloadRaw) return null;
    try {
        const bytes = Uint8Array.from(atob(payloadRaw), c => c.charCodeAt(0));
        const uncompressedStream = new Blob([bytes]).stream().pipeThrough(new DecompressionStream('gzip'));
        return JSON.parse(await new Response(uncompressedStream).text());
    } catch {
        return JSON.parse(atob(payloadRaw));
    }
}

function decodeSignaler(reponseJson) {
    if (reponseJson?.boost?.info?.includes("a déjà été signalé")) {
        return { couleur: "orange", reason : reponseJson?.boost?.value || null }; //byother
    }
    if (reponseJson?.message?.includes("Vous avez déjà signalé ce contenu")) {
        return { couleur: "red" }; //byme
    }
    if (reponseJson?.errors?.[0]?.includes("Cet utilisateur ne peut pas être signalé")) {
        return { couleur: "#9393f5" }; //isadmin
    }
    if (reponseJson?.message?.includes("Ce contenu a déjà été modéré. En cas de problème")) {
        return { couleur: "lightgreen" }; //ishandledbymod
    }
    if (reponseJson?.message?.includes("Ce contenu a déjà été modéré par un administrateur")) {
        return { couleur: "turquoise" }; //ishandledbyadmin
    }
    return null;
}

async function traiterListeTopics() {
    const listPayload = await getPayload(document);
    const totalTopics = listPayload.listTopics.length;
    let processed = 0;
    for (const topic of listPayload.listTopics) {
         /*await*/ (async () => {

            // [PIEGE] topic.id ne match pas pour les Topics pre-respawn
            const topicId = topic.url.split('/').pop().split('-')[2]; 

            //-- Open, Fetch, Parse Topic
            const resTopic = await fetch(new URL(topic.url, location.origin));
            if (!resTopic.ok) return;
            const rawTopic = await resTopic.text();
            const documentTopic = new DOMParser().parseFromString(rawTopic, 'text/html');
            //--

            const topicPayload = await getPayload(documentTopic);

            const firstTopicMessage = topicPayload.listMessage[0];
            const urlSignaler = firstTopicMessage.actions?.report?.url;
            if (!urlSignaler) return;

            const reponseDDBJson = await fetch(new URL(urlSignaler, location.origin)).then(res => res.json());
            const result = decodeSignaler(reponseDDBJson);
            if (!result) return;

            //Utiliser Url pour match, car l'id n'est pas visible en recherche
            RainbowDDBCSS.textContent += `
            .tablesForum__cellSubject[href*="-${topicId}-1-0-1-0-"] {
                color:${result.couleur} !important;
            }`;

        })();
        processed++;
        document.getElementById('rainbow-ddb-btn').textContent = `Rainbow DDB (${processed}/${totalTopics})`;
    }
}

async function traiterListeMessages() {
    const topicPayload = await getPayload(document);
    const totalMessages = topicPayload.listMessage.length;
    let processed = 0;
    for (const message of topicPayload.listMessage) {
        await (async () => {

            const messageId = message.id;

            const urlSignaler = message.actions?.report?.url;
            if (!urlSignaler) return;

            const reponseDDBJson = await fetch(new URL(urlSignaler, location.origin)).then(res => res.json());
            const result = decodeSignaler(reponseDDBJson);
            if (!result) return;

            RainbowDDBCSS.textContent += `
            #message-${messageId} .messageUser__card {
                box-shadow:0 0 5px 5px ${result.couleur} !important;
            }`;
            if (!result.reason) return;
            RainbowDDBCSS.textContent += `
            #message-${messageId} .messageUser__msg::before {
                content: "Signalé pour ${result.reason}";
                font-weight: 700;
                color: ${result.couleur} !important;
            }`;

        })();
        processed++;
        document.getElementById('rainbow-ddb-btn').textContent = `Rainbow DDB (${processed}/${totalMessages})`;
    }
}

function initBtn() {

    let placeForBtn = (window.innerWidth >= 1000) ? '.layout__contentAside > *:first-child' : '.titleMessagesUsers__title'

    document.querySelector(placeForBtn).insertAdjacentHTML('beforebegin', `
        <button id="rainbow-ddb-btn" class="btn btn-outline-dark jvchat-hide">
           RainbowDDB
        </button>`);
    document.getElementById('rainbow-ddb-btn').addEventListener('click', () => {

        if (!sessionStorage.getItem('rainbow-ddb-confirme') && !DISABLE_ALERT) {
            alert("Ce script fait énormement de requêtes (concept de 2016).\nA utiliser avec modération (Cloudflared).");
            sessionStorage.setItem('rainbow-ddb-confirme', '1');
        }
        if (location.href.includes('/forums/42-') || location.href.includes('/forums/1-')) {
            traiterListeMessages();
        }
        if (location.href.includes('/forums/0-') || location.href.includes('/recherche/forums/0-')) {
            traiterListeTopics();
        }

    }, { once: true });
}
initBtn();