// ==UserScript== // @name ๐Ÿ› ๏ธ Discord Plus+ V1 โ€” Bulk Delete, Msg Logger, Ghost Ping & Export // @name:vi Discord Plus+ V1 โ€” Xรณa tin nhแบฏn hร ng loแบกt, theo dรตi xรณa, ghost ping & xuแบฅt file // @name:zh-CN Discord Plus+ V1 โ€” ๆ‰น้‡ๅˆ ๆถˆๆฏใ€ๆถˆๆฏ่ฎฐๅฝ•ใ€Ghost Ping ๆฃ€ๆต‹ไธŽๅฏผๅ‡บ // @name:zh-TW Discord Plus+ V1 โ€” ๆ‰น้‡ๅˆช่จŠๆฏใ€่จŠๆฏ่จ˜้Œ„ใ€Ghost Ping ๅตๆธฌ่ˆ‡ๅŒฏๅ‡บ // @name:ru Discord Plus+ V1 โ€” ะœะฐััะพะฒะพะต ัƒะดะฐะปะตะฝะธะต, ะปะพะณะณะตั€ ัะพะพะฑั‰ะตะฝะธะน, Ghost Ping ะธ ัะบัะฟะพั€ั‚ // @name:ja Discord Plus+ V1 โ€” ไธ€ๆ‹ฌๅ‰Š้™คใƒปใƒกใƒƒใ‚ปใƒผใ‚ธใƒญใ‚ฐใƒปGhost Ping ๆคœๅ‡บใƒปใ‚จใ‚ฏใ‚นใƒใƒผใƒˆ // @name:ko Discord Plus+ V1 โ€” ๋Œ€๋Ÿ‰ ์‚ญ์ œ, ๋ฉ”์‹œ์ง€ ๋กœ๊ฑฐ, Ghost Ping ๊ฐ์ง€ ๋ฐ ๋‚ด๋ณด๋‚ด๊ธฐ // @name:es Discord Plus+ V1 โ€” Borrado masivo, registro de mensajes, Ghost Ping y exportaciรณn // @name:pt-BR Discord Plus+ V1 โ€” Exclusรฃo em massa, logger de mensagens, Ghost Ping e exportaรงรฃo // @name:fr Discord Plus+ V1 โ€” Suppression en masse, journal, Ghost Ping et export // @name:de Discord Plus+ V1 โ€” Massenlรถschung, Nachrichten-Logger, Ghost Ping & Export // @name:tr Discord Plus+ V1 โ€” Toplu Silme, Mesaj Kaydedici, Ghost Ping ve DฤฑลŸa Aktarma // @name:id Discord Plus+ V1 โ€” Hapus Massal, Logger Pesan, Ghost Ping & Ekspor // @name:pl Discord Plus+ V1 โ€” Masowe usuwanie, logger wiadomoล›ci, Ghost Ping i eksport // @name:th Discord Plus+ V1 โ€” เธฅเธšเธ‚เน‰เธญเธ„เธงเธฒเธกเธˆเธณเธ™เธงเธ™เธกเธฒเธ, เธšเธฑเธ™เธ—เธถเธเธ‚เน‰เธญเธ„เธงเธฒเธก, Ghost Ping เนเธฅเธฐเธชเนˆเธ‡เธญเธญเธ // @name:ar Discord Plus+ V1 โ€” ุงู„ุญุฐู ุงู„ุฌู…ุงุนูŠ, ุชุณุฌูŠู„ ุงู„ุฑุณุงุฆู„, Ghost Ping ูˆุงู„ุชุตุฏูŠุฑ // @description ๐Ÿ—‘ Bulk delete YOUR messages in any channel or DM using Discord API v10 (smart rate-limit, retry, date/content filters). ๐Ÿ‘ Log deleted messages in real-time. ๐Ÿ‘ป Auto-detect ghost pings with toast alerts. ๐Ÿ“ฆ Export channel history to HTML/JSON/TXT. ๐Ÿ”‘ One-click token detector + account info. All-in-one Discord web toolkit โ€” no data leaves your browser. Works with Tampermonkey & Violentmonkey. // @description:vi ๐Ÿ—‘ Xรณa hร ng loแบกt TIN NHแบฎN CแปฆA Bแบ N trong bแบฅt kแปณ kรชnh hoแบทc DM nร o bแบฑng Discord API v10 (giแป›i hแบกn tแป‘c ฤ‘แป™ thรดng minh, thแปญ lแบกi, bแป™ lแปc ngร y/nแป™i dung). ๐Ÿ‘ Ghi lแบกi tin nhแบฏn bแป‹ xรณa theo thแปi gian thแปฑc. ๐Ÿ‘ป Tแปฑ ฤ‘แป™ng phรกt hiแป‡n ghost ping vแป›i thรดng bรกo. ๐Ÿ“ฆ Xuแบฅt lแป‹ch sแปญ kรชnh sang HTML/JSON/TXT. ๐Ÿ”‘ Phรกt hiแป‡n token mแป™t cรบ nhแบฅp + thรดng tin tร i khoแบฃn. Bแป™ cรดng cแปฅ Discord web all-in-one โ€” khรดng cรณ dแปฏ liแป‡u rแปi khแปi trรฌnh duyแป‡t cแปงa bแบกn. // @description:zh-CN ๐Ÿ—‘ ไฝฟ็”จ Discord API v10 ๆ‰น้‡ๅˆ ้™คไปปๆ„้ข‘้“ๆˆ–็ง่Šไธญ็š„ๆถˆๆฏ๏ผˆๆ™บ่ƒฝ้™้€Ÿใ€้‡่ฏ•ใ€ๆ—ฅๆœŸ/ๅ†…ๅฎน่ฟ‡ๆปค๏ผ‰ใ€‚๐Ÿ‘ ๅฎžๆ—ถ่ฎฐๅฝ•่ขซๅˆ ๆถˆๆฏใ€‚๐Ÿ‘ป ่‡ชๅŠจๆฃ€ๆต‹ Ghost Ping ๅนถๅผนๅ‡บๆ็คบใ€‚๐Ÿ“ฆ ๅฐ†้ข‘้“ๅކๅฒๅฏผๅ‡บไธบ HTML/JSON/TXTใ€‚๐Ÿ”‘ ไธ€้”ฎ่Žทๅ– Token + ่ดฆๆˆทไฟกๆฏใ€‚ๅ…จ่ƒฝ Discord ๅทฅๅ…ทๅŒ…โ€”โ€”ๆ•ฐๆฎไธ็ฆปๅผ€ๆ‚จ็š„ๆต่งˆๅ™จใ€‚ // @description:ru ๐Ÿ—‘ ะœะฐััะพะฒะพะต ัƒะดะฐะปะตะฝะธะต ะ’ะะจะ˜ะฅ ัะพะพะฑั‰ะตะฝะธะน ะฒ ะปัŽะฑะพะผ ะบะฐะฝะฐะปะต ะธะปะธ ะ›ะก ั‡ะตั€ะตะท Discord API v10 (ัƒะผะฝั‹ะน rate-limit, ะฟะพะฒั‚ะพั€ะฝั‹ะต ะฟะพะฟั‹ั‚ะบะธ, ั„ะธะปัŒั‚ั€ั‹ ะฟะพ ะดะฐั‚ะต ะธ ัะพะดะตั€ะถะธะผะพะผัƒ). ๐Ÿ‘ ะ›ะพะณะธั€ะพะฒะฐะฝะธะต ัƒะดะฐะปั‘ะฝะฝั‹ั… ัะพะพะฑั‰ะตะฝะธะน ะฒ ั€ะตะฐะปัŒะฝะพะผ ะฒั€ะตะผะตะฝะธ. ๐Ÿ‘ป ะะฒั‚ะพะดะตั‚ะตะบั‚ ghost ping ั ัƒะฒะตะดะพะผะปะตะฝะธัะผะธ. ๐Ÿ“ฆ ะญะบัะฟะพั€ั‚ ะธัั‚ะพั€ะธะธ ะบะฐะฝะฐะปะฐ ะฒ HTML/JSON/TXT. ๐Ÿ”‘ ะะฒั‚ะพะพะฟั€ะตะดะตะปะตะฝะธะต ั‚ะพะบะตะฝะฐ + ะธะฝั„ะพั€ะผะฐั†ะธั ะพะฑ ะฐะบะบะฐัƒะฝั‚ะต. // @description:ja ๐Ÿ—‘ Discord API v10ใงใƒใƒฃใƒณใƒใƒซใพใŸใฏDMๅ†…ใฎใƒกใƒƒใ‚ปใƒผใ‚ธใ‚’ไธ€ๆ‹ฌๅ‰Š้™ค๏ผˆใ‚นใƒžใƒผใƒˆใชใƒฌใƒผใƒˆใƒชใƒŸใƒƒใƒˆใƒปใƒชใƒˆใƒฉใ‚คใƒปๆ—ฅไป˜/ๅ†…ๅฎนใƒ•ใ‚ฃใƒซใ‚ฟ๏ผ‰ใ€‚๐Ÿ‘ ๅ‰Š้™คใ•ใ‚ŒใŸใƒกใƒƒใ‚ปใƒผใ‚ธใ‚’ใƒชใ‚ขใƒซใ‚ฟใ‚คใƒ ใง่จ˜้Œฒใ€‚๐Ÿ‘ป Ghost Pingใ‚’่‡ชๅ‹•ๆคœๅ‡บใ—ใƒˆใƒผใ‚นใƒˆ้€š็Ÿฅใ€‚๐Ÿ“ฆ ใƒใƒฃใƒณใƒใƒซๅฑฅๆญดใ‚’HTML/JSON/TXTใธใ‚จใ‚ฏใ‚นใƒใƒผใƒˆใ€‚๐Ÿ”‘ ใƒฏใƒณใ‚ฏใƒชใƒƒใ‚ฏใงใƒˆใƒผใ‚ฏใƒณๅ–ๅพ—๏ผ†ใ‚ขใ‚ซใ‚ฆใƒณใƒˆๆƒ…ๅ ฑ่กจ็คบใ€‚ // @description:ko ๐Ÿ—‘ Discord API v10์œผ๋กœ ์ฑ„๋„/DM์—์„œ ๋ฉ”์‹œ์ง€ ๋Œ€๋Ÿ‰ ์‚ญ์ œ(์Šค๋งˆํŠธ rate-limit, ์žฌ์‹œ๋„, ๋‚ ์งœ/๋‚ด์šฉ ํ•„ํ„ฐ). ๐Ÿ‘ ์‚ญ์ œ๋œ ๋ฉ”์‹œ์ง€ ์‹ค์‹œ๊ฐ„ ๊ธฐ๋ก. ๐Ÿ‘ป Ghost Ping ์ž๋™ ๊ฐ์ง€ + ํ† ์ŠคํŠธ ์•Œ๋ฆผ. ๐Ÿ“ฆ ์ฑ„๋„ ๊ธฐ๋ก์„ HTML/JSON/TXT๋กœ ๋‚ด๋ณด๋‚ด๊ธฐ. ๐Ÿ”‘ ์›ํด๋ฆญ ํ† ํฐ ๊ฐ์ง€ + ๊ณ„์ • ์ •๋ณด. // @description:zh-TW ๐Ÿ—‘ ไฝฟ็”จ Discord API v10 ๆ‰น้‡ๅˆช้™คไปปๆ„้ ป้“ๆˆ–็ง่Šไธญ็š„่จŠๆฏ๏ผˆๆ™บ่ƒฝ้™้€Ÿใ€้‡่ฉฆใ€ๆ—ฅๆœŸ/ๅ…งๅฎน้Žๆฟพ๏ผ‰ใ€‚๐Ÿ‘ ๅณๆ™‚่จ˜้Œ„่ขซๅˆช่จŠๆฏใ€‚๐Ÿ‘ป ่‡ชๅ‹•ๅตๆธฌ Ghost Ping ไธฆๅฝˆๅ‡บๆ็คบใ€‚๐Ÿ“ฆ ๅฐ‡้ ป้“ๆญทๅฒๅŒฏๅ‡บ็‚บ HTML/JSON/TXTใ€‚๐Ÿ”‘ ไธ€้ต็ฒๅ– Token + ๅธณๆˆถ่ณ‡่จŠใ€‚ๅ…จ่ƒฝ Discord ๅทฅๅ…ทๅŒ…โ€”โ€”่ณ‡ๆ–™ไธ้›ข้–‹ๆ‚จ็š„็€่ฆฝๅ™จใ€‚ // @description:es ๐Ÿ—‘ Elimina en masa TUS mensajes en cualquier canal o DM con Discord API v10 (lรญmite de velocidad inteligente, reintentos, filtros de fecha/contenido). ๐Ÿ‘ Registra mensajes eliminados en tiempo real. ๐Ÿ‘ป Detecta automรกticamente ghost pings con alertas. ๐Ÿ“ฆ Exporta el historial del canal a HTML/JSON/TXT. ๐Ÿ”‘ Detector de token con un clic + info de cuenta. Cero datos salen de tu navegador. // @description:pt-BR ๐Ÿ—‘ Exclua em massa SUAS mensagens em qualquer canal ou DM com Discord API v10 (rate-limit inteligente, tentativas, filtros de data/conteรบdo). ๐Ÿ‘ Registre mensagens deletadas em tempo real. ๐Ÿ‘ป Detecte automaticamente ghost pings com alertas. ๐Ÿ“ฆ Exporte o histรณrico do canal para HTML/JSON/TXT. ๐Ÿ”‘ Detector de token com um clique + info da conta. Nenhum dado sai do seu navegador. // @description:fr ๐Ÿ—‘ Supprimez en masse VOS messages dans n'importe quel salon ou DM via Discord API v10 (rate-limit intelligent, nouvelles tentatives, filtres date/contenu). ๐Ÿ‘ Enregistrez les messages supprimรฉs en temps rรฉel. ๐Ÿ‘ป Dรฉtectez automatiquement les ghost pings. ๐Ÿ“ฆ Exportez l'historique du salon en HTML/JSON/TXT. ๐Ÿ”‘ Dรฉtection de token en un clic + infos du compte. Aucune donnรฉe ne quitte votre navigateur. // @description:de ๐Ÿ—‘ Massenlรถschung DEINER Nachrichten in jedem Kanal oder DM mit Discord API v10 (intelligentes Rate-Limit, Wiederholungen, Datum-/Inhaltsfilter). ๐Ÿ‘ Gelรถschte Nachrichten in Echtzeit protokollieren. ๐Ÿ‘ป Ghost Pings automatisch erkennen mit Benachrichtigung. ๐Ÿ“ฆ Kanalverlauf als HTML/JSON/TXT exportieren. ๐Ÿ”‘ Ein-Klick-Token-Erkennung + Kontoinformationen. Keine Daten verlassen Ihren Browser. // @description:tr ๐Ÿ—‘ Discord API v10 ile herhangi bir kanal veya DM'deki MESAJLARINIZI toplu silin (akฤฑllฤฑ rate-limit, yeniden deneme, tarih/iรงerik filtreleri). ๐Ÿ‘ Silinen mesajlarฤฑ gerรงek zamanlฤฑ kaydedin. ๐Ÿ‘ป Ghost ping'leri otomatik tespit edin. ๐Ÿ“ฆ Kanal geรงmiลŸini HTML/JSON/TXT olarak dฤฑลŸa aktarฤฑn. ๐Ÿ”‘ Tek tฤฑkla token tespiti + hesap bilgisi. Hiรงbir veri tarayฤฑcฤฑnฤฑzdan รงฤฑkmaz. // @description:id ๐Ÿ—‘ Hapus massal PESAN ANDA di channel atau DM mana pun menggunakan Discord API v10 (rate-limit cerdas, percobaan ulang, filter tanggal/konten). ๐Ÿ‘ Catat pesan yang dihapus secara real-time. ๐Ÿ‘ป Deteksi ghost ping otomatis dengan notifikasi. ๐Ÿ“ฆ Ekspor riwayat channel ke HTML/JSON/TXT. ๐Ÿ”‘ Deteksi token satu klik + info akun. Tidak ada data yang keluar dari browser Anda. // @description:pl ๐Ÿ—‘ Masowe usuwanie TWOICH wiadomoล›ci na dowolnym kanale lub DM przez Discord API v10 (inteligentny rate-limit, ponowne prรณby, filtry daty/treล›ci). ๐Ÿ‘ Rejestruj usuniฤ™te wiadomoล›ci w czasie rzeczywistym. ๐Ÿ‘ป Automatyczne wykrywanie ghost pingรณw z powiadomieniami. ๐Ÿ“ฆ Eksportuj historiฤ™ kanaล‚u do HTML/JSON/TXT. ๐Ÿ”‘ Wykrywanie tokena jednym klikniฤ™ciem + informacje o koncie. // @description:th ๐Ÿ—‘ เธฅเธšเธ‚เน‰เธญเธ„เธงเธฒเธกเธ‚เธญเธ‡เธ„เธธเธ“เธˆเธณเธ™เธงเธ™เธกเธฒเธเนƒเธ™เธŠเนˆเธญเธ‡เธซเธฃเธทเธญ DM เนƒเธ”เธเน‡เน„เธ”เน‰เธ”เน‰เธงเธข Discord API v10 (เธˆเธณเธเธฑเธ”เธญเธฑเธ•เธฃเธฒเธญเธฑเธˆเธ‰เธฃเธดเธขเธฐ, เธฅเธญเธ‡เนƒเธซเธกเนˆ, เธเธฃเธญเธ‡เธงเธฑเธ™เธ—เธตเนˆ/เน€เธ™เธทเน‰เธญเธซเธฒ) ๐Ÿ‘ เธšเธฑเธ™เธ—เธถเธเธ‚เน‰เธญเธ„เธงเธฒเธกเธ—เธตเนˆเธ–เธนเธเธฅเธšเนเธšเธšเน€เธฃเธตเธขเธฅเน„เธ—เธกเนŒ ๐Ÿ‘ป เธ•เธฃเธงเธˆเธˆเธฑเธš ghost ping เธญเธฑเธ•เน‚เธ™เธกเธฑเธ•เธดเธžเธฃเน‰เธญเธกเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™ ๐Ÿ“ฆ เธชเนˆเธ‡เธญเธญเธเธ›เธฃเธฐเธงเธฑเธ•เธดเธŠเนˆเธญเธ‡เน€เธ›เน‡เธ™ HTML/JSON/TXT ๐Ÿ”‘ เธ•เธฃเธงเธˆเธˆเธฑเธš token เธ„เธฅเธดเธเน€เธ”เธตเธขเธง + เธ‚เน‰เธญเธกเธนเธฅเธšเธฑเธเธŠเธต เน„เธกเนˆเธกเธตเธ‚เน‰เธญเธกเธนเธฅเธญเธญเธเธˆเธฒเธเน€เธšเธฃเธฒเธงเนŒเน€เธ‹เธญเธฃเนŒเธ‚เธญเธ‡เธ„เธธเธ“ // @description:ar ๐Ÿ—‘ ุงุญุฐู ุฑุณุงุฆู„ูƒ ุจุดูƒู„ ุฌู…ุงุนูŠ ููŠ ุฃูŠ ู‚ู†ุงุฉ ุฃูˆ DM ุจุงุณุชุฎุฏุงู… Discord API v10 (ุญุฏ ู…ุนุฏู„ ุฐูƒูŠุŒ ุฅุนุงุฏุฉ ุงู„ู…ุญุงูˆู„ุฉุŒ ูู„ุงุชุฑ ุงู„ุชุงุฑูŠุฎ/ุงู„ู…ุญุชูˆู‰). ๐Ÿ‘ ุณุฌู‘ู„ ุงู„ุฑุณุงุฆู„ ุงู„ู…ุญุฐูˆูุฉ ููŠ ุงู„ูˆู‚ุช ุงู„ูุนู„ูŠ. ๐Ÿ‘ป ุงูƒุชุดู Ghost Ping ุชู„ู‚ุงุฆูŠู‹ุง ู…ุน ุฅุดุนุงุฑุงุช. ๐Ÿ“ฆ ุตุฏู‘ุฑ ุชุงุฑูŠุฎ ุงู„ู‚ู†ุงุฉ ุจุตูŠุบุฉ HTML/JSON/TXT. ๐Ÿ”‘ ูƒุดู ุงู„ุชูˆูƒู† ุจู†ู‚ุฑุฉ ูˆุงุญุฏุฉ + ู…ุนู„ูˆู…ุงุช ุงู„ุญุณุงุจ. ู„ุง ุชุบุงุฏุฑ ุฃูŠ ุจูŠุงู†ุงุช ู…ุชุตูุญูƒ. // @namespace https://greasyfork.org/users/1510019 // @version 1.0.0 // @author 2pixel // @license MIT // @icon https://raw.githubusercontent.com/not2pixel/TampermonkeyProjects/refs/heads/main/EasyTube.png // @icon64 https://raw.githubusercontent.com/not2pixel/TampermonkeyProjects/refs/heads/main/EasyTube.png // @homepageURL https://discord.gg/Gvmd7deFtS // @supportURL https://discord.gg/Gvmd7deFtS // @match https://discord.com/* // @match https://discordapp.com/* // @exclude https://discord.com/developers/* // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @connect discord.com // @connect discordapp.com // @run-at document-idle // @compatible chrome Tested on Chrome 120+ with Tampermonkey // @compatible firefox Tested on Firefox 120+ with Tampermonkey / Violentmonkey // @compatible edge Tested on Edge 120+ with Tampermonkey // @compatible brave Recommended (Manifest V3 compatible) // @downloadURL https://update.greasyfork.icu/scripts/569876/%F0%9F%9B%A0%EF%B8%8F%20Discord%20Plus%2B%20V1%20%E2%80%94%20Bulk%20Delete%2C%20Msg%20Logger%2C%20Ghost%20Ping%20%20Export.user.js // @updateURL https://update.greasyfork.icu/scripts/569876/%F0%9F%9B%A0%EF%B8%8F%20Discord%20Plus%2B%20V1%20%E2%80%94%20Bulk%20Delete%2C%20Msg%20Logger%2C%20Ghost%20Ping%20%20Export.meta.js // ==/UserScript== 'use strict'; // โ”€โ”€โ”€ CONSTANTS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ const VERSION = '1.0.0'; const API = 'https://discord.com/api/v10'; const DISCORD_EPOCH = 1420070400000n; const COMMUNITY = 'https://discord.gg/Gvmd7deFtS'; const MAX_RETRIES = 5; const PANEL_ID = 'dp2_panel'; const TOGGLE_ID = 'dp2_toggle'; // โ”€โ”€โ”€ STATE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ const S = { token: null, activeTab: 'delete', delRunning: false, delStopped: false, delCount: 0, failCount: 0, scanCount: 0, deletedLog: [], // { id, content, author, channel, time } ghostPings: [], // { author, channel, content, time } observers: [], }; // โ”€โ”€โ”€ UTILS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ const sleep = ms => new Promise(r => setTimeout(r, ms)); function snowflakeFromDate(d) { return ((BigInt(d.getTime()) - DISCORD_EPOCH) << 22n).toString(); } function esc(s) { return String(s ?? '').replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } function fmtTime(d) { return new Date(d).toLocaleTimeString('en-GB', { hour12:false }); } function fmtDate(d) { return new Date(d).toLocaleDateString('en-GB') + ' ' + fmtTime(d); } // Multi-strategy token extraction function grabToken() { // Strategy 1: iframe sandbox (most reliable) try { const f = document.createElement('iframe'); f.style.display = 'none'; document.body.appendChild(f); const t = f.contentWindow.localStorage.getItem('token'); document.body.removeChild(f); if (t) return t.replace(/"/g,''); } catch(_) {} // Strategy 2: direct localStorage try { const t = localStorage.getItem('token'); if (t) return t.replace(/"/g,''); } catch(_) {} // Strategy 3: webpack module cache try { const wpReq = window.webpackChunkdiscord_app?.push?.([[Symbol()],{},e=>e]); if (wpReq) { for (const id of Object.keys(wpReq.m || {})) { try { const mod = wpReq(id); if (mod?.default?.getToken) { const t = mod.default.getToken(); if (t) return t; } } catch(_) {} } } } catch(_) {} return null; } function getChannelId() { return location.pathname.match(/channels\/(?:@me|\d+)\/(\d+)/)?.[1] || null; } function getGuildId() { return location.pathname.match(/channels\/(\d+)\//)?.[1] || null; } // โ”€โ”€โ”€ API LAYER โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ async function apiCall(method, path, body, retries = 0) { if (!S.token) throw new Error('No token set'); const opts = { method, headers: { 'Authorization': S.token, 'Content-Type': 'application/json', 'X-Discord-Locale': 'en-US', 'X-Super-Properties': btoa(unescape(encodeURIComponent(JSON.stringify({ os:'Windows', browser:'Chrome', device:'', browser_version:'122.0.0.0', os_version:'10', release_channel:'stable', client_build_number:263192, })))), }, }; if (body) opts.body = JSON.stringify(body); let res; try { res = await fetch(`${API}${path}`, opts); } catch(e) { if (retries < MAX_RETRIES) { await sleep(1500); return apiCall(method, path, body, retries+1); } throw e; } if (res.status === 429) { const d = await res.json().catch(()=>({})); const w = Math.ceil((d.retry_after||2)*1000)+300; appendLog(`โณ Rate limited โ€” waiting ${(w/1000).toFixed(1)}s`, 'warn'); await sleep(w); if (retries < MAX_RETRIES) return apiCall(method, path, body, retries+1); throw new Error('Too many rate-limit retries'); } if (res.status === 401) throw new Error('Invalid token โ€” refresh Discord'); if (res.status === 403) throw new Error('No permission'); if (res.status === 404) return null; return res; } async function getMe() { const r = await apiCall('GET','/users/@me'); return r ? r.json() : null; } async function searchMsgs({ guildId, channelId, authorId, minId, maxId, content, hasLink, hasFile, nsfw }) { const p = new URLSearchParams(); if (authorId) p.set('author_id', authorId); if (minId) p.set('min_id', minId); if (maxId) p.set('max_id', maxId); if (content) p.set('content', content); if (hasLink) p.set('has','link'); if (hasFile) p.set('has','file'); p.set('include_nsfw', nsfw ? 'true':'false'); p.set('limit','25'); const ep = guildId ? `/guilds/${guildId}/messages/search?${p}` : `/channels/${channelId}/messages/search?${p}`; const r = await apiCall('GET', ep); if (!r) return null; if (r.status === 202) { await sleep(1600); return searchMsgs(...arguments); } return r.json(); } async function deleteMsg(channelId, msgId) { const r = await apiCall('DELETE', `/channels/${channelId}/messages/${msgId}`); return r !== null; } // โ”€โ”€โ”€ FEATURE: BULK DELETE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ async function runDelete(opts) { const { channelId, authorId, guildId, minDate, maxDate, content, hasLink, hasFile, nsfw, delayMs } = opts; S.delRunning = true; S.delStopped = false; S.delCount = S.failCount = S.scanCount = 0; setStatus('running'); appendLog('๐Ÿ—‘ Bulk delete started', 'brand'); appendLog(`Channel: ${channelId}${guildId ? ` | Guild: ${guildId}` : ''}`, 'info'); const minId = minDate ? snowflakeFromDate(minDate) : undefined; let maxId = maxDate ? snowflakeFromDate(maxDate) : undefined; let round = 0; while (!S.delStopped) { round++; appendLog(`Round ${round} โ€” searchingโ€ฆ`, 'info'); let data; try { data = await searchMsgs({ guildId, channelId, authorId, minId, maxId, content, hasLink, hasFile, nsfw }); } catch(e) { appendLog('Search error: '+e.message,'error'); break; } await sleep(950); if (!data) { appendLog('Nothing returned.','warn'); break; } const msgs = (data.messages||[]).flat(); S.scanCount += msgs.length; uiSync(); if (!msgs.length) { appendLog('โœ… No more messages found.','ok'); break; } const toDelete = authorId ? msgs.filter(m=>m.author?.id===authorId) : msgs; if (!toDelete.length) { appendLog('No matches in batch.','ok'); break; } appendLog(`Found ${toDelete.length} to delete`, 'info'); for (const msg of toDelete) { if (S.delStopped) break; try { const ok = await deleteMsg(msg.channel_id||channelId, msg.id); if (ok) { S.delCount++; appendLog(`โœ“ ${msg.id}`, 'ok'); } else { appendLog(`Already gone: ${msg.id}`, 'warn'); } } catch(e) { S.failCount++; appendLog(`โœ— ${msg.id}: ${e.message}`, 'error'); } uiSync(); await sleep(delayMs + Math.floor(Math.random()*250)); } const oldest = toDelete.reduce((a,b)=>BigInt(a.id) { for (const m of muts) { for (const node of m.removedNodes) { if (node.nodeType !== 1) continue; const msgEl = node.id?.startsWith('chat-messages-') ? node : node.querySelector?.('[id^="chat-messages-"]'); if (!msgEl) continue; const contentEl = msgEl.querySelector('[id^="message-content-"]'); const authorEl = msgEl.querySelector('h3 span[class*="username"]') || msgEl.querySelector('[class*="username"]'); const content = contentEl?.innerText?.trim() || ''; const author = authorEl?.innerText?.trim() || 'Unknown'; if (content.length < 1) continue; const entry = { id: msgEl.id, content, author, channel: location.pathname.split('/').pop(), time: Date.now() }; S.deletedLog.unshift(entry); if (S.deletedLog.length > 500) S.deletedLog.pop(); renderLogList(); // Ghost ping detection if (/@(everyone|here|\w+)/.test(content)) { S.ghostPings.unshift({ author, channel: entry.channel, content, time: entry.time }); if (S.ghostPings.length > 200) S.ghostPings.pop(); renderGhostList(); showToast(`๐Ÿ‘ป Ghost ping by ${author}`, content.slice(0,80), '#7b1fa2'); } } } }); obs.observe(document.body, { childList:true, subtree:true }); S.observers.push(obs); } // โ”€โ”€โ”€ FEATURE: EXPORT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ async function exportChannel(channelId, format, limit) { appendLog(`Fetching up to ${limit} messagesโ€ฆ`, 'info'); let all = [], before; let remaining = limit; while (remaining > 0 && !S.delStopped) { const batch = Math.min(remaining, 100); const qs = `limit=${batch}${before ? `&before=${before}` : ''}`; const r = await apiCall('GET', `/channels/${channelId}/messages?${qs}`); if (!r) break; const d = await r.json(); if (!Array.isArray(d)||!d.length) break; all = all.concat(d); before = d[d.length-1].id; remaining -= d.length; appendLog(`Fetched ${all.length}โ€ฆ`, 'info'); await sleep(600); } appendLog(`Collected ${all.length} messages.`, 'ok'); let blob, filename; if (format === 'json') { blob = new Blob([JSON.stringify(all,null,2)], { type:'application/json' }); filename = `discord-${channelId}.json`; } else if (format === 'txt') { const lines = all.map(m=>`[${fmtDate(m.timestamp)}] ${m.author.username}: ${m.content}`).join('\n'); blob = new Blob([lines], { type:'text/plain' }); filename = `discord-${channelId}.txt`; } else { const rows = all.map(m=>`${esc(fmtDate(m.timestamp))}${esc(m.author.username)}${esc(m.content)}`).join(''); const html = `Export ยท ${esc(channelId)}

