Example #1
0
        static Dictionary <uint, Dictionary <uint, SqFile> > readIndex(string indexPath)
        {
            Dictionary <uint, Dictionary <uint, SqFile> > sqFiles = new Dictionary <uint, Dictionary <uint, SqFile> >();

            using (FileStream fs = File.OpenRead(indexPath))
                using (BinaryReader br = new BinaryReader(fs))
                {
                    br.BaseStream.Position = 0xc;
                    int headerOffset = br.ReadInt32();

                    br.BaseStream.Position = headerOffset + 0x8;
                    int fileOffset = br.ReadInt32();
                    int fileCount  = br.ReadInt32() / 0x10;

                    br.BaseStream.Position = fileOffset;
                    for (int i = 0; i < fileCount; i++)
                    {
                        SqFile sqFile = new SqFile();
                        sqFile.Key           = br.ReadUInt32();
                        sqFile.DirectoryKey  = br.ReadUInt32();
                        sqFile.WrappedOffset = br.ReadInt32();
                        br.ReadInt32();

                        if (!sqFiles.ContainsKey(sqFile.DirectoryKey))
                        {
                            sqFiles.Add(sqFile.DirectoryKey, new Dictionary <uint, SqFile>());
                        }
                        sqFiles[sqFile.DirectoryKey].Add(sqFile.Key, sqFile);
                    }
                }

            return(sqFiles);
        }
        // Decode ExD from the raw data and create new ExD instance.
        public ExDFile(SqFile sqFile, ExHFile exHFile)
        {
            Header = exHFile;

            // Read the raw data from SqFile.
            byte[] data = sqFile.ReadData();

            // Quit if no data is available.
            if (data == null || data.Length == 0)
            {
                return;
            }

            // Retrieve offset entries and total row sizes from the data header.
            int offsetEntriesSize = ToInt32(data, 0x8, true);
            int totalRowSize      = ToInt32(data, 0xc, true);

            // Copy offset entries from raw data for easier manipulation.
            // Offset entries start from 0x20.
            byte[] offsetEntries = new byte[offsetEntriesSize];
            Array.Copy(data, 0x20, offsetEntries, 0, offsetEntriesSize);

            // Copy all rows from raw data for easier manipulation.
            // Rows start right after offset entries.
            byte[] rawRows = new byte[totalRowSize];
            Array.Copy(data, 0x20 + offsetEntriesSize, rawRows, 0, totalRowSize);

            // Going through each offset entry.
            // Offset entry size is 0x8.
            for (int i = 0; i < offsetEntriesSize; i += 0x8)
            {
                ExDRow row = new ExDRow();
                row.Parent = this;

                // First 32 bits of the offset entry is the key for the row that we're reading.
                row.Key = ToInt32(offsetEntries, i, true);

                // Next 32 bits are the actual offset.
                row.Offset = ToInt32(offsetEntries, i + 0x4, true);

                // The offset includes the offset entries and 0x20 bytes for the raw header.
                // Actual position in the raw row byte array would be offset - raw header size - offset entries size.
                int rawRowPosition = row.Offset - 0x20 - offsetEntriesSize;

                // First 4 bytes in the raw row data is the size of the raw data.
                row.Size = ToInt32(rawRows, rawRowPosition, true);

                // Next 2 bytes are the check digit.
                row.CheckDigit = ToInt16(rawRows, rawRowPosition + 0x4, true);

                // After the size and the check digit, the raw data is actually divided into two sections.
                // First section is the fixed size data.
                // Copy it over to separate array for easier manipulation.
                byte[] fixedSizeData = new byte[exHFile.FixedSizeDataLength];
                Array.Copy(rawRows, rawRowPosition + 0x6, fixedSizeData, 0, exHFile.FixedSizeDataLength);

                // Finally, rest of the raw row is the second section which contains the additional data that are used for some columns with varying lengths. (i.e. string type)
                byte[] additionalData = new byte[row.Size - exHFile.FixedSizeDataLength];
                Array.Copy(rawRows, rawRowPosition + 0x6 + exHFile.FixedSizeDataLength, additionalData, 0, additionalData.Length);

                // Let's go through each column of this row now.
                foreach (ExHColumn column in exHFile.Columns)
                {
                    ExDData parsedData = new ExDData();

                    switch (column.Type)
                    {
                    // String type.
                    case 0x0:
                        // The first 4 bytes of the fixed size data contain the starting offset for the additional data section.
                        int valueStart = ToInt32(fixedSizeData, column.Offset, true);

                        // The additional data is 0-terminated.
                        int valueEnd = valueStart;
                        while (valueEnd < additionalData.Length && additionalData[valueEnd] != 0)
                        {
                            valueEnd++;
                        }

                        // Copy the value from additional data to new byte array for decoding.
                        byte[] field = new byte[valueEnd - valueStart];
                        Array.Copy(additionalData, valueStart, field, 0, field.Length);

                        // Decode it as string.
                        parsedData.Type  = typeof(string);
                        parsedData.Value = DecodeString(field);
                        break;

                    // Bool type.
                    case 0x1:
                        // The first byte of the fixed size data is the boolean value.
                        parsedData.Type  = typeof(bool);
                        parsedData.Value = fixedSizeData[column.Offset] != 0;
                        break;

                    // Signed byte type.
                    case 0x2:
                        // The first byte of the fixed size data is the value.
                        parsedData.Type  = typeof(sbyte);
                        parsedData.Value = (sbyte)fixedSizeData[column.Offset];
                        break;

                    // Byte type.
                    case 0x3:
                        // The first byte of the fixed size data is the value.
                        parsedData.Type  = typeof(byte);
                        parsedData.Value = fixedSizeData[column.Offset];
                        break;

                    // Short type.
                    case 0x4:
                        // The first 2 bytes of the fixed size data are the value.
                        parsedData.Type  = typeof(short);
                        parsedData.Value = ToInt16(fixedSizeData, column.Offset, true);
                        break;

                    // Ushort type.
                    case 0x5:
                        // The first 2 bytes of the fixed size data are the value.
                        parsedData.Type  = typeof(ushort);
                        parsedData.Value = ToUInt16(fixedSizeData, column.Offset, true);
                        break;

                    // Int type.
                    case 0x6:
                        // The first 4 bytes of the fixed size data are the value.
                        parsedData.Type  = typeof(int);
                        parsedData.Value = ToInt32(fixedSizeData, column.Offset, true);
                        break;

                    // Uint type.
                    case 0x7:
                        // The first 4 bytes of the fixed size data are the value.
                        parsedData.Type  = typeof(uint);
                        parsedData.Value = ToUInt32(fixedSizeData, column.Offset, true);
                        break;

                    // Float type.
                    case 0x9:
                        // The first 4 bytes of the fixed size data are the value.
                        parsedData.Type  = typeof(float);
                        parsedData.Value = ToSingle(fixedSizeData, column.Offset, true);
                        break;

                    // Long type.
                    case 0xb:
                        // The first 8 bytes of the fixed size data are the value.
                        parsedData.Type  = typeof(long);
                        parsedData.Value = ToInt64(fixedSizeData, column.Offset, true);
                        break;

                    // Masked boolean types.
                    // The first byte of the fixed size data contains the boolean value, where the bit offset is type value - 0x19 from right.
                    case 0x19:
                    case 0x1a:
                    case 0x1b:
                    case 0x1c:
                    case 0x1d:
                    case 0x1e:
                    case 0x1f:
                    case 0x20:
                        parsedData.Type  = typeof(bool);
                        parsedData.Value = (fixedSizeData[column.Offset] & (0x1 << (column.Type - 0x19))) != 0;
                        break;

                    // Unrecognized type.
                    default:
                        throw new Exception($"Unrecognized column type: 0x{column.Type.ToString("x")}");
                    }

                    row.Data.Add(column, parsedData);
                }

                Rows.Add(row);
            }
        }
