您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
改良版:自動で学籍番号、パスワード、マトリクス暗号を入力し、低遅延で自動送信します
// ==UserScript== // @name 東京科学大学理工学部ポータル自動認証システム // @namespace http://tampermonkey.net/ // @version 0.1 // @description 改良版:自動で学籍番号、パスワード、マトリクス暗号を入力し、低遅延で自動送信します // @author https://github.com/catyyy // @match https://portal.nap.gsic.titech.ac.jp/GetAccess/Login* // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js // @run-at document-end // @license MIT // ==/UserScript== (function($) { 'use strict'; // スタイル定義 GM_addStyle(` .auth-helper { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #ffffff; padding: 2rem; border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,0.2); z-index: 99999; min-width: 600px; font-family: 'Segoe UI', sans-serif; } .matrix-container { display: grid; grid-template-columns: auto 1fr; gap: 10px; margin: 1rem 0; } .row-labels { display: grid; gap: 5px; grid-template-rows: repeat(7, 45px); } .row-label { display: flex; align-items: center; justify-content: center; background: #f5f5f5; border-radius: 4px; } .matrix-grid { display: grid; grid-template-columns: repeat(10, 45px); grid-auto-rows: 45px; gap: 5px; } .matrix-input { width: 100%; height: 100%; border: 2px solid #ddd; text-align: center; font-size: 16px; text-transform: uppercase; transition: all 0.3s; border-radius: 4px; } .matrix-input:focus { border-color: #2196F3; background: #e3f2fd; outline: none; box-shadow: 0 2px 6px rgba(33,150,243,0.3); } .col-labels { display: grid; grid-template-columns: repeat(10, 45px); gap: 5px; margin-bottom: 5px; } .col-label { text-align: center; font-weight: bold; color: #666; } .auth-toast { position: fixed; top: 20px; right: 20px; padding: 12px 24px; border-radius: 8px; color: white; background: #00C851; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 99999; animation: slideIn 0.3s; } .auth-toast.error { background: #ff4444; } @keyframes slideIn { from { transform: translateX(100%); } to { transform: translateX(0); } } .save-footer { margin-top: 1rem; text-align: right; } `); // ストレージシステム const Storage = { getCredentials: () => { try { return JSON.parse(GM_getValue('auth_creds', '{}')); } catch (e) { showToast('設定の読み込みに失敗しました', 'error'); return {}; } }, saveCredentials: (data) => { try { GM_setValue('auth_creds', JSON.stringify(data)); return true; } catch (e) { showToast('保存に失敗しました: ストレージ容量不足', 'error'); return false; } }, getMatrixMap: () => { try { const map = JSON.parse(GM_getValue('matrix_map', '{}')); return Object.keys(map).length > 0 ? map : null; } catch (e) { return null; } }, saveMatrixMap: (map) => { try { GM_setValue('matrix_map', JSON.stringify(map)); return true; } catch (e) { showToast('マトリクス設定の保存に失敗しました', 'error'); return false; } }, isConfigured: () => { const creds = Storage.getCredentials(); return !!creds.username && !!Storage.getMatrixMap(); } }; // UIコンポーネント:トーストメッセージ表示 function showToast(message, type = 'info') { const toast = $(`<div class="auth-toast ${type === 'error' ? 'error' : ''}">${message}</div>`); $('body').append(toast); setTimeout(() => toast.fadeOut(), 2000); } // ログイン情報設定ウィザード function showCredentialWizard() { const creds = Storage.getCredentials() || {}; const html = ` <div class="auth-helper"> <h3>🔑 ログイン情報設定</h3> <input type="text" id="cred-username" placeholder="学籍番号" value="${creds.username || ''}" style="margin: 8px 0; width: 100%; padding: 8px;"> <input type="password" id="cred-password" placeholder="パスワード" value="${creds.password || ''}" style="margin: 8px 0; width: 100%; padding: 8px;"> <div class="save-footer"> <button id="save-credentials" style="background: #2196F3; color: white; padding: 8px 16px;"> 保存して閉じる </button> </div> </div> `; const $wrapper = $(html).appendTo('body'); $('#save-credentials').on('click', function() { const data = { username: $('#cred-username').val().trim(), password: $('#cred-password').val().trim() }; if (!data.username || !data.password) { showToast('すべての項目を入力してください', 'error'); return; } if (Storage.saveCredentials(data)) { showToast('正常に保存されました'); $wrapper.remove(); if (!Storage.getMatrixMap()) { showMatrixEditor(true); } } }); } // マトリクスエディタ function showMatrixEditor(initialSetup = false) { let currentMap = Storage.getMatrixMap() || {}; const colLabels = ['A','B','C','D','E','F','G','H','I','J']; let gridHTML = ''; gridHTML += `<div class="col-labels">`; colLabels.forEach(label => gridHTML += `<div class="col-label">${label}</div>`); gridHTML += `</div>`; gridHTML += `<div class="matrix-container">`; gridHTML += `<div class="row-labels">`; for (let row = 1; row <= 7; row++) { gridHTML += `<div class="row-label">${row}</div>`; } gridHTML += `</div>`; gridHTML += `<div class="matrix-grid">`; for (let row = 1; row <= 7; row++) { colLabels.forEach(col => { const key = `${col},${row}`; gridHTML += ` <input type="text" class="matrix-input" data-key="${key}" value="${currentMap[key] || ''}" maxlength="1"> `; }); } gridHTML += `</div></div>`; const html = ` <div class="auth-helper"> <h3>🔢 マトリクス暗号設定</h3> ${gridHTML} <div class="save-footer"> <button id="save-matrix" style="background: #4CAF50; color: white; padding: 8px 16px;"> 保存して閉じる </button> </div> <div style="margin-top:1rem; color:#666; font-size:0.9em;"> ※ 入力後自動で次のセルに移動(方向キーも使用可) </div> </div> `; const $wrapper = $(html).appendTo('body'); const $inputs = $wrapper.find('.matrix-input'); // 入力処理:大文字変換と自動移動 $inputs.on('input', function() { const $input = $(this); const value = $input.val().toUpperCase(); const key = $input.data('key'); if (!/^[A-Z]$/.test(value)) { $input.val(''); return; } currentMap[key] = value; moveToNextCell($input); }); // キーボードナビゲーション $inputs.on('keydown', function(e) { const $input = $(this); const index = $inputs.index($input); const key = e.key.toLowerCase(); const navigation = { arrowright: () => moveFocus(index + 1), arrowleft: () => moveFocus(index - 1), arrowdown: () => moveFocus(index + 10), arrowup: () => moveFocus(index - 10), enter: () => { if (initialSetup) return; moveToNextCell($input); } }; if (navigation[key]) { e.preventDefault(); navigation[key](); } }); // 保存処理 $('#save-matrix').on('click', function() { if (Object.keys(currentMap).length < 10) { showToast('少なくとも10セル以上入力してください', 'error'); return; } if (Storage.saveMatrixMap(currentMap)) { showToast('マトリクス設定を保存しました'); $wrapper.remove(); if (initialSetup) { showToast('初期設定が完了しました'); } } }); $inputs.first().focus(); } // ナビゲーション補助 function moveToNextCell($current) { const index = $('.matrix-input').index($current); moveFocus(index + 1); } function moveFocus(newIndex) { const $inputs = $('.matrix-input'); newIndex = Math.max(0, Math.min(newIndex, $inputs.length - 1)); $inputs.eq(newIndex).focus().select(); } // 自動ログイン:学籍番号とパスワードを入力し、OK ボタンをクリック function autoLogin() { if (!Storage.isConfigured()) { showToast('初期設定が必要です', 'error'); showCredentialWizard(); return; } const creds = Storage.getCredentials(); const $username = $('input[name="usr_name"]'); const $password = $('input[name="usr_password"]'); if ($username.length && $password.length) { $username.val(creds.username); $password.val(creds.password); $('input[name="OK"]').trigger('click'); } } // 自動マトリクス入力:id="authentication" 内の各行を走査し、[B,4] 等のラベルに対応する値を入力 function autoMatrixFill() { const matrixMap = Storage.getMatrixMap(); if (!matrixMap) { showToast('マトリクス設定が未保存です', 'error'); return; } $('#authentication tr').each(function() { const $tr = $(this); const labelText = $tr.find('th').first().text().trim(); const m = labelText.match(/\[\s*([A-J])\s*,\s*(\d)\s*\]/); if (m) { const key = `${m[1]},${m[2]}`; const value = matrixMap[key] || ''; $tr.find('input[type="password"]').val(value); } }); // 入力完了後、500ms 遅延して OK ボタンを自動クリック setTimeout(() => { $('input[name="OK"]').trigger('click'); }, 500); } // 右クリックメニューの登録 GM_registerMenuCommand("⚙️ ログイン情報設定", () => showCredentialWizard()); GM_registerMenuCommand("🔣 マトリクス設定", () => showMatrixEditor()); // ページ読み込み完了時の処理 $(document).ready(function() { if (location.href.includes('Login')) { if (Storage.isConfigured()) { autoLogin(); } else { showCredentialWizard(); } } }); // すべての onLoad 処理完了後、150ms 遅延して自動マトリクス入力と自動送信を実行 window.addEventListener('load', () => { setTimeout(autoMatrixFill, 150); }); })(jQuery);