// ==UserScript==
// @name Full_Black_List
// @namespace Full_Black_List
// @version 0.37.1
// @description Supprime totalement les sujets des pseudo blacklistés depuis la blacklist JVC.
// @author Atlantis
// @match *://www.jeuxvideo.com/recherche/forums/0-*
// @match *://www.jeuxvideo.com/forums/0-*
// @match *://www.jeuxvideo.com/forums/42-*
// @match *://www.jeuxvideo.com/forums/1-*
// @match *://www.jeuxvideo.com/forums/message*
// @match *://www.jeuxvideo.com/messages-prives/message.php*
// @match *://www.jeuxvideo.com/messages-prives/indesirables.php
// @match *://www.jeuxvideo.com/sso/blacklist.php
// @match *://www.jeuxvideo.com/login*
// @icon https://images.emojiterra.com/microsoft/fluent-emoji/15.1/128px/1f6ab_color.png
// @license MIT
// @grant none
// ==/UserScript==
// === SOMMAIRE RAPIDE DU SCRIPT ===
// FONCTIONS RESEAU FETCH :
// [1] synckBLForums() : Forum / blacklist.php => LocStorage
// [2] getBlockedListMP() / deleteBlacklistMP() : MP / indesirables.php => LocStorage
//
// CODE PAR PAGE :
// [3] /login => Réinitialise la BL Storage
// [5] /forums/0-* (liste sujets) => Masque sujets BL
// [6] /forums/1- /42- => Masque messages BL + Synch : Fofo => localStorage
// [7] /messages-prives/message.php => masque messages BL MP + Synch : localStorage <=> BL MP <=> BL Fofo
// [8] /messages-prives/indesirables.php => Suppression Storage MP + Synch Fofo
// [9] /sso/blacklist.php => Gestion BL Forum - MP + Boutons Import / Export / Reset
///// FONTIONS RESEAU FETCH //////
const forumPageUrlForm = '/forums/0-36-0-1-0-1-0-0.htm'
//1___FETCH___SYNCH__BL___(FETCH_FORUM_LIST_PAGE)_
//PUSH — blacklist.php => LocStorage
async function synckBLForums() {
let response = await fetch('/sso/blacklist.php');
let htmlText = await response.text();
let docFetched = new DOMParser().parseFromString(htmlText, 'text/html');
let pseudos = docFetched.querySelectorAll('#blacklist span');
// /SSO/BLACKLIST.PHP => SYNCH_BL_LOCAL_STORAGE
let pseudoList = [...pseudos].map(span => span.textContent.trim());
localStorage.setItem('fullblacklistJVC', JSON.stringify(pseudoList));
}
//2___Fetch_MP_LIST_______(FETCH_MP_LIST_PAGE)___
// GET — ID et Hash Blacklist /indesirables.php
let idListFetch = [];
let hashListFetch = [];
async function getBlockedListMP() {
let response = await fetch('/messages-prives/indesirables.php');
let htmlText = await response.text();
let docFetched = new DOMParser().parseFromString(htmlText, 'text/html');
let listItems = docFetched.querySelectorAll('#blacklist .mp_delete_blacklist');
//recupere pour chaque id
listItems.forEach(user => {
let idAlias = user.getAttribute('data-id');
let hashtempo = user.getAttribute('data-hash');
idListFetch.push(idAlias); // Get ID en list
hashListFetch.push(hashtempo); // Get hash temp en list
});
}
//2A___CLEAN_MP___
// POST — Delete User MP
function deleteBlacklistMP(idAlias) {
const index = idListFetch.indexOf(idAlias);
if (index === -1) return; // No index
const hashtempo = hashListFetch[index];
const urlStrike = `/messages-prives/message.php?del_blacklist=${idAlias}&h=${hashtempo}`;
fetch(urlStrike);
}
//2B___CLEAN_MP_ALL_____
// POST_LOT — Delete All Users MP
async function deleteBlacklistMPALL(onProgress) {
for (const [index, idAlias] of idListFetch.entries()) {
const urlStrike = `/messages-prives/message.php?del_blacklist=${idAlias}&h=${hashListFetch[index]}`;
await fetch(urlStrike); // Effectuer la suppression
onProgress(); // return call back
}
}
///// PAGES GEREES //////
//3_______PAGE_DE______CONNEXION___(Login)___
if (location.href.includes('jeuxvideo.com/login')) {
localStorage.removeItem('fullblacklistJVC'); // efface local storage => en cas de deconnexion
}
//5______BLACKLIST____LISTE_SUJETS___(Liste_Sujet_et_Recherche)___
if (location.href.includes('jeuxvideo.com/forums/0-') || location.href.includes('jeuxvideo.com/recherche/forums/0-')) {
let liste = localStorage.getItem('fullblacklistJVC');
// Si aucune blacklist locale, on synchronise depuis le serveur JVC et on recharge la page
if (!liste) {
synckBLForums().then(() => location.reload());
} else {
// Liste pseudos blacklistés en minuscules
const blacklistStorage = JSON.parse(liste).map(p => p.toLowerCase());
// Supprime sujet avec correspondance (includes)
document.querySelectorAll('.topic-author').forEach(authorEl => {
const pseudo = authorEl.textContent.trim().toLowerCase();
if (blacklistStorage.includes(pseudo)) authorEl.closest('li')?.remove();
});
}
}
//5B_______BOUTON_____BLACKLIST___LISTE_SUJET_(Liste_Sujet)_____
if (location.href.includes('jeuxvideo.com/forums/0-')) {
document.querySelector('.bloc-pagi-default .pagi-before-list-topic')?.insertAdjacentHTML('afterend', `
<div class="cust-btn-container">
<span id="bl-refresh" class="btn btn-actu-new-list-forum icon-refresh"
title="Actualiser la blacklist des Sujets"
style="border-radius:6px; min-width:5rem;">
Actu BL
</span>
<a href="/sso/blacklist.php" style="outline:none;" target="_blank">
<span class="btn btn-actu-new-list-forum"
title="Voir/Editer/Exporter la BlackList"
style="border-radius:6px; min-width:4rem;">
Voir BL
</span>
</a>
</div>
`);
document.querySelector('.cust-btn-container #bl-refresh').addEventListener('click', async () => {
await synckBLForums();
alert('Filtrage des topics actualisés avec la blacklist JVC ✅');
location.reload();
});
}
//6______MASQUAGE_____BLOC____MESSAGE____FORUM__(Topic_1_42)____
if (location.href.includes('jeuxvideo.com/forums/1-') || location.href.includes('jeuxvideo.com/forums/42-') || location.href.includes('jeuxvideo.com/forums/message/')) {
//masquage_message
document.querySelectorAll('.msg-pseudo-blacklist').forEach(block => block.remove());
//ajout dun event au bouton blacklist
document.querySelectorAll('.picto-msg-tronche').forEach(btn => {
btn.addEventListener('click', () => sessionStorage.setItem('fullblacklistJVCAwait', 'true'));
});
// Mise à jour de la Blacklist du script apres actualisation
if (sessionStorage.getItem('fullblacklistJVCAwait') === 'true') {
synckBLForums();
sessionStorage.removeItem('fullblacklistJVCAwait');
}
}
//7______________MASQUAGE____BLOC__MESSAGE_MP__(Message_MP)____
if (location.href.includes('jeuxvideo.com/messages-prives/message.php')) {
// [1] Préparer les boutons "blacklist" pour synch vers fofo
document.querySelectorAll('.picto-msg-tronche').forEach(btn => {
btn.addEventListener('click', () => {
const idAlias = btn.getAttribute('data-url').match(/add_blacklist=(\d+)/)[1];
sessionStorage.setItem('fullblacklistJVCidAlias', idAlias);
});
});
// [2] localStorage => simulation de clic sur bouton (blacklist MP)
let liste = localStorage.getItem('fullblacklistJVC');
// Si aucune blacklist locale, on synchronise depuis le serveur JVC et on recharge la page
if (!liste) {
synckBLForums().then(() => location.reload());
} else {
const blacklistStorage = JSON.parse(liste).map(p => p.toLowerCase()); // Liste pseudos en minuscules
const messageBlocks = document.querySelectorAll('.bloc-message-forum')
messageBlocks.forEach(block => {
const pseudoBloc = block.querySelector('.bloc-pseudo-msg')?.textContent.trim().toLowerCase();
const blacklistButton = block.querySelector('.picto-msg-tronche');
if (blacklistStorage.includes(pseudoBloc) && blacklistButton) blacklistButton.click();
});
}
// [3] Appel black list MP => Synch Fofo
let idAlias = sessionStorage.getItem('fullblacklistJVCidAlias');
if (idAlias) (async () => {
// Fetch recuperer hash preference forum
let response = await fetch(forumPageUrlForm);
let htmlText = await response.text();
let docFetched = new DOMParser().parseFromString(htmlText, 'text/html');
let hashValue = docFetched.querySelector('#ajax_hash_preference_user')?.value;
// AjoutBL_Forum
await fetch(`/forums/ajax_forum_blacklist.php?id_alias_msg=${idAlias}&action=add&ajax_hash=${hashValue}`);
await synckBLForums();
//clean
sessionStorage.removeItem('fullblacklistJVCidAlias'); // Supprime ID attente
})();
// [4] Cacher les messages déjà blacklistés
document.querySelectorAll('.msg-pseudo-blacklist').forEach(block => block.remove());
}
//8________________Suuppression_combiné_BL___(Page_BlackList_MP)____
if (location.href.includes('jeuxvideo.com/messages-prives/indesirables.php')) {
document.querySelectorAll('.mp_delete_blacklist').forEach(button => {
button.addEventListener('click', () => {
const userId = button.getAttribute('data-id');
fetch(`/sso/ajax_delete_blacklist.php?id_alias_unblacklist=${userId}`);
localStorage.removeItem('fullblacklistJVC');
});
});
}
//9________________MISE_A_JOUR_PAGE_BLACK_LISTE__(Page_BlackList_Forums)____
if (location.href.includes('jeuxvideo.com/sso/blacklist.php')) {
updatePseudosFofoBL(); //lit les pseudo visible sur la page
// Suppression par pseudo
document.querySelectorAll('.icon-cross-entypo').forEach(cross => {
cross.addEventListener('click', async () => {
let idAlias = cross.closest('li')?.getAttribute('data-id-alias'); // Récupérer l'id
let alreadyListed; //Get_MP_BL
if (!alreadyListed) alreadyListed = await getBlockedListMP().then(() => true);
deleteBlacklistMP(idAlias); // Supprime PSEUDO EN MP
updatePseudosFofoBL(); // MAJ LOCALSTORAGE
});
});
async function updatePseudosFofoBL() { //lit les pseudo visible sur la page
await new Promise(resolve => setTimeout(resolve, 1000)); //delais pour capturer la page à jour
let pseudos = document.querySelectorAll('#blacklist span');
let pseudoList = [...pseudos].map(span => span.textContent.trim());
localStorage.setItem('fullblacklistJVC', JSON.stringify(pseudoList));
}
}
//9b_______________BOUTON_SCRIPT_PAGE__BLACKLIST___(Page_BlackList_Forums)____
if (location.href.includes('jeuxvideo.com/sso/blacklist.php')) {
//SUPPRESSION TOTALE BL LOT FOFO + MP
async function deleteBlacklist() {
document.getElementById('bl-clear').textContent = 'Loading...';
let listItems = document.querySelectorAll('#blacklist li');
// Suppression All ID Fofo une à une
let count = 1;
for (const liItem of listItems) {
const idAlias = liItem.getAttribute('data-id-alias');
await fetch(`/sso/ajax_delete_blacklist.php?id_alias_unblacklist=${idAlias}`);
document.getElementById('bl-clear').textContent = `Loading (${count})`;
count++;
}
//toute les bl fofo sont strike => continue
// Suppression All ID MP
let countMP = 1
await getBlockedListMP(); // récupère sa propre liste depuis la messagerie
await deleteBlacklistMPALL(() => { // supprime côté MP
document.getElementById('bl-clear').textContent = `Loading (OK) (MP : ${countMP})`;
countMP++;
});
window.location.reload();
}
//IMPORTATION BLACKLIST fichier JSON
async function importBlacklist(bljson) {
const filejson = bljson.target.files[0];
if (!filejson) return;
let blacklistjson;
try {
// Lecture + parsing du fichier JSON
blacklistjson = JSON.parse(await filejson.text());
} catch {
alert("Fichier JSON invalide.");
return;
}
document.getElementById('bl-import').textContent = 'Load...';
// Récupération du hash AJAX
let response = await fetch(forumPageUrlForm);
let htmlText = await response.text();
let docFetched = new DOMParser().parseFromString(htmlText, 'text/html');
let hash = docFetched.querySelector('#ajax_hash_preference_user')?.value;
// REQUÊTES D’AJOUT UN À UNE FOFO
let count = 1;
for (const obj of blacklistjson) {
await fetch(`/forums/ajax_forum_blacklist.php?id_alias_msg=${obj.id}&action=add&ajax_hash=${hash}`);
document.getElementById('bl-import').textContent = `Load (${count})`;
count++;
}
window.location.reload();
}
//EXPORT BLACKLIST fichier JSON
function exportBlacklist() {
const blacklistItems = [...document.querySelectorAll('#blacklist li')];
const idList = blacklistItems.map(li => ({
id: li.getAttribute('data-id-alias'),
pseudo: li.querySelector('span')?.textContent.trim()
}));
const blob = new Blob([JSON.stringify(idList, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'Blacklist_JVC.json';
link.click();
URL.revokeObjectURL(url); // libère la mémoire
}
// CREATION BOUTON
let container = document.querySelector('.layout__row.layout__content.layout__row--gutter.mb-5');
container.insertAdjacentHTML('beforeend', `
<ul>
<button id="bl-import" title="Importer BlackList depuis un Fichier" class="simpleButton" style="border-radius:6px;">
Importer
</button>
<button id="bl-export" title="Exporter BlackList JVC en Fichier" class="simpleButton" style="border-radius:6px;">
Exporter
</button>
</ul>
<ul>
<button id="bl-clear" title="Vider toute la blacklist JVC + MP + Script" class="simpleButton" style="border-radius:6px; background-color:red;">
Vider BL Forum et MP
</button>
</ul>
`);
container.querySelector('#bl-import').addEventListener('click', () => {
let input = document.createElement('input');
input.type = 'file';
input.accept = '.json';
input.addEventListener('change', importBlacklist);
input.click();
});
container.querySelector('#bl-export').addEventListener('click', exportBlacklist);
container.querySelector('#bl-clear').addEventListener('click', () => {
if (!window.confirm('⚠️ Supprimer toute la blacklist (JVC + MP + Script) ??⚠️')) return;
deleteBlacklist();
});
}
/*
MIT License
Copyright (c) 2025 Atlantis (https://github.com/Lantea-Git)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/