您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
For each account: Home -> Login -> My Links -> Export, then back to Home for next
当前为
// ==UserScript== // @name SecureMyPass Bare Bot (home-loop with static XPath) // @namespace https://securemypass.com/ // @version 1.6 // @description For each account: Home -> Login -> My Links -> Export, then back to Home for next // @match https://securemypass.com/* // @run-at document-end // @grant none // ==/UserScript== (function () { 'use strict'; if (window.__SMP_HOME_LOOP__) return; window.__SMP_HOME_LOOP__ = true; // --- UI --- const box = document.createElement('div'); box.style = ` position:fixed;bottom:20px;right:20px;z-index:2147483647; background:#111;color:#eee;padding:10px;border:1px solid #333;border-radius:6px; font:13px/1.4 system-ui;width:260px `; box.innerHTML = ` <h3 style="margin:0 0 6px;font-size:14px">SMP Bot</h3> <label>Number of Accounts</label> <input id="smpCount" type="number" value="1" min="1" style="width:100%;margin:4px 0"/> <div id="smpCreds"></div> <button id="smpStart" style="margin-top:6px;width:100%">Start</button> <div id="smpLog" style="margin-top:6px;font-size:12px;color:#aaa">Idle</div> `; document.body.appendChild(box); const el = (sel) => box.querySelector(sel); const log = (m) => (el('#smpLog').textContent = m); const renderCreds = () => { const n = parseInt(el('#smpCount').value || '1', 10); const wrap = document.createElement('div'); for (let i = 0; i < n; i++) { const d = document.createElement('div'); d.style = 'border:1px solid #333;padding:4px;margin:4px 0;border-radius:4px'; d.innerHTML = ` <div>Account ${i + 1}</div> <input class="smpUser" type="text" placeholder="Username" style="width:100%"/> <input class="smpPass" type="password" placeholder="Password" style="width:100%"/> `; wrap.appendChild(d); } el('#smpCreds').innerHTML = ''; el('#smpCreds').appendChild(wrap); }; renderCreds(); el('#smpCount').addEventListener('input', renderCreds); // --- Utils --- const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); const xp = (path) => document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; // --- State in sessionStorage --- const S = { get queue() { try { return JSON.parse(sessionStorage.getItem('SMP_QUEUE') || '[]'); } catch { return []; } }, set queue(v) { sessionStorage.setItem('SMP_QUEUE', JSON.stringify(v || [])); }, get idx() { return parseInt(sessionStorage.getItem('SMP_IDX') || '0', 10); }, set idx(v) { sessionStorage.setItem('SMP_IDX', String(v)); }, get phase() { return sessionStorage.getItem('SMP_PHASE') || 'IDLE'; }, set phase(v) { sessionStorage.setItem('SMP_PHASE', v); }, clear() { sessionStorage.removeItem('SMP_QUEUE'); sessionStorage.removeItem('SMP_IDX'); sessionStorage.removeItem('SMP_PHASE'); } }; // --- Steps --- async function doHomeStep() { if (location.pathname !== '/') { log('Going to Home…'); location.href = 'https://securemypass.com/'; return; } log('Proceeding to Login…'); S.phase = 'LOGIN'; location.href = 'https://securemypass.com/login'; } async function doLoginStep(u, p) { log('Typing username…'); const uEl = xp('//*[@id="loginUsername"]'); if (!uEl) throw new Error('Username field not found'); uEl.value = u; await sleep(500); log('Clicking continue…'); const btn1 = xp('//*[@id="root"]/div[1]/main/div/div/div/div/div[1]/div/form/div[2]/button'); btn1?.click(); await sleep(1500); log('Typing password…'); const pEl = xp('//*[@id="loginPassword"]'); pEl.value = p; await sleep(500); log('Clicking login…'); const btn2 = xp('//*[@id="root"]/div[1]/main/div/div/div/div/div[1]/div/form/div[2]/button'); btn2?.click(); await sleep(2500); S.phase = 'EXPORT'; log('Going to My Links…'); location.href = 'https://securemypass.com/my-links'; } async function doExportStep() { log('Waiting for Export button…'); const t0 = performance.now(); let btn; while (!(btn = xp('//*[@id=":r24:"]'))) { // <-- direct XPath if (performance.now() - t0 > 20000) throw new Error('Export button not found'); await sleep(500); } await sleep(800); btn.click(); log('Export clicked (check downloads).'); await sleep(2000); const next = S.idx + 1; if (next < S.queue.length) { S.idx = next; S.phase = 'HOME'; log(`Next account ${next + 1}/${S.queue.length}…`); location.href = 'https://securemypass.com/'; } else { log('All done.'); S.clear(); } } // --- Resume on load --- (async function resume() { const phase = S.phase; if (phase === 'IDLE') return; const q = S.queue, i = S.idx, acct = q[i]; if (!acct) { S.clear(); log('Idle'); return; } if (phase === 'HOME') return doHomeStep(); if (phase === 'LOGIN' && location.pathname.startsWith('/login')) return doLoginStep(acct.username, acct.password); if (phase === 'EXPORT' && location.pathname.startsWith('/my-links')) return doExportStep(); })(); // --- Start button seeds state --- el('#smpStart').onclick = async () => { const users = [...box.querySelectorAll('.smpUser')].map((i) => i.value.trim()); const passes = [...box.querySelectorAll('.smpPass')].map((i) => i.value); const queue = users.map((u, idx) => ({ username: u, password: passes[idx] })).filter(a => a.username && a.password); if (!queue.length) { log('Enter credentials'); return; } S.queue = queue S.idx = 0; S.phase = 'HOME'; log(`Starting account 1/${queue.length}…`); location.href = 'https://securemypass.com/'; }; })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址