Example #3
0
        // Decode ExH from the raw data and create new ExH instance.
        public ExHFile(SqFile sqFile)
        {
            // Read the SqFile raw data.
            byte[] data = sqFile.ReadData();

            // Quit if no data is available.
            if (data == null || data.Length == 0)
            {
                return;
            }

            // Some big endian values from fixed offset.
            FixedSizeDataLength = ToUInt16(data, 0x6, true);
            Variant             = ToUInt16(data, 0x10, true);

            // Counts for various entries.
            ushort columnCount = ToUInt16(data, 0x8, true);
            ushort rangeCount  = ToUInt16(data, 0xa, true);
            ushort langCount   = ToUInt16(data, 0xc, true);

            // Only care about ExD data table type headers.
            if (Variant != 1)
            {
                return;
            }

            Columns = new ExHColumn[columnCount];
            for (int i = 0; i < columnCount; i++)
            {
                // Column offsets start after the fixed offset values (0x20).
                // Each column offset is 4 bytes long.
                int columnOffset = 0x20 + i * 0x4;
                Columns[i] = new ExHColumn()
                {
                    Type   = ToUInt16(data, columnOffset, true),
                    Offset = ToUInt16(data, columnOffset + 0x2, true)
                };
            }

            Ranges = new ExHRange[rangeCount];
            for (int i = 0; i < rangeCount; i++)
            {
                // Range offsets start after the column offsets.
                // Each range offset is 8 bytes long.
                int rangeOffset = (0x20 + columnCount * 0x4) + i * 0x8;
                Ranges[i] = new ExHRange()
                {
                    Start  = ToInt32(data, rangeOffset, true),
                    Length = ToInt32(data, rangeOffset + 0x4, true)
                };
            }

            Languages = new ExHLanguage[langCount];
            for (int i = 0; i < langCount; i++)
            {
                // Language offsets start after the range offsets.
                // Each language offset is 2 bytes long.
                int langOffset = ((0x20 + columnCount * 0x4) + rangeCount * 0x8) + i * 0x2;
                Languages[i] = new ExHLanguage()
                {
                    Value = data[langOffset]
                };
            }
        }
