public itemFormat(BinaryReader br, FFXIEncoding FFXIConvert) { String[] ItemTexts = new String[9]; itemHeader = new itemHeaderFormat(br); long data_pos = 0; UInt32 num_strings = 0, offset = 0, flags = 0; // Objects (General Items) skip 6 bytes // Objects (General Items) skip 10 bytes (another 4 [UINT32]) sometime before January 8, 2014) if ((itemHeader.ID <= 0x0FFF) && (itemHeader.ID >= 0x0000)) br.BaseStream.Position = itemHeader.HeaderSize + 10; // Usable items skip 2 bytes // Usable Items skip 6 bytes as of March 10, 2008 Update (new UINT32) // Usable Items skip another 4 bytes (total of 10) sometime before January 8, 2014 (new UINT32) else if ((itemHeader.ID <= 0x1FFF) && (itemHeader.ID >= 0x1000)) br.BaseStream.Position = itemHeader.HeaderSize + 10; // Gil skip just 2 bytes else if (itemHeader.ID == 0xFFFF) br.BaseStream.Position = itemHeader.HeaderSize + 2; // Puppet Items, skip 8 bytes else if ((itemHeader.ID <= 0x27FF) && (itemHeader.ID >= 0x2000)) br.BaseStream.Position = itemHeader.HeaderSize + 10; // Unknown is 0x04 bytes not 0x02 // Armor Specific Info, 22 bytes to skip to get to text // 26 in March 10, 2008 Update (new UINT32) else if ((itemHeader.ID <= 0x3FFF) && (itemHeader.ID >= 0x2800)) br.BaseStream.Position = itemHeader.HeaderSize + 26; // Weapon Specific Info, 30 bytes to skip // 34 bytes in March 10, 2008 Update (new UINT32) else if ((itemHeader.ID <= 0x6FFF) && (itemHeader.ID >= 0x4000)) br.BaseStream.Position = itemHeader.HeaderSize + 34; // Unknown, should not have anything in the way... else br.BaseStream.Position = itemHeader.HeaderSize + 2; data_pos = br.BaseStream.Position; num_strings = br.ReadUInt32(); long fallback_pos = 0; for (int i = 0; (i < num_strings); i++) { // if (num_strings >= 5) //{ int x = i; } offset = br.ReadUInt32(); flags = br.ReadUInt32(); fallback_pos = br.BaseStream.Position; // Indicator (UInt32) + UInt32 x 6 Padding before text br.BaseStream.Position = data_pos + offset + 28; byte[] b = new byte[4]; int counter = 0; do { if (br.BaseStream.Position >= br.BaseStream.Length) break; if (b == null) b = new byte[4]; else if ((counter + 4) > b.Length) Array.Resize(ref b, (int)(counter + 4)); b[counter++] = br.ReadByte(); b[counter++] = br.ReadByte(); b[counter++] = br.ReadByte(); b[counter++] = br.ReadByte(); if (b[counter - 1] == 0x00) break; } while (true); /*if (i > ItemTexts.Length) { i = i+0; break; }*/ ItemTexts[i] = FFXIConvert.GetString(b).Trim().Trim("\0\u0001.".ToCharArray()); br.BaseStream.Position = fallback_pos; } text = ItemTexts[0]; if (num_strings <= 4) // Japanese (no log name, same as shortname) logtext = text; else if (num_strings <= 5) // English (shortname, logname is position 3) logtext = ItemTexts[2]; else if (num_strings <= 6) // French (shortname, logname is position 4) logtext = ItemTexts[3]; else if (num_strings <= 9) logtext = ItemTexts[4]; else logtext = text; }
public d_msgEntryFormat(BinaryReader _bfile, d_msgHeaderFormat _header, FFXIEncoding FFXIConvert) { if (_bfile.BaseStream.Position == _bfile.BaseStream.Length) return; // Loader for the new way as of April 2007 long start_of_data_block = _bfile.BaseStream.Position; long saved_pos = _bfile.BaseStream.Position; UInt32 string_count; if (_header.ToCSize == 0) // no ToC, use EntrySize { #region if _header.ToCSize == 0 (Use EntrySize) start_of_data_block = _bfile.BaseStream.Position; if (_header.AreBitsFlipped) string_count = ~(_bfile.ReadUInt32()); else string_count = _bfile.ReadUInt32(); if ((string_count < 1) || (string_count > 100)) { _bfile.BaseStream.Position = start_of_data_block + _header.EntrySize; return; } data = new String[string_count]; byte[] b; UInt32 type = 0; for (int str_cnt = 0; str_cnt < string_count; str_cnt++) { data[str_cnt] = String.Empty; if (_header.AreBitsFlipped) { offset = ~(_bfile.ReadUInt32()); length = ~(_bfile.ReadUInt32()); // Use "length" for flags } else { offset = _bfile.ReadUInt32(); length = _bfile.ReadUInt32(); // Use "length" for flags } saved_pos = _bfile.BaseStream.Position; _bfile.BaseStream.Position = start_of_data_block + offset; type = _bfile.ReadUInt32(); if (_header.AreBitsFlipped) type = ~type; b = new byte[4]; if ((length == 1) && (str_cnt == 0) && (string_count > 3)) // It's not a String. { // Hack right now for Key Items. MessageID = (byte)(type & 0x00FF); // already converted. GroupID = (byte)((type & 0xFF00) >> 8); _bfile.BaseStream.Position = saved_pos; continue; } else if (length == 1) { _bfile.BaseStream.Position = saved_pos; continue; } _bfile.BaseStream.Position += 24; // add 24 bytes to get to actual text. byte[] b_xfer = null; do { b[0] = _bfile.ReadByte(); b[1] = _bfile.ReadByte(); b[2] = _bfile.ReadByte(); b[3] = _bfile.ReadByte(); if (_header.AreBitsFlipped) { b[0] = (byte)(~((uint)b[0])); b[1] = (byte)(~((uint)b[1])); b[2] = (byte)(~((uint)b[2])); b[3] = (byte)(~((uint)b[3])); } if (b_xfer == null) b_xfer = new byte[4]; else Array.Resize(ref b_xfer, b_xfer.Length + 4); b_xfer[b_xfer.Length - 4] = b[0]; b_xfer[b_xfer.Length - 3] = b[1]; b_xfer[b_xfer.Length - 2] = b[2]; b_xfer[b_xfer.Length - 1] = b[3]; if (b[3] == 0x00) break; } while (true); data[str_cnt] = FFXIConvert.GetString(b_xfer).Trim('\0'); _bfile.BaseStream.Position = saved_pos; } _bfile.BaseStream.Position = start_of_data_block + _header.EntrySize; #endregion } else if (_header.EntrySize == 0) // use ToCSize { #region if _header.EntrySize == 0 (Use ToCSize) start_of_data_block = _header.HeaderSize + _header.ToCSize; offset = _bfile.ReadUInt32(); length = _bfile.ReadUInt32(); if (_header.AreBitsFlipped) { offset = ~offset; length = ~length; } saved_pos = _bfile.BaseStream.Position; _bfile.BaseStream.Position = start_of_data_block + offset + 40; data = new String[1]; if (_header.AreBitsFlipped) data[0] = FFXIConvert.GetString(Fix(_bfile.ReadBytes((int)length - 40))).Trim('\0'); else data[0] = FFXIConvert.GetString(_bfile.ReadBytes((int)length - 40)).Trim('\0'); _bfile.BaseStream.Position = saved_pos; #endregion } else return; }