Supprime totalement les sujets des pseudo blacklistés depuis la blacklist JVC.
// ==UserScript==
// @name Full_Black_List
// @namespace Full_Black_List
// @version 0.38.0
// @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] fonctionSynckBLForums() : blacklist.php => LocalStorage
// [2] getBLListMP() : Check BlackList MP
// [2] deleteBlacklistMP() : BlackListForum => Strike BlackListForumMP
//
// CODE PAR PAGE :
// [3] /login => Page Login reinitialise la BlackList du LocalStorage
// [5] /forums/0-* (liste sujets) => Masque sujets via BlackList dans local storage
// [6] /forums/1- /42- => Masque messages BL / Synch BL 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 fonctionSynckBLForums() {
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 => VERS_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 getBLListMP() {
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 liste
hashListFetch.push(hashTempo); // Get hash temp (necessaire pour suppression)
});
}
//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];
// Effectuer la fetch de suppression (EN MP)
fetch(`/messages-prives/message.php?del_blacklist=${idAlias}&h=${hashTempo}`);
}
//2B___CLEAN_MP_ALL_____
// POST_LOT — Delete All Users MP
async function deleteBlacklistMPALL(onProgress) {
for (const [index, idAlias] of idListFetch.entries()) {
// Effectuer la fetch de suppression (EN MP)
await fetch(`/messages-prives/message.php?del_blacklist=${idAlias}&h=${hashListFetch[index]}`);
onProgress(); // Call Back avancement.
}
}
///// PAGES GEREES //////
//3_______PAGE_DE______CONNEXION___(Login)___
if (location.href.includes('jeuxvideo.com/login')) {
localStorage.removeItem('fullblacklistJVC'); // Efface LocalStorage => 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 listeLocalStorage = localStorage.getItem('fullblacklistJVC');
// Si aucune blacklist locale, on synchronise depuis le serveur JVC et on recharge la page
if (!listeLocalStorage) {
fonctionSynckBLForums().then(() => location.reload());
} else {
// Recupere pseudos blacklistés en minuscules
const blacklistStorage = JSON.parse(listeLocalStorage).map(p => p.toLowerCase());
// Supprime sujet avec pseudo blacklisté (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 fonctionSynckBLForums();
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_avec_.msg-pseudo-blacklist
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') {
fonctionSynckBLForums();
sessionStorage.removeItem('fullblacklistJVCAwait');
}
}
//7______________MASQUAGE____BLOC__MESSAGE_MP__(Message_MP)____
if (location.href.includes('jeuxvideo.com/messages-prives/message.php')) {
// [1] Ajout d'un event sur les boutons "blacklist MP" pour quils agissent aussi sur la blacklist forum
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 listeLocalStorage = localStorage.getItem('fullblacklistJVC');
// Si aucune blacklist locale, on synchronise depuis le serveur JVC et on recharge la page
if (!listeLocalStorage) {
fonctionSynckBLForums().then(() => location.reload());
} else {
// Liste pseudos en minuscules
const blacklistStorage = JSON.parse(listeLocalStorage).map(p => p.toLowerCase());
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 fonctionSynckBLForums();
//Clean
sessionStorage.removeItem('fullblacklistJVCidAlias'); // Supprime ID => Il vient d'etre traité.
})();
// [4] Cacher les messages déjà blacklistés
document.querySelectorAll('.msg-pseudo-blacklist').forEach(block => block.remove());
}
//8________________Suppression_combine_BL___(Page_BlackList_MP)____
if (location.href.includes('jeuxvideo.com/messages-prives/indesirables.php')) {
// Une suppression dans la BlackList MP => Suppression BL Forum + Suppression LocalStorage
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')) {
fonctionSynckBLForumsNoFetch(); // Liste Page vers LocalStorage (on est sur la page => PAS de fetch)
let hashMPListed;
// 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
if (typeof hashMPListed === 'undefined') {
await getBLListMP(); //Get_MP_BL
hashMPListed = true;
}
deleteBlacklistMP(idAlias); // Supprime PSEUDO EN MP
fonctionSynckBLForumsNoFetch(); // Liste Page vers LocalStorage
});
});
async function fonctionSynckBLForumsNoFetch() { //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 deleteAllBlacklist() {
document.getElementById('bl-clear').textContent = 'Loading...';
let listItems = document.querySelectorAll('#blacklist li');
// Nettoyage de TOUT pseudo blacklistes
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++;
}
// Nettoyage de TOUT pseudo blacklistes en MP
let countMP = 1
await getBLListMP(); // 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); // LIBERE LA MEMOIRE apres telechargement
}
// CREATION_HTML_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>
`);
// ATTACH_LISTENER_IMPORT
container.querySelector('#bl-import').addEventListener('click', () => {
let input = document.createElement('input');
input.type = 'file';
input.accept = '.json';
input.addEventListener('change', importBlacklist);
input.click();
});
// ATTACH_LISTENER_EXPORT
container.querySelector('#bl-export').addEventListener('click', exportBlacklist);
// ATTACH_LISTENER_SUPPRESSION
container.querySelector('#bl-clear').addEventListener('click', () => {
if (!window.confirm('⚠️ Supprimer toute la blacklist (JVC + MP + Script) ??⚠️')) return;
deleteAllBlacklist();
});
}
/*
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.
*/