public void SaveLocale(int LocaleTableIndex, int StringIndex, string strName) { //Get our Locale Table LocaleHandler.LocaleTable selectedTable = LocaleTables[LocaleTableIndex]; //Compare our string lengths. if (selectedTable.LocaleStrings[StringIndex].Name.Length == strName.Length) { //Open our IO Map.OpenIO(); //Go to that locale's position Map.IO.Out.BaseStream.Position = selectedTable.LocaleTableOffset + selectedTable.LocaleStrings[StringIndex].Offset; //Write our new locale. Map.IO.Out.WriteAsciiString(strName, strName.Length); //Close our IO Map.CloseIO(); } else { //Get our variables int differenceStringLength = strName.Length - selectedTable.LocaleStrings[StringIndex].Name.Length; int oldTableSize = selectedTable.LocaleTableSize; int newTableSize = selectedTable.LocaleTableSize + differenceStringLength; int oldTableSizePadded = oldTableSize + ExtraFunctions.CalculatePadding(oldTableSize, 0x1000); int newTableSizePadded = newTableSize + ExtraFunctions.CalculatePadding(newTableSize, 0x1000); int differenceTableSize = newTableSizePadded - oldTableSizePadded; //Let's recalculate some variables. //Open our IO Map.OpenIO(); //Go to our following string index's position Map.IO.Out.BaseStream.Position = selectedTable.LocaleTableIndexOffset + ((StringIndex + 1) * 8); //Loop for every string after. for (int i = StringIndex + 1; i < selectedTable.LocaleCount; i++) { //Skip 4 bytes Map.IO.Out.BaseStream.Position += 4; //Write our new index Map.IO.Out.Write(selectedTable.LocaleStrings[i].Offset + differenceStringLength); } //Let's shift our other tables //Loop for each table after this one. for (int i = LocaleTableIndex + 1; i < LocaleTables.Count; i++) { //Go to that table's offset. Map.IO.Out.BaseStream.Position = LocaleTables[i].Offset + 8; //Shift our values LocaleTables[i].LocaleTableOffset += differenceTableSize; LocaleTables[i].LocaleTableIndexOffset += differenceTableSize; //Write our values. Map.IO.Out.Write((LocaleTables[i].LocaleTableIndexOffset - Map.MapHeader.localeTableAddressModifier)); Map.IO.Out.Write((LocaleTables[i].LocaleTableOffset - Map.MapHeader.localeTableAddressModifier)); } byte[] restOfTable = new byte[0]; try { //Read the rest of our table after we'll insert Map.IO.In.BaseStream.Position = selectedTable.LocaleTableOffset + selectedTable.LocaleStrings[StringIndex + 1].Offset; restOfTable = Map.IO.In.ReadBytes(oldTableSize - selectedTable.LocaleStrings[StringIndex].Offset); } catch { } //Close our IO Map.CloseIO(); //Check our difference. if (differenceTableSize > 0) { //Insert ExtraFunctions.InsertBytes(Map.FileName, selectedTable.LocaleTableOffset + oldTableSizePadded, differenceTableSize); } else if (differenceTableSize < 0) { //Delete ExtraFunctions.DeleteBytes(Map.FileName, selectedTable.LocaleTableOffset + newTableSizePadded, oldTableSizePadded - newTableSizePadded); } //Open our IO Map.OpenIO(); //Let's write our new strings name. Map.IO.Out.BaseStream.Position = selectedTable.LocaleTableOffset + selectedTable.LocaleStrings[StringIndex].Offset; Map.IO.Out.WriteAsciiString(strName, strName.Length + 1); //Write the ending of our table Map.IO.Out.Write(restOfTable); Map.IO.Out.Write(new byte[newTableSizePadded - newTableSize]); //Lets go write our new locale table size Map.IO.Out.BaseStream.Position = selectedTable.Offset + 4; //Write our new size. Map.IO.Out.Write(newTableSize); //Close our IO Map.CloseIO(); //Set our new table size selectedTable.LocaleTableSize = newTableSize; } //Open our IO Map.OpenIO(); //Go back to the beginning of the table Map.IO.SeekTo(selectedTable.LocaleTableOffset); byte[] hash = SHA1.Create().ComputeHash(Map.IO.In.ReadBytes( selectedTable.LocaleTableSize)); //Seek to where the hash is Map.IO.SeekTo(selectedTable.Offset + 0x24); //Write it Map.IO.Out.Write(hash); //Go back to the beginning of the index table Map.IO.SeekTo(selectedTable.LocaleTableIndexOffset); hash = SHA1.Create().ComputeHash(Map.IO.In.ReadBytes(0x08 * selectedTable.LocaleCount)); //Seek to where the hash is Map.IO.SeekTo(selectedTable.Offset + 0x10); //Write it Map.IO.Out.Write(hash); //Close our IO Map.CloseIO(); }