public static SctItem CreateFromStream(DataStream dsr, uint size) { // All we care about right now is if it's a dialog item or not. // Skip the preamble long startPosition = dsr.StreamPosition; byte[] rawData = dsr.ReadBytes((int)size); SctItem item; // Dialog items start with 5C 68 28 if (size < ItemPreambleSize + 3 || rawData[ItemPreambleSize + 0] != 0x5C || rawData[ItemPreambleSize + 1] != 0x68 || rawData[ItemPreambleSize + 2] != 0x28) { item = new SctItem(rawData); } else { item = new DialogItem(rawData); } dsr.StreamPosition = startPosition; return(item); }
private void ReadDataBlocks(DataStream ds) { for (int i = 0; i < ItemHeaders.Count; i++) { ds.StreamPosition = ItemHeaders[i].DataOffset; var item = SctItem.CreateFromStream(ds, ItemHeaders[i].DataSize); bool isLastItem = (i == ItemHeaders.Count - 1); uint start = ItemHeaders[i].DataOffset; DataStream dataStream = new DataStream(new MemoryStream(item.Data), Endianness.BigEndian); for (long offset = 0; offset < ItemHeaders[i].DataSize; offset += 4) { long relOffset = dataStream.ReadUint(); long absOffset = relOffset + start + offset; long filenameSectionOffset = ItemHeaders[ItemHeaders.Count - 1].DataOffset; // Check if the offset points to one of the filenames at the end of the file. if (!isLastItem && absOffset >= filenameSectionOffset && absOffset < ds.Length) { long oldPos = ds.StreamPosition; ds.Stream.Seek(absOffset, SeekOrigin.Begin); int nameLength = 0; while (true) { byte b = ds.ReadByte(); char c = (char)b; if (char.IsLetterOrDigit(c) || c == '.' || c == '_') { nameLength++; } else if (b == 0 && nameLength > 0) { ItemHeaders[i].FileNamePointers.Add(offset); break; } else { break; } } ds.Stream.Seek(oldPos, SeekOrigin.Begin); } if (absOffset <= int.MaxValue) { for (int j = 0; j < ItemHeaders.Count; j++) { if (i != j && ItemHeaders[j].DataOffset == absOffset) { if (!PointerRecords.ContainsKey(i)) { PointerRecords.Add(i, new List <PointerRecord>()); } var pointersForItem = PointerRecords[i]; pointersForItem.Add(new PointerRecord { TargetIndex = j, Offset = offset }); } } } } Items.Add(item); } }