240 lines
6.4 KiB
JavaScript
240 lines
6.4 KiB
JavaScript
// 配置日志文件
|
|
const now = new Date();
|
|
const log = require('log4js').configure({
|
|
appenders: {
|
|
file: { type: 'file', filename: `./log/${now.getFullYear()}.${now.getMonth() + 1}.${now.getDate()}.log` }
|
|
},
|
|
categories: {
|
|
default: { appenders: ['file'], level: 'info' }
|
|
}
|
|
}).getLogger();
|
|
|
|
// 전역 예외 처리
|
|
process.on('uncaughtException', (error) => {
|
|
log.error('Uncaught Exception:', error);
|
|
});
|
|
process.on('unhandledRejection', (reason) => {
|
|
log.error('Unhandled Rejection:', reason);
|
|
});
|
|
|
|
// 플러그인 클래스
|
|
const ws = require('ws');
|
|
class Plugins {
|
|
static language = process.argv[9] ? JSON.parse(process.argv[9]).application.language : 'en';
|
|
static globalSettings = {};
|
|
getGlobalSettingsFlag = true;
|
|
|
|
constructor() {
|
|
if (Plugins.instance) {
|
|
return Plugins.instance;
|
|
}
|
|
|
|
log.info("process.argv", process.argv);
|
|
this.ws = new ws("ws://127.0.0.1:" + process.argv[3]);
|
|
this.ws.on('open', () => this.ws.send(JSON.stringify({ uuid: process.argv[5], event: process.argv[7] })));
|
|
this.ws.on('close', process.exit);
|
|
this.ws.on('message', e => {
|
|
if (this.getGlobalSettingsFlag) {
|
|
// 한 번만 가져오기
|
|
this.getGlobalSettingsFlag = false;
|
|
this.getGlobalSettings();
|
|
}
|
|
const data = JSON.parse(e.toString());
|
|
log.info('Received event:', data);
|
|
|
|
const action = data.action?.split('.').pop();
|
|
|
|
// 액션별 이벤트 처리
|
|
if (this[action] && this[action][data.event]) {
|
|
log.info(`Calling ${action}.${data.event}`);
|
|
this[action][data.event](data);
|
|
}
|
|
|
|
// 전역 이벤트 처리
|
|
if (data.event === 'didReceiveGlobalSettings') {
|
|
Plugins.globalSettings = data.payload.settings;
|
|
}
|
|
if (this[data.event]) {
|
|
this[data.event](data);
|
|
}
|
|
});
|
|
Plugins.instance = this;
|
|
}
|
|
|
|
setGlobalSettings(payload) {
|
|
Plugins.globalSettings = payload;
|
|
this.ws.send(JSON.stringify({
|
|
event: "setGlobalSettings",
|
|
context: process.argv[5],
|
|
payload
|
|
}));
|
|
}
|
|
|
|
getGlobalSettings() {
|
|
this.ws.send(JSON.stringify({
|
|
event: "getGlobalSettings",
|
|
context: process.argv[5],
|
|
}));
|
|
}
|
|
|
|
// 제목 설정
|
|
setTitle(context, str, row = 0, num = 6) {
|
|
let newStr = null;
|
|
if (row && str) {
|
|
let nowRow = 1, strArr = str.split('');
|
|
strArr.forEach((item, index) => {
|
|
if (nowRow < row && index >= nowRow * num) { nowRow++; newStr += '\n'; }
|
|
if (nowRow <= row && index < nowRow * num) { newStr += item; }
|
|
});
|
|
if (strArr.length > row * num) { newStr = newStr.substring(0, newStr.length - 1); newStr += '..'; }
|
|
}
|
|
this.ws.send(JSON.stringify({
|
|
event: "setTitle",
|
|
context,
|
|
payload: {
|
|
target: 0,
|
|
title: newStr || str + ''
|
|
}
|
|
}));
|
|
}
|
|
|
|
// 이미지 설정
|
|
setImage(context, url) {
|
|
this.ws.send(JSON.stringify({
|
|
event: "setImage",
|
|
context,
|
|
payload: {
|
|
target: 0,
|
|
image: url
|
|
}
|
|
}));
|
|
}
|
|
|
|
// 상태 설정
|
|
setState(context, state) {
|
|
this.ws.send(JSON.stringify({
|
|
event: "setState",
|
|
context,
|
|
payload: { state }
|
|
}));
|
|
}
|
|
|
|
// 설정 저장
|
|
setSettings(context, payload) {
|
|
this.ws.send(JSON.stringify({
|
|
event: "setSettings",
|
|
context,
|
|
payload
|
|
}));
|
|
}
|
|
|
|
// 경고 표시
|
|
showAlert(context) {
|
|
this.ws.send(JSON.stringify({
|
|
event: "showAlert",
|
|
context
|
|
}));
|
|
}
|
|
|
|
// 성공 표시
|
|
showOk(context) {
|
|
this.ws.send(JSON.stringify({
|
|
event: "showOk",
|
|
context
|
|
}));
|
|
}
|
|
|
|
// 속성 검사기로 전송
|
|
sendToPropertyInspector(payload) {
|
|
this.ws.send(JSON.stringify({
|
|
action: Actions.currentAction,
|
|
context: Actions.currentContext,
|
|
payload,
|
|
event: "sendToPropertyInspector"
|
|
}));
|
|
}
|
|
|
|
// URL 열기
|
|
openUrl(url) {
|
|
this.ws.send(JSON.stringify({
|
|
event: "openUrl",
|
|
payload: { url }
|
|
}));
|
|
}
|
|
}
|
|
|
|
// 액션 클래스
|
|
class Actions {
|
|
constructor(data) {
|
|
this.data = {};
|
|
this.default = {};
|
|
Object.assign(this, data);
|
|
}
|
|
|
|
// 속성 검사기 관련
|
|
static currentAction = null;
|
|
static currentContext = null;
|
|
static actions = {};
|
|
|
|
propertyInspectorDidAppear(data) {
|
|
Actions.currentAction = data.action;
|
|
Actions.currentContext = data.context;
|
|
this._propertyInspectorDidAppear?.(data);
|
|
}
|
|
|
|
// 액션 초기화
|
|
willAppear(data) {
|
|
Plugins.globalContext = data.context;
|
|
Actions.actions[data.context] = data.action;
|
|
const { context, payload: { settings } } = data;
|
|
this.data[context] = Object.assign({ ...this.default }, settings);
|
|
this._willAppear?.(data);
|
|
}
|
|
|
|
didReceiveSettings(data) {
|
|
this.data[data.context] = data.payload.settings;
|
|
this._didReceiveSettings?.(data);
|
|
}
|
|
|
|
// 키 이벤트
|
|
keyUp(data) {
|
|
log.info('keyUp called with data:', data);
|
|
if (typeof this._keyUp === 'function') {
|
|
this._keyUp(data);
|
|
}
|
|
}
|
|
|
|
keyDown(data) {
|
|
log.info('keyDown called with data:', data);
|
|
if (typeof this._keyDown === 'function') {
|
|
this._keyDown(data);
|
|
}
|
|
}
|
|
|
|
// 다이얼 이벤트
|
|
dialRotate(data) {
|
|
log.info('dialRotate called with data:', data);
|
|
if (typeof this._dialRotate === 'function') {
|
|
this._dialRotate(data);
|
|
}
|
|
}
|
|
|
|
dialDown(data) {
|
|
log.info('dialDown called with data:', data);
|
|
if (typeof this._dialDown === 'function') {
|
|
this._dialDown(data);
|
|
}
|
|
}
|
|
|
|
// 액션 해제
|
|
willDisappear(data) {
|
|
this._willDisappear?.(data);
|
|
delete this.data[data.context];
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
log,
|
|
Plugins,
|
|
Actions,
|
|
}; |