您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Enhanced learning assistant for Gimkit
// ==UserScript== // @name Gimkit Enhanced Assistant // @namespace Violentmonkey Scripts // @match *://*.gimkit.com/* // @grant none // @version 1.0 // @author CMH // @description Enhanced learning assistant for Gimkit // ==/UserScript== (function() { 'use strict'; // Configuration const config = { highlightCorrectAnswers: true, autoAnswerDelay: 0, // Set to 0 to disable auto-answer showAnswerStats: true, enableKeyboardShortcuts: true }; // Add custom CSS const style = document.createElement('style'); style.textContent = ` .enhanced-assistant-panel { position: fixed; top: 10px; right: 10px; background: rgba(30, 30, 30, 0.9); color: white; border: 2px solid #6c5ce7; border-radius: 8px; padding: 10px; z-index: 9999; max-width: 300px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3); font-family: Arial, sans-serif; transition: all 0.3s ease; } .enhanced-assistant-panel h3 { margin-top: 0; color: #6c5ce7; font-size: 16px; display: flex; justify-content: space-between; align-items: center; } .enhanced-assistant-button { background: #6c5ce7; color: white; border: none; padding: 5px 10px; border-radius: 4px; margin: 5px; cursor: pointer; transition: background 0.2s; } .enhanced-assistant-button:hover { background: #5b4bc4; } .enhanced-assistant-button.active { background: #4a3cb3; box-shadow: inset 0 0 5px rgba(0,0,0,0.3); } .study-notes { margin-top: 10px; border-top: 1px solid #444; padding-top: 10px; } .study-notes textarea { width: 100%; height: 100px; margin-top: 5px; border-radius: 4px; border: 1px solid #444; padding: 5px; background: #222; color: #eee; } .timer-display { font-size: 1.2em; font-weight: bold; margin: 5px 0; text-align: center; } .answer-stats { margin-top: 10px; border-top: 1px solid #444; padding-top: 10px; } .answer-stats-item { display: flex; justify-content: space-between; margin-bottom: 4px; } .answer-stats-item .question { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-right: 10px; } .answer-stats-item .answer { color: #6c5ce7; font-weight: bold; } .hidden { display: none; } .correct-answer { box-shadow: 0 0 0 2px #4CAF50 !important; position: relative; } .correct-answer::after { content: "✓"; position: absolute; top: 5px; right: 5px; background: #4CAF50; color: white; width: 20px; height: 20px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; } .settings-section { margin-top: 10px; border-top: 1px solid #444; padding-top: 10px; } .settings-item { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; } .toggle-switch { position: relative; display: inline-block; width: 40px; height: 20px; } .toggle-switch input { opacity: 0; width: 0; height: 0; } .toggle-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #444; transition: .4s; border-radius: 20px; } .toggle-slider:before { position: absolute; content: ""; height: 16px; width: 16px; left: 2px; bottom: 2px; background-color: white; transition: .4s; border-radius: 50%; } input:checked + .toggle-slider { background-color: #6c5ce7; } input:checked + .toggle-slider:before { transform: translateX(20px); } .delay-input { width: 50px; background: #222; color: white; border: 1px solid #444; border-radius: 4px; padding: 2px 5px; } .keyboard-shortcuts { margin-top: 10px; border-top: 1px solid #444; padding-top: 10px; font-size: 12px; } .keyboard-shortcut-item { display: flex; justify-content: space-between; margin-bottom: 4px; } .keyboard-shortcut-item .key { background: #333; padding: 2px 6px; border-radius: 3px; border: 1px solid #555; } .made-by { font-size: 10px; opacity: 0.7; text-align: center; margin-top: 10px; border-top: 1px solid #444; padding-top: 5px; } `; document.head.appendChild(style); // Create the assistant panel const panel = document.createElement('div'); panel.className = 'enhanced-assistant-panel'; panel.innerHTML = ` <h3> <span>Enhanced Assistant</span> <span class="version" style="font-size: 10px; opacity: 0.7;">v1.0</span> </h3> <div class="button-container"> <button class="enhanced-assistant-button toggle-notes">Notes</button> <button class="enhanced-assistant-button toggle-timer">Timer</button> <button class="enhanced-assistant-button toggle-stats">Stats</button> <button class="enhanced-assistant-button toggle-settings">Settings</button> <button class="enhanced-assistant-button toggle-panel">Hide</button> </div> <div class="study-notes hidden"> <p>Quick Notes:</p> <textarea placeholder="Take notes here..."></textarea> <button class="enhanced-assistant-button save-notes">Save</button> </div> <div class="timer-container hidden"> <div class="timer-display">00:00</div> <div style="display: flex; justify-content: center;"> <button class="enhanced-assistant-button start-timer">Start</button> <button class="enhanced-assistant-button reset-timer">Reset</button> </div> </div> <div class="answer-stats hidden"> <p>Recent Answers:</p> <div class="answer-stats-list"></div> </div> <div class="settings-section hidden"> <div class="settings-item"> <span>Highlight Answers</span> <label class="toggle-switch"> <input type="checkbox" id="highlight-toggle" ${config.highlightCorrectAnswers ? 'checked' : ''}> <span class="toggle-slider"></span> </label> </div> <div class="settings-item"> <span>Auto-Answer Delay (ms)</span> <input type="number" id="auto-answer-delay" class="delay-input" value="${config.autoAnswerDelay}" min="0" max="10000" step="100"> </div> <div class="settings-item"> <span>Show Answer Stats</span> <label class="toggle-switch"> <input type="checkbox" id="stats-toggle" ${config.showAnswerStats ? 'checked' : ''}> <span class="toggle-slider"></span> </label> </div> <div class="settings-item"> <span>Keyboard Shortcuts</span> <label class="toggle-switch"> <input type="checkbox" id="shortcuts-toggle" ${config.enableKeyboardShortcuts ? 'checked' : ''}> <span class="toggle-slider"></span> </label> </div> </div> <div class="keyboard-shortcuts ${config.enableKeyboardShortcuts ? '' : 'hidden'}"> <p>Shortcuts:</p> <div class="keyboard-shortcut-item"> <span>Toggle Panel</span> <span class="key">Alt+P</span> </div> <div class="keyboard-shortcut-item"> <span>Quick Note</span> <span class="key">Alt+N</span> </div> <div class="keyboard-shortcut-item"> <span>Timer Start/Pause</span> <span class="key">Alt+T</span> </div> </div> <div class="made-by">Made by CMH</div> `; document.body.appendChild(panel); // Timer functionality let timerInterval; let seconds = 0; const timerDisplay = panel.querySelector('.timer-display'); const startTimerBtn = panel.querySelector('.start-timer'); const resetTimerBtn = panel.querySelector('.reset-timer'); function updateTimerDisplay() { const minutes = Math.floor(seconds / 60); const remainingSeconds = seconds % 60; timerDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`; } startTimerBtn.addEventListener('click', function() { if (this.textContent === 'Start') { timerInterval = setInterval(function() { seconds++; updateTimerDisplay(); }, 1000); this.textContent = 'Pause'; } else { clearInterval(timerInterval); this.textContent = 'Start'; } }); resetTimerBtn.addEventListener('click', function() { clearInterval(timerInterval); seconds = 0; updateTimerDisplay(); startTimerBtn.textContent = 'Start'; }); // Toggle functionality const toggleNotesBtn = panel.querySelector('.toggle-notes'); const toggleTimerBtn = panel.querySelector('.toggle-timer'); const toggleStatsBtn = panel.querySelector('.toggle-stats'); const toggleSettingsBtn = panel.querySelector('.toggle-settings'); const togglePanelBtn = panel.querySelector('.toggle-panel'); const notesSection = panel.querySelector('.study-notes'); const timerSection = panel.querySelector('.timer-container'); const statsSection = panel.querySelector('.answer-stats'); const settingsSection = panel.querySelector('.settings-section'); function hideAllSections() { notesSection.classList.add('hidden'); timerSection.classList.add('hidden'); statsSection.classList.add('hidden'); settingsSection.classList.add('hidden'); toggleNotesBtn.classList.remove('active'); toggleTimerBtn.classList.remove('active'); toggleStatsBtn.classList.remove('active'); toggleSettingsBtn.classList.remove('active'); } toggleNotesBtn.addEventListener('click', function() { if (notesSection.classList.contains('hidden')) { hideAllSections(); notesSection.classList.remove('hidden'); this.classList.add('active'); } else { notesSection.classList.add('hidden'); this.classList.remove('active'); } }); toggleTimerBtn.addEventListener('click', function() { if (timerSection.classList.contains('hidden')) { hideAllSections(); timerSection.classList.remove('hidden'); this.classList.add('active'); } else { timerSection.classList.add('hidden'); this.classList.remove('active'); } }); toggleStatsBtn.addEventListener('click', function() { if (statsSection.classList.contains('hidden')) { hideAllSections(); statsSection.classList.remove('hidden'); this.classList.add('active'); } else { statsSection.classList.add('hidden'); this.classList.remove('active'); } }); toggleSettingsBtn.addEventListener('click', function() { if (settingsSection.classList.contains('hidden')) { hideAllSections(); settingsSection.classList.remove('hidden'); this.classList.add('active'); } else { settingsSection.classList.add('hidden'); this.classList.remove('active'); } }); togglePanelBtn.addEventListener('click', function() { if (this.textContent === 'Hide') { hideAllSections(); panel.style.width = 'auto'; panel.style.height = 'auto'; panel.style.overflow = 'hidden'; panel.style.padding = '5px'; Array.from(panel.children).forEach(child => { if (child.tagName !== 'H3' && !child.contains(togglePanelBtn)) { child.style.display = 'none'; } }); this.textContent = 'Show'; } else { panel.style.width = ''; panel.style.height = ''; panel.style.overflow = ''; panel.style.padding = '10px'; Array.from(panel.children).forEach(child => { if (child.tagName !== 'H3') { child.style.display = ''; } }); this.textContent = 'Hide'; } }); // Save notes functionality const saveNotesBtn = panel.querySelector('.save-notes'); const notesTextarea = panel.querySelector('textarea'); saveNotesBtn.addEventListener('click', function() { const notes = notesTextarea.value; localStorage.setItem('gimkitEnhancedNotes', notes); alert('Notes saved!'); }); // Load saved notes const savedNotes = localStorage.getItem('gimkitEnhancedNotes'); if (savedNotes) { notesTextarea.value = savedNotes; } // Settings functionality const highlightToggle = document.getElementById('highlight-toggle'); const autoAnswerDelayInput = document.getElementById('auto-answer-delay'); const statsToggle = document.getElementById('stats-toggle'); const shortcutsToggle = document.getElementById('shortcuts-toggle'); const keyboardShortcutsSection = panel.querySelector('.keyboard-shortcuts'); highlightToggle.addEventListener('change', function() { config.highlightCorrectAnswers = this.checked; localStorage.setItem('gimkitConfig', JSON.stringify(config)); }); autoAnswerDelayInput.addEventListener('change', function() { config.autoAnswerDelay = parseInt(this.value, 10); localStorage.setItem('gimkitConfig', JSON.stringify(config)); }); statsToggle.addEventListener('change', function() { config.showAnswerStats = this.checked; localStorage.setItem('gimkitConfig', JSON.stringify(config)); }); shortcutsToggle.addEventListener('change', function() { config.enableKeyboardShortcuts = this.checked; localStorage.setItem('gimkitConfig', JSON.stringify(config)); if (this.checked) { keyboardShortcutsSection.classList.remove('hidden'); } else { keyboardShortcutsSection.classList.add('hidden'); } }); // Load saved config const savedConfig = localStorage.getItem('gimkitConfig'); if (savedConfig) { try { const parsedConfig = JSON.parse(savedConfig); Object.assign(config, parsedConfig); // Update UI to match loaded config highlightToggle.checked = config.highlightCorrectAnswers; autoAnswerDelayInput.value = config.autoAnswerDelay; statsToggle.checked = config.showAnswerStats; shortcutsToggle.checked = config.enableKeyboardShortcuts; if (config.enableKeyboardShortcuts) { keyboardShortcutsSection.classList.remove('hidden'); } else { keyboardShortcutsSection.classList.add('hidden'); } } catch (e) { console.error('Error loading saved config:', e); } } // Answer tracking const answerMap = new Map(); const answerStatsList = panel.querySelector('.answer-stats-list'); function updateAnswerStats() { if (!config.showAnswerStats) return; answerStatsList.innerHTML = ''; // Get the last 5 entries const entries = Array.from(answerMap.entries()).slice(-5); entries.forEach(([question, answer]) => { const item = document.createElement('div'); item.className = 'answer-stats-item'; item.innerHTML = ` <span class="question" title="${question}">${question}</span> <span class="answer">${answer}</span> `; answerStatsList.appendChild(item); }); } // Keyboard shortcuts if (config.enableKeyboardShortcuts) { document.addEventListener('keydown', function(e) { // Alt+P to toggle panel if (e.altKey && e.key === 'p') { togglePanelBtn.click(); } // Alt+N to toggle notes if (e.altKey && e.key === 'n') { toggleNotesBtn.click(); } // Alt+T to toggle timer if (e.altKey && e.key === 't') { toggleTimerBtn.click(); } }); } // Detect quiz questions and provide assistance const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.addedNodes && mutation.addedNodes.length > 0) { for (let i = 0; i < mutation.addedNodes.length; i++) { const node = mutation.addedNodes[i]; if (node.nodeType === 1) { // Check if this is a question container const questionElement = node.querySelector && node.querySelector('[data-testid="question-text"]'); if (questionElement) { const questionText = questionElement.textContent.trim(); // Look for answer options const answerOptions = Array.from(document.querySelectorAll('[role="button"]')).filter(el => el.textContent && el.textContent.length > 0 && !el.textContent.includes('Skip') ); // If we have a stored answer for this question if (answerMap.has(questionText) && config.highlightCorrectAnswers) { const correctAnswer = answerMap.get(questionText); // Find and highlight the correct answer answerOptions.forEach(option => { if (option.textContent.trim() === correctAnswer) { option.classList.add('correct-answer'); // Auto-answer if enabled if (config.autoAnswerDelay > 0) { setTimeout(() => { option.click(); }, config.autoAnswerDelay); } } }); } // Add click listeners to capture correct answers answerOptions.forEach(option => { option.addEventListener('click', function() { // We'll check after a short delay if the answer was correct setTimeout(() => { // If we're still on the same question, the answer was wrong // If we moved to a new question, the answer was correct const currentQuestion = document.querySelector('[data-testid="question-text"]'); if (currentQuestion && currentQuestion.textContent.trim() !== questionText) { // The answer was correct, store it answerMap.set(questionText, option.textContent.trim()); updateAnswerStats(); } }, 500); }, { once: true }); }); } } } } }); }); observer.observe(document.body, { childList: true, subtree: true }); console.log('Gimkit Enhanced Assistant loaded successfully!'); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址