// ==UserScript== // @name lck // @namespace lck // @version 1.4 // @description 롤캐 숙제 바로가기 // @match https://lolcast.kr/* // @grant GM_xmlhttpRequest // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 채널 정보 const CHANNELS = { youtube: { id: 'UCw1DsweY9b2AKGjV4kGJP1A', buttonLabel: '유튜브', color: '#FF0000', url: (id) => `/#/player/youtube/${id}` }, chzzk: { buttonLabel: '치지직', color: '#00FFA3', url: () => '/#/player/chzzk/9381e7d6816e6d915a44a13c0195b202' }, afreeca: { buttonLabel: '숲', color: '#2970B6', url: () => '/#/player/afreeca/aflol' } }; // YouTube 라이브 영상 ID 가져오기 async function fetchLiveVideoId(channelId) { const YOUTUBE_LIVE_URL = `https://www.youtube.com/channel/${channelId}/live`; return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: YOUTUBE_LIVE_URL, onload: function(response) { const videoIdMatch = response.responseText.match(/"videoId":"([\w-]+)"/); const isLiveNow = response.responseText.includes('"isLiveNow":true') || response.responseText.includes('"isLive":true'); const liveBroadcastContentMatch = response.responseText.match(/"liveBroadcastContent":"(\w+)"/); const isLiveBroadcast = liveBroadcastContentMatch && liveBroadcastContentMatch[1] === 'live'; if (videoIdMatch && videoIdMatch[1] && (isLiveNow || isLiveBroadcast)) { resolve(videoIdMatch[1]); } else { reject('No live video found.'); } }, onerror: reject }); }); } // 컨트롤 패널 생성 const controlPanel = document.createElement('div'); controlPanel.style.cssText = ` position: fixed; top: 380px; left: 0; padding: 8px; border-radius: 0 4px 4px 0; z-index: 9999; display: flex; gap: 8px; background: transparent !important; `; // 버튼 생성 함수 function createChannelButton(channel) { const button = document.createElement('button'); button.textContent = channel.buttonLabel; button.style.cssText = ` padding: 6px 12px; color: ${channel.color}; border: 2px solid ${channel.color}; border-radius: 4px; cursor: pointer; font-size: 14px; transition: all 0.2s; background: transparent; `; button.onmouseover = () => { button.style.background = channel.color; button.style.color = 'white'; }; button.onmouseout = () => { button.style.background = 'transparent'; button.style.color = channel.color; }; button.onclick = async () => { if(channel.buttonLabel === '유튜브') { try { const liveVideoId = await fetchLiveVideoId(channel.id); window.location.href = channel.url(liveVideoId); } catch { alert('유튜브 라이브 방송이 없습니다.'); } } else { window.location.href = channel.url(); } }; return button; } // 버튼 추가 const youtubeButton = createChannelButton(CHANNELS.youtube); const chzzkButton = createChannelButton(CHANNELS.chzzk); const afreecaButton = createChannelButton(CHANNELS.afreeca); controlPanel.appendChild(youtubeButton); controlPanel.appendChild(chzzkButton); controlPanel.appendChild(afreecaButton); document.body.appendChild(controlPanel); // 버튼 숨기기 const toggleButton = document.createElement('button'); toggleButton.textContent = '숨기기'; toggleButton.style.cssText = ` padding: 6px 12px; color: #000; border: 2px solid #000; border-radius: 4px; cursor: pointer; font-size: 14px; transition: all 0.2s; background: transparent; `; toggleButton.onclick = () => { controlPanel.style.display = controlPanel.style.display === 'block' ? 'none' : 'block'; }; document.body.appendChild(toggleButton); })();