172 lines
5.4 KiB
JavaScript

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 통신 플러그인 시작됨');