UNPKG

il2cpp-dump-analyzer-mcp

Version:

Agentic RAG system for analyzing IL2CPP dump.cs files from Unity games

273 lines 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.IL2CPPCodeChunker = void 0; const textsplitters_1 = require("@langchain/textsplitters"); /** * Specialized chunker for IL2CPP code that preserves semantic meaning * Enhanced with IL2CPP-specific optimizations for better RAG performance */ class IL2CPPCodeChunker { constructor(chunkSize = 1000, chunkOverlap = 200, methodChunkSize = 500, methodChunkOverlap = 100) { this.chunkSize = chunkSize; this.chunkOverlap = chunkOverlap; this.methodChunkSize = methodChunkSize; this.methodChunkOverlap = methodChunkOverlap; // Initialize the text splitter with C# specific separators for classes this.splitter = new textsplitters_1.RecursiveCharacterTextSplitter({ chunkSize: this.chunkSize, chunkOverlap: this.chunkOverlap, separators: [ // Class level separators "\n\n", "\n", " ", "", // Method level separators "{", "}", "(", ")", ";", ] }); // Specialized splitter for methods with smaller chunk size this.methodSplitter = new textsplitters_1.RecursiveCharacterTextSplitter({ chunkSize: this.methodChunkSize, chunkOverlap: this.methodChunkOverlap, separators: [ // Method level separators "\n", ";", "{", "}", "(", ")", ",", " ", "" ] }); } /** * Create chunks from a class definition * @param classEntity IL2CPP class entity * @returns Array of chunks with metadata */ async chunkClass(classEntity) { const chunks = []; // Create a chunk for the class definition const classDefinition = this.formatClassDefinition(classEntity); const classChunks = await this.splitter.createDocuments([classDefinition]); for (const chunk of classChunks) { chunks.push({ text: chunk.pageContent, metadata: { type: 'class', name: classEntity.name, namespace: classEntity.namespace, fullName: classEntity.fullName, isMonoBehaviour: classEntity.isMonoBehaviour, typeDefIndex: classEntity.typeDefIndex } }); } // Create chunks for each method for (const method of classEntity.methods) { const methodChunks = await this.chunkMethod(method, classEntity); chunks.push(...methodChunks); } return chunks; } /** * Create chunks from a method definition * @param methodEntity IL2CPP method entity * @param parentClass Parent class of the method * @returns Array of chunks with metadata */ async chunkMethod(methodEntity, parentClass) { const chunks = []; // Format the method signature with more context const methodSignature = this.formatMethodSignature(methodEntity); // Add class context to the method for better semantic understanding const methodWithContext = `Class: ${parentClass.fullName}\n${methodSignature}`; // Create chunks for the method using the specialized method splitter const methodChunks = await this.methodSplitter.createDocuments([methodWithContext]); for (const chunk of methodChunks) { chunks.push({ text: chunk.pageContent, metadata: { type: 'method', name: methodEntity.name, returnType: methodEntity.returnType, parentClass: parentClass.name, parentNamespace: parentClass.namespace, fullName: `${parentClass.fullName}.${methodEntity.name}`, isStatic: methodEntity.isStatic, isVirtual: methodEntity.isVirtual, isOverride: methodEntity.isOverride, isAbstract: methodEntity.isAbstract, rva: methodEntity.rva, offset: methodEntity.offset, parameters: methodEntity.parameters.map(p => `${p.type} ${p.name}`).join(', '), // Add IL2CPP specific metadata typeDefIndex: parentClass.typeDefIndex, isMonoBehaviour: parentClass.isMonoBehaviour || false } }); } return chunks; } /** * Create chunks from an enum definition * @param enumEntity IL2CPP enum entity * @returns Array of chunks with metadata */ async chunkEnum(enumEntity) { const chunks = []; // Format the enum definition const enumDefinition = this.formatEnumDefinition(enumEntity); // Create chunks for the enum const enumChunks = await this.splitter.createDocuments([enumDefinition]); for (const chunk of enumChunks) { chunks.push({ text: chunk.pageContent, metadata: { type: 'enum', name: enumEntity.name, namespace: enumEntity.namespace, fullName: enumEntity.fullName, typeDefIndex: enumEntity.typeDefIndex } }); } return chunks; } /** * Create chunks from an interface definition * @param interfaceEntity IL2CPP interface entity * @returns Array of chunks with metadata */ async chunkInterface(interfaceEntity) { const chunks = []; // Format the interface definition const interfaceDefinition = this.formatInterfaceDefinition(interfaceEntity); // Create chunks for the interface const interfaceChunks = await this.splitter.createDocuments([interfaceDefinition]); for (const chunk of interfaceChunks) { chunks.push({ text: chunk.pageContent, metadata: { type: 'interface', name: interfaceEntity.name, namespace: interfaceEntity.namespace, fullName: interfaceEntity.fullName, typeDefIndex: interfaceEntity.typeDefIndex } }); } return chunks; } // Helper methods to format code entities formatClassDefinition(classEntity) { let definition = ''; // Add namespace if (classEntity.namespace) { definition += `namespace ${classEntity.namespace} {\n`; } // Add class declaration definition += `public class ${classEntity.name}`; // Add inheritance if (classEntity.baseClass || classEntity.interfaces.length > 0) { definition += ' : '; if (classEntity.baseClass) { definition += classEntity.baseClass; } if (classEntity.baseClass && classEntity.interfaces.length > 0) { definition += ', '; } if (classEntity.interfaces.length > 0) { definition += classEntity.interfaces.join(', '); } } definition += ' {\n'; // Add fields for (const field of classEntity.fields) { const accessModifier = field.isPublic ? 'public' : 'private'; const staticModifier = field.isStatic ? 'static ' : ''; const readonlyModifier = field.isReadOnly ? 'readonly ' : ''; // Add attributes if present const attributes = field.attributes || []; if (attributes.length > 0) { definition += ` [${attributes.join(', ')}]\n`; } definition += ` ${accessModifier} ${staticModifier}${readonlyModifier}${field.type} ${field.name};\n`; } // Add method signatures (not implementations) for (const method of classEntity.methods) { const accessModifier = method.isPublic ? 'public' : 'private'; const staticModifier = method.isStatic ? 'static ' : ''; const virtualModifier = method.isVirtual ? 'virtual ' : ''; const overrideModifier = method.isOverride ? 'override ' : ''; const abstractModifier = method.isAbstract ? 'abstract ' : ''; // Add attributes if present const attributes = method.attributes || []; if (attributes.length > 0) { definition += ` [${attributes.join(', ')}]\n`; } definition += ` ${accessModifier} ${staticModifier}${virtualModifier}${overrideModifier}${abstractModifier}${method.returnType} ${method.name}(`; // Add parameters const params = method.parameters.map(p => `${p.type} ${p.name}`).join(', '); definition += `${params});\n`; } // Close class and namespace definition += '}\n'; if (classEntity.namespace) { definition += '}\n'; } return definition; } formatMethodSignature(methodEntity) { const accessModifier = methodEntity.isPublic ? 'public' : 'private'; const staticModifier = methodEntity.isStatic ? 'static ' : ''; const virtualModifier = methodEntity.isVirtual ? 'virtual ' : ''; const overrideModifier = methodEntity.isOverride ? 'override ' : ''; const abstractModifier = methodEntity.isAbstract ? 'abstract ' : ''; let signature = `${accessModifier} ${staticModifier}${virtualModifier}${overrideModifier}${abstractModifier}${methodEntity.returnType} ${methodEntity.name}(`; // Add parameters const params = methodEntity.parameters.map(p => `${p.type} ${p.name}`).join(', '); signature += `${params})`; // Add RVA and offset information if (methodEntity.rva || methodEntity.offset) { signature += ` // RVA: ${methodEntity.rva}, Offset: ${methodEntity.offset}`; } return signature; } formatEnumDefinition(enumEntity) { let definition = ''; // Add namespace if (enumEntity.namespace) { definition += `namespace ${enumEntity.namespace} {\n`; } // Add enum declaration definition += `public enum ${enumEntity.name} {\n`; // Add enum values for (const value of enumEntity.values) { definition += ` ${value.name} = ${value.value},\n`; } // Close enum and namespace definition += '}\n'; if (enumEntity.namespace) { definition += '}\n'; } return definition; } formatInterfaceDefinition(interfaceEntity) { let definition = ''; // Add namespace if (interfaceEntity.namespace) { definition += `namespace ${interfaceEntity.namespace} {\n`; } // Add interface declaration definition += `public interface ${interfaceEntity.name} {\n`; // Add method signatures for (const method of interfaceEntity.methods) { definition += ` ${method.returnType} ${method.name}(`; // Add parameters const params = method.parameters.map(p => `${p.type} ${p.name}`).join(', '); definition += `${params});\n`; } // Close interface and namespace definition += '}\n'; if (interfaceEntity.namespace) { definition += '}\n'; } return definition; } } exports.IL2CPPCodeChunker = IL2CPPCodeChunker; //# sourceMappingURL=chunker.js.map