您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
실시간으로 참여자 수 변화를 감지해 사인파 소리 재생 및 자동 시작/관전 버튼 클릭
当前为
// ==UserScript== // @name 끄투 방 참가 알림 // @namespace 끄투 방 참가 알림 // @match https://kkutu.co.kr/* // @version 1.0 // @description 실시간으로 참여자 수 변화를 감지해 사인파 소리 재생 및 자동 시작/관전 버튼 클릭 // @icon https://www.google.com/s2/favicons?domain=kkutu.co.kr // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; let previousCount = 0; // 이전 참여자 수 const autoStartCheckboxId = 'autoStartCheckbox'; const autoSpectateCheckboxId = 'autoSpectateCheckbox'; function createCheckbox(id, labelText, topOffset) { const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.id = id; checkbox.style.position = 'fixed'; checkbox.style.top = `${topOffset}px`; checkbox.style.right = '10px'; document.body.appendChild(checkbox); const label = document.createElement('label'); label.htmlFor = id; label.innerText = labelText; label.style.position = 'fixed'; label.style.top = `${topOffset}px`; label.style.right = '30px'; document.body.appendChild(label); return checkbox; } const autoStartCheckbox = createCheckbox(autoStartCheckboxId, '자동 시작', 10); const autoSpectateCheckbox = createCheckbox(autoSpectateCheckboxId, '자동 관전', 40); // 사인파 소리 재생 함수 function playSineWave(frequency, duration) { const audioContext = new (window.AudioContext || window.webkitAudioContext)(); const oscillator = audioContext.createOscillator(); oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(frequency, audioContext.currentTime); oscillator.connect(audioContext.destination); oscillator.start(); oscillator.stop(audioContext.currentTime + duration); } // 사인파 소리 세 번 재생 함수 function playTripleBeep() { const audioContext = new (window.AudioContext || window.webkitAudioContext)(); const frequencies = [1220, 1220, 1220]; const times = [0, 0.3, 0.6]; frequencies.forEach((freq, index) => { const oscillator = audioContext.createOscillator(); oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(freq, audioContext.currentTime + times[index]); oscillator.connect(audioContext.destination); oscillator.start(audioContext.currentTime + times[index]); oscillator.stop(audioContext.currentTime + times[index] + 0.2); }); } // 자동 시작 함수 function autoStartGame() { const startBtn = document.getElementById('StartBtn'); const participantInfo = document.querySelector('.room-head-limit').innerText; // 참여자 정보 가져오기 const participants = parseInt(participantInfo.split(' ')[1]); // 참여자 수 추출 if (!startBtn || startBtn.style.display === 'none') { return; } let readyUsers = document.querySelectorAll('.room-user-ready.room-user-readied').length; // 준비 완료된 인원 수 let waitingUsers = document.querySelectorAll('.room-user-ready').length - readyUsers; // 대기 인원 수 // 방장 체크 const masterElement = document.querySelector('.room-user-ready.room-user-master'); if (masterElement) { if (masterElement.innerText.includes('관전')) { if (readyUsers > 0) readyUsers -= 1; } // 방장 대기 인원에서 제외 waitingUsers -= 1; } // 관전자가 대기 인원에서 제외되도록 처리 const spectators = document.querySelectorAll('.room-user-ready.room-user-spectate').length; waitingUsers -= spectators; // 대기 인원 존재 시 준비 인원 0으로 설정 if (waitingUsers > 0) { readyUsers = 0; } // console.log(`준비 인원: ${readyUsers}, 대기 인원: ${waitingUsers}`); if (readyUsers >= 1 && participants >= 2) { // console.log('자동 시작 조건을 만족했습니다. 시작 버튼을 클릭합니다.'); startBtn.click(); // alert("게임이 시작됩니다! 🎮"); } else { // console.log('자동 시작 조건을 만족하지 못했습니다.'); if (readyUsers === 0) { // alert("준비 인원이 없습니다. 준비해 주세요."); } } } function autoSpectate() { const spectateBtn = document.getElementById('SpectateBtn'); if (spectateBtn && spectateBtn.style.display === 'block' && !spectateBtn.classList.contains('toggled')) { spectateBtn.click(); // alert("관전 모드로 전환되었습니다! 👀"); } } const observer = new MutationObserver(() => { const element = document.querySelector('.room-head-limit'); if (!element) return; const match = element.textContent.match(/참여자 (\d+) \/ (\d+)/); if (!match) return; const currentCount = parseInt(match[1], 10); const maxCount = parseInt(match[2], 10); // 참여자 수가 변했을 때 if (currentCount !== previousCount) { if (currentCount > previousCount) { // 참여자가 늘어났을 때 if (currentCount === maxCount) { // 최대 인원일 때 playTripleBeep(); } else { // 일반적인 증가 playSineWave(880, 0.2); // 경쾌한 음 (880Hz) } } else { // 참여자가 줄어들었을 때 playSineWave(440, 0.2); // 경고음에 가까운 음 (440Hz) } // 이전 참여자 수 업데이트 previousCount = currentCount; } if (autoStartCheckbox.checked) { autoStartGame(); } if (autoSpectateCheckbox.checked) { autoSpectate(); } }); const targetNode = document.body; const config = { childList: true, subtree: true, characterData: true }; observer.observe(targetNode, config); })();