Files
cocos-mcp/source/tools/broadcast-tools.ts
2025-07-17 18:12:56 +08:00

264 lines
9.2 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ToolDefinition, ToolResponse, ToolExecutor } from '../types';
export class BroadcastTools implements ToolExecutor {
private listeners: Map<string, Function[]> = new Map();
private messageLog: Array<{ message: string; data: any; timestamp: number }> = [];
constructor() {
this.setupBroadcastListeners();
}
getTools(): ToolDefinition[] {
return [
{
name: 'get_broadcast_log',
description: 'Get recent broadcast messages log',
inputSchema: {
type: 'object',
properties: {
limit: {
type: 'number',
description: 'Number of recent messages to return',
default: 50
},
messageType: {
type: 'string',
description: 'Filter by message type (optional)'
}
}
}
},
{
name: 'listen_broadcast',
description: 'Start listening for specific broadcast messages',
inputSchema: {
type: 'object',
properties: {
messageType: {
type: 'string',
description: 'Message type to listen for'
}
},
required: ['messageType']
}
},
{
name: 'stop_listening',
description: 'Stop listening for specific broadcast messages',
inputSchema: {
type: 'object',
properties: {
messageType: {
type: 'string',
description: 'Message type to stop listening for'
}
},
required: ['messageType']
}
},
{
name: 'clear_broadcast_log',
description: 'Clear the broadcast messages log',
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'get_active_listeners',
description: 'Get list of active broadcast listeners',
inputSchema: {
type: 'object',
properties: {}
}
}
];
}
async execute(toolName: string, args: any): Promise<ToolResponse> {
switch (toolName) {
case 'get_broadcast_log':
return await this.getBroadcastLog(args.limit, args.messageType);
case 'listen_broadcast':
return await this.listenBroadcast(args.messageType);
case 'stop_listening':
return await this.stopListening(args.messageType);
case 'clear_broadcast_log':
return await this.clearBroadcastLog();
case 'get_active_listeners':
return await this.getActiveListeners();
default:
throw new Error(`Unknown tool: ${toolName}`);
}
}
private setupBroadcastListeners(): void {
// 设置预定义的重要广播消息监听
const importantMessages = [
'build-worker:ready',
'build-worker:closed',
'scene:ready',
'scene:close',
'scene:light-probe-edit-mode-changed',
'scene:light-probe-bounding-box-edit-mode-changed',
'asset-db:ready',
'asset-db:close',
'asset-db:asset-add',
'asset-db:asset-change',
'asset-db:asset-delete'
];
importantMessages.forEach(messageType => {
this.addBroadcastListener(messageType);
});
}
private addBroadcastListener(messageType: string): void {
const listener = (data: any) => {
this.messageLog.push({
message: messageType,
data: data,
timestamp: Date.now()
});
// 保持日志大小在合理范围内
if (this.messageLog.length > 1000) {
this.messageLog = this.messageLog.slice(-500);
}
console.log(`[Broadcast] ${messageType}:`, data);
};
if (!this.listeners.has(messageType)) {
this.listeners.set(messageType, []);
}
this.listeners.get(messageType)!.push(listener);
// 注册 Editor 消息监听 - 暂时注释掉Editor.Message API可能不支持
// Editor.Message.on(messageType, listener);
console.log(`[BroadcastTools] Added listener for ${messageType} (simulated)`);
}
private removeBroadcastListener(messageType: string): void {
const listeners = this.listeners.get(messageType);
if (listeners) {
listeners.forEach(listener => {
// Editor.Message.off(messageType, listener);
console.log(`[BroadcastTools] Removed listener for ${messageType} (simulated)`);
});
this.listeners.delete(messageType);
}
}
private async getBroadcastLog(limit: number = 50, messageType?: string): Promise<ToolResponse> {
return new Promise((resolve) => {
let filteredLog = this.messageLog;
if (messageType) {
filteredLog = this.messageLog.filter(entry => entry.message === messageType);
}
const recentLog = filteredLog.slice(-limit).map(entry => ({
...entry,
timestamp: new Date(entry.timestamp).toISOString()
}));
resolve({
success: true,
data: {
log: recentLog,
count: recentLog.length,
totalCount: filteredLog.length,
filter: messageType || 'all',
message: 'Broadcast log retrieved successfully'
}
});
});
}
private async listenBroadcast(messageType: string): Promise<ToolResponse> {
return new Promise((resolve) => {
try {
if (!this.listeners.has(messageType)) {
this.addBroadcastListener(messageType);
resolve({
success: true,
data: {
messageType: messageType,
message: `Started listening for broadcast: ${messageType}`
}
});
} else {
resolve({
success: true,
data: {
messageType: messageType,
message: `Already listening for broadcast: ${messageType}`
}
});
}
} catch (err: any) {
resolve({ success: false, error: err.message });
}
});
}
private async stopListening(messageType: string): Promise<ToolResponse> {
return new Promise((resolve) => {
try {
if (this.listeners.has(messageType)) {
this.removeBroadcastListener(messageType);
resolve({
success: true,
data: {
messageType: messageType,
message: `Stopped listening for broadcast: ${messageType}`
}
});
} else {
resolve({
success: true,
data: {
messageType: messageType,
message: `Was not listening for broadcast: ${messageType}`
}
});
}
} catch (err: any) {
resolve({ success: false, error: err.message });
}
});
}
private async clearBroadcastLog(): Promise<ToolResponse> {
return new Promise((resolve) => {
const previousCount = this.messageLog.length;
this.messageLog = [];
resolve({
success: true,
data: {
clearedCount: previousCount,
message: 'Broadcast log cleared successfully'
}
});
});
}
private async getActiveListeners(): Promise<ToolResponse> {
return new Promise((resolve) => {
const activeListeners = Array.from(this.listeners.keys()).map(messageType => ({
messageType: messageType,
listenerCount: this.listeners.get(messageType)?.length || 0
}));
resolve({
success: true,
data: {
listeners: activeListeners,
count: activeListeners.length,
message: 'Active listeners retrieved successfully'
}
});
});
}
}