您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
This tool helps you listen to music while studying
当前为
// ==UserScript== // @name Duolingo Helper // @namespace http://tampermonkey.net/ // @version 1.0.6 // @description This tool helps you listen to music while studying // @author @kietxx and @. // @match https://*.duolingo.com/* // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @icon https://d35aaqx5ub95lt.cloudfront.net/images/leagues/afe5c7067cd5fb7de936d3928ea7add6.svg // ==/UserScript== (function() { 'use strict'; let basePing = 100; // Basic Ping (ms) let baseFps = 60; // Basic FPS let ping = basePing; // Current ping value (ms) let fps = baseFps; // Current FPS value let sessionStartTime = Date.now(); // Session start time function isLocalStorageSupported() { try { const testKey = '__testKey'; localStorage.setItem(testKey, testKey); localStorage.removeItem(testKey); return true; } catch (error) { return false; } } if (!isLocalStorageSupported()) { console.error('LocalStorage is not supported.'); return; } const style = document.createElement('style'); style.textContent = ` :root { --text-color: black; /* Default text color */ --background-color: white; /* Default background color */ } @keyframes rainbow-border { 0% { border-color: red; } 14% { border-color: orange; } 28% { border-color: yellow; } 42% { border-color: green; } 57% { border-color: blue; } 71% { border-color: indigo; } 85% { border-color: violet; } 100% { border-color: red; } } #performanceMonitor { position: fixed; top: 10px; right: 10px; padding: 8px; border: 5px solid; border-radius: 8px; font-family: Arial, sans-serif; font-size: 14px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); width: 200px; height: auto; text-align: left; overflow: hidden; cursor: pointer; z-index: 9999; transition: opacity 0.3s ease-in-out, width 0.3s ease-in-out, transform 0.3s ease-in-out; background-color: var(--background-color); /* Use the CSS variable for background color */ background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAAA...'); background-size: 32px 32px; background-repeat: no-repeat; background-position: 10px center; animation: rainbow-border 3s linear infinite; color: var(--text-color); /* Use the CSS variable for text color */ } #performanceMonitor.hidden { width: 80px; transform: scale(0.9); } #performanceContentWrapper { transition: opacity 0.3s ease-in-out; } #performanceContentWrapper.hidden { opacity: 0; height: 0; overflow: hidden; } #performanceMonitor button { display: block; margin-bottom: 5px; cursor: pointer; background-color: #444; /* Fixed button background color */ color: white; /* Fixed button text color */ border: none; border-radius: 4px; padding: 4px 8px; font-size: 12px; transition: background-color 0.3s, transform 0.3s; } #performanceMonitor button:hover { background-color: #666; transform: scale(1.05); } .modal { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(0); background-color: rgba(255, 255, 255, 0.9); /* Default modal background */ color: var(--text-color); /* Use the CSS variable for modal text color */ border-radius: 8px; padding: 20px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); z-index: 10000; transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out; opacity: 0; } .modal.show { transform: translate(-50%, -50%) scale(1); opacity: 1; } .modal h3 { margin-bottom: 10px; } .modal label { display: block; margin-bottom: 5px; } .modal input[type="email"], .modal textarea { width: 100%; padding: 8px; margin-bottom: 10px; border: 1px solid #666; border-radius: 4px; background-color: #f9f9f9; /* Default input background color */ color: var(--text-color); /* Use the CSS variable for input text color */ } .modal textarea { height: 100px; /* Set height for feedback textarea */ resize: vertical; /* Allow vertical resizing */ } .modal button { margin-top: 10px; padding: 8px 16px; background-color: #1cb0f6; color: white; border: none; border-radius: 4px; cursor: pointer; transition: background-color 0.3s; } .modal button:hover { background-color: #0a7bb0; } #settingsPanel { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(0); background-color: rgba(255, 255, 255, 0.9); /* Default settings panel background */ color: var(--text-color); /* Use the CSS variable for settings panel text color */ border-radius: 8px; padding: 20px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); z-index: 10001; transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out; opacity: 0; } #settingsPanel.show { transform: translate(-50%, -50%) scale(1); opacity: 1; } #settingsPanel h3 { margin-bottom: 10px; } #musicMenu { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(0); background-color: rgba(255, 255, 255, 0.9); color: var(--text-color); border-radius: 8px; padding: 20px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); z-index: 10001; transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out; opacity: 0; max-height: 80%; overflow-y: auto; } #musicMenu.show { transform: translate(-50%, -50%) scale(1); opacity: 1; } #musicMenu button { display: block; margin-bottom: 5px; cursor: pointer; background-color: #444; color: white; border: none; border-radius: 4px; padding: 4px 8px; font-size: 12px; transition: background-color 0.3s, transform 0.3s; } #musicMenu button:hover { background-color: #666; transform: scale(1.05); } `; document.head.appendChild(style); // Add audio element const audio = document.createElement('audio'); audio.id = 'backgroundMusic'; audio.src = 'https://ia600605.us.archive.org/8/items/NeverGonnaGiveYouUp/jocofullinterview41.mp3'; // Thay thế URL bằng liên kết đến file nhạc của bạn audio.loop = true; // Lặp lại nhạc liên tục document.body.appendChild(audio); const container = document.createElement('div'); container.id = 'performanceMonitor'; container.title = 'Click to hide/show'; document.body.appendChild(container); const contentWrapper = document.createElement('div'); contentWrapper.id = 'performanceContentWrapper'; container.appendChild(contentWrapper); const content = document.createElement('div'); content.id = 'performanceContent'; contentWrapper.appendChild(content); const toggleButton = document.createElement('button'); toggleButton.textContent = 'Hide'; toggleButton.addEventListener('mouseover', () => { toggleButton.style.backgroundColor = '#666'; }); toggleButton.addEventListener('mouseout', () => { toggleButton.style.backgroundColor = '#444'; }); toggleButton.addEventListener('click', () => { const isVisible = !contentWrapper.classList.contains('hidden'); contentWrapper.classList.toggle('hidden', isVisible); toggleButton.textContent = isVisible ? 'Show' : 'Hide'; const monitor = document.getElementById('performanceMonitor'); monitor.classList.toggle('hidden', isVisible); }); container.appendChild(toggleButton); const reloadButton = document.createElement('button'); reloadButton.textContent = 'Reload Page'; reloadButton.addEventListener('click', () => { location.reload(); }); contentWrapper.appendChild(reloadButton); const discordButton = document.createElement('button'); discordButton.textContent = 'Join Discord Server'; discordButton.addEventListener('click', () => { window.open('https://discord.gg/rXZcQn5F', '_blank'); }); contentWrapper.appendChild(discordButton); // New Choose Music Button const chooseMusicButton = document.createElement('button'); chooseMusicButton.textContent = 'Choose Music'; chooseMusicButton.addEventListener('click', () => { showMusicMenu(); }); contentWrapper.appendChild(chooseMusicButton); // Music Menu const musicMenu = document.createElement('div'); musicMenu.id = 'musicMenu'; musicMenu.innerHTML = ` <h3>Select Music</h3> <button data-music-url="https://ia600605.us.archive.org/8/items/NeverGonnaGiveYouUp/jocofullinterview41.mp3">Secret :))</button> <button data-music-url="https://ia804703.us.archive.org/34/items/sapientdream-pastlives-lyrics-mp-3-320-k/sapientdream%20-%20Pastlives%20%28lyrics%29%28MP3_320K%29.mp3">PastLives</button> <button data-music-url="https://ia601604.us.archive.org/29/items/gio-jank/GI%C3%93%20-%20JANK.mp3">Gió (Song by JanK)</button> <button data-music-url="https://ia904703.us.archive.org/4/items/ha-con-vuong-nang-dat-kaa_202210/H%E1%BA%A1%20C%C3%B2n%20V%C6%B0%C6%A1ng%20N%E1%BA%AFng%20-%20DatKaa.mp3">Hạ còn vương nắng</button> <button data-music-url="https://ia803408.us.archive.org/29/items/keo-bong-gon-xuan-ken/Keo-Bong-Gon-XuanKen.mp3">Kẹo Bông Gòn</button> <button data-music-url="https://ia904609.us.archive.org/24/items/VicetoneFeat.CoziZuehlsdorff-Nevadamp3edm.eu/Vicetone%20feat.%20Cozi%20Zuehlsdorff%20%E2%80%93%20Nevada%20%5Bmp3edm.eu%5D.mp3">Nevada</button> <button data-music-url="https://ia801709.us.archive.org/20/items/10-lies/06%20Runaway.mp3">Runaway</button> <button data-music-url="https://ia902307.us.archive.org/35/items/the-kid-laroi-justin-bieber-stay_20211019/The%20Kid%20LAROI%20Justin%20Bieber%20STAY.mp3">STAY</button> <button data-music-url="https://ia801801.us.archive.org/26/items/tuyet-sac-orinn-remix-nam-duc-nhac-tre-mo-xuyen-tet-v.-a-playlist-nhac-cua-tui/Tuy%E1%BB%87t%20S%E1%BA%AFc%20%28Orinn%20Remix%29%20-%20Nam%20%C4%90%E1%BB%A9c%20-%20Nh%E1%BA%A1c%20Tr%E1%BA%BB%20M%E1%BB%9F%20Xuy%C3%AAn%20T%E1%BA%BFt%20-%20V.A%20-%20Playlist%20NhacCuaTui.mp3">Tuyệt Sắc</button> <button data-music-url="https://ia601409.us.archive.org/9/items/youtube-Ko63BameVgI/Ko63BameVgI.mp4">少女A</button> <button data-music-url="https://dn720300.ca.archive.org/0/items/muon-roi-ma-sao-con-son-tung-m-tp-di-dau-cung-nghe-v.-a-playlist-nhac-cua-tui-2/Mu%E1%BB%99n%20R%E1%BB%93i%20M%C3%A0%20Sao%20C%C3%B2n%20-%20S%C6%A1n%20T%C3%B9ng%20M-TP%20-%20%C4%90i%20%C4%90%C3%A2u%20C%C5%A9ng%20Nghe%20-%20V.A%20-%20Playlist%20NhacCuaTui_2.mp3">Muộn Rồi Mà Sao Còn</button> <button data-music-url="https://ia601502.us.archive.org/0/items/NoiNayCoAnhSonTungMTPZingMP3/N%C6%A1i%20N%C3%A0y%20C%C3%B3%20Anh%20-%20S%C6%A1n%20T%C3%B9ng%20M-TP%20_%20Zing%20MP3.MP3">Nơi Này Có Anh</button> <button data-music-url="https://ia801404.us.archive.org/28/items/duong-toi-cho-em-ve-cukak-remix-buitruonglinh-cukak/%C4%90%C6%B0%E1%BB%9Dng%20T%C3%B4i%20Ch%E1%BB%9F%20Em%20V%E1%BB%81%20%28Cukak%20Remix%29%20-%20buitruonglinh%2C%20Cukak.mp3">đường tôi chở em về</button> <button data-music-url="https://ia802701.us.archive.org/11/items/hoa-co-lau-phong-max-bai-hat-lyrics/Hoa%20C%E1%BB%8F%20Lau%20-%20Phong%20Max%20-%20B%C3%A0i%20h%C3%A1t%2C%20lyrics.mp3">Hoa Cỏ Lau</button> <button data-music-url="https://ia800106.us.archive.org/30/items/LacTroiSonTungMTP/Lac-Troi-Son-Tung-M-TP.mp3">Lạc Trôi</button> <button data-music-url="https://dn720301.ca.archive.org/0/items/vietnamese-communist-anthems-old-recordings/Vietnamese%20Communist%20Anthems%20%5BOld%20Recordings%5D.mp3">Quốc Ca Việt Nam</button> <button data-music-url="https://ia600304.us.archive.org/16/items/soundcloud-295595865/Alan_Walker_-_Fade-295595865.mp3">Faded</button> <button data-music-url="https://ia800909.us.archive.org/0/items/AlanWalkerAlone_201902/Alan_Walker_-_Alone.mp3">Alone by Alan Walker</button> <button data-music-url="https://ia801503.us.archive.org/26/items/soundcloud-251045088/Janji_Heroes_Tonight_feat_Johnning_SNC-251045088.mp3">Heroes Tonight</button> <button data-music-url="https://ia601403.us.archive.org/24/items/soundcloud-1013787601/1013787601.mp3">Royalty</button> <button data-music-url="https://example.com/your-other-music.mp3">Stop Music</button> <button id="closeMusicMenu">Close</button `; document.body.appendChild(musicMenu); document.getElementById('closeMusicMenu').addEventListener('click', () => { musicMenu.classList.remove('show'); }); musicMenu.querySelectorAll('button[data-music-url]').forEach(button => { button.addEventListener('click', () => { const musicUrl = button.getAttribute('data-music-url'); const audioElement = document.getElementById('backgroundMusic'); audioElement.src = musicUrl; audioElement.play(); chooseMusicButton.textContent = 'Choose Music'; musicMenu.classList.remove('show'); }); }); const feedbackButton = document.createElement('button'); feedbackButton.textContent = 'Feedback'; feedbackButton.addEventListener('click', () => { showFeedbackModal(); }); contentWrapper.appendChild(feedbackButton); const settingsButton = document.createElement('button'); settingsButton.textContent = 'Settings'; settingsButton.addEventListener('click', () => { showSettingsPanel(); }); contentWrapper.appendChild(settingsButton); async function measurePing(url) { try { const start = performance.now(); const response = await fetch(url, { method: 'HEAD' }); await response; const end = performance.now(); const pingValue = Math.round(end - start) + ' ms'; updateDisplay(pingValue); } catch (error) { console.error('Ping Error:', error); updateDisplay('Error'); } } let lastFrameTime = performance.now(); let frameCount = 0; function measureFPS() { const now = performance.now(); const delta = now - lastFrameTime; frameCount++; if (delta >= 1000) { const fpsValue = Math.round((frameCount * 1000) / delta); updateDisplay(null, fpsValue); frameCount = 0; lastFrameTime = now; } requestAnimationFrame(measureFPS); } function updateDisplay(pingValue, fpsValue) { if (pingValue !== undefined) { ping = pingValue; } if (fpsValue !== undefined) { fps = fpsValue; } const elapsedTime = formatSessionTime(Date.now() - sessionStartTime); const display = document.getElementById('performanceContent'); display.innerHTML = ` <div><strong>Ping:</strong> ${ping}</div> <div><strong>FPS:</strong> ${fps}</div> <div><strong>Session Time:</strong> ${elapsedTime}</div> `; } function formatSessionTime(milliseconds) { let seconds = Math.floor(milliseconds / 1000); const hours = Math.floor(seconds / 3600); seconds %= 3600; const minutes = Math.floor(seconds / 60); seconds %= 60; return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`; } const feedbackModal = document.createElement('div'); feedbackModal.className = 'modal'; feedbackModal.innerHTML = ` <h3>Send Feedback</h3> <div> <label for="feedbackMessage">Your Report:</label> <textarea id="feedbackMessage"></textarea> </div> <button id="sendFeedback" style="margin-top: 10px;">Submit</button> <button id="cancelFeedback" style="margin-top: 10px;">Cancel</button> `; document.body.appendChild(feedbackModal); const settingsPanel = document.createElement('div'); settingsPanel.id = 'settingsPanel'; settingsPanel.innerHTML = ` <h3>Settings</h3> <div> <label for="fontSize">Font Size:</label> <input type="number" id="fontSize" value="14" min="10" max="30" /> </div> <div> <label for="backgroundColor">Background Color:</label> <input type="color" id="backgroundColor" value="#ffffff" /> </div> <div> <label for="transparentBackground">Transparent Background:</label> <input type="checkbox" id="transparentBackground" /> </div> <button id="applySettings" style="margin-top: 10px;">Apply</button> <button id="resetSettings" style="margin-top: 10px;">Reset to Default</button> <button id="cancelSettings" style="margin-top: 10px;">Cancel</button> `; document.body.appendChild(settingsPanel); function hideAllPanels() { feedbackModal.classList.remove('show'); settingsPanel.classList.remove('show'); musicMenu.classList.remove('show'); document.getElementById('performanceContentWrapper').classList.remove('hidden'); } document.getElementById('sendFeedback').addEventListener('click', () => { const feedback = document.getElementById('feedbackMessage').value; if (feedback) { // Normally, you would send the feedback to your backend here. console.log('Feedback:', feedback); alert('Feedback sent!'); feedbackModal.classList.remove('show'); } else { alert('Please enter your feedback.'); } }); document.getElementById('cancelFeedback').addEventListener('click', () => { feedbackModal.classList.remove('show'); }); document.getElementById('applySettings').addEventListener('click', () => { const fontSize = document.getElementById('fontSize').value + 'px'; const backgroundColor = document.getElementById('backgroundColor').value; const isTransparent = document.getElementById('transparentBackground').checked; const performanceMonitor = document.getElementById('performanceMonitor'); performanceMonitor.style.fontSize = fontSize; performanceMonitor.style.backgroundColor = isTransparent ? 'rgba(255, 255, 255, 0)' : backgroundColor; // Update text color based on background color const textColor = getContrastColor(backgroundColor); document.documentElement.style.setProperty('--text-color', textColor); alert('Settings applied.'); }); document.getElementById('resetSettings').addEventListener('click', () => { document.getElementById('fontSize').value = '14'; document.getElementById('backgroundColor').value = '#ffffff'; document.getElementById('transparentBackground').checked = false; const performanceMonitor = document.getElementById('performanceMonitor'); performanceMonitor.style.fontSize = '14px'; performanceMonitor.style.backgroundColor = 'white'; // Reset text color to default document.documentElement.style.setProperty('--text-color', 'black'); alert('Settings reset to default.'); }); document.getElementById('cancelSettings').addEventListener('click', () => { settingsPanel.classList.remove('show'); }); function showFeedbackModal() { hideAllPanels(); feedbackModal.classList.add('show'); } function showSettingsPanel() { hideAllPanels(); settingsPanel.classList.add('show'); } function showMusicMenu() { hideAllPanels(); musicMenu.classList.add('show'); } function getContrastColor(hex) { // Calculate luminance and return black or white based on contrast const r = parseInt(hex.substring(1, 3), 16); const g = parseInt(hex.substring(3, 5), 16); const b = parseInt(hex.substring(5, 7), 16); const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b; return luminance > 128 ? 'black' : 'white'; } measureFPS(); setInterval(() => { measurePing('https://www.google.com'); }, 30000); })();