294 lines
9.3 KiB
JavaScript
294 lines
9.3 KiB
JavaScript
// Item Controller Property Inspector
|
|
let websocket = null;
|
|
let uuid = null;
|
|
let settings = {};
|
|
let itemList = [];
|
|
let isUnityConnected = false;
|
|
|
|
// DOM 요소들
|
|
let itemSelect = null;
|
|
let statusDot = null;
|
|
let connectionStatus = null;
|
|
let currentItem = null;
|
|
let refreshButton = null;
|
|
let autoSwitch = 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() {
|
|
itemSelect = document.getElementById('item-select');
|
|
statusDot = document.getElementById('statusDot');
|
|
connectionStatus = document.getElementById('connection-status');
|
|
currentItem = document.getElementById('current-item');
|
|
refreshButton = document.getElementById('refresh-button');
|
|
autoSwitch = document.getElementById('autoSwitch');
|
|
logArea = document.getElementById('logArea');
|
|
|
|
if (refreshButton) refreshButton.addEventListener('click', onRefreshClicked);
|
|
if (itemSelect) itemSelect.addEventListener('change', onItemSelectionChanged);
|
|
if (autoSwitch) autoSwitch.addEventListener('change', onAutoSwitchChanged);
|
|
|
|
console.log('✅ Item 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.item',
|
|
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 'item_list':
|
|
updateItemList(jsonObj.payload.items, jsonObj.payload.currentIndex);
|
|
break;
|
|
case 'item_changed':
|
|
updateItemState(jsonObj.payload.currentIndex);
|
|
break;
|
|
case 'camera_list':
|
|
console.log('📹 카메라 목록 수신 (아이템 Property Inspector에서는 무시)');
|
|
console.log('⚠️ 아이템 컨트롤러에서 카메라 데이터를 받았습니다. 이는 잘못된 데이터 전송입니다.');
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (jsonObj.event === 'didReceiveSettings' && jsonObj.payload && jsonObj.context) {
|
|
settings = jsonObj.payload.settings || {};
|
|
console.log('⚙️ 설정 수신:', settings);
|
|
|
|
if (settings.itemIndex !== undefined && itemSelect) {
|
|
itemSelect.value = settings.itemIndex;
|
|
}
|
|
|
|
if (settings.autoSwitch !== undefined && autoSwitch) {
|
|
autoSwitch.checked = settings.autoSwitch;
|
|
}
|
|
}
|
|
}
|
|
|
|
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 (itemSelect) {
|
|
itemSelect.disabled = !connected;
|
|
}
|
|
|
|
if (refreshButton) {
|
|
refreshButton.disabled = !connected;
|
|
}
|
|
|
|
console.log('🔗 Unity 연결 상태 변경:', connected);
|
|
}
|
|
|
|
function updateItemList(items, currentIndex) {
|
|
itemList = items || [];
|
|
console.log('🎯 아이템 목록 업데이트:', itemList.length, '개');
|
|
|
|
if (!itemSelect) return;
|
|
|
|
itemSelect.innerHTML = '';
|
|
|
|
if (itemList.length === 0) {
|
|
const option = document.createElement('option');
|
|
option.value = '';
|
|
option.textContent = '아이템 그룹이 없습니다';
|
|
itemSelect.appendChild(option);
|
|
} else {
|
|
itemList.forEach((item, index) => {
|
|
const option = document.createElement('option');
|
|
option.value = index;
|
|
option.textContent = item.name || item.groupName || `아이템 그룹 ${index + 1}`;
|
|
itemSelect.appendChild(option);
|
|
});
|
|
}
|
|
|
|
// 현재 선택된 아이템 설정
|
|
if (settings.itemIndex !== undefined) {
|
|
itemSelect.value = settings.itemIndex;
|
|
} else if (currentIndex !== undefined) {
|
|
itemSelect.value = currentIndex;
|
|
}
|
|
|
|
updateCurrentItem();
|
|
}
|
|
|
|
function updateCurrentItem() {
|
|
if (!currentItem || !itemSelect) return;
|
|
|
|
const selectedIndex = parseInt(itemSelect.value);
|
|
if (isNaN(selectedIndex) || selectedIndex < 0 || selectedIndex >= itemList.length) {
|
|
currentItem.textContent = '현재 아이템 그룹: -';
|
|
return;
|
|
}
|
|
|
|
const selectedItem = itemList[selectedIndex];
|
|
if (selectedItem) {
|
|
const status = selectedItem.isActive ? '활성' : '비활성';
|
|
currentItem.textContent = `현재 아이템 그룹: ${selectedItem.name || selectedItem.groupName || `그룹 ${selectedIndex + 1}`} (${status})`;
|
|
}
|
|
}
|
|
|
|
function updateItemState(currentIndex) {
|
|
if (currentIndex !== undefined && itemSelect) {
|
|
itemSelect.value = currentIndex;
|
|
}
|
|
updateCurrentItem();
|
|
}
|
|
|
|
function onItemSelectionChanged() {
|
|
const selectedIndex = parseInt(itemSelect.value);
|
|
if (isNaN(selectedIndex)) return;
|
|
|
|
// 항상 actionType: 'item'을 포함
|
|
settings.itemIndex = selectedIndex;
|
|
settings.actionType = 'item';
|
|
updateCurrentItem();
|
|
|
|
// 설정 저장 (actionType 포함)
|
|
if (websocket && uuid) {
|
|
websocket.send(JSON.stringify({
|
|
action: 'com.mirabox.streamingle.item',
|
|
event: 'setSettings',
|
|
context: uuid,
|
|
payload: settings
|
|
}));
|
|
}
|
|
|
|
// 버튼 제목 업데이트 요청 (actionType 포함)
|
|
sendToPlugin('update_title', { itemIndex: selectedIndex, actionType: 'item' });
|
|
|
|
// 즉시 버튼 제목 업데이트 요청
|
|
if (websocket && uuid) {
|
|
websocket.send(JSON.stringify({
|
|
action: 'com.mirabox.streamingle.item',
|
|
event: 'setTitle',
|
|
context: uuid,
|
|
payload: {
|
|
title: `아이템 ${selectedIndex + 1}`,
|
|
target: 0
|
|
}
|
|
}));
|
|
}
|
|
|
|
console.log('🎯 아이템 그룹 선택 변경:', selectedIndex, settings);
|
|
}
|
|
|
|
function onAutoSwitchChanged() {
|
|
if (!autoSwitch) return;
|
|
|
|
settings.autoSwitch = autoSwitch.checked;
|
|
|
|
// 설정 저장
|
|
if (websocket && uuid) {
|
|
websocket.send(JSON.stringify({
|
|
action: 'com.mirabox.streamingle.item',
|
|
event: 'setSettings',
|
|
context: uuid,
|
|
payload: settings
|
|
}));
|
|
}
|
|
|
|
console.log('⚙️ 자동 전환 설정 변경:', autoSwitch.checked);
|
|
}
|
|
|
|
function onRefreshClicked() {
|
|
if (!isUnityConnected) {
|
|
console.log('⚠️ Unity가 연결되지 않음');
|
|
return;
|
|
}
|
|
|
|
console.log('🔄 아이템 그룹 목록 새로고침 요청');
|
|
sendToPlugin('refresh_item_list');
|
|
}
|