Example #1
0
        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);
        }
Example #2
0
        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);
            }
        }