Example #4
0
        static void Main(string[] args)
        {
            string baseDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            string globalIndexPath = Path.Combine(baseDir, "global", "000000.win32.index");
            string globalDatPath   = Path.Combine(baseDir, "global", "000000.win32.dat0");

            string koIndexPath = Path.Combine(baseDir, "korean", "000000.win32.index");
            string koDatPath   = Path.Combine(baseDir, "korean", "000000.win32.dat0");

            string outputDir = Path.Combine(baseDir, "output");

            if (!Directory.Exists(outputDir))
            {
                Directory.CreateDirectory(outputDir);
            }

            Dictionary <uint, Dictionary <uint, SqFile> > globalSqFiles = readIndex(globalIndexPath);
            Dictionary <uint, Dictionary <uint, SqFile> > koSqFiles     = readIndex(koIndexPath);

            string outputIndexPath = Path.Combine(outputDir, Path.GetFileName(globalIndexPath));

            File.Copy(globalIndexPath, outputIndexPath, true);
            //File.Copy(koIndexPath, outputIndexPath, true);
            string outputDatPath = Path.Combine(outputDir, Path.GetFileName(globalDatPath));

            File.Copy(globalDatPath, outputDatPath, true);
            string outputNewDatPath = Path.Combine(outputDir, "000000.win32.dat1");

            File.Copy(koDatPath, outputNewDatPath, true);

            byte[] index = File.ReadAllBytes(outputIndexPath);

            /*Console.WriteLine(koSqFiles[Hash.Compute("common/font")].ContainsKey(Hash.Compute("KrnAxis_96.fdt")));
             * Console.ReadLine();*/

            /*
             * using (StreamWriter sw = new StreamWriter(Path.Combine(outputDir, "global_keys"), false))
             * {
             *  foreach (uint globalKey in globalSqFiles[Hash.Compute("common/font")].Keys)
             *  {
             *      sw.WriteLine(globalKey.ToString());
             *  }
             * }
             *
             * using (StreamWriter sw = new StreamWriter(Path.Combine(outputDir, "korean_keys"), false))
             * {
             *  foreach (uint koreanKey in koSqFiles[Hash.Compute("common/font")].Keys)
             *  {
             *      sw.WriteLine(koreanKey.ToString());
             *  }
             * }
             */

            List <Exchange> exchanges = new List <Exchange>();

            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("font1.tex"),
                GlobalNewKey = Hash.Compute("font1.tex"),
                KoreanKey    = Hash.Compute("font_krn_1.tex")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("font2.tex"),
                GlobalNewKey = Hash.Compute("font2.tex"),
                KoreanKey    = Hash.Compute("font_krn_2.tex")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("font3.tex"),
                GlobalNewKey = Hash.Compute("font3.tex"),
                KoreanKey    = Hash.Compute("font_krn_3.tex")
            });

            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("font_lobby1.tex"),
                GlobalNewKey = Hash.Compute("font_lobby1.tex"),
                KoreanKey    = Hash.Compute("font_krn_1.tex")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("font_lobby2.tex"),
                GlobalNewKey = Hash.Compute("font_lobby2.tex"),
                KoreanKey    = Hash.Compute("font_krn_2.tex")
            });

            /*exchanges.Add(new Exchange()
             * {
             *  GlobalKey = Hash.Compute("font_krn_3.tex"),
             *  GlobalNewKey = Hash.Compute("font_lobby3.tex"),
             *  KoreanKey = Hash.Compute("font_krn_3.tex")
             * });*/

            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("axis_12.fdt"),
                GlobalNewKey = Hash.Compute("axis_12.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_120.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("axis_14.fdt"),
                GlobalNewKey = Hash.Compute("axis_14.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("axis_18.fdt"),
                GlobalNewKey = Hash.Compute("axis_18.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("axis_36.fdt"),
                GlobalNewKey = Hash.Compute("axis_36.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("axis_96.fdt"),
                GlobalNewKey = Hash.Compute("axis_96.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });

            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("miedingermid_10.fdt"),
                GlobalNewKey = Hash.Compute("miedingermid_10.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("miedingermid_12.fdt"),
                GlobalNewKey = Hash.Compute("miedingermid_12.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("miedingermid_14.fdt"),
                GlobalNewKey = Hash.Compute("miedingermid_14.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("miedingermid_18.fdt"),
                GlobalNewKey = Hash.Compute("miedingermid_18.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });

            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("meidinger_16.fdt"),
                GlobalNewKey = Hash.Compute("meidinger_16.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("meidinger_20.fdt"),
                GlobalNewKey = Hash.Compute("meidinger_20.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });

            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("trumpgothic_23.fdt"),
                GlobalNewKey = Hash.Compute("trumpgothic_23.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("trumpgothic_34.fdt"),
                GlobalNewKey = Hash.Compute("trumpgothic_34.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("trumpgothic_184.fdt"),
                GlobalNewKey = Hash.Compute("trumpgothic_184.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });

            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("jupiter_16.fdt"),
                GlobalNewKey = Hash.Compute("jupiter_16.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("jupiter_20.fdt"),
                GlobalNewKey = Hash.Compute("jupiter_20.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("jupiter_23.fdt"),
                GlobalNewKey = Hash.Compute("jupiter_23.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("jupiter_45.fdt"),
                GlobalNewKey = Hash.Compute("jupiter_45.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_180.fdt")
            });

            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("axis_12_lobby.fdt"),
                GlobalNewKey = Hash.Compute("axis_12_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_120.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("axis_14_lobby.fdt"),
                GlobalNewKey = Hash.Compute("axis_14_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("axis_18_lobby.fdt"),
                GlobalNewKey = Hash.Compute("axis_18_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });

            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("miedingermid_10_lobby.fdt"),
                GlobalNewKey = Hash.Compute("miedingermid_10_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("miedingermid_12_lobby.fdt"),
                GlobalNewKey = Hash.Compute("miedingermid_12_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("miedingermid_14_lobby.fdt"),
                GlobalNewKey = Hash.Compute("miedingermid_14_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("miedingermid_18_lobby.fdt"),
                GlobalNewKey = Hash.Compute("miedingermid_18_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });

            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("meidinger_16_lobby.fdt"),
                GlobalNewKey = Hash.Compute("meidinger_16_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("meidinger_20_lobby.fdt"),
                GlobalNewKey = Hash.Compute("meidinger_20_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });

            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("trumpgothic_23_lobby.fdt"),
                GlobalNewKey = Hash.Compute("trumpgothic_23_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("trumpgothic_34_lobby.fdt"),
                GlobalNewKey = Hash.Compute("trumpgothic_34_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("trumpgothic_184_lobby.fdt"),
                GlobalNewKey = Hash.Compute("trumpgothic_184_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });

            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("jupiter_16_lobby.fdt"),
                GlobalNewKey = Hash.Compute("jupiter_16_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("jupiter_20_lobby.fdt"),
                GlobalNewKey = Hash.Compute("jupiter_20_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("jupiter_23_lobby.fdt"),
                GlobalNewKey = Hash.Compute("jupiter_23_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });
            exchanges.Add(new Exchange()
            {
                GlobalKey    = Hash.Compute("jupiter_45_lobby.fdt"),
                GlobalNewKey = Hash.Compute("jupiter_45_lobby.fdt"),
                KoreanKey    = Hash.Compute("KrnAxis_140.fdt")
            });

            foreach (Exchange exchange in exchanges)
            {
                SqFile globalSqFile = globalSqFiles[Hash.Compute("common/font")][exchange.GlobalKey];
                SqFile koSqFile     = koSqFiles[Hash.Compute("common/font")][exchange.KoreanKey];
                koSqFile.DatFile = 1;

                int headerOffset = BitConverter.ToInt32(index, 0xc);
                index[headerOffset + 0x50] = 2;
                int fileOffset = BitConverter.ToInt32(index, headerOffset + 0x8);
                int fileCount  = BitConverter.ToInt32(index, headerOffset + 0xc) / 0x10;
                for (int i = 0; i < fileCount; i++)
                {
                    int  keyOffset    = fileOffset + i * 0x10;
                    uint key          = BitConverter.ToUInt32(index, keyOffset);
                    uint directoryKey = BitConverter.ToUInt32(index, keyOffset + 0x4);

                    if (key == globalSqFile.Key && directoryKey == globalSqFile.DirectoryKey)
                    {
                        Array.Copy(BitConverter.GetBytes(exchange.GlobalNewKey), 0, index, keyOffset, 0x4);
                        Array.Copy(BitConverter.GetBytes(koSqFile.WrappedOffset), 0, index, keyOffset + 0x8, 0x4);
                    }
                }
            }

            /*
             * List<KeyValuePair<string, string>> exchange = new List<KeyValuePair<string, string>>();
             * exchange.Add(new KeyValuePair<string, string>("font_krn_1.tex", "font1.tex"));
             * exchange.Add(new KeyValuePair<string, string>("font_krn_2.tex", "font2.tex"));
             * exchange.Add(new KeyValuePair<string, string>("font_krn_3.tex", "font3.tex"));
             * exchange.Add(new KeyValuePair<string, string>("font_krn_1.tex", "font_lobby1.tex"));
             * exchange.Add(new KeyValuePair<string, string>("KrnAxis_120.fdt", "axis_12.fdt"));
             * exchange.Add(new KeyValuePair<string, string>("KrnAxis_120.fdt", "axis_12_lobby.fdt"));
             * exchange.Add(new KeyValuePair<string, string>("KrnAxis_140.fdt", "axis_14.fdt"));
             * exchange.Add(new KeyValuePair<string, string>("KrnAxis_140.fdt", "axis_14_lobby.fdt"));
             * exchange.Add(new KeyValuePair<string, string>("KrnAxis_180.fdt", "axis_18.fdt"));
             * exchange.Add(new KeyValuePair<string, string>("KrnAxis_180.fdt", "axis_18_lobby.fdt"));
             *
             * foreach (KeyValuePair<string, string> pair in exchange)
             * {
             *  string koKey = pair.Key;
             *  string globalKey = pair.Value;
             *
             *  SqFile globalSqFile = globalSqFiles[Hash.Compute("common/font")][Hash.Compute(globalKey)];
             *  SqFile koSqFile = koSqFiles[Hash.Compute("common/font")][Hash.Compute(koKey)];
             *  koSqFile.DatFile = 1;
             *
             *  int headerOffset = BitConverter.ToInt32(index, 0xc);
             *  index[headerOffset + 0x50] = 2;
             *  int fileOffset = BitConverter.ToInt32(index, headerOffset + 0x8);
             *  int fileCount = BitConverter.ToInt32(index, headerOffset + 0xc) / 0x10;
             *  for (int i = 0; i < fileCount; i++)
             *  {
             *      int keyOffset = fileOffset + i * 0x10;
             *      uint key = BitConverter.ToUInt32(index, keyOffset);
             *      uint directoryKey = BitConverter.ToUInt32(index, keyOffset + 0x4);
             *
             *      if (key == globalSqFile.Key && directoryKey == globalSqFile.DirectoryKey)
             *      {
             *          Array.Copy(BitConverter.GetBytes(koSqFile.WrappedOffset), 0, index, keyOffset + 0x8, 0x4);
             *      }
             *  }
             * }*/

            File.WriteAllBytes(outputIndexPath, index);
        }