smoothretro1982

pastebin archiver (update 1)

Mar 21st, 2026 (edited)
25
0
Never
2
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.42 KB | None | 0 0
  1. (function () {
  2. const RAW_PREFIX = "https://pastebin.com/raw/";
  3. const PROXIES = [
  4. "https://api.allorigins.win/raw?url=",
  5. "https://cors.isomorphic-git.org/",
  6. "https://api.codetabs.com/v1/proxy?quest="
  7. ];
  8. const THREADS = 4;
  9. const PREVIEW_LIMIT = 2000;
  10. const LOG_LIMIT = 200;
  11. const MAX_RETRIES = 3;
  12.  
  13. // ---------------- IndexedDB Storage Engine ----------------
  14. const DB_NAME = "PastebinArchiveDB";
  15. const DB_VERSION = 1;
  16. const STORE_NAME = "archive_state";
  17.  
  18. function openDB() {
  19. return new Promise((resolve, reject) => {
  20. const req = indexedDB.open(DB_NAME, DB_VERSION);
  21. req.onupgradeneeded = e => {
  22. const db = e.target.result;
  23. if (!db.objectStoreNames.contains(STORE_NAME)) {
  24. db.createObjectStore(STORE_NAME);
  25. }
  26. };
  27. req.onsuccess = e => resolve(e.target.result);
  28. req.onerror = e => reject(e.target.error);
  29. });
  30. }
  31.  
  32. async function saveIDB(key, val) {
  33. try {
  34. const db = await openDB();
  35. const tx = db.transaction(STORE_NAME, "readwrite");
  36. tx.objectStore(STORE_NAME).put(val, key);
  37. return new Promise(r => tx.oncomplete = r);
  38. } catch (e) {
  39. console.warn("IndexedDB Save Error:", e);
  40. }
  41. }
  42.  
  43. async function getIDB(key) {
  44. try {
  45. const db = await openDB();
  46. const tx = db.transaction(STORE_NAME, "readonly");
  47. const req = tx.objectStore(STORE_NAME).get(key);
  48. return new Promise(r => req.onsuccess = () => r(req.result));
  49. } catch (e) {
  50. console.warn("IndexedDB Load Error:", e);
  51. return null;
  52. }
  53. }
  54.  
  55. async function clearIDB() {
  56. try {
  57. const db = await openDB();
  58. const tx = db.transaction(STORE_NAME, "readwrite");
  59. tx.objectStore(STORE_NAME).clear();
  60. return new Promise(r => tx.oncomplete = r);
  61. } catch (e) {
  62. console.warn("IndexedDB Clear Error:", e);
  63. }
  64. }
  65.  
  66. // ---------------- State Variables ----------------
  67. function sleep(ms) {
  68. return new Promise(resolve => setTimeout(resolve, ms));
  69. }
  70.  
  71. let users = [],
  72. currentUserIndex = 0,
  73. user = "";
  74. let proxyIndex = 0;
  75. let running = false;
  76. let active = 0;
  77. let found = new Set();
  78. let queue = [];
  79. let results = [];
  80. let metadataMap = new Map(); // Stores scraped metadata per paste ID
  81. let searchDebounceTimer = null;
  82.  
  83. // ---------------- Helper Functions ----------------
  84. function escapeHTML(t) {
  85. return (t || "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
  86. }
  87.  
  88. async function proxyFetch(url) {
  89. for (let i = 0; i < PROXIES.length; i++) {
  90. const proxy = PROXIES[(proxyIndex + i) % PROXIES.length];
  91. try {
  92. const targetUrl = proxy.includes("isomorphic-git")
  93. ? proxy + url
  94. : proxy + encodeURIComponent(url);
  95. const r = await fetch(targetUrl);
  96. if (r.ok) return r;
  97. } catch {}
  98. }
  99. proxyIndex++;
  100. throw new Error("All proxies failed");
  101. }
  102.  
  103. async function saveProgress() {
  104. await saveIDB("found", [...found]);
  105. await saveIDB("queue", queue);
  106. await saveIDB("results", results);
  107. await saveIDB("users", users);
  108. await saveIDB("currentUserIndex", currentUserIndex);
  109. await saveIDB("metadataMap", [...metadataMap.entries()]);
  110. }
  111.  
  112. async function loadProgress() {
  113. const f = await getIDB("found");
  114. const q = await getIDB("queue");
  115. const res = await getIDB("results");
  116. const u = await getIDB("users");
  117. const ci = await getIDB("currentUserIndex");
  118. const mm = await getIDB("metadataMap");
  119.  
  120. if (f) found = new Set(f);
  121. if (q) queue = q;
  122. if (res) results = res;
  123. if (mm) metadataMap = new Map(mm);
  124. if (u) {
  125. users = u;
  126. const usersInput = document.getElementById("ah-users");
  127. if (usersInput) usersInput.value = users.join("\n");
  128. }
  129. if (ci !== null && ci !== undefined) currentUserIndex = parseInt(ci, 10) || 0;
  130. }
  131.  
  132. // ---------------- HUD Injection ----------------
  133. if (document.getElementById("archiveHUD")) return;
  134. const hud = document.createElement("div");
  135. hud.id = "archiveHUD";
  136. hud.style = `
  137. position:fixed;top:20px;left:20px;width:440px;height:580px;
  138. background:#111;color:#0f0;font-family:monospace;
  139. border:1px solid #0f0;padding:10px;z-index:999999;
  140. resize:both;overflow:hidden;box-sizing:border-box;
  141. `;
  142. hud.innerHTML = `
  143. <div id="ah-header" style="cursor:move;font-weight:bold;display:flex;justify-content:space-between;user-select:none;">
  144. <span>Pastebin Archive HUD (IndexedDB)</span>
  145. <button id="ah-close" style="background:#222;color:#0f0;border:1px solid #0f0;cursor:pointer;">X</button>
  146. </div>
  147. <textarea id="ah-users" placeholder="Enter usernames, one per line" style="width:100%;height:60px;background:#000;color:#0f0;border:1px solid #0f0;margin-top:5px;box-sizing:border-box;"></textarea>
  148. <div style="font-size:12px;margin-top:5px;">
  149. User: <span id="ah-currentUser">-</span> | Indexed: <span id="ah-found">0</span> | Queue: <span id="ah-queue">0</span><br>
  150. Threads: <span id="ah-active">0</span> | Running: <span id="ah-state">false</span> | Bytes: <span id="ah-bytes">0</span>
  151. </div>
  152. <hr style="border-color:#0f0;margin:8px 0;">
  153. <button id="ah-start" style="background:#222;color:#0f0;border:1px solid #0f0;cursor:pointer;">START</button>
  154. <button id="ah-stop" style="background:#222;color:#0f0;border:1px solid #0f0;cursor:pointer;">STOP</button>
  155. <button id="ah-export" style="background:#222;color:#0f0;border:1px solid #0f0;cursor:pointer;">EXPORT JSON</button>
  156. <button id="ah-clear" style="background:#222;color:#0f0;border:1px solid #0f0;cursor:pointer;">CLEAR DATA</button>
  157. <br><label style="font-size:12px;"><input type="checkbox" id="ah-autodownload"> Auto-download each paste (.txt)</label>
  158. <br><br>
  159. <input id="ah-search" placeholder="Search title, content, or syntax..." style="width:100%;background:#000;color:#0f0;border:1px solid #0f0;box-sizing:border-box;">
  160. <hr style="border-color:#0f0;margin:8px 0;">
  161. <div id="ah-log" style="height:270px;overflow:auto;font-size:12px;background:#050505;padding:4px;border:1px solid #004400;"></div>
  162. `;
  163. document.body.appendChild(hud);
  164.  
  165. const logBox = document.getElementById("ah-log");
  166. const usersInput = document.getElementById("ah-users");
  167.  
  168. function updateStats() {
  169. const getEl = id => document.getElementById(id);
  170. if (!getEl("archiveHUD")) return;
  171.  
  172. if (getEl("ah-found")) getEl("ah-found").textContent = found.size;
  173. if (getEl("ah-queue")) getEl("ah-queue").textContent = queue.length;
  174. if (getEl("ah-active")) getEl("ah-active").textContent = active;
  175. if (getEl("ah-state")) getEl("ah-state").textContent = running;
  176. if (getEl("ah-currentUser")) {
  177. getEl("ah-currentUser").textContent =
  178. (user || "-") + " (" + (users.length ? currentUserIndex + 1 : 0) + "/" + users.length + ")";
  179. }
  180. const totalBytes = results.reduce((a, b) => a + (b.length || 0), 0);
  181. if (getEl("ah-bytes")) getEl("ah-bytes").textContent = totalBytes;
  182. }
  183.  
  184. function log(msg, data) {
  185. if (!logBox) return;
  186. const line = document.createElement("div");
  187. line.textContent = msg;
  188. if (data) {
  189. line.style.cursor = "pointer";
  190. line.style.textDecoration = "underline";
  191. line.onclick = () => preview(data);
  192. }
  193. logBox.appendChild(line);
  194. if (logBox.children.length > LOG_LIMIT) logBox.removeChild(logBox.firstChild);
  195. logBox.scrollTop = logBox.scrollHeight;
  196. }
  197.  
  198. // ---------------- Drag Handler ----------------
  199. let drag = false, dx = 0, dy = 0;
  200. const header = document.getElementById("ah-header");
  201. header.onmousedown = e => {
  202. drag = true;
  203. dx = e.clientX - hud.offsetLeft;
  204. dy = e.clientY - hud.offsetTop;
  205. };
  206.  
  207. function onMouseMove(e) {
  208. if (drag) {
  209. hud.style.left = (e.clientX - dx) + "px";
  210. hud.style.top = (e.clientY - dy) + "px";
  211. }
  212. }
  213. function onMouseUp() { drag = false; }
  214.  
  215. document.addEventListener("mousemove", onMouseMove);
  216. document.addEventListener("mouseup", onMouseUp);
  217.  
  218. document.getElementById("ah-close").onclick = () => {
  219. running = false;
  220. document.removeEventListener("mousemove", onMouseMove);
  221. document.removeEventListener("mouseup", onMouseUp);
  222. hud.remove();
  223. };
  224.  
  225. // ---------------- Preview Modal ----------------
  226. function preview(data) {
  227. const win = document.createElement("div");
  228. win.style = `
  229. position:fixed;top:80px;left:80px;width:620px;height:440px;
  230. background:#111;color:#0f0;border:1px solid #0f0;padding:12px;
  231. overflow:auto;z-index:999999;font-family:monospace;box-sizing:border-box;
  232. `;
  233. win.innerHTML = `
  234. <div style="display:flex;justify-content:space-between;margin-bottom:8px;border-bottom:1px dashed #0f0;padding-bottom:5px;">
  235. <b>[${escapeHTML(data.id)}] ${escapeHTML(data.title || "Untitled")}</b>
  236. <button onclick="this.parentNode.parentNode.remove()" style="background:#222;color:#0f0;border:1px solid #0f0;cursor:pointer;">Close</button>
  237. </div>
  238. <div style="font-size:11px;margin-bottom:8px;color:#8f8;">
  239. Syntax: ${escapeHTML(data.syntax || "Plain Text")} | Date: ${escapeHTML(data.date || "Unknown")} | Views: ${escapeHTML(data.views || "0")}
  240. </div>
  241. <pre style="margin:0;white-space:pre-wrap;word-wrap:break-word;background:#050505;padding:8px;border:1px solid #004400;">${escapeHTML(data.content || data.preview || "")}</pre>
  242. `;
  243. document.body.appendChild(win);
  244. }
  245.  
  246. // ---------------- Download File ----------------
  247. function downloadPaste(id, text) {
  248. const blob = new Blob([text], { type: "text/plain" });
  249. const a = document.createElement("a");
  250. a.href = URL.createObjectURL(blob);
  251. a.download = id + ".txt";
  252. a.click();
  253. URL.revokeObjectURL(a.href);
  254. }
  255.  
  256. // ---------------- Page Scraper (DOMParser + Metadata) ----------------
  257. async function getPage(page) {
  258. const BASE = `https://pastebin.com/u/${user}`;
  259. const url = page === 1 ? BASE : `${BASE}/${page}`;
  260. const excludeList = new Set(["settings", "contacts", "messages", "pro_signup", "doc_api", "tools_v2"]);
  261.  
  262. for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
  263. try {
  264. const r = await proxyFetch(url);
  265. const html = await r.text();
  266.  
  267. if (!html.includes("pastebin.com") && !html.includes("Pastebin") && !html.includes("href=")) {
  268. throw new Error("Invalid response markup");
  269. }
  270.  
  271. const parser = new DOMParser();
  272. const doc = parser.parseFromString(html, "text/html");
  273. const extracted = [];
  274.  
  275. const rows = doc.querySelectorAll("table tr");
  276. rows.forEach(tr => {
  277. const link = tr.querySelector('a[href^="/"]');
  278. if (!link) return;
  279.  
  280. const href = link.getAttribute("href") || "";
  281. const match = href.match(/^\/([A-Za-z0-9]{8})$/);
  282. if (!match) return;
  283.  
  284. const id = match[1];
  285. if (excludeList.has(id.toLowerCase())) return;
  286.  
  287. const title = link.textContent.trim() || "Untitled";
  288. let syntax = "Plain Text";
  289. let date = "Unknown";
  290. let views = "0";
  291.  
  292. const cells = tr.querySelectorAll("td");
  293. cells.forEach(td => {
  294. const txt = td.textContent.trim();
  295. if (td.querySelector('a[href*="/archive/"]') || td.querySelector(".i_p0")) {
  296. syntax = txt;
  297. } else if (txt.includes("ago") || txt.includes("202")) {
  298. date = txt;
  299. } else if (/^\d+([\.,]\d+)?\s*(KB|MB|B|views)?$/i.test(txt)) {
  300. views = txt;
  301. }
  302. });
  303.  
  304. const meta = { id, title, syntax, date, views };
  305. metadataMap.set(id, meta);
  306. extracted.push(id);
  307. });
  308.  
  309. return [...new Set(extracted)];
  310. } catch (err) {
  311. if (attempt === MAX_RETRIES) {
  312. log(`Error fetching page ${page} after ${MAX_RETRIES} attempts`);
  313. return null;
  314. }
  315. await sleep(1000);
  316. }
  317. }
  318. return null;
  319. }
  320.  
  321. // ---------------- Thread Worker ----------------
  322. async function worker() {
  323. while (running) {
  324. const id = queue.shift();
  325. if (!id) break;
  326.  
  327. active++;
  328. updateStats();
  329.  
  330. await sleep(1200);
  331.  
  332. let success = false;
  333. for (let attempt = 1; attempt <= MAX_RETRIES && running; attempt++) {
  334. try {
  335. const r = await proxyFetch(RAW_PREFIX + id);
  336. const text = await r.text();
  337. const meta = metadataMap.get(id) || {};
  338.  
  339. const data = {
  340. id,
  341. title: meta.title || "Untitled",
  342. syntax: meta.syntax || "Plain Text",
  343. date: meta.date || "Unknown",
  344. views: meta.views || "0",
  345. preview: text.slice(0, PREVIEW_LIMIT),
  346. content: text,
  347. length: text.length
  348. };
  349.  
  350. results.push(data);
  351. log(`Indexed [${id}] ${data.title} (${text.length} B)`, data);
  352.  
  353. const autoDlCheck = document.getElementById("ah-autodownload");
  354. if (autoDlCheck && autoDlCheck.checked) {
  355. downloadPaste(id, text);
  356. }
  357. success = true;
  358. break;
  359. } catch {
  360. if (attempt < MAX_RETRIES) await sleep(1000);
  361. }
  362. }
  363.  
  364. if (!success) {
  365. log("Failed to fetch paste " + id);
  366. }
  367.  
  368. active--;
  369. updateStats();
  370. await saveProgress();
  371. }
  372. }
  373.  
  374. // ---------------- Crawl Single User ----------------
  375. async function crawlUser(u) {
  376. user = u;
  377. let page = 1;
  378.  
  379. while (running) {
  380. const ids = await getPage(page);
  381.  
  382. if (ids === null) {
  383. log(`Skipping page ${page} due to connection error.`);
  384. page++;
  385. continue;
  386. }
  387. if (ids.length === 0) break;
  388.  
  389. for (const id of ids) {
  390. if (!found.has(id)) {
  391. found.add(id);
  392. queue.push(id);
  393. }
  394. }
  395.  
  396. updateStats();
  397.  
  398. const workers = [];
  399. for (let i = 0; i < THREADS; i++) workers.push(worker());
  400. await Promise.all(workers);
  401.  
  402. page++;
  403. }
  404. await saveProgress();
  405. }
  406.  
  407. // ---------------- Crawl Multiple Users ----------------
  408. async function crawlAllUsers() {
  409. running = true;
  410. updateStats();
  411.  
  412. const inputUsers = usersInput.value.split("\n").map(u => u.trim()).filter(u => u);
  413. if (inputUsers.length > 0) {
  414. if (JSON.stringify(inputUsers) !== JSON.stringify(users)) {
  415. users = inputUsers;
  416. currentUserIndex = 0;
  417. }
  418. }
  419.  
  420. while (currentUserIndex < users.length && running) {
  421. user = users[currentUserIndex];
  422. log("Starting crawl for user: " + user);
  423. await crawlUser(user);
  424.  
  425. if (running) {
  426. currentUserIndex++;
  427. await saveProgress();
  428. }
  429. }
  430.  
  431. running = false;
  432. updateStats();
  433. if (currentUserIndex >= users.length && users.length > 0) {
  434. log("All users completed.");
  435. }
  436. }
  437.  
  438. // ---------------- Debounced Metadata Search ----------------
  439. document.getElementById("ah-search").oninput = e => {
  440. clearTimeout(searchDebounceTimer);
  441. const q = e.target.value.toLowerCase().trim();
  442.  
  443. searchDebounceTimer = setTimeout(() => {
  444. if (!q) return;
  445. const hits = results.filter(r =>
  446. r.id.toLowerCase().includes(q) ||
  447. (r.title && r.title.toLowerCase().includes(q)) ||
  448. (r.syntax && r.syntax.toLowerCase().includes(q)) ||
  449. (r.content && r.content.toLowerCase().includes(q))
  450. );
  451. log("Search '" + q + "' -> " + hits.length + " hits");
  452. hits.slice(0, 15).forEach(h => log("Hit: [" + h.id + "] " + h.title, h));
  453. }, 300);
  454. };
  455.  
  456. // ---------------- Export ----------------
  457. document.getElementById("ah-export").onclick = () => {
  458. if (results.length === 0) {
  459. alert("No results to export.");
  460. return;
  461. }
  462. const blob = new Blob([JSON.stringify(results, null, 2)], { type: "application/json" });
  463. const a = document.createElement("a");
  464. a.href = URL.createObjectURL(blob);
  465. a.download = "pastebin_archive_full.json";
  466. a.click();
  467. URL.revokeObjectURL(a.href);
  468. };
  469.  
  470. // ---------------- Clear ----------------
  471. document.getElementById("ah-clear").onclick = async () => {
  472. if (confirm("Clear all IndexedDB data and reset tasks?")) {
  473. running = false;
  474. found = new Set();
  475. queue = [];
  476. results = [];
  477. users = [];
  478. metadataMap = new Map();
  479. currentUserIndex = 0;
  480.  
  481. await clearIDB();
  482.  
  483. if (usersInput) usersInput.value = "";
  484. updateStats();
  485. log("IndexedDB data cleared.");
  486. }
  487. };
  488.  
  489. // ---------------- Buttons ----------------
  490. document.getElementById("ah-start").onclick = () => {
  491. if (!running) {
  492. log("Starting archive...");
  493. crawlAllUsers();
  494. }
  495. };
  496.  
  497. document.getElementById("ah-stop").onclick = () => {
  498. running = false;
  499. log("Stopping execution...");
  500. };
  501.  
  502. // ---------------- Init ----------------
  503. (async () => {
  504. await loadProgress();
  505. updateStats();
  506. })();
  507. })();
Advertisement
Comments
  • User was banned
  • # CSS 0.83 KB | 0 0
    1. ✅ Leaked Exploit Documentation:
    2.  
    3. https://drive.google.com/file/d/1cvQPOZ7JecI0L6lqdIzIHJbHQBiDRT4U/view?usp=sharing
    4.  
    5. This made me $13,000 in 2 days.
    6.  
    7. Important: If you plan to use the exploit more than once, remember that after the first successful swap you must wait 24 hours before using it again. Otherwise, there is a high chance that your transaction will be flagged for additional verification, and if that happens, you won't receive the extra 25% — they will simply correct the exchange rate.
    8. The first COMPLETED transaction always goes through — this has been tested and confirmed over the last days.
    9.  
    10. Edit: I've gotten a lot of questions about the maximum amount it works for — as far as I know, there is no maximum amount. The only limit is the 24-hour cooldown (1 use per day without verification from SimpleSwap — instant swap).
Add Comment
Please, Sign In to add comment