Discord Export ยท #${esc(channelId)}

${all.length} messages ยท ${fmtDate(Date.now())}

${rows}
TimeAuthorContent
`; blob = new Blob([html], { type:'text/html' }); filename = `discord-${channelId}.html`; } const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = filename; a.click(); appendLog(`โœ… Saved as ${filename}`, 'ok'); } // โ”€โ”€โ”€ TOAST โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ function showToast(title, body, color='#5865F2') { document.getElementById('dp2_toast')?.remove(); const el = document.createElement('div'); el.id = 'dp2_toast'; Object.assign(el.style, { position:'fixed', bottom:'90px', right:'80px', background: color, color:'#fff', padding:'10px 16px', borderRadius:'12px', fontSize:'12px', fontWeight:'700', zIndex:'1000001', pointerEvents:'none', maxWidth:'260px', boxShadow:'0 8px 24px rgba(0,0,0,.4)', lineHeight:'1.4', animation:'dp2fade 3s forwards', }); el.innerHTML = `
${esc(title)}
${esc(body)}
`; document.body.appendChild(el); setTimeout(()=>el.remove(), 3100); } // โ”€โ”€โ”€ CSS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ GM_addStyle(` @import url('https://fonts.googleapis.com/css2?family=Nunito:wght@600;700;800;900&display=swap'); @keyframes dp2fade { 0% { opacity:1; transform:translateY(0); } 75% { opacity:1; } 100% { opacity:0; transform:translateY(-8px); } } @keyframes dp2pulse { 0%,100% { opacity:1; } 50% { opacity:.35; } } @keyframes dp2spin { to { transform:rotate(360deg); } } @keyframes dp2bar { 0% { margin-left:-40%; width:40%; } 60% { margin-left:100%; width:40%; } 100% { margin-left:100%; width:40%; } } #${PANEL_ID}, #${PANEL_ID} * { box-sizing:border-box; font-family:'Nunito', system-ui, sans-serif; } /* โ”€โ”€ Float toggle button โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ #${TOGGLE_ID} { position:fixed; bottom:90px; right:18px; width:56px; height:36px; border-radius:999px; background:rgba(255,255,255,0.16); border:1px solid rgba(255,255,255,0.22); box-shadow:0 8px 24px rgba(0,0,0,.25); z-index:99998; cursor:pointer; display:flex; align-items:center; justify-content:center; backdrop-filter:blur(20px); -webkit-backdrop-filter:blur(20px); transition:transform .18s, box-shadow .18s; } #${TOGGLE_ID}:hover { transform:translateY(-2px); box-shadow:0 12px 30px rgba(0,0,0,.32); } #${TOGGLE_ID}:active { transform:scale(.97); } .dp2-tog-icon { font-size:20px; transition:transform .3s; } #${TOGGLE_ID}.dp2-active .dp2-tog-icon { transform:rotate(20deg); } /* โ”€โ”€ Panel โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ #${PANEL_ID} { position:fixed; top:0; left:0; width:370px; max-width:94vw; max-height:min(580px, calc(100vh - 120px)); display:flex; flex-direction:column; background:rgba(30,32,40,0.82); backdrop-filter:blur(36px) saturate(180%); -webkit-backdrop-filter:blur(36px) saturate(180%); border:1px solid rgba(255,255,255,0.10); border-radius:24px; box-shadow:0 24px 64px rgba(0,0,0,.55), 0 0 0 1px rgba(255,255,255,.04) inset; z-index:99999; overflow:hidden; opacity:0; pointer-events:none; transform:translateY(18px) scale(.97); transition:opacity .32s ease, transform .38s cubic-bezier(.25,.46,.45,.94); } #${PANEL_ID}.dp2-show { opacity:1; pointer-events:all; transform:translateY(0) scale(1); } #${PANEL_ID}.dp2-dragging { transition:none !important; } /* โ”€โ”€ Header โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-hdr { background:linear-gradient(135deg, #5865F2, #3b3f8c); padding:13px 15px 12px; cursor:move; user-select:none; display:flex; align-items:center; justify-content:space-between; flex:0 0 auto; border-radius:24px 24px 0 0; } .dp2-hdr-l { display:flex; align-items:center; gap:10px; } .dp2-logo { width:38px; height:38px; background:rgba(255,255,255,0.16); border-radius:12px; display:flex; align-items:center; justify-content:center; font-size:20px; } .dp2-hdr-title { color:#fff; font-size:15px; font-weight:900; letter-spacing:.2px; line-height:1.2; } .dp2-hdr-sub { color:rgba(255,255,255,.72); font-size:10px; font-weight:700; letter-spacing:.3px; margin-top:1px; } .dp2-drag-dot { color:rgba(255,255,255,.7); font-size:22px; cursor:move; } .dp2-win-btns { display:flex; gap:5px; align-items:center; } .dp2-win-btn { width:11px; height:11px; border-radius:50%; border:none; cursor:pointer; padding:0; transition:filter .15s; } .dp2-win-btn:hover { filter:brightness(1.4); } .dp2-win-btn.close { background:#ff5f56; } .dp2-win-btn.minimize { background:#27293d; } /* โ”€โ”€ Stat pills โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-pills { display:flex; gap:6px; padding:8px 14px; background:rgba(0,0,0,.18); border-bottom:1px solid rgba(255,255,255,.07); flex:0 0 auto; } .dp2-pill { flex:1; display:flex; align-items:center; justify-content:center; gap:4px; background:rgba(255,255,255,.10); border:1px solid rgba(255,255,255,.08); border-radius:999px; padding:5px 10px; font-size:11px; font-weight:800; color:#dbdee1; } .dp2-pill span { font-size:13px; font-weight:900; color:#fff; } /* โ”€โ”€ Tabs โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-tabs { display:flex; gap:0; padding:0 14px; background:rgba(0,0,0,.14); border-bottom:1px solid rgba(255,255,255,.07); flex:0 0 auto; overflow-x:auto; scrollbar-width:none; } .dp2-tabs::-webkit-scrollbar { display:none; } .dp2-tab { padding:9px 10px 8px; font-size:11px; font-weight:800; color:rgba(255,255,255,.35); cursor:pointer; white-space:nowrap; border-bottom:2px solid transparent; letter-spacing:.2px; transition:color .15s, border-color .15s; } .dp2-tab:hover { color:rgba(255,255,255,.65); } .dp2-tab.active { color:#fff; border-bottom-color:#5865F2; } /* โ”€โ”€ Body โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-body { padding:14px; overflow-y:auto; flex:1 1 auto; scrollbar-width:thin; scrollbar-color:rgba(255,255,255,.15) transparent; display:flex; flex-direction:column; gap:10px; } .dp2-body::-webkit-scrollbar { width:6px; } .dp2-body::-webkit-scrollbar-thumb { background:rgba(255,255,255,.15); border-radius:999px; } .dp2-pane { display:none; flex-direction:column; gap:10px; } .dp2-pane.active { display:flex; } /* โ”€โ”€ Section label โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-lbl { font-size:9.5px; font-weight:900; letter-spacing:.9px; text-transform:uppercase; color:rgba(255,255,255,.3); margin-bottom:4px; } /* โ”€โ”€ Cards โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-card { background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.09); border-radius:16px; padding:12px; } /* โ”€โ”€ Inputs โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-field { position:relative; flex:1; } .dp2-field label { display:block; font-size:9.5px; font-weight:800; letter-spacing:.6px; text-transform:uppercase; color:rgba(255,255,255,.3); margin-bottom:4px; } .dp2-row { display:flex; gap:7px; } .dp2-input { width:100%; background:rgba(0,0,0,.25); border:1px solid rgba(255,255,255,.10); border-radius:10px; padding:8px 10px; color:#dbdee1; font-family:inherit; font-size:12px; font-weight:700; outline:none; transition:border-color .15s, box-shadow .15s; } .dp2-input:focus { border-color:#5865F2; box-shadow:0 0 0 3px rgba(88,101,242,.2); } .dp2-input::placeholder { color:rgba(255,255,255,.18); font-weight:600; } .dp2-input.error { border-color:#ed4245; } .dp2-input[type="password"] { letter-spacing:3px; } .dp2-input[type="password"]::placeholder { letter-spacing:normal; } .dp2-inline-btn { position:absolute; right:7px; top:50%; transform:translateY(-50%); background:rgba(88,101,242,.25); border:none; border-radius:6px; color:#949cf7; font-size:9.5px; font-weight:900; font-family:inherit; padding:2px 6px; cursor:pointer; letter-spacing:.3px; transition:background .15s; } .dp2-inline-btn:hover { background:rgba(88,101,242,.45); } /* โ”€โ”€ Checkbox grid โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-chk-grid { display:grid; grid-template-columns:1fr 1fr; gap:6px; } .dp2-chk { display:flex; align-items:center; gap:7px; background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.08); border-radius:10px; padding:8px 10px; cursor:pointer; transition:border-color .15s; } .dp2-chk:hover { border-color:rgba(255,255,255,.15); } .dp2-chk.on { border-color:#5865F244; background:rgba(88,101,242,.1); } .dp2-chk-box { width:14px; height:14px; border-radius:4px; border:1.5px solid rgba(255,255,255,.2); background:rgba(0,0,0,.25); display:flex; align-items:center; justify-content:center; flex-shrink:0; transition:all .15s; } .dp2-chk.on .dp2-chk-box { background:#5865F2; border-color:#5865F2; } .dp2-chk.on .dp2-chk-box::after { content:''; width:5px; height:3px; border-left:1.5px solid #fff; border-bottom:1.5px solid #fff; transform:rotate(-45deg) translate(.5px,-.5px); } .dp2-chk-lbl { font-size:11.5px; font-weight:700; color:rgba(255,255,255,.45); } .dp2-chk.on .dp2-chk-lbl { color:#dbdee1; } /* โ”€โ”€ Slider โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-slider-row { display:flex; align-items:center; gap:10px; } .dp2-slider { flex:1; -webkit-appearance:none; height:3px; border-radius:2px; background:rgba(255,255,255,.12); outline:none; cursor:pointer; } .dp2-slider::-webkit-slider-thumb { -webkit-appearance:none; width:14px; height:14px; border-radius:50%; background:#5865F2; cursor:pointer; box-shadow:0 0 8px rgba(88,101,242,.6); transition:transform .15s; } .dp2-slider::-webkit-slider-thumb:hover { transform:scale(1.2); } .dp2-slider-val { font-size:11.5px; font-weight:800; color:#949cf7; min-width:42px; text-align:right; } /* โ”€โ”€ Stats row โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-stats-row { display:grid; grid-template-columns:1fr 1fr 1fr; background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.08); border-radius:14px; padding:10px; gap:0; } .dp2-stat { text-align:center; } .dp2-stat-val { font-size:20px; font-weight:900; color:#fff; line-height:1; } .dp2-stat-lbl { font-size:9px; font-weight:800; text-transform:uppercase; letter-spacing:.6px; color:rgba(255,255,255,.3); margin-top:3px; } /* โ”€โ”€ Progress bar โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-bar-track { height:3px; background:rgba(255,255,255,.08); border-radius:2px; overflow:hidden; margin-top:6px; } .dp2-bar-fill { height:100%; background:linear-gradient(90deg, #5865F2, #949cf7); border-radius:2px; width:0; transition:width .3s; } .dp2-bar-fill.running { animation:dp2bar 1.5s ease infinite; } /* โ”€โ”€ Log โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-log { background:rgba(0,0,0,.3); border:1px solid rgba(255,255,255,.07); border-radius:10px; padding:8px 10px; height:80px; overflow-y:auto; font-family:'JetBrains Mono','Courier New',monospace; font-size:10px; color:rgba(255,255,255,.3); } .dp2-log::-webkit-scrollbar { width:3px; } .dp2-log::-webkit-scrollbar-thumb { background:rgba(255,255,255,.1); border-radius:2px; } .dp2-ll { margin:1px 0; line-height:1.55; } .dp2-ll.info { color:rgba(255,255,255,.4); } .dp2-ll.ok { color:#57f287; } .dp2-ll.warn { color:#fee75c; } .dp2-ll.error { color:#ed4245; } .dp2-ll.brand { color:#949cf7; } /* โ”€โ”€ Buttons โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-btn-row { display:flex; gap:7px; } .dp2-btn { flex:1; padding:10px 12px; border:none; border-radius:12px; font-family:inherit; font-size:12px; font-weight:900; cursor:pointer; transition:all .15s; letter-spacing:.2px; display:flex; align-items:center; justify-content:center; gap:6px; } .dp2-btn:active { transform:scale(.97); } .dp2-btn-primary { background:linear-gradient(135deg, #5865F2, #3b3f8c); color:#fff; box-shadow:0 4px 16px rgba(88,101,242,.35); } .dp2-btn-primary:hover { filter:brightness(1.1); box-shadow:0 6px 22px rgba(88,101,242,.5); } .dp2-btn-primary:disabled { background:rgba(255,255,255,.08); color:rgba(255,255,255,.25); box-shadow:none; cursor:not-allowed; } .dp2-btn-secondary { background:rgba(255,255,255,.08); border:1px solid rgba(255,255,255,.10); color:rgba(255,255,255,.5); } .dp2-btn-secondary:hover { background:rgba(255,255,255,.12); color:#dbdee1; } .dp2-btn-danger { background:rgba(237,66,69,.15); color:#ed4245; border:1px solid rgba(237,66,69,.25); } .dp2-btn-danger:hover { background:rgba(237,66,69,.25); border-color:#ed4245; } .dp2-btn-green { background:linear-gradient(135deg, #3ba55d, #2d7d46); color:#fff; box-shadow:0 4px 14px rgba(59,165,93,.3); } .dp2-btn-green:hover { filter:brightness(1.08); } /* โ”€โ”€ Toggle cards (3-col) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-tc-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:7px; } .dp2-tc { background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.09); border-radius:14px; padding:10px 9px; display:flex; flex-direction:column; gap:7px; transition:transform .15s, border-color .2s; } .dp2-tc.on { border-color:#5865F244; background:rgba(88,101,242,.1); } .dp2-tc:hover { transform:translateY(-1px); } .dp2-tc-top { display:flex; align-items:center; justify-content:space-between; } .dp2-tc-ico { font-size:18px; line-height:1; } .dp2-tc-bot { display:flex; align-items:center; justify-content:space-between; } .dp2-tc-title { font-size:11px; font-weight:900; color:#dbdee1; } .dp2-tc-state { font-size:10px; font-weight:800; color:rgba(255,255,255,.3); letter-spacing:.3px; } .dp2-tc.on .dp2-tc-state { color:#949cf7; } /* Mac-style switch */ .dp2-sw { width:38px; height:22px; border-radius:999px; border:none; background:rgba(255,255,255,.15); position:relative; cursor:pointer; flex-shrink:0; transition:background .18s; box-shadow:inset 0 0 0 1px rgba(0,0,0,.15); } .dp2-sw.on { background:#5865F2; } .dp2-sw-thumb { position:absolute; top:2px; left:2px; width:18px; height:18px; border-radius:50%; background:#fff; box-shadow:0 3px 8px rgba(0,0,0,.2); transition:transform .18s; } .dp2-sw.on .dp2-sw-thumb { transform:translateX(16px); } /* โ”€โ”€ Warning box โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-warn { background:rgba(254,231,92,.08); border:1px solid rgba(254,231,92,.18); border-radius:10px; padding:8px 10px; font-size:10.5px; font-weight:700; color:rgba(254,231,92,.75); line-height:1.5; } /* โ”€โ”€ Message lists โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-list { display:flex; flex-direction:column; gap:5px; max-height:240px; overflow-y:auto; } .dp2-list::-webkit-scrollbar { width:4px; } .dp2-list::-webkit-scrollbar-thumb { background:rgba(255,255,255,.1); border-radius:2px; } .dp2-list-empty { text-align:center; color:rgba(255,255,255,.2); font-size:11.5px; padding:24px 0; font-weight:700; line-height:1.6; } .dp2-li { background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.08); border-radius:10px; padding:8px 10px; font-size:11.5px; } .dp2-li-head { display:flex; justify-content:space-between; margin-bottom:3px; } .dp2-li-author { font-weight:900; color:#949cf7; font-size:11px; } .dp2-li-time { font-size:10px; color:rgba(255,255,255,.25); font-family:monospace; } .dp2-li-body { color:rgba(255,255,255,.55); line-height:1.45; word-break:break-word; font-weight:600; } .dp2-li.ghost { border-color:rgba(123,31,162,.4); background:rgba(123,31,162,.1); } .dp2-li.ghost .dp2-li-author { color:#c084fc; } /* โ”€โ”€ Select โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-select { width:100%; background:rgba(0,0,0,.25); border:1px solid rgba(255,255,255,.10); border-radius:10px; padding:8px 10px; color:#dbdee1; font-family:inherit; font-size:12px; font-weight:700; outline:none; appearance:none; cursor:pointer; } .dp2-select:focus { border-color:#5865F2; box-shadow:0 0 0 3px rgba(88,101,242,.2); } /* โ”€โ”€ About card โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-about { background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.09); border-radius:18px; padding:18px; text-align:center; } .dp2-about-logo { width:52px; height:52px; margin:0 auto 12px; background:linear-gradient(135deg, #5865F2, #3b3f8c); border-radius:16px; display:flex; align-items:center; justify-content:center; font-size:26px; box-shadow:0 6px 20px rgba(88,101,242,.4); } .dp2-about-title { font-size:18px; font-weight:900; color:#fff; } .dp2-about-sub { font-size:10.5px; color:rgba(255,255,255,.35); margin:4px 0 14px; font-weight:700; } .dp2-feat-list { text-align:left; margin-bottom:14px; } .dp2-feat-list li { list-style:none; font-size:11.5px; font-weight:700; color:rgba(255,255,255,.55); padding:3px 0; line-height:1.45; } .dp2-feat-list li::before { content:'โ†’ '; color:#5865F2; font-weight:900; } .dp2-community-btn { display:inline-flex; align-items:center; justify-content:center; gap:8px; width:100%; padding:11px 16px; border-radius:12px; background:linear-gradient(135deg, #5865F2, #3b3f8c); color:#fff; font-size:13px; font-weight:900; text-decoration:none; cursor:pointer; box-shadow:0 4px 16px rgba(88,101,242,.35); transition:filter .15s, transform .15s; } .dp2-community-btn:hover { filter:brightness(1.1); transform:translateY(-1px); } .dp2-foot { padding:9px 14px; background:rgba(0,0,0,.15); border-top:1px solid rgba(255,255,255,.06); border-radius:0 0 24px 24px; text-align:center; flex:0 0 auto; } .dp2-foot-txt { font-size:10px; font-weight:700; color:rgba(255,255,255,.25); } /* โ”€โ”€ User info card โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ .dp2-user-card { background:rgba(0,0,0,.25); border:1px solid rgba(255,255,255,.08); border-radius:12px; padding:12px; font-size:12px; font-weight:700; } .dp2-status-dot { display:inline-block; width:8px; height:8px; border-radius:50%; background:rgba(255,255,255,.15); margin-right:4px; vertical-align:middle; transition:background .3s, box-shadow .3s; } .dp2-status-dot.running { background:#fee75c; box-shadow:0 0 6px #fee75c; animation:dp2pulse 1.2s ease infinite; } .dp2-status-dot.ok { background:#57f287; box-shadow:0 0 6px #57f287; } `); // โ”€โ”€โ”€ BUILD UI โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ function buildPanel() { const tog = document.createElement('div'); tog.id = TOGGLE_ID; const togIcon = document.createElement('span'); togIcon.className = 'dp2-tog-icon'; togIcon.textContent = '๐Ÿ› ๏ธ'; tog.appendChild(togIcon); document.body.appendChild(tog); const panel = document.createElement('div'); panel.id = PANEL_ID; panel.innerHTML = `
Discord Plus+ V1
DELETE ยท LOG ยท GHOST ยท EXPORT ยท TOKEN
โ‹ฎ
๐Ÿ—‘ Deleted: 0
โœ— Failed: 0
๐Ÿ” Scanned: 0
๐Ÿ—‘ Delete
๐Ÿ‘ Logger
๐Ÿ‘ป Ghost
๐Ÿ“ฆ Export
๐Ÿ”‘ Token
โ„น About
Authentication
โš  Token never leaves your browser. NEVER share it.
Target
Filters
Has File
NSFW
Pinned
Delete delay Idle
750ms
0
Deleted
0
Failed
0
Scanned
Deleted Message Log

