308 lines
10 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Event Controller Property Inspector
let websocket = null;
let uuid = null;
let settings = {};
let eventList = [];
let isUnityConnected = false;
// DOM 요소들
let eventSelect = null;
let statusDot = null;
let connectionStatus = null;
let currentEvent = null;
let refreshButton = null;
let executeButton = null;
let autoExecute = null;
let logArea = null;
function logToScreen(msg, color = "#fff") {
let logDiv = document.getElementById('logArea');
if (!logDiv) return;
const line = document.createElement('div');
line.style.color = color;
line.textContent = `[${new Date().toLocaleTimeString()}] ${msg}`;
logDiv.appendChild(line);
logDiv.scrollTop = logDiv.scrollHeight;
}
console.log = function(...args) {
logToScreen(args.map(a => (typeof a === 'object' ? JSON.stringify(a) : a)).join(' '), '#0f0');
};
console.error = function(...args) {
logToScreen(args.map(a => (typeof a === 'object' ? JSON.stringify(a) : a)).join(' '), '#f55');
};
// DOM 초기화
window.addEventListener('DOMContentLoaded', function() {
eventSelect = document.getElementById('event-select');
statusDot = document.getElementById('statusDot');
connectionStatus = document.getElementById('connection-status');
currentEvent = document.getElementById('current-event');
refreshButton = document.getElementById('refresh-button');
executeButton = document.getElementById('execute-button');
autoExecute = document.getElementById('autoExecute');
logArea = document.getElementById('logArea');
if (refreshButton) refreshButton.addEventListener('click', onRefreshClicked);
if (executeButton) executeButton.addEventListener('click', onExecuteClicked);
if (eventSelect) eventSelect.addEventListener('change', onEventSelectionChanged);
if (autoExecute) autoExecute.addEventListener('change', onAutoExecuteChanged);
console.log('✅ Event Property Inspector 준비 완료');
});
// StreamDeck 연결
window.connectElgatoStreamDeckSocket = function(inPort, inUUID, inEvent, inInfo, inActionInfo) {
uuid = inUUID;
console.log('🔌 StreamDeck 연결 시작:', inPort, inUUID);
try {
if (inActionInfo) {
const actionInfo = JSON.parse(inActionInfo);
settings = actionInfo.payload?.settings || {};
console.log('⚙️ 초기 설정:', settings);
}
} catch (e) {
console.error('ActionInfo 파싱 오류:', e);
}
if (!websocket) {
websocket = new WebSocket('ws://localhost:' + inPort);
websocket.onopen = function() {
console.log('✅ StreamDeck 연결됨');
websocket.send(JSON.stringify({ event: inEvent, uuid: inUUID }));
// Unity 상태 요청
setTimeout(() => {
sendToPlugin('get_unity_status');
}, 500);
};
websocket.onmessage = function(evt) {
try {
const jsonObj = JSON.parse(evt.data);
handleMessage(jsonObj);
} catch (e) {
console.error('메시지 파싱 오류:', e);
}
};
websocket.onclose = function() {
console.log('❌ StreamDeck 연결 끊어짐');
websocket = null;
};
websocket.onerror = function(e) {
console.error('WebSocket 오류:', e);
};
}
};
function sendToPlugin(command, data = {}) {
if (!websocket) return;
const message = {
action: 'com.mirabox.streamingle.event',
event: 'sendToPlugin',
context: uuid,
payload: { command, ...data }
};
websocket.send(JSON.stringify(message));
console.log('📤 Plugin으로 메시지 전송:', command, data);
}
function handleMessage(jsonObj) {
console.log('📨 메시지 수신:', jsonObj.event);
if (jsonObj.event === 'sendToPropertyInspector' && jsonObj.payload && jsonObj.payload.event) {
const innerEvent = jsonObj.payload.event;
console.log('📨 Property Inspector 이벤트:', innerEvent);
switch (innerEvent) {
case 'unity_connected':
updateUnityConnection(true);
break;
case 'unity_disconnected':
updateUnityConnection(false);
break;
case 'event_list':
updateEventList(jsonObj.payload.events, jsonObj.payload.currentIndex);
break;
case 'event_changed':
updateEventState(jsonObj.payload.currentIndex);
break;
case 'camera_list':
console.log('📹 카메라 목록 수신 (이벤트 Property Inspector에서는 무시)');
break;
case 'item_list':
console.log('🎯 아이템 목록 수신 (이벤트 Property Inspector에서는 무시)');
break;
}
}
if (jsonObj.event === 'didReceiveSettings' && jsonObj.payload && jsonObj.context) {
settings = jsonObj.payload.settings || {};
console.log('⚙️ 설정 수신:', settings);
if (settings.eventIndex !== undefined && eventSelect) {
eventSelect.value = settings.eventIndex;
console.log('🎯 이벤트 인덱스 설정됨:', settings.eventIndex);
}
if (settings.autoExecute !== undefined && autoExecute) {
autoExecute.checked = settings.autoExecute;
}
updateCurrentEvent();
}
}
function updateUnityConnection(connected) {
isUnityConnected = connected;
if (statusDot) {
statusDot.className = 'dot ' + (connected ? 'green' : 'red');
}
if (connectionStatus) {
connectionStatus.textContent = connected ? 'Unity 연결됨' : 'Unity 연결 안됨';
connectionStatus.className = connected ? 'connected' : 'disconnected';
}
if (eventSelect) {
eventSelect.disabled = !connected;
}
if (refreshButton) {
refreshButton.disabled = !connected;
}
if (executeButton) {
executeButton.disabled = !connected;
}
console.log('🔗 Unity 연결 상태 변경:', connected);
}
function updateEventList(events, currentIndex) {
eventList = events || [];
console.log('🎯 이벤트 목록 업데이트:', eventList.length, '개');
if (!eventSelect) return;
eventSelect.innerHTML = '';
if (eventList.length === 0) {
const option = document.createElement('option');
option.value = '';
option.textContent = '이벤트 그룹이 없습니다';
eventSelect.appendChild(option);
} else {
eventList.forEach((event, index) => {
const option = document.createElement('option');
option.value = index;
option.textContent = event.name || event.groupName || `이벤트 그룹 ${index + 1}`;
eventSelect.appendChild(option);
});
}
// 현재 선택된 이벤트 설정
if (settings.eventIndex !== undefined) {
eventSelect.value = settings.eventIndex;
} else if (currentIndex !== undefined) {
eventSelect.value = currentIndex;
}
updateCurrentEvent();
}
function updateCurrentEvent() {
if (!currentEvent) return;
const selectedIndex = eventSelect ? parseInt(eventSelect.value) : -1;
if (selectedIndex >= 0 && selectedIndex < eventList.length) {
const selectedEvent = eventList[selectedIndex];
currentEvent.textContent = `현재 이벤트 그룹: ${selectedEvent.name || selectedEvent.groupName || `이벤트 그룹 ${selectedIndex + 1}`}`;
} else {
currentEvent.textContent = '현재 이벤트 그룹: -';
}
}
function updateEventState(currentIndex) {
console.log('🎯 이벤트 상태 업데이트:', currentIndex);
if (eventSelect && currentIndex !== undefined) {
eventSelect.value = currentIndex;
updateCurrentEvent();
}
}
function onEventSelectionChanged() {
if (!eventSelect) return;
const selectedIndex = parseInt(eventSelect.value);
console.log('🎯 이벤트 선택 변경:', selectedIndex);
if (selectedIndex >= 0) {
settings.eventIndex = selectedIndex;
// StreamDeck에 설정 저장 (카메라 컨트롤러와 동일한 방식)
if (websocket && uuid) {
websocket.send(JSON.stringify({
action: 'com.mirabox.streamingle.event',
event: 'setSettings',
context: uuid,
payload: {
eventIndex: selectedIndex,
actionType: 'event' // actionType 명시적으로 설정
}
}));
console.log('💾 설정 저장됨:', { eventIndex: selectedIndex, actionType: 'event' });
}
// Unity에 이벤트 설정 요청 (자동 실행 여부와 관계없이)
if (isUnityConnected) {
console.log('📤 Unity에 이벤트 설정 전송:', selectedIndex);
sendToPlugin('set_event', { event_index: selectedIndex });
} else {
console.log('⚠️ Unity가 연결되지 않아 이벤트 설정을 전송할 수 없습니다');
}
updateCurrentEvent();
}
}
function onAutoExecuteChanged() {
if (!autoExecute) return;
settings.autoExecute = autoExecute.checked;
console.log('⚙️ 자동 실행 설정 변경:', settings.autoExecute);
// StreamDeck에 설정 저장 (카메라 컨트롤러와 동일한 방식)
if (websocket && uuid) {
websocket.send(JSON.stringify({
action: 'com.mirabox.streamingle.event',
event: 'setSettings',
context: uuid,
payload: { autoExecute: settings.autoExecute }
}));
console.log('💾 자동 실행 설정 저장됨:', { autoExecute: settings.autoExecute });
}
}
function onRefreshClicked() {
console.log('🔄 이벤트 목록 새로고침 요청');
sendToPlugin('get_event_list');
}
function onExecuteClicked() {
if (!eventSelect) return;
const selectedIndex = parseInt(eventSelect.value);
if (selectedIndex >= 0) {
console.log(' 이벤트 실행 요청:', selectedIndex);
sendToPlugin('execute_event', { event_index: selectedIndex });
} else {
console.log(' 이벤트가 선택되지 않았습니다');
}
}