const { Plugins, Actions, log } = require('./utils/plugin'); const WebSocket = require('ws'); // 플러그인 인스턴스 const plugin = new Plugins(); // Unity WebSocket 서버 const WS_PORT = 15732; let wss = null; let unityConnections = new Set(); let isUnityConnected = false; // Unity 서버 시작 function startUnityServer() { try { wss = new WebSocket.Server({ port: WS_PORT }); log.info(`Unity WebSocket 서버 시작: 포트 ${WS_PORT}`); // 서버 연결 시 기존 연결 확인 setTimeout(() => { if (wss.clients.size > 0) { log.info(`기존 Unity 연결 발견: ${wss.clients.size}개`); isUnityConnected = true; wss.clients.forEach(ws => { unityConnections.add(ws); }); updateConnectionStatus(); } }, 1000); wss.on('connection', (ws, req) => { const clientIP = req.socket.remoteAddress; log.info(`Unity 클라이언트 연결됨 - IP: ${clientIP}`); unityConnections.add(ws); isUnityConnected = true; updateConnectionStatus(); // 연결 확인 메시지 전송 ws.send(JSON.stringify({ type: 'connection_confirmed', data: { message: '플러그인에 성공적으로 연결되었습니다', timestamp: Date.now() } })); ws.on('message', (message) => { log.info(`Unity에서 메시지 수신: ${message}`); }); ws.on('close', () => { log.info(`Unity 클라이언트 연결 해제 - IP: ${clientIP}`); unityConnections.delete(ws); if (unityConnections.size === 0) { isUnityConnected = false; updateConnectionStatus(); } }); ws.on('error', (error) => { log.error(`Unity 연결 오류: ${error.message}`); }); }); wss.on('error', (error) => { log.error(`WebSocket 서버 오류: ${error.message}`); }); } catch (error) { log.error('WebSocket 서버 오류: ' + error.message); } } // Unity로 메시지 전송 function sendToUnity(message) { if (unityConnections.size === 0) { log.warn('Unity 연결 없음'); return false; } const messageStr = JSON.stringify(message); unityConnections.forEach(ws => { if (ws.readyState === WebSocket.OPEN) { ws.send(messageStr); log.info('Unity로 전송: ' + messageStr); } }); return true; } // 연결 상태 업데이트 function updateConnectionStatus() { const status = isUnityConnected ? '연결됨' : '연결안됨'; log.info(`Unity 연결 상태: ${status}`); // 모든 버튼의 제목 업데이트 if (plugin.action1 && plugin.action1.currentContext) { plugin.setTitle(plugin.action1.currentContext, isUnityConnected ? "Unity 버튼" : "연결안됨"); } } // 버튼 액션 plugin.action1 = new Actions({ currentContext: null, _willAppear({ context }) { this.currentContext = context; const title = isUnityConnected ? "Unity 버튼" : "연결안됨"; plugin.setTitle(context, title); log.info('Unity 버튼 로드됨'); }, _keyUp({ context }) { log.info('버튼 클릭됨!'); if (!isUnityConnected) { plugin.setTitle(context, "연결없음"); setTimeout(() => { const title = isUnityConnected ? "Unity 버튼" : "연결안됨"; plugin.setTitle(context, title); }, 1000); return; } const success = sendToUnity({ type: 'button_clicked', data: { message: 'StreamDock 버튼이 클릭되었습니다!', timestamp: Date.now() } }); if (success) { plugin.setTitle(context, "전송됨!"); setTimeout(() => plugin.setTitle(context, "Unity 버튼"), 1000); } else { plugin.setTitle(context, "실패"); setTimeout(() => plugin.setTitle(context, "Unity 버튼"), 1000); } }, _willDisappear({ context }) { this.currentContext = null; } }); // 서버 시작 startUnityServer(); // 주기적으로 연결 상태 확인 (5초마다) setInterval(() => { const actualConnections = wss ? wss.clients.size : 0; const wasConnected = isUnityConnected; if (actualConnections > 0 && !isUnityConnected) { log.info(`연결 상태 동기화: Unity 연결됨 (${actualConnections}개)`); isUnityConnected = true; updateConnectionStatus(); } else if (actualConnections === 0 && isUnityConnected) { log.info('연결 상태 동기화: Unity 연결 해제'); isUnityConnected = false; unityConnections.clear(); updateConnectionStatus(); } if (wasConnected !== isUnityConnected) { log.info(`연결 상태 변경: ${wasConnected ? '연결됨' : '연결안됨'} → ${isUnityConnected ? '연결됨' : '연결안됨'}`); } }, 5000); log.info('Unity 통신 플러그인 시작됨');