Captures messages removed from the DOM while you're in a channel.

No deleted messages captured yet.
Open a channel and wait.
Ghost Ping Tracker

Detects @mentions deleted immediately โ€” shows toast notification.

No ghost pings detected.
Export Channel Messages
โš  Token must be set in the Delete tab first.
Your Token
โš  NEVER share your token. It gives full access to your account. If exposed โ€” logout, change password, enable 2FA immediately.
Detect token to see account info.
Discord Plus+ V1
v${VERSION} ยท The all-in-one Discord web toolkit
  • Bulk Message Deleter โ€” Discord API v10, smart rate-limit & retry
  • Deleted Message Logger โ€” real-time DOM capture, 500 msg buffer
  • Ghost Ping Detector โ€” auto-alert with toast notification
  • Message Exporter โ€” HTML / JSON / TXT download
  • Token Detector โ€” 3-strategy extraction + account info
  • Draggable panel โ€” tabbed UI, glassmorphism design
  • Alt+D shortcut โ€” toggle panel anytime
  • 100% local โ€” zero external requests
๐Ÿ’ฌ Join Community ยท discord.gg/Gvmd7deFtS
โš  Self-bot actions may violate Discord TOS. Use at your own risk.
MIT License ยท Works with Tampermonkey & Violentmonkey
ยฉ Discord Plus+ v${VERSION} by 2pixel ยท Alt+D to toggle
`; document.body.appendChild(panel); return { panel, tog }; } // โ”€โ”€โ”€ WIRE EVENTS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ function wire(panel, tog) { // Drag const hdr = panel.querySelector('.dp2-hdr'); let drag = false, ox = 0, oy = 0, cx, cy; const vw = innerWidth, vh = innerHeight; cx = vw - 390; cy = Math.max(8, vh - 620); panel.style.transform = `translate3d(${cx}px,${cy}px,0)`; hdr.addEventListener('pointerdown', e => { drag = true; panel.classList.add('dp2-dragging'); const r = panel.getBoundingClientRect(); ox = e.clientX - r.left; oy = e.clientY - r.top; try { hdr.setPointerCapture(e.pointerId); } catch(_){} e.preventDefault(); }, { passive: false }); hdr.addEventListener('pointermove', e => { if (!drag) return; e.preventDefault(); const maxX = innerWidth - panel.offsetWidth - 8; const maxY = innerHeight - panel.offsetHeight - 8; cx = Math.max(8, Math.min(maxX, e.clientX - ox)); cy = Math.max(8, Math.min(maxY, e.clientY - oy)); panel.style.transform = `translate3d(${cx}px,${cy}px,0)`; }, { passive: false }); hdr.addEventListener('pointerup', () => { drag = false; panel.classList.remove('dp2-dragging'); }); hdr.addEventListener('pointercancel', () => { drag = false; panel.classList.remove('dp2-dragging'); }); // Toggle let vis = false; tog.addEventListener('click', () => { vis = !vis; panel.classList.toggle('dp2-show', vis); tog.classList.toggle('dp2-active', vis); }); // Close / Minimize panel.querySelector('#dp2-close').onclick = () => { vis = false; panel.classList.remove('dp2-show'); tog.classList.remove('dp2-active'); }; panel.querySelector('#dp2-min').onclick = () => { const b = panel.querySelector('.dp2-body'); const f = panel.querySelector('.dp2-foot'); const p = panel.querySelector('.dp2-pills'); const t = panel.querySelector('.dp2-tabs'); const hidden = b.style.display === 'none'; [b, f, p, t].forEach(el => { if(el) el.style.display = hidden ? '' : 'none'; }); }; // Tabs panel.querySelectorAll('.dp2-tab').forEach(tab => { tab.onclick = () => { panel.querySelectorAll('.dp2-tab').forEach(t=>t.classList.remove('active')); panel.querySelectorAll('.dp2-pane').forEach(p=>p.classList.remove('active')); tab.classList.add('active'); panel.querySelector(`#dp2-pane-${tab.dataset.tab}`).classList.add('active'); }; }); // Checkboxes panel.querySelectorAll('.dp2-chk').forEach(c => c.onclick = ()=>c.classList.toggle('on')); // Delay slider const slider = panel.querySelector('#dp2-delay'); const slLbl = panel.querySelector('#dp2-delay-lbl'); slider.oninput = () => { slLbl.textContent = slider.value + 'ms'; }; // โ”€โ”€ Delete tab โ”€โ”€ const tokenIn = panel.querySelector('#dp2-token'); panel.querySelector('#dp2-auto-tok').onclick = () => { const t = grabToken(); if (t) { tokenIn.value = t; S.token = t; appendLog('Token auto-detected โœ“', 'ok'); } else appendLog('Could not detect โ€” paste manually', 'warn'); }; panel.querySelector('#dp2-auto-ch').onclick = () => { const ch = getChannelId(); if (ch) { panel.querySelector('#dp2-channel').value = ch; appendLog(`Channel: ${ch}`, 'ok'); } else appendLog('Navigate to a channel first', 'warn'); }; panel.querySelector('#dp2-auto-guild').onclick = () => { const g = getGuildId(); if (g) { panel.querySelector('#dp2-guild').value = g; appendLog(`Guild: ${g}`, 'ok'); } else appendLog('Not in a guild', 'warn'); }; panel.querySelector('#dp2-auto-me').onclick = async () => { const t = tokenIn.value.trim() || grabToken(); if (!t) { appendLog('Set token first', 'warn'); return; } S.token = t; try { const me = await getMe(); panel.querySelector('#dp2-author').value = me.id; appendLog(`Author: ${me.id} (${me.username})`, 'ok'); } catch(e) { appendLog('Error: '+e.message, 'error'); } }; panel.querySelector('#dp2-clear-btn').onclick = () => { if (S.delRunning) return; ['#dp2-token','#dp2-channel','#dp2-guild','#dp2-author','#dp2-content','#dp2-from','#dp2-to'] .forEach(s => { panel.querySelector(s).value = ''; }); panel.querySelectorAll('.dp2-chk').forEach(c=>c.classList.remove('on')); panel.querySelector('#dp2-log').innerHTML = ''; setStatus(''); S.delCount = S.failCount = S.scanCount = 0; uiSync(); }; panel.querySelector('#dp2-stop-btn').onclick = () => { S.delStopped = true; S.delRunning = false; }; panel.querySelector('#dp2-start-btn').onclick = async () => { if (S.delRunning) return; const token = tokenIn.value.trim() || grabToken(); const ch = panel.querySelector('#dp2-channel').value.trim(); if (!token) { appendLog('Token required', 'error'); return; } if (!ch) { panel.querySelector('#dp2-channel').classList.add('error'); appendLog('Channel ID required', 'error'); return; } panel.querySelectorAll('.dp2-input').forEach(i=>i.classList.remove('error')); S.token = token; toggleBtn('start', false); toggleBtn('stop', true); await runDelete({ channelId: ch, authorId: panel.querySelector('#dp2-author').value.trim() || null, guildId: panel.querySelector('#dp2-guild').value.trim() || null, content: panel.querySelector('#dp2-content').value.trim() || null, minDate: panel.querySelector('#dp2-from').value ? new Date(panel.querySelector('#dp2-from').value+'T00:00:00') : null, maxDate: panel.querySelector('#dp2-to').value ? new Date(panel.querySelector('#dp2-to').value+'T23:59:59') : null, hasLink: panel.querySelector('#chk-link').classList.contains('on'), hasFile: panel.querySelector('#chk-file').classList.contains('on'), nsfw: panel.querySelector('#chk-nsfw').classList.contains('on'), delayMs: parseInt(slider.value), }); toggleBtn('stop', false); toggleBtn('start', true); }; // โ”€โ”€ Logger tab โ”€โ”€ panel.querySelector('#dp2-clear-log').onclick = () => { S.deletedLog = []; renderLogList(); }; panel.querySelector('#dp2-export-log').onclick = () => { const b = new Blob([JSON.stringify(S.deletedLog, null, 2)], { type:'application/json' }); const a = document.createElement('a'); a.href = URL.createObjectURL(b); a.download = 'deleted-messages.json'; a.click(); }; // โ”€โ”€ Ghost tab โ”€โ”€ panel.querySelector('#dp2-clear-ghost').onclick = () => { S.ghostPings = []; renderGhostList(); }; // โ”€โ”€ Export tab โ”€โ”€ panel.querySelector('#dp2-exp-auto').onclick = () => { const ch = getChannelId(); if (ch) panel.querySelector('#dp2-exp-ch').value = ch; }; panel.querySelector('#dp2-exp-start').onclick = async () => { const t = tokenIn.value.trim() || grabToken(); if (!t) { showToast('Error', 'Set token in Delete tab first', '#ed4245'); return; } S.token = t; const ch = panel.querySelector('#dp2-exp-ch').value.trim(); const fmt = panel.querySelector('#dp2-exp-fmt').value; const lim = parseInt(panel.querySelector('#dp2-exp-lim').value) || 500; if (!ch) return; await exportChannel(ch, fmt, lim); }; // โ”€โ”€ Token tab โ”€โ”€ panel.querySelector('#dp2-tok-detect').onclick = async () => { const t = grabToken(); if (!t) { showToast('Error', 'Could not detect token', '#ed4245'); return; } S.token = t; tokenIn.value = t; panel.querySelector('#dp2-tok-disp').value = t; try { const me = await getMe(); panel.querySelector('#dp2-userinfo').innerHTML = `
${esc(me.username)}#${me.discriminator||'0'}
ID: ${me.id}
Email: ${esc(me.email||'hidden')}
2FA: ${me.mfa_enabled?'Enabled โœ“':'Disabled โœ—'}
`; } catch(e) { panel.querySelector('#dp2-userinfo').innerHTML = `${esc(e.message)}`; } }; panel.querySelector('#dp2-tok-copy').onclick = () => { const t = S.token || panel.querySelector('#dp2-tok-disp').value; if (t) navigator.clipboard.writeText(t).then(()=>showToast('Copied!','Token copied โ€” keep it safe','#3ba55d')); }; panel.querySelector('#dp2-tok-clear').onclick = () => { S.token = null; tokenIn.value = ''; panel.querySelector('#dp2-tok-disp').value = ''; panel.querySelector('#dp2-userinfo').textContent = 'Detect token to see account info.'; panel.querySelector('#dp2-userinfo').style.color = 'rgba(255,255,255,.3)'; }; // Alt+D shortcut document.addEventListener('keydown', e => { if (e.altKey && e.key === 'D') { vis = !vis; panel.classList.toggle('dp2-show', vis); tog.classList.toggle('dp2-active', vis); } }); // Auto-detect on load setTimeout(() => { const t = grabToken(); if (t) { S.token = t; tokenIn.value = t; } }, 1500); } // โ”€โ”€โ”€ UI STATE HELPERS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ function uiSync() { const set = (id, v) => { const el = document.getElementById(id); if(el) el.textContent = v; }; set('dp2-s-del', S.delCount); set('dp2-s-fail', S.failCount); set('dp2-s-scan', S.scanCount); set('dp2-v-del', S.delCount); set('dp2-v-fail', S.failCount); set('dp2-v-scan', S.scanCount); } function appendLog(msg, type='info') { ['#dp2-log','#dp2-exp-log'].forEach(sel => { const el = document.querySelector(sel); if (!el) return; const t = new Date().toLocaleTimeString('en-GB',{hour12:false}); const line = document.createElement('div'); line.className = 'dp2-ll ' + type; line.textContent = `[${t}] ${msg}`; el.appendChild(line); el.scrollTop = el.scrollHeight; while (el.childElementCount > 300) el.removeChild(el.firstChild); }); } function setStatus(state) { const dot = document.getElementById('dp2-sdot'); const lbl = document.getElementById('dp2-status-lbl'); const bar = document.getElementById('dp2-bar'); if (dot) dot.className = 'dp2-status-dot' + (state ? ' '+state : ''); if (lbl) { const labels = { running:'Runningโ€ฆ', done:'Done โœ“', '':'Idle' }; lbl.innerHTML = `${labels[state]||'Idle'}`; } if (bar) { bar.classList.toggle('running', state==='running'); if (state==='done') bar.style.width='100%'; if (!state) bar.style.width='0'; } } function toggleBtn(id, show) { const el = document.getElementById(id==='start' ? 'dp2-start-btn' : 'dp2-stop-btn'); if (!el) return; if (id==='start') el.disabled = !show; el.style.display = show ? '' : 'none'; } function renderLogList() { const list = document.getElementById('dp2-del-list'); const cnt = document.getElementById('dp2-log-cnt'); if (!list) return; if (cnt) cnt.textContent = `(${S.deletedLog.length})`; if (!S.deletedLog.length) { list.innerHTML = '
No deleted messages captured yet.
Open a channel and wait.
'; return; } list.innerHTML = S.deletedLog.slice(0,100).map(e=>`
${esc(e.author)} ${fmtTime(e.time)}
${esc(e.content.slice(0,200))}${e.content.length>200?'โ€ฆ':''}
`).join(''); } function renderGhostList() { const list = document.getElementById('dp2-ghost-list'); const cnt = document.getElementById('dp2-ghost-cnt'); if (!list) return; if (cnt) cnt.textContent = `(${S.ghostPings.length})`; if (!S.ghostPings.length) { list.innerHTML = '
No ghost pings detected.
'; return; } list.innerHTML = S.ghostPings.slice(0,50).map(e=>`
๐Ÿ‘ป ${esc(e.author)} ${fmtTime(e.time)}
${esc(e.content.slice(0,200))}
`).join(''); } // โ”€โ”€โ”€ BOOT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ function boot() { if (document.getElementById(PANEL_ID)) return; const { panel, tog } = buildPanel(); wire(panel, tog); setTimeout(() => startLogger(), 2000); console.log(`%cDiscord Plus+ v${VERSION} loaded ๐Ÿ› ๏ธ`, 'color:#949cf7;font-weight:bold;font-size:13px;background:#1e2028;padding:4px 10px;border-radius:8px'); console.log(`%cCommunity: ${COMMUNITY}`, 'color:#5865F2;font-size:11px'); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => setTimeout(boot, 1200)); } else { setTimeout(boot, 1200); }