private void ConvertGuerillaPlugins(object sender, DoWorkEventArgs e) { // Cast the sender object to a background worker. BackgroundWorker worker = sender as BackgroundWorker; string outputFolder = e.Argument as string; // Update the status label. worker.ReportProgress(0, "Reading guerilla..."); // Initialize a new instance of our guerilla reader and read the definitions from the executable. GuerillaReader reader = new GuerillaReader(Application.StartupPath + "\\H2Guerilla.exe"); if (reader.Read() == false) { // Failed to read guerilla, return to the calling thread with an error. e.Result = "Error reading guerilla.exe!"; return; } // Create a new tag layout generator, and process all of the tag layouts. TagLayoutGenerator layoutGenerator = new TagLayoutGenerator(); layoutGenerator.GenerateLayouts(reader, outputFolder); // Set the worker result value. e.Result = (string)"Completed successfully!"; }
private void ProcessTagBlockDefinition(GuerillaReader reader, TagBlockDefinition blockDefinition, MutationCodeCreator blockCodeCreator, MutationCodeScope blockCodeScope, MutationCodeScope parentScope) { // Get the field set index that most closely resembles halo 2 xbox layout. int fieldSetIndex = blockDefinition.GetFieldSetIndexClosestToH2Xbox(); // Process all of the fields in the field_set. ProcessFields(blockDefinition.TagFields[fieldSetIndex], reader, blockCodeCreator, blockCodeScope, parentScope); }
public void CreateTagLayout(GuerillaReader reader, MutationCodeScope parentScope) { // Our child code creator for the tag group/block. MutationCodeCreator childCodeCreator = null; // Check if this tag block is a tag group. if (this.TagBlockDefinition.IsTagGroup == true) { // Get the tag group that points to this tag block definition. tag_group tagGroup = reader.TagGroups.First(tag => tag.definition_address == this.TagBlockDefinition.s_tag_block_definition.address); // Compute the size of the definition. int definitionSize = TagLayoutValidator.ComputeMutationDefinitionSize(reader, tagGroup.Definition.TagFields[tagGroup.Definition.GetFieldSetIndexClosestToH2Xbox()]); // Check if the tag group has a parent tag group it inherits from. if (tagGroup.ParentGroupTag != string.Empty) { // Get the parent tag group object. tag_group parentTagGroup = reader.TagGroups.First(tag => tag.GroupTag.Equals(tagGroup.ParentGroupTag) == true); // Now find the code scope for the parent tag layout. MutationCodeScope parentTagScope = parentScope.Types.Values.First(scope => scope.DefinitionAddress == parentTagGroup.definition_address); // Create a new tag group class. childCodeCreator = this.CodeCreator.CreateTagGroupClass(this.TypeName, TagGroupDefinitionAttribute.CreateAttributeDeclaration(tagGroup, definitionSize), parentTagScope.Namespace); } else { // Create a new tag group class. childCodeCreator = this.CodeCreator.CreateTagGroupClass(this.TypeName, TagGroupDefinitionAttribute.CreateAttributeDeclaration(tagGroup, definitionSize)); } } else { // Compute the size of the definition. int definitionSize = TagLayoutValidator.ComputeMutationDefinitionSize(reader, this.TagBlockDefinition.TagFields[this.TagBlockDefinition.GetFieldSetIndexClosestToH2Xbox()]); // Create a new tag block class. childCodeCreator = this.CodeCreator.CreateTagBlockClass(this.TypeName, TagBlockDefinitionAttribute.CreateAttributeDeclaration(this.TagBlockDefinition, definitionSize)); } // Process the tag block definition. ProcessTagBlockDefinition(reader, this.TagBlockDefinition, childCodeCreator, this.CodeScope, parentScope); }
private void ProcessFields(List <tag_field> fields, GuerillaReader reader, MutationCodeCreator blockCodeCreator, MutationCodeScope blockCodeScope, MutationCodeScope parentScope) { // Loop through all of the fields in the collection. for (int i = 0; i < fields.Count; i++) { // Create a new field and add it to the scope for this block. string displayName, units, tooltip; EditorMarkUpFlags markupFlags; string fieldName = blockCodeScope.CreateCodeSafeFieldName(fields[i].type, fields[i].Name, out displayName, out units, out tooltip, out markupFlags); // Create an attribute collection for any attributes we might add to the field. CodeAttributeDeclarationCollection attributeCollection = new CodeAttributeDeclarationCollection(); // Make sure at least one of the required fields for a UI markup attribute is valid. if (markupFlags != EditorMarkUpFlags.None || displayName != string.Empty || units != string.Empty || tooltip != string.Empty) { // Create the UI markup attribute using the information provided. attributeCollection.Add(EditorMarkUpAttribute.CreateAttributeDeclaration(flags: markupFlags, displayName: displayName, unitsSpecifier: units, tooltipText: tooltip)); } // Handle each field accordingly. switch (fields[i].type) { case field_type._field_char_enum: case field_type._field_enum: case field_type._field_long_enum: { // Cast the field to a enum_definition struct. enum_definition enumDefinition = (enum_definition)fields[i]; // Check if there is an existing code scope for this enum type. MutationCodeScope enumScope = blockCodeScope.FindExistingCodeScope(enumDefinition.definition_address); if (enumScope == null) { // Create a new code scope for the enum type. enumScope = blockCodeScope.CreateCodeScopeForType(enumDefinition.Name, enumDefinition.definition_address, MutationCodeScopeType.Enum); // Create a new enum in the block definition for this field. blockCodeCreator.AddEnumOrBitmask(enumScope, enumDefinition); } // Add a field to the block definition for this enum type. blockCodeCreator.AddCustomTypedField(fields[i].type, fieldName, enumScope.Namespace, attributeCollection); break; } case field_type._field_byte_flags: case field_type._field_word_flags: case field_type._field_long_flags: { // Cast the field to a enum_definition struct. enum_definition enumDefinition = (enum_definition)fields[i]; // Check if there is an existing code scope for this bitmask type. MutationCodeScope bitmaskScope = blockCodeScope.FindExistingCodeScope(enumDefinition.definition_address); if (bitmaskScope == null) { // Create a new code scope for the bitmask type. bitmaskScope = blockCodeScope.CreateCodeScopeForType(enumDefinition.Name, enumDefinition.definition_address, MutationCodeScopeType.Bitmask); // Create a new bitmask in the block definition for this field. blockCodeCreator.AddEnumOrBitmask(bitmaskScope, enumDefinition); } // Add a field to the block definition for this bitmask type. blockCodeCreator.AddCustomTypedField(fields[i].type, fieldName, bitmaskScope.Namespace, attributeCollection); break; } case field_type._field_block: { // Get the definition struct from the field address. TagBlockDefinition tagBlockDefinition = reader.TagBlockDefinitions[fields[i].definition_address]; // Check if the tag block definition already exists in the parent code scope. MutationCodeScope tagBlockScope = parentScope.FindExistingCodeScope(tagBlockDefinition.s_tag_block_definition.address); if (tagBlockScope == null) { // Create a new code scope for the tag block definition. tagBlockScope = parentScope.CreateCodeScopeForType(tagBlockDefinition.s_tag_block_definition.Name, tagBlockDefinition.s_tag_block_definition.address, MutationCodeScopeType.TagBlock); // Compute the size of the definition. int definitionSize = TagLayoutValidator.ComputeMutationDefinitionSize(reader, tagBlockDefinition.TagFields[tagBlockDefinition.GetFieldSetIndexClosestToH2Xbox()]); // Create a new class for the tag block definition. MutationCodeCreator childBlockCodeCreator = this.CodeCreator.CreateTagBlockClass(tagBlockScope.Namespace, TagBlockDefinitionAttribute.CreateAttributeDeclaration(tagBlockDefinition, definitionSize)); // Process the tag block definition. ProcessTagBlockDefinition(reader, tagBlockDefinition, childBlockCodeCreator, tagBlockScope, parentScope); } // Create a field for the tag block. blockCodeCreator.AddTagBlockField(fieldName, tagBlockScope.Namespace, attributeCollection); break; } case field_type._field_struct: { // Cast the field to a tag_struct_definition. tag_struct_definition tagStruct = (tag_struct_definition)fields[i]; // Get the definition struct from the field address. TagBlockDefinition tagBlockDefinition = reader.TagBlockDefinitions[tagStruct.block_definition_address]; // Check if the tag block definition already exists in the parent code scope. MutationCodeScope tagBlockScope = parentScope.FindExistingCodeScope(tagBlockDefinition.s_tag_block_definition.address); if (tagBlockScope == null) { // Create a new code scope for the tag block definition. tagBlockScope = parentScope.CreateCodeScopeForType(tagBlockDefinition.s_tag_block_definition.Name, tagBlockDefinition.s_tag_block_definition.address, MutationCodeScopeType.Struct); // Compute the size of the definition. int definitionSize = TagLayoutValidator.ComputeMutationDefinitionSize(reader, tagBlockDefinition.TagFields[tagBlockDefinition.GetFieldSetIndexClosestToH2Xbox()]); // Create a new class for the tag block definition. MutationCodeCreator childBlockCodeCreator = this.CodeCreator.CreateTagBlockClass(tagBlockScope.Namespace, TagBlockDefinitionAttribute.CreateAttributeDeclaration(tagBlockDefinition, definitionSize)); // Process the tag block definition. ProcessTagBlockDefinition(reader, tagBlockDefinition, childBlockCodeCreator, tagBlockScope, parentScope); } // Build the tag block definition attribute for the field. attributeCollection.Add(TagStructAttribute.CreateAttributeDeclaration()); // Create a field for the tag block. blockCodeCreator.AddCustomTypedField(field_type._field_struct, fieldName, tagBlockScope.Namespace, attributeCollection); break; } case field_type._field_tag_reference: { // Cast the field to a tag_reference_definition definition. tag_reference_definition tagRegDefinition = (tag_reference_definition)fields[i]; // Build the tag reference attribute for the field. attributeCollection.Add(TagReferenceAttribute.CreateAttributeDeclaration(tagRegDefinition)); // Add the field with the group tag filter attribute. blockCodeCreator.AddField(fields[i].type, fieldName, attributeCollection); break; } case field_type._field_pad: case field_type._field_skip: case field_type._field_useless_pad: { // Build the padding attribute for the field. attributeCollection.Add(PaddingAttribute.CreateAttributeDeclaration(fields[i].type, fields[i].definition_address)); // Add the field with the padding attribute. blockCodeCreator.AddPaddingField(fieldName, fields[i].definition_address, attributeCollection); break; } case field_type._field_explanation: { // Cast the field to a explanation_definition. explaination_definition explanation = (explaination_definition)fields[i]; // Create a field for the explanation block. blockCodeCreator.AddExplanationField(fieldName, explanation.Name, explanation.Explaination); break; } case field_type._field_array_start: { // Build a list of fields inside of the array. List <tag_field> arrayFields = CreateArrayFieldList(fields, i); // Loop for the length of the array and process the fields. for (int x = 0; x < fields[i].definition_address; x++) { // Process the array fields. ProcessFields(arrayFields, reader, blockCodeCreator, blockCodeScope, parentScope); } // Skip the fields we just processed and the array terminator. i += arrayFields.Count + 1; break; } case field_type._field_data: { // Cast the field to a tag_dat_definition. tag_data_definition tagData = (tag_data_definition)fields[i]; // Create a tag data attribute for this field. attributeCollection.Add(TagDataAttribute.CreateAttributeDeclaration(tagData)); // Add the field to the collection. blockCodeCreator.AddField(fields[i].type, fieldName, attributeCollection); break; } case field_type._field_custom: break; case field_type._field_terminator: break; default: { // Check if the value type dictionary contains this field type. if (MutationCodeCreator.ValueTypeDictionary.Keys.Contains(fields[i].type) == false) { break; } // Add the field to the collection. blockCodeCreator.AddField(fields[i].type, fieldName, attributeCollection); break; } } } }
public void GenerateLayouts(GuerillaReader reader, string outputFolder) { // Check if the subfolder for block definitions exists. if (Directory.Exists(string.Format("{0}\\BlockDefinitions", outputFolder)) == false) { // Create the subfolder for block definitions. Directory.CreateDirectory(string.Format("{0}\\BlockDefinitions", outputFolder)); } // Loop through all of the definitions in Guerilla and verify the size of each one. for (int i = 0; i < reader.TagBlockDefinitions.Keys.Count; i++) { // Get the tag block definition. TagBlockDefinition tagBlock = reader.TagBlockDefinitions[reader.TagBlockDefinitions.Keys.ElementAt(i)]; // Verify the definition address is correct. int definitionSize = TagLayoutValidator.ComputeGuerillaDefinitionSize(reader, tagBlock.TagFields[tagBlock.GetFieldSetIndexClosestToH2Xbox()]); if (definitionSize != tagBlock.TagFieldSets[tagBlock.GetFieldSetIndexClosestToH2Xbox()].size) { // Print the details to the console. System.Diagnostics.Debug.WriteLine(string.Format("Size mismatch on block \"{0}\" computed: {1} actual: {2}", tagBlock.s_tag_block_definition.Name, definitionSize, tagBlock.TagFieldSets[tagBlock.GetFieldSetIndexClosestToH2Xbox()].size)); } } // Build a list of references for each tag block definition we have. Dictionary <string, List <TagBlockDefinition> > tagBlockReferences = PreProcessTagBlockDefinitions(reader); Dictionary <string, List <TagBlockDefinition> > nonUniqueDefinitions = tagBlockReferences.Where(b => b.Value.Count > 1).ToDictionary(p => p.Key, p => p.Value); // Initialize our list of tag definitions to process with the tag groups from the guerilla reader. //tag_group hlmt = reader.TagGroups.First(tag => tag.GroupTag.Equals("hlmt")); List <TagBlockDefinition> tagBlockDefinitions = new List <TagBlockDefinition>(reader.TagBlockDefinitions.Values.Where(block => block.IsTagGroup == true)); //tagBlockDefinitions.Add(reader.TagBlockDefinitions[hlmt.definition_address]); // Loop through all of the non-unique tag blocks and add them to the list of definitions to be processed. foreach (TagBlockDefinition definition in reader.TagBlockDefinitions.Values) { // Check if the definition name is in the non-unique block list. if (nonUniqueDefinitions.Keys.Contains(definition.s_tag_block_definition.Name) == true) { // Add the definition to the list to be extracted. tagBlockDefinitions.Add(definition); } } // Pre-process any tag layouts that need fixups. for (int i = 0; i < this.preProcessingFunctions.Count; i++) { // Find the tag block definition this preprocessing function is associated with. TagBlockDefinition tagBlock = reader.TagBlockDefinitions.Single( block => block.Value.s_tag_block_definition.Name.Equals(this.preProcessingFunctions.ElementAt(i).Key) == true).Value; // Invoke the preprocessing method. this.preProcessingFunctions.ElementAt(i).Value.Invoke(null, new object[] { tagBlock }); } // Create a list of layout creators for all of the definitions we will be processing. List <MutationTagLayoutCreator> layoutCreators = new List <MutationTagLayoutCreator>(); // Loop through the list of tag block definitions and create a code scope for each one. // This will build a list of types in the global namespace which we need before we start processing layouts. for (int i = 0; i < tagBlockDefinitions.Count; i++) { // Create a new tag layout creator and have it create its code scope using the tag block definition. MutationTagLayoutCreator layoutCreator = new MutationTagLayoutCreator(tagBlockDefinitions[i]); layoutCreator.CreateCodeScope(this.globalCodeScope); // Add the layout creator to the list. layoutCreators.Add(layoutCreator); } // Now that we have a type list built loop through all of the layout creators and create the actual tag layouts. for (int i = 0; i < layoutCreators.Count; i++) { // Generate the layout. layoutCreators[i].CreateTagLayout(reader, this.globalCodeScope); // Check if there is a post process function for this block. if (this.postProcessingFunctions.Keys.Contains(layoutCreators[i].TagBlockDefinition.s_tag_block_definition.Name) == true) { // Invoke the post processing function. this.postProcessingFunctions[layoutCreators[i].TagBlockDefinition.s_tag_block_definition.Name].Invoke(null, new object[] { layoutCreators[i] }); } // Write it to file. layoutCreators[i].WriteToFile(outputFolder); } }
private void PreProcessTagBlockDefinitions(TagBlockDefinition definition, GuerillaReader reader, Dictionary <string, List <TagBlockDefinition> > references) { // Loop through all of the fields and process each one. foreach (tag_field field in definition.TagFields[definition.TagFieldSetLatestIndex]) { // Handle the field type accordingly. switch (field.type) { case field_type._field_block: { // Get the definition struct from the field address. TagBlockDefinition def = reader.TagBlockDefinitions[field.definition_address]; // Format the name and check if it is already in the references dictionary. if (references.Keys.Contains(def.s_tag_block_definition.Name) == true) { // Increment the reference count. if (references[def.s_tag_block_definition.Name].Contains(definition) == false) { references[def.s_tag_block_definition.Name].Add(definition); } } else { // Add the block name to the references dictionary. references.Add(def.s_tag_block_definition.Name, new List <TagBlockDefinition>(new TagBlockDefinition[] { definition })); // Preprocess the tag block definition. PreProcessTagBlockDefinitions(def, reader, references); } break; } case field_type._field_struct: { // Cast the field to a tag_struct_definition. tag_struct_definition tagStruct = (tag_struct_definition)field; // Get the definition struct from the field address. TagBlockDefinition def = reader.TagBlockDefinitions[tagStruct.block_definition_address]; // Format the name and check if it is already in the references dictionary. if (references.Keys.Contains(def.s_tag_block_definition.Name) == true) { // Increment the reference count. if (references[def.s_tag_block_definition.Name].Contains(definition) == false) { references[def.s_tag_block_definition.Name].Add(definition); } } else { // Add the block name to the references dictionary. references.Add(def.s_tag_block_definition.Name, new List <TagBlockDefinition>(new TagBlockDefinition[] { definition })); // Preprocess the tag block definition. PreProcessTagBlockDefinitions(def, reader, references); } break; } } } }
private Dictionary <string, List <TagBlockDefinition> > PreProcessTagBlockDefinitions(GuerillaReader reader) { // Create a new reference dictionary. Dictionary <string, List <TagBlockDefinition> > references = new Dictionary <string, List <TagBlockDefinition> >(); // Loop through all of the tag block definitions and preprocess each one. for (int i = 0; i < reader.TagGroups.Length; i++) { // Get the tag block definition for the tag group. TagBlockDefinition definition = reader.TagBlockDefinitions[reader.TagGroups[i].definition_address]; // Preprocess the tag block definition. PreProcessTagBlockDefinitions(definition, reader, references); } // Return the references dictionary we just built. return(references); }
/// <summary> /// Computes the size of a tag layout definition using the Mutation field type sizes. /// </summary> /// <param name="reader">Guerilla reader instance.</param> /// <param name="fields">Fields in the tag layout definition.</param> /// <returns>Size of the fields in terms of Mutation field type sizes.</returns> public static int ComputeMutationDefinitionSize(GuerillaReader reader, List <tag_field> fields) { int definitionSize = 0; // Loop through all of the fields and compute the size of the definition. for (int i = 0; i < fields.Count; i++) { // Handle the field size accordingly. switch (fields[i].type) { case field_type._field_struct: { // Cast the field to a tag_struct_definition. tag_struct_definition tagStruct = (tag_struct_definition)fields[i]; // Get the definition struct from the field address. TagBlockDefinition tagBlockDefinition = reader.TagBlockDefinitions[tagStruct.block_definition_address]; // Get the size of the struct definition from the field_set most close to h2x. definitionSize += ComputeMutationDefinitionSize(reader, tagBlockDefinition.TagFields[tagBlockDefinition.GetFieldSetIndexClosestToH2Xbox()]); break; } case field_type._field_array_start: { // Get a list of fields that are in the array. List <tag_field> arrayFields = MutationTagLayoutCreator.CreateArrayFieldList(fields, i); // Get the size of the array fields and multiply it by the length of the array. definitionSize += fields[i].definition_address * ComputeMutationDefinitionSize(reader, arrayFields); // Skip the array fields and the array terminator. i += arrayFields.Count + 1; break; } case field_type._field_pad: case field_type._field_skip: { // Field size is the length of the padding field. definitionSize += fields[i].definition_address; break; } default: { // Make sure the type array contains the field type. if (MutationFieldSizes.Keys.Contains(fields[i].type) == false) { break; } // Get the field size from the type array. definitionSize += MutationFieldSizes[fields[i].type]; break; } } } // Return the definition size. return(definitionSize); }