/// <summary> /// This function renames a tag. /// </summary> /// <param name="tagIndex">The index of the tag to rename.</param> /// <param name="newName">The new name of the tag to rename as.</param> public void RenameTag(int tagIndex, string newName) { //Get our tag instance HaloMap.TagItem tagItem = map.IndexItems[tagIndex]; //Compare our string lengths.. if (tagItem.Name.Length == newName.Length) { //They are the same length. Let's write our new string. //Open our IO map.OpenIO(); //Go to our tag_name_index_entry map.IO.In.BaseStream.Position = map.MapHeader.fileTableIndexOffset + (tagIndex * 4); //Read our tagnameoffset int tagNameOffset = map.IO.In.ReadInt32() + map.MapHeader.fileTableOffset; //Go to this position map.IO.In.BaseStream.Position = tagNameOffset; //Write our tagname map.IO.Out.WriteAsciiString(newName, tagItem.Name.Length); //Close our IO map.CloseIO(); //Set our tagname. map.IndexItems[tagIndex].Name = newName; } else { //Calculate our table difference. int differenceInStringLength = (tagItem.Name.Length - newName.Length); int newTableSizeUnpadded = map.MapHeader.fileTableSize - differenceInStringLength; int newTableSize = newTableSizeUnpadded + ExtraFunctions.CalculatePadding(newTableSizeUnpadded, 0x1000); int oldTableSize = map.MapHeader.fileTableSize + ExtraFunctions.CalculatePadding(map.MapHeader.fileTableSize, 0x1000); int differenceInSize = oldTableSize - newTableSize; //Open our IO map.OpenIO(); //Go to our tag_name_index_entry map.IO.In.BaseStream.Position = map.MapHeader.fileTableIndexOffset + (tagIndex * 4); //Read our tagnameoffset int tagNameOffset = map.IO.In.ReadInt32() + map.MapHeader.fileTableOffset; //Loop for each tag_name_index after it. for (int i = tagIndex + 1; i < map.IndexHeader.tagCount; i++) { //Go to our tag_name_index_entry map.IO.In.BaseStream.Position = map.MapHeader.fileTableIndexOffset + (i * 4); //Read our tagindex int tagOff = map.IO.In.ReadInt32(); //Recalculate it. tagOff -= differenceInStringLength; //Go to our tag_name_index_entry map.IO.Out.BaseStream.Position = map.MapHeader.fileTableIndexOffset + (i * 4); //Write it map.IO.Out.Write(tagOff); } //Close our IO map.CloseIO(); //If it's any different. if (differenceInSize > 0) { ExtraFunctions.DeleteBytes(map.FileName, map.MapHeader.fileTableOffset + newTableSize, oldTableSize - newTableSize); } else { ExtraFunctions.InsertBytes(map.FileName, map.MapHeader.fileTableOffset + oldTableSize, newTableSize - oldTableSize); } //Open our IO map.OpenIO(); //Go to this position map.IO.Out.BaseStream.Position = tagNameOffset; //Write our tagname map.IO.Out.WriteAsciiString(newName, newName.Length); map.IO.Out.Write((byte)0); for (int i = tagIndex + 1; i < map.IndexHeader.tagCount; i++) { //Write the tagname map.IO.Out.WriteAsciiString(map.IndexItems[i].Name, map.IndexItems[i].Name.Length); map.IO.Out.Write((byte)0); } //For the rest of our table, write the padding. byte[] padding = new byte[newTableSize - newTableSizeUnpadded]; //Write our padding map.IO.Out.Write(padding); //Recalculate some header values. map.IO.Out.BaseStream.Position = 20; map.IO.Out.Write(((map.MapHeader.virtSegmentStart - differenceInSize) + map.MapHeader.headerMagic)); map.IO.Out.BaseStream.Position = 700; map.IO.Out.Write(newTableSizeUnpadded); map.IO.Out.BaseStream.Position = 704; map.IO.Out.Write(((map.MapHeader.fileTableIndexOffset - differenceInSize) + map.MapHeader.headerMagic)); map.IO.Out.BaseStream.Position = 1136; map.IO.Out.Write((map.MapHeader.RawTableOffset - differenceInSize)); map.IO.Out.BaseStream.Position = 1144; map.IO.Out.Write((map.MapHeader.localeTableAddressModifier - differenceInSize)); //Close our IO map.CloseIO(); //Reload our map map.Reload(); } }