private void PaddingSeek(BinaryReaderX br) { long remainder = br.BaseStream.Position % 16; if (remainder > 0) { paddingChar = br.ReadByte(); br.BaseStream.Seek(-1, SeekOrigin.Current); br.BaseStream.Seek(16 - remainder, SeekOrigin.Current); } }
private void ReadTXT2(BinaryReaderX br) { TXT2.Identifier = br.ReadBytes(4); TXT2.SectionSize = br.ReadUInt32(); TXT2.Unknown1 = br.ReadBytes(8); long startOfStrings = br.BaseStream.Position; TXT2.NumberOfStrings = br.ReadUInt32(); List<UInt32> offsets = new List<UInt32>(); for (int i = 0; i < TXT2.NumberOfStrings; i++) offsets.Add(br.ReadUInt32()); for (int i = 0; i < TXT2.NumberOfStrings; i++) { Entry entry = new Entry(); bool eos = false; UInt32 nextOffset = (i + 1 < offsets.Count) ? ((UInt32)startOfStrings + offsets[i + 1]) : ((UInt32)startOfStrings + TXT2.SectionSize); br.BaseStream.Seek(startOfStrings + offsets[i], SeekOrigin.Begin); List<byte> result = new List<byte>(); while (!eos) { if (br.BaseStream.Position == nextOffset || br.BaseStream.Position == Header.FileSize) eos = true; else { byte[] unichar = br.ReadBytes(2); if (Header.ByteOrderMark[0] == 0xFE) Array.Reverse(unichar); if (unichar[0] != 0x0 || unichar[1] != 0x0) result.AddRange(unichar); else { Value val = new Value(); val.Data = result.ToArray(); if (result.Count == 0) val.Editable = false; entry.Values.Add(val); result.Clear(); } } } // Strange extended string without null termination if (result.Count > 1) { Value finalVal = new Value(); finalVal.Data = result.ToArray(); finalVal.Editable = false; finalVal.NullTerminated = false; entry.Values.Add(finalVal); } entry.Index = i; TXT2.OriginalEntries.Add(entry); // Duplicate entries for editing Entry entryEdited = new Entry(); foreach (Value value in entry.Values) { Value val = new Value(); val.Data = value.Data; val.Editable = value.Editable; val.NullTerminated = value.NullTerminated; entryEdited.Values.Add(val); } entryEdited.Value = entry.Value; entryEdited.Index = entry.Index; TXT2.Entries.Add(entryEdited); } PaddingSeek(br); }
private void ReadTSY1(BinaryReaderX br) { TSY1.Identifier = br.ReadBytes(4); TSY1.SectionSize = br.ReadUInt32(); TSY1.Unknown1 = br.ReadBytes(8); TSY1.Unknown2 = br.ReadBytes((int)TSY1.SectionSize); // Read in the entire section at once since we don't know what it's for PaddingSeek(br); }
private void ReadATR1(BinaryReaderX br) { ATR1.Identifier = br.ReadBytes(4); ATR1.SectionSize = br.ReadUInt32(); ATR1.Unknown1 = br.ReadBytes(8); ATR1.NumberOfAttributes = br.ReadUInt32(); ATR1.Unknown2 = br.ReadBytes((int)ATR1.SectionSize - sizeof(UInt32)); // Read in the rest of the section at once since we don't know what it's for PaddingSeek(br); }
private void ReadLBL1(BinaryReaderX br) { // TODO: Continue reverse engineering the LBL1 section because the magic value below shouldn't be the end game long offset = br.BaseStream.Position; LBL1.Identifier = br.ReadBytes(4); LBL1.SectionSize = br.ReadUInt32(); LBL1.Unknown1 = br.ReadBytes(8); LBL1.Unknown2 = br.ReadBytes(8); uint startOfLabels = 0x35C; // Magic LBL1 label start position LBL1.Unknown3 = br.ReadBytes((int)(startOfLabels - br.BaseStream.Position)); while (br.BaseStream.Position < (offset + LBL1.Identifier.Length + sizeof(UInt32) + LBL1.Unknown1.Length + LBL1.SectionSize)) { Entry lbl = new Entry(); lbl.Length = Convert.ToUInt32(br.ReadByte()); lbl.Value = br.ReadBytes((int)lbl.Length); lbl.Index = br.ReadInt32(); LBL1.Labels.Add(lbl); } HasLabels = LBL1.Labels.Count > 0; PaddingSeek(br); }
public MSBT(string filename) { File = new FileInfo(filename); if (File.Exists && filename.Length > 0) { FileStream fs = System.IO.File.Open(File.FullName, FileMode.Open, FileAccess.Read, FileShare.None); BinaryReaderX br = new BinaryReaderX(fs); // Initialize Members LBL1.Labels = new List<Entry>(); ATR1.Attributes = new List<UInt32>(); TXT2.OriginalEntries = new List<Entry>(); TXT2.Entries = new List<Entry>(); // Header Header.Identifier = br.ReadBytes(8); if (Encoding.ASCII.GetString(Header.Identifier) != "MsgStdBn") throw new InvalidMSBTException("The file provided is not a valid MSBT file."); Header.ByteOrderMark = br.ReadBytes(2); // Byte Order br.ByteOrder = Header.ByteOrderMark[0] > Header.ByteOrderMark[1] ? ByteOrder.LittleEndian : ByteOrder.BigEndian; Header.Unknown1 = br.ReadUInt16(); Header.Unknown2 = br.ReadUInt16(); Header.NumberOfSections = br.ReadUInt16(); Header.Unknown3 = br.ReadUInt16(); Header.FileSizeOffset = (UInt32)br.BaseStream.Position; Header.FileSize = br.ReadUInt32(); Header.Unknown4 = br.ReadBytes(10); if (Header.FileSize != br.BaseStream.Length) throw new InvalidMSBTException("The file provided is not a valid MSBT file."); SectionOrder.Clear(); for (int i = 0; i < Header.NumberOfSections; i++) { // Section Detection if (br.PeekString() == "LBL1") { ReadLBL1(br); SectionOrder.Add("LBL1"); } else if (br.PeekString() == "NLI1") { ReadNLI1(br); SectionOrder.Add("NLI1"); } else if (br.PeekString() == "ATR1") { ReadATR1(br); SectionOrder.Add("ATR1"); } else if (br.PeekString() == "TSY1") { ReadTSY1(br); SectionOrder.Add("TSY1"); } else if (br.PeekString() == "TXT2") { ReadTXT2(br); SectionOrder.Add("TXT2"); } } br.Close(); } }