229 lines
10 KiB
TypeScript
229 lines
10 KiB
TypeScript
import { readSettings } from '../../settings';
|
|
import { readFileSync } from 'fs-extra';
|
|
import { join } from 'path';
|
|
|
|
/**
|
|
* @zh 如果希望兼容 3.3 之前的版本可以使用下方的代码
|
|
* @en You can add the code below if you want compatibility with versions prior to 3.3
|
|
*/
|
|
// Editor.Panel.define = Editor.Panel.define || function(options: any) { return options }
|
|
|
|
module.exports = Editor.Panel.define({
|
|
listeners: {
|
|
show() { console.log('MCP Server panel shown'); },
|
|
hide() { console.log('MCP Server panel hidden'); }
|
|
},
|
|
template: readFileSync(join(__dirname, '../../../static/template/default/index.html'), 'utf-8'),
|
|
style: readFileSync(join(__dirname, '../../../static/style/default/index.css'), 'utf-8'),
|
|
$: {
|
|
panelTitle: '#panelTitle',
|
|
serverStatusLabel: '#serverStatusLabel',
|
|
serverStatusLabelProp: '#serverStatusLabelProp',
|
|
serverStatusValue: '#serverStatusValue',
|
|
connectedLabel: '#connectedLabel',
|
|
connectedClients: '#connectedClients',
|
|
toggleServerBtn: '#toggleServerBtn',
|
|
settingsLabel: '#settingsLabel',
|
|
portLabel: '#portLabel',
|
|
autoStartLabel: '#autoStartLabel',
|
|
debugLogLabel: '#debugLogLabel',
|
|
maxConnectionsLabel: '#maxConnectionsLabel',
|
|
connectionInfoLabel: '#connectionInfoLabel',
|
|
httpUrlLabel: '#httpUrlLabel',
|
|
httpUrlInput: '#httpUrlInput',
|
|
copyBtn: '#copyBtn',
|
|
saveSettingsBtn: '#saveSettingsBtn',
|
|
// 新增输入控件id
|
|
portInput: '#portInput',
|
|
maxConnInput: '#maxConnInput',
|
|
autoStartInput: '#autoStartInput',
|
|
debugLogInput: '#debugLogInput',
|
|
},
|
|
methods: {
|
|
async updateServerStatus(this: any) {
|
|
try {
|
|
const status = await Editor.Message.request('cocos-mcp-server', 'get-server-status');
|
|
this.serverRunning = status.running;
|
|
this.connectedClients = status.clients || 0;
|
|
this.serverStatus = this.serverRunning ?
|
|
Editor.I18n.t('cocos-mcp-server.connected') :
|
|
Editor.I18n.t('cocos-mcp-server.disconnected');
|
|
this.statusClass = this.serverRunning ? 'running' : 'stopped';
|
|
this.buttonText = this.serverRunning ?
|
|
Editor.I18n.t('cocos-mcp-server.stop_server') :
|
|
Editor.I18n.t('cocos-mcp-server.start_server');
|
|
// 刷新UI
|
|
this.$.serverStatusValue.innerText = this.serverStatus;
|
|
this.$.connectedClients.innerText = this.connectedClients;
|
|
this.$.toggleServerBtn.innerText = this.buttonText;
|
|
if (this.serverRunning) {
|
|
this.httpUrl = `http://localhost:${this.settings.port}/mcp`;
|
|
this.$.httpUrlInput.value = this.httpUrl;
|
|
} else {
|
|
this.httpUrl = '';
|
|
this.$.httpUrlInput.value = '';
|
|
}
|
|
} catch (err) {
|
|
console.error('Failed to update server status:', err);
|
|
}
|
|
},
|
|
|
|
async toggleServer(this: any) {
|
|
this.isProcessing = true;
|
|
try {
|
|
if (this.serverRunning) {
|
|
await this.stopServer();
|
|
} else {
|
|
await this.startServer();
|
|
}
|
|
} finally {
|
|
this.isProcessing = false;
|
|
}
|
|
},
|
|
|
|
async startServer(this: any) {
|
|
try {
|
|
await Editor.Message.request('cocos-mcp-server', 'start-server');
|
|
Editor.Dialog.info(Editor.I18n.t('cocos-mcp-server.server_started'), {
|
|
detail: Editor.I18n.t('cocos-mcp-server.server_running').replace('{0}', this.settings.port.toString())
|
|
});
|
|
await this.updateServerStatus();
|
|
} catch (err: any) {
|
|
Editor.Dialog.error(Editor.I18n.t('cocos-mcp-server.failed_to_start'), err.message);
|
|
}
|
|
},
|
|
|
|
async stopServer(this: any) {
|
|
try {
|
|
await Editor.Message.request('cocos-mcp-server', 'stop-server');
|
|
Editor.Dialog.info(Editor.I18n.t('cocos-mcp-server.server_stopped_msg'), {
|
|
detail: Editor.I18n.t('cocos-mcp-server.server_stopped')
|
|
});
|
|
await this.updateServerStatus();
|
|
} catch (err: any) {
|
|
Editor.Dialog.error(Editor.I18n.t('cocos-mcp-server.failed_to_stop'), err.message);
|
|
}
|
|
},
|
|
|
|
async saveSettings(this: any) {
|
|
try {
|
|
// 直接用 this.$ 获取所有输入控件的当前值
|
|
const port = this.$.portInput ? Number((this.$.portInput as any).value) : 3000;
|
|
const maxConnections = this.$.maxConnInput ? Number((this.$.maxConnInput as any).value) : 10;
|
|
const autoStart = this.$.autoStartInput ? !!(this.$.autoStartInput as any).checked : false;
|
|
const enableDebugLog = this.$.debugLogInput ? !!(this.$.debugLogInput as any).checked : false;
|
|
// 组装 settings
|
|
const settings = {
|
|
...this.settings,
|
|
port,
|
|
maxConnections,
|
|
autoStart,
|
|
enableDebugLog,
|
|
};
|
|
await Editor.Message.request('cocos-mcp-server', 'update-settings', settings);
|
|
// 重新拉取设置
|
|
const newSettings = await Editor.Message.request('cocos-mcp-server', 'get-server-settings');
|
|
this.settings = newSettings;
|
|
this.originalSettings = JSON.stringify(newSettings);
|
|
Editor.Dialog.info(Editor.I18n.t('cocos-mcp-server.settings_saved'));
|
|
} catch (err: any) {
|
|
Editor.Dialog.error(Editor.I18n.t('cocos-mcp-server.failed_to_save'), err.message);
|
|
}
|
|
},
|
|
|
|
copyUrl(this: any) {
|
|
Editor.Clipboard.write('text', this.httpUrl);
|
|
Editor.Dialog.info(Editor.I18n.t('cocos-mcp-server.url_copied'));
|
|
},
|
|
|
|
settingsChanged(this: any) {
|
|
return JSON.stringify(this.settings) !== this.originalSettings;
|
|
},
|
|
bindSettingsEvents(this: any) {
|
|
// 端口输入框
|
|
const portInput = document.querySelectorAll('ui-num-input[slot="content"]')[0];
|
|
if (portInput) {
|
|
portInput.addEventListener('change', (e: any) => {
|
|
this.settings.port = Number(e.detail.value);
|
|
});
|
|
}
|
|
// 最大连接数
|
|
const maxConnInput = document.querySelectorAll('ui-num-input[slot="content"]')[1];
|
|
if (maxConnInput) {
|
|
maxConnInput.addEventListener('change', (e: any) => {
|
|
this.settings.maxConnections = Number(e.detail.value);
|
|
});
|
|
}
|
|
// 复选框
|
|
const checkboxes = document.querySelectorAll('ui-checkbox[slot="content"]');
|
|
if (checkboxes && checkboxes.length >= 2) {
|
|
checkboxes[0].addEventListener('change', (e: any) => {
|
|
this.settings.autoStart = !!e.detail.value;
|
|
});
|
|
checkboxes[1].addEventListener('change', (e: any) => {
|
|
this.settings.enableDebugLog = !!e.detail.value;
|
|
});
|
|
}
|
|
},
|
|
|
|
},
|
|
ready() {
|
|
Editor.Message.request('cocos-mcp-server', 'get-server-settings').then((settings) => {
|
|
this.settings = settings;
|
|
this.originalSettings = JSON.stringify(settings);
|
|
// 本地化label赋值
|
|
this.$.panelTitle.innerText = Editor.I18n.t('cocos-mcp-server.panel_title');
|
|
this.$.serverStatusLabel.innerText = Editor.I18n.t('cocos-mcp-server.server_status');
|
|
this.$.serverStatusLabelProp.innerText = Editor.I18n.t('cocos-mcp-server.server_status');
|
|
this.$.connectedLabel.innerText = Editor.I18n.t('cocos-mcp-server.connected');
|
|
this.$.settingsLabel.innerText = Editor.I18n.t('cocos-mcp-server.settings');
|
|
this.$.portLabel.innerText = Editor.I18n.t('cocos-mcp-server.port');
|
|
this.$.autoStartLabel.innerText = Editor.I18n.t('cocos-mcp-server.auto_start');
|
|
this.$.debugLogLabel.innerText = Editor.I18n.t('cocos-mcp-server.debug_log');
|
|
this.$.maxConnectionsLabel.innerText = Editor.I18n.t('cocos-mcp-server.max_connections');
|
|
this.$.connectionInfoLabel.innerText = Editor.I18n.t('cocos-mcp-server.connection_info');
|
|
this.$.httpUrlLabel.innerText = Editor.I18n.t('cocos-mcp-server.http_url');
|
|
this.$.copyBtn.innerText = Editor.I18n.t('cocos-mcp-server.copy');
|
|
this.$.saveSettingsBtn.innerText = Editor.I18n.t('cocos-mcp-server.save_settings');
|
|
// 动态内容初始化
|
|
this.$.serverStatusValue.innerText = '';
|
|
this.$.connectedClients.innerText = '';
|
|
this.$.toggleServerBtn.innerText = '';
|
|
this.$.httpUrlInput.value = '';
|
|
// 绑定按钮事件
|
|
this.$.toggleServerBtn.addEventListener('confirm', this.toggleServer.bind(this));
|
|
this.$.saveSettingsBtn.addEventListener('confirm', this.saveSettings.bind(this));
|
|
this.$.copyBtn.addEventListener('confirm', this.copyUrl.bind(this));
|
|
// 延迟绑定事件,确保 UI 组件已渲染
|
|
setTimeout(() => {
|
|
this.bindSettingsEvents();
|
|
}, 100);
|
|
// Set up periodic status updates
|
|
(this as any).statusInterval = setInterval(() => {
|
|
(this as any).updateServerStatus();
|
|
}, 2000);
|
|
// 不再自动启动服务器,用户点击才启动
|
|
(this as any).updateServerStatus();
|
|
});
|
|
},
|
|
beforeClose() {
|
|
if ((this as any).statusInterval) {
|
|
clearInterval((this as any).statusInterval);
|
|
}
|
|
},
|
|
close() {
|
|
// Panel close cleanup
|
|
},
|
|
|
|
// Direct properties for data access
|
|
serverRunning: false,
|
|
connectedClients: 0,
|
|
serverStatus: '',
|
|
statusClass: 'stopped',
|
|
buttonText: '',
|
|
isProcessing: false,
|
|
settings: {},
|
|
httpUrl: '',
|
|
statusInterval: null as any,
|
|
originalSettings: ''
|
|
} as any); |