您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
verification script (buttons fixed: waits for DOM, uses delegation, no eval, pointer-events fixes)
// ==UserScript== // @name Verify kour.io - Fixed Buttons & Gold Badge // @namespace strange_carrot // @version 3.4 // @description verification script (buttons fixed: waits for DOM, uses delegation, no eval, pointer-events fixes) // @author LC // @license CC BY-ND 4.0 // @match https://kour.io/* // @grant GM_addStyle // ==/UserScript== (async function() { 'use strict'; // Wait for document.body to exist (safe insertion) await new Promise(resolve => { if (document.body) return resolve(); const mo = new MutationObserver(() => { if (document.body) { mo.disconnect(); resolve(); } }); mo.observe(document.documentElement || document, { childList: true, subtree: true }); }); // Add styles (ensure pointer events and visibility) GM_addStyle(` #lcVerifyContainer { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; position: fixed; top: 20px; left: 20px; z-index: 2147483647; /* extremely high so nothing overlays it */ background: #1a1a1a; box-shadow: 0 2px 15px rgba(0,0,0,0.35); border-radius: 8px; padding: 15px; width: 260px; border: 1px solid #333; pointer-events: auto !important; } #lcVerifyContainer, #lcVerifyContainer * { pointer-events: auto !important; } #lcVerifyHeader { color: #FFD700; margin-bottom:12px; font-size:16px; font-weight:600; display:flex; justify-content:space-between; align-items:center; } #lcVerifyBtn { background: linear-gradient(135deg,#FFD700,#e6c200); color: black; border: none; padding: 8px 12px; border-radius:6px; font-weight:600; width:100%; cursor:pointer; } #lcVerifyBtn:hover { transform: translateY(-1px); opacity: 0.92; } #lcHideBtn { background:#333; color:#ccc; border:none; padding:5px 8px; border-radius:4px; cursor:pointer; } #lcVerifyStatus { font-size:13px; color:#aaa; margin-top:10px; padding-top:10px; border-top:1px solid #333; text-align:center; } .success { color: #FFD700 !important; } .error { color: #ff4757 !important; } .processing { color: #FFD700 !important; } .hidden { display:none !important; } /* If the site uses a .verify-badge or similar, force its background/fill to gold */ .verify-badge, .verified-icon, .badge-verified, .user-verified { background-color: #FFD700 !important; fill: #FFD700 !important; color: #FFD700 !important; background-image: none !important; } `); // Create the verification panel HTML const panelHTML = ` <div id="lcVerifyContainer" role="dialog" aria-label="LC Verification Panel"> <div id="lcVerifyHeader"> <span>LC Verification</span> <button id="lcHideBtn" type="button" aria-label="Hide verification panel">Hide</button> </div> <button id="lcVerifyBtn" type="button">Verify Account</button> <div id="lcVerifyStatus">Ready to verify</div> </div> `; document.body.insertAdjacentHTML('beforeend', panelHTML); // Grab references (will exist because we just inserted the HTML) const container = document.getElementById('lcVerifyContainer'); const statusText = document.getElementById('lcVerifyStatus'); // Event delegation: listen once on container for clicks container.addEventListener('click', async (evt) => { const btn = evt.target.closest('button'); if (!btn) return; if (btn.id === 'lcHideBtn') { // Toggle hide/show container.classList.toggle('hidden'); btn.textContent = container.classList.contains('hidden') ? 'Show' : 'Hide'; return; } if (btn.id === 'lcVerifyBtn') { // Verify button pressed statusText.textContent = 'Verifying...'; statusText.className = 'processing'; try { const result = await doVerify(); if (result && result.ok) { statusText.textContent = result.message || 'Account verified successfully!'; statusText.className = 'success'; } else { throw result && result.error ? result.error : new Error('Unknown verification failure'); } } catch (err) { console.error('Verification error:', err); statusText.textContent = 'Error: ' + (err && err.message ? err.message : String(err)); statusText.className = 'error'; } } }); // Main verification routine (no eval) async function doVerify() { // If Firebase is present on the page, try to run the real write (only if allowed) if (window.firebase && firebase.auth && firebase.database) { try { const user = firebase.auth().currentUser; if (!user) { return { ok: false, error: new Error('No logged-in user detected (firebase.auth().currentUser is null).') }; } // Optional: check token claims if you use admin/custom claims // const tokenResult = await user.getIdTokenResult(); console.log(tokenResult); // Attempt to write verified flag (will throw if permission denied) // Note: goOffline/goOnline isn't necessary; left out to avoid race issues await firebase.database().ref('users/' + user.uid + '/verified').set(1); // If showUserDetails exists on the page, call it to refresh UI if (typeof window.showUserDetails === 'function') { try { window.showUserDetails(user.email, user); } catch (err) { console.warn('showUserDetails call failed:', err); } } return { ok: true, message: 'Account verified (firebase write succeeded)' }; } catch (err) { // Permission errors or other Firebase issues will surface here return { ok: false, error: err }; } } // If Firebase isn't available: fallback demo behavior -> add a gold badge next to a likely username selector try { const selectors = [ '.player-username', '.username', '.user-name', '.profile-name', '.display-name' ]; let placed = false; for (const sel of selectors) { const el = document.querySelector(sel); if (el) { if (!el.querySelector('.verify-badge-lc')) { const span = document.createElement('span'); span.className = 'verify-badge-lc'; span.setAttribute('aria-hidden', 'true'); span.style.display = 'inline-block'; span.style.width = '20px'; span.style.height = '20px'; span.style.marginLeft = '6px'; span.style.backgroundImage = 'url("data:image/svg+xml;utf8,' + encodeURIComponent('<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#FFFFFF\" d=\"M9 16.2l-3.5-3.5L4 14l5 5 10-10-1.5-1.5L9 16.2z\"/></svg>') + '")'; span.style.backgroundColor = '#FFD700'; span.style.backgroundSize = 'contain'; span.style.backgroundRepeat = 'no-repeat'; el.appendChild(span); placed = true; break; } else { placed = true; break; } } } if (placed) { return { ok: true, message: 'Demo verify: added local gold badge (no firebase present)' }; } else { return { ok: false, error: new Error('Demo verify: could not find username element to attach badge.') }; } } catch (err) { return { ok: false, error: err }; } } // Expose debug helper window.__lcVerifyDebug = { doVerify, panelElement: container, setStatus: (s, cls) => { statusText.textContent = s; statusText.className = cls || ''; } }; console.log('[LC Verify] Panel injected. Buttons wired. Debug helper: window.__lcVerifyDebug'); })();