Suppression msg lot
// ==UserScript==
// @name Respawn Lot Message Delete
// @version 5.8.2
// @description Suppression msg lot
// @namespace Respawn Lot Message Delete
// @author Craftbukkit debug par ROMANCE_DAWN adapt for payload
// @icon https://images.emojiterra.com/microsoft/fluent-emoji/15.1/128px/1f5d1_color.png
// @match https://www.jeuxvideo.com/profil/*?mode=historique_forum*
// @license MIT
// ==/UserScript==
//Global Variables
let nMessageAlreadyDelete;
let nMessageNonDelete;
let nMessageDelete;
let freshHash;
//Show Update UI
function hydrateUI(nPage) {
document.getElementById("papage").innerHTML = `
<b>Vidage Message :</b><br>
Message supprimé : ${nMessageDelete} <br>
Message déjà supprimé : ${nMessageAlreadyDelete} <br>
Message non supprimé : ${nMessageNonDelete} <br>
Page n°${nPage}<br><br>`;
}
const sleep = ms => new Promise(r => setTimeout(r, ms));
const monthList = ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"];
// Get Parse / jvc.*Payload
function getJsonPayload(rawData) {
const payload64 = rawData.match(/jvc\.\w*Payload\s*=\s*["']([^"']+)["']/)?.[1];
return JSON.parse(atob(payload64));
}
//Fetch 403 / 429 - JSON / HTML
async function fetchGetPage403(url) {
const jsonHeaders = { 'Accept': 'application/json', 'X-Requested-With': 'XMLHttpRequest' };
for (let attempt = 1; attempt <= 6; attempt++) {
await sleep(500);
const response = await fetch(url, { headers : jsonHeaders });
if (response.status === 403 || response.status === 429) {
console.log(`Rate limit ${response.status}, attente 3s (essai ${attempt}/6)`);
await sleep(3000);
continue;
}
return response;
}
return null;
}
// Get_Hash_By_Fetch
async function fechGetHash() {
const response = await fetch('https://www.jeuxvideo.com/forums/0-36-0-1-0-1-0-guerre-des-consoles.htm');
const data = await response.text();
const jsonData = getJsonPayload(data);
return jsonData?.ajaxModerationToken;
}
//REQUEST DELETE MESSAGE
async function requestDeleteMessage(idMessages, retryOnce = true) {
const reponse = await fetch(`https://www.jeuxvideo.com/forums/message/delete?ids=${idMessages.join(',')}&type=delete&ajax_hash=${freshHash}`, { method: 'POST' });
if (!reponse.ok && retryOnce) {
freshHash = await fechGetHash();
return requestDeleteMessage(idMessages, false);
}
return reponse;
}
async function videPage(nPage, data) {
//Lecture champs User
const [yearMin, monthMin, dayMin] = document.getElementById('mindate').value.split('-');
const [yearMax, monthMax, dayMax] = document.getElementById('maxdate').value.split('-');
let minDate = new Date(yearMin, monthMin - 1, dayMin).getTime(); //TimeStamp Min
let maxDate = new Date(yearMax, monthMax - 1, dayMax).getTime(); //TimeStamp Max
let jsonData;
try {
jsonData = JSON.parse(data); //Json from serv
} catch {
jsonData = getJsonPayload(data); //FallBack Html Payload
}
const messages = jsonData?.listMessage ?? [];
const messageToDelete = [];
for (const message of messages) {
if (message.stateMessage === 'msg-visible') {
const idMessage = message.id;
// publishedDate format: "19 sptembre 1999 à 00:00:00"
const [day, monthStr, year] = message.publishedDate.split(' ');
const messageTimestamp = new Date(year, monthList.indexOf(monthStr), day).getTime();
if (!monthList.includes(monthStr)) throw new Error('Mois invalide => Annulation'); //Guard
// DATES MATCH => DELETE
if (messageTimestamp >= minDate && messageTimestamp <= maxDate) {
/*
const deletedMessage = await requestDeleteMessage([idMessage]);
if (!deletedMessage?.ok) {
throw new Error(`Échec suppression message ${idMessage}`);
}
nMessageDelete++;
*/
messageToDelete.push(idMessage);
} else {
nMessageNonDelete++;
}
} else {
nMessageAlreadyDelete++;
}
}
// SUPPRESSION EN UNE SEULE REQUETTE POUR EVITER DE SPAM
if (messageToDelete.length) {
const deletedMessage = await requestDeleteMessage(messageToDelete);
if (!deletedMessage?.ok) {
throw new Error(`Échec suppression de (${messageToDelete.length} messages)`);
}
nMessageDelete += messageToDelete.length;
}
hydrateUI(nPage);
const nextPage = jsonData?.pagerView?.next?.url;
if (nextPage) {
console.log(nextPage);
const response = await fetchGetPage403(nextPage);
const nextData = await response.text();
await videPage(nPage + 1, nextData);
} else {
alert('Dernière Page Traité')
}
}
document.querySelector(".titre-bloc").insertAdjacentHTML('beforeend', `
<div style="font-size: 1.2rem;"><br> -> Du :
<input type="date" id="mindate" value="1970-01-01" class="form-control" style="width: 230px; font-weight: 600; font-size: 1rem; display: inline-flex; margin: 5px;">
au
<input type="date" id="maxdate" value="1998-01-01" class="form-control" style="width: 230px; font-weight: 600; font-size: 1rem; display: inline-flex; margin: 5px;">
<button class="btn icon-bin" title="Tout supprimer" id="viderAll" style="display: inline-flex; align-items: center; font-size: 1.1rem; height: 2.2rem;">Vider</button></div>`);
document.getElementById("viderAll").onclick = async function() {
if (confirm("Le script va commencer de la page en cours\n/!\ Êtes-vous sûr de vouloir tout supprimer ? /!\\ ")) {
this.style.display = 'none';
document.getElementById('forum-main-col').style.display = 'none';
document.getElementById('mindate').disabled = true;
document.getElementById('maxdate').disabled = true;
nMessageDelete = 0;
nMessageAlreadyDelete = 0;
nMessageNonDelete = 0;
const nPage = 1;
document.querySelector(".titre-head-bloc").insertAdjacentHTML("afterend", "<span id='papage'></span>");
hydrateUI(nPage);
//Get hash from forum (Le hash de suppression nest plus dans lhisto on va le chercher sur les forums).
freshHash = await fechGetHash();
const startUrl = location.href;
const response = await fetchGetPage403(startUrl);
const startData = await response.text();
await videPage(nPage, startData);
}
};