您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
文字通り、Discordでログイン中のTOKENを取得します。
// ==UserScript== // @name TOKEN取得 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 文字通り、Discordでログイン中のTOKENを取得します。 // @author Freeze // @match https://discord.com/* // @grant unsafeWindow // @license You can modify as long as you credit me // ==/UserScript== (function() { 'use strict'; const STORAGE_KEY = 'authorizationExtractorSettings'; /** * 設定を localStorage から読み込む * 戻り値例: * { * top: '10px', * left: '10px', * width: '320px', * height: '220px', * showToken: false, * isVisible: false * } */ function loadSettings() { try { const raw = window.localStorage.getItem(STORAGE_KEY); if (!raw) return null; return JSON.parse(raw); } catch (e) { console.warn('Failed to load settings:', e); return null; } } /** * 設定を localStorage に保存 */ function saveSettings(settings) { try { window.localStorage.setItem(STORAGE_KEY, JSON.stringify(settings)); } catch (e) { console.warn('Failed to save settings:', e); } } /** * トークンをマスク表示する関数 */ function maskToken(token) { return '*'.repeat(token.length); } /** * localStorage からトークンを取得して返す */ function getToken() { const storage = (typeof unsafeWindow !== 'undefined' && unsafeWindow.localStorage) ? unsafeWindow.localStorage : window.localStorage; let raw = null; try { raw = storage.getItem('token'); } catch (e) { console.warn('Unable to read from storage:', e); } if (raw) { return raw.slice(1, -1); } return null; } /** * 要素をドラッグ可能にする関数 * ヘッダー部分を掴んでドラッグし、mouseup時に saveCallback() を呼ぶ */ function makeElementDraggable(el, saveCallback) { el.addEventListener('mousedown', function(event) { if (event.target.closest('.header-bar')) { event.preventDefault(); let shiftX = event.clientX - el.getBoundingClientRect().left; let shiftY = event.clientY - el.getBoundingClientRect().top; function moveAt(pageX, pageY) { const newLeft = pageX - shiftX; const newTop = pageY - shiftY; el.style.left = Math.min(Math.max(0, newLeft), window.innerWidth - el.offsetWidth) + 'px'; el.style.top = Math.min(Math.max(0, newTop), window.innerHeight - el.offsetHeight) + 'px'; } function onMouseMove(event) { moveAt(event.pageX, event.pageY); } document.addEventListener('mousemove', onMouseMove); function onMouseUp() { document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); saveCallback(); } document.addEventListener('mouseup', onMouseUp); } }); el.ondragstart = function() { return false; }; } /** * UI を作成し、container 要素を返す */ function createUI() { const defaultWidth = '320px'; const defaultHeight = '220px'; const settings = loadSettings() || {}; // コンテナ const container = document.createElement('div'); container.id = 'tokenContainer'; container.style.position = 'fixed'; container.style.top = settings.top || '10px'; container.style.left = settings.left || '10px'; container.style.width = settings.width || defaultWidth; container.style.height = settings.height || defaultHeight; container.style.backgroundColor= 'rgba(30, 30, 30, 0.95)'; container.style.color = '#ffffff'; container.style.borderRadius = '8px'; container.style.boxShadow = '0 6px 20px rgba(0, 0, 0, 0.6)'; container.style.resize = 'both'; container.style.overflow = 'auto'; container.style.zIndex = '10000'; container.style.fontFamily = 'Arial, sans-serif'; // 初期表示は loadSettings().isVisible に従う。未定義なら非表示 container.style.display = settings.isVisible ? 'block' : 'none'; document.body.appendChild(container); // ヘッダー(ドラッグ用バー) const headerBar = document.createElement('div'); headerBar.classList.add('header-bar'); headerBar.style.width = '100%'; headerBar.style.height = '30px'; headerBar.style.cursor = 'move'; headerBar.style.backgroundColor = '#2c2f33'; headerBar.style.borderTopLeftRadius = '8px'; headerBar.style.borderTopRightRadius = '8px'; headerBar.style.display = 'flex'; headerBar.style.alignItems = 'center'; headerBar.style.justifyContent = 'space-between'; headerBar.style.padding = '0 10px'; headerBar.style.boxSizing = 'border-box'; container.appendChild(headerBar); // タイトル const title = document.createElement('span'); title.textContent = 'Freeze - TOKEN取得'; title.style.fontSize = '14px'; title.style.fontWeight = '600'; title.style.userSelect = 'none'; headerBar.appendChild(title); // 閉じるボタン const closeBtn = document.createElement('span'); closeBtn.textContent = '✕'; closeBtn.style.cursor = 'pointer'; closeBtn.style.fontSize = '14px'; closeBtn.style.padding = '2px 6px'; closeBtn.style.borderRadius = '4px'; closeBtn.style.userSelect = 'none'; closeBtn.style.transition = 'background-color 0.2s'; closeBtn.addEventListener('mouseenter', () => { closeBtn.style.backgroundColor = '#ff4d4d'; }); closeBtn.addEventListener('mouseleave', () => { closeBtn.style.backgroundColor = 'transparent'; }); closeBtn.addEventListener('click', () => { container.style.display = 'none'; persistSettings(); }); headerBar.appendChild(closeBtn); // 本文エリア const bodyWrapper = document.createElement('div'); bodyWrapper.style.padding = '12px'; bodyWrapper.style.boxSizing = 'border-box'; container.appendChild(bodyWrapper); // トークン表示 const tokenDisplay = document.createElement('code'); tokenDisplay.style.whiteSpace = 'pre-wrap'; tokenDisplay.style.wordBreak = 'break-word'; tokenDisplay.style.display = 'block'; tokenDisplay.style.marginBottom = '12px'; tokenDisplay.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; tokenDisplay.style.color = '#00FF00'; tokenDisplay.style.padding = '10px'; tokenDisplay.style.borderRadius = '4px'; tokenDisplay.style.fontSize = '13px'; tokenDisplay.textContent = 'Failed acquisition. Press “Refresh” to try again.'; bodyWrapper.appendChild(tokenDisplay); // ボタンエリア const buttonWrapper = document.createElement('div'); buttonWrapper.style.display = 'flex'; buttonWrapper.style.justifyContent = 'space-between'; buttonWrapper.style.alignItems = 'center'; buttonWrapper.style.gap = '10px'; bodyWrapper.appendChild(buttonWrapper); // 左ボタン群 const leftButtons = document.createElement('div'); leftButtons.style.display = 'flex'; leftButtons.style.gap = '8px'; buttonWrapper.appendChild(leftButtons); // Copy ボタン const copyButton = document.createElement('button'); copyButton.textContent = 'Copy'; copyButton.style.padding = '6px 14px'; copyButton.style.backgroundColor = '#7289da'; copyButton.style.color = '#ffffff'; copyButton.style.border = 'none'; copyButton.style.borderRadius = '4px'; copyButton.style.cursor = 'pointer'; copyButton.style.transition = 'background-color 0.2s, transform 0.1s'; copyButton.addEventListener('mouseenter', () => { copyButton.style.backgroundColor = '#667bc4'; }); copyButton.addEventListener('mouseleave', () => { copyButton.style.backgroundColor = '#7289da'; }); copyButton.addEventListener('mousedown', () => { copyButton.style.transform = 'scale(0.95)'; }); copyButton.addEventListener('mouseup', () => { copyButton.style.transform = 'scale(1)'; }); leftButtons.appendChild(copyButton); copyButton.addEventListener('click', function() { const dummy = document.createElement('textarea'); document.body.appendChild(dummy); dummy.value = tokenDisplay.getAttribute('data-token') || ''; dummy.select(); document.execCommand('copy'); document.body.removeChild(dummy); copyButton.textContent = 'Copied!'; setTimeout(() => { copyButton.textContent = 'Copy'; }, 1000); }); // Refresh ボタン const refreshButton = document.createElement('button'); refreshButton.textContent = 'Refresh'; refreshButton.style.padding = '6px 14px'; refreshButton.style.backgroundColor = '#ffa500'; refreshButton.style.color = '#ffffff'; refreshButton.style.border = 'none'; refreshButton.style.borderRadius = '4px'; refreshButton.style.cursor = 'pointer'; refreshButton.style.transition = 'background-color 0.2s, transform 0.1s'; refreshButton.addEventListener('mouseenter', () => { refreshButton.style.backgroundColor = '#e59400'; }); refreshButton.addEventListener('mouseleave', () => { refreshButton.style.backgroundColor = '#ffa500'; }); refreshButton.addEventListener('mousedown', () => { refreshButton.style.transform = 'scale(0.95)'; }); refreshButton.addEventListener('mouseup', () => { refreshButton.style.transform = 'scale(1)'; }); leftButtons.appendChild(refreshButton); // Show/Hide ボタン const toggleButton = document.createElement('button'); toggleButton.textContent = settings.showToken ? 'Hide' : 'Show'; toggleButton.style.padding = '6px 14px'; toggleButton.style.backgroundColor = settings.showToken ? '#f04747' : '#43b581'; toggleButton.style.color = '#ffffff'; toggleButton.style.border = 'none'; toggleButton.style.borderRadius = '4px'; toggleButton.style.cursor = 'pointer'; toggleButton.style.transition = 'opacity 0.2s'; toggleButton.addEventListener('mouseenter', () => { toggleButton.style.opacity = '0.8'; }); toggleButton.addEventListener('mouseleave', () => { toggleButton.style.opacity = '1'; }); buttonWrapper.appendChild(toggleButton); /** * 設定を保存する */ function persistSettings() { const current = { top: container.style.top, left: container.style.left, width: container.style.width, height: container.style.height, showToken: toggleButton.textContent === 'Hide', isVisible: container.style.display === 'block' }; saveSettings(current); } // 初回表示:保存された showToken に従いトークンを表示 const initialRaw = getToken(); if (initialRaw) { tokenDisplay.setAttribute('data-token', initialRaw); if (settings.showToken) { tokenDisplay.textContent = initialRaw; } else { tokenDisplay.textContent = maskToken(initialRaw); } } // Refresh ボタン押下時 refreshButton.addEventListener('click', () => { refreshButton.disabled = true; refreshButton.textContent = 'Refreshing…'; setTimeout(() => { const raw = getToken(); if (raw) { tokenDisplay.setAttribute('data-token', raw); if (toggleButton.textContent === 'Hide') { tokenDisplay.textContent = raw; } else { tokenDisplay.textContent = maskToken(raw); } } else { tokenDisplay.textContent = 'Failed acquisition. Press “Refresh”.'; tokenDisplay.removeAttribute('data-token'); } refreshButton.textContent = 'Refresh'; refreshButton.disabled = false; }, 100); }); // Show/Hide トグル押下時 toggleButton.addEventListener('click', () => { const raw = tokenDisplay.getAttribute('data-token'); if (!raw) return; if (toggleButton.textContent === 'Show') { tokenDisplay.textContent = raw; toggleButton.textContent = 'Hide'; toggleButton.style.backgroundColor = '#f04747'; } else { tokenDisplay.textContent = maskToken(raw); toggleButton.textContent = 'Show'; toggleButton.style.backgroundColor = '#43b581'; } persistSettings(); }); // ドラッグ可能化(ヘッダーのみ) makeElementDraggable(container, persistSettings); // リサイズ終了後に設定保存 container.addEventListener('mouseup', () => { persistSettings(); }); // container に保存用メソッドをアタッチ(外部から呼べるように) container.persistSettings = persistSettings; return { container }; } /** * 「TOKEN取得」ボタンを作成し、クリックで UI の表示・非表示を切り替える */ function createFetchButton(container) { const fetchBtn = document.createElement('button'); fetchBtn.textContent = 'TOKEN取得'; fetchBtn.style.position = 'fixed'; fetchBtn.style.bottom = '20px'; fetchBtn.style.right = '20px'; fetchBtn.style.padding = '10px 20px'; fetchBtn.style.backgroundColor= '#5865f2'; fetchBtn.style.color = '#ffffff'; fetchBtn.style.border = 'none'; fetchBtn.style.borderRadius = '6px'; fetchBtn.style.cursor = 'pointer'; fetchBtn.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.3)'; fetchBtn.style.fontSize = '14px'; fetchBtn.style.fontWeight = '600'; fetchBtn.style.zIndex = '10001'; fetchBtn.style.transition = 'background-color 0.2s, transform 0.1s'; fetchBtn.addEventListener('mouseenter', () => { fetchBtn.style.backgroundColor = '#4953c8'; }); fetchBtn.addEventListener('mouseleave', () => { fetchBtn.style.backgroundColor = '#5865f2'; fetchBtn.style.transform = 'scale(1)'; }); fetchBtn.addEventListener('mousedown', () => { fetchBtn.style.transform = 'scale(0.95)'; }); fetchBtn.addEventListener('mouseup', () => { fetchBtn.style.transform = 'scale(1)'; }); document.body.appendChild(fetchBtn); fetchBtn.addEventListener('click', () => { const isHidden = container.style.display === 'none'; container.style.display = isHidden ? 'block' : 'none'; // 表示状態が変わったので保存 container.persistSettings(); }); } // ──────────────────────────────────────────────────── // スクリプト本体 // ──────────────────────────────────────────────────── // UI 作成 const { container } = createUI(); // 「TOKEN取得」ボタン作成 createFetchButton(container); // 保存設定があれば表示状態を復元(初期 loadSettings() 内で適用済) // 特に何もしなくてOK })();