Пример #1
0
        private byte[] PackedChunk(ResourceIndexEntry ie)
        {
            byte[] chunk;
            if (ie.IsDirty)
            {
                Stream       res = GetResource(ie);
                BinaryReader r   = new BinaryReader(res);

                res.Position = 0;
                chunk        = r.ReadBytes((int)ie.Memsize);
                if (Checking)
                {
                    if (chunk.Length != (int)ie.Memsize)
                    {
                        throw new OverflowException(
                                  $"packedChunk, dirty resource - T: 0x{ie.ResourceType:X}, G: 0x{ie.ResourceGroup:X}, I: 0x{ie.Instance:X}: Length expected: 0x{ie.Memsize:X}, read: 0x{chunk.Length:X}");
                    }
                }

                byte[] comp = ie.Compressed != 0 ? Compression.CompressStream(chunk) : chunk;
                if (comp.Length < chunk.Length)
                {
                    chunk = comp;
                }
            }
            else
            {
                if (Checking)
                {
                    if (_packageStream == null)
                    {
                        throw new InvalidOperationException(
                                  $"Clean resource with undefined \"current package\" - T: 0x{ie.ResourceType:X}, G: 0x{ie.ResourceGroup:X}, I: 0x{ie.Instance:X}");
                    }
                }
                _packageStream.Position = ie.Chunkoffset;
                chunk = (new BinaryReader(_packageStream)).ReadBytes((int)ie.Filesize);
                if (Checking)
                {
                    if (chunk.Length != (int)ie.Filesize)
                    {
                        throw new OverflowException(
                                  $"packedChunk, clean resource - T: 0x{ie.ResourceType:X}, G: 0x{ie.ResourceGroup:X}, I: 0x{ie.Instance:X}: Length expected: 0x{ie.Filesize:X}, read: 0x{chunk.Length:X}");
                    }
                }
            }
            return(chunk);
        }
Пример #2
0
        public IResourceIndexEntry Add(IResourceKey rk)
        {
            ResourceIndexEntry rc = new ResourceIndexEntry(new int[Hdrsize], new int[NumFields - Hdrsize])
            {
                ResourceType   = rk.ResourceType,
                ResourceGroup  = rk.ResourceGroup,
                Instance       = rk.Instance,
                Chunkoffset    = 0xffffffff,
                Unknown2       = 1,
                ResourceStream = null
            };


            base.Add(rc);
            return(rc);
        }
Пример #3
0
        /// <summary>
        /// Return the index entry with the matching TGI
        /// </summary>
        /// <param name="type">Entry type</param>
        /// <param name="group">Entry group</param>
        /// <param name="instance">Entry instance</param>
        /// <returns>Matching entry</returns>
        public IResourceIndexEntry this[uint type, uint group, ulong instance]
        {
            get
            {
                for (int index = 0; index < Count; index++)
                {
                    ResourceIndexEntry rie = (ResourceIndexEntry)this[index];
                    if (rie.ResourceType != type)
                    {
                        continue;
                    }
                    if (rie.ResourceGroup != @group)
                    {
                        continue;
                    }
                    if (rie.Instance == instance)
                    {
                        return(rie);
                    }
                }

                return(null);
            }
        }
Пример #4
0
        /// <summary>
        /// Save the package to a given stream
        /// </summary>
        /// <param name="s">Stream to save to</param>
        public override void SaveAs(Stream s)
        {
            BinaryWriter w = new BinaryWriter(s);

            w.Write(_header);

            List <uint> lT  = new List <uint>();
            List <uint> lG  = new List <uint>();
            List <uint> lIh = new List <uint>();

            for (int i = 0; i < Index.Count; i++)
            {
                IResourceIndexEntry x = Index[i];
                if (!lT.Contains(x.ResourceType))
                {
                    lT.Add(x.ResourceType);
                }
                if (!lG.Contains(x.ResourceGroup))
                {
                    lG.Add(x.ResourceGroup);
                }
                if (!lIh.Contains((uint)(x.Instance >> 32)))
                {
                    lIh.Add((uint)(x.Instance >> 32));
                }
            }

            uint indexType = (uint)(lIh.Count <= 1 ? 0x04 : 0x00) | (uint)(lG.Count <= 1 ? 0x02 : 0x00) | (uint)(lT.Count <= 1 ? 0x01 : 0x00);

            PackageIndex newIndex = new PackageIndex(indexType);

            for (int i = 0; i < Index.Count; i++)
            {
                IResourceIndexEntry ie = Index[i];
                if (ie.IsDeleted)
                {
                    continue;
                }

                ResourceIndexEntry newIe = (ie as ResourceIndexEntry)?.Clone();
                ((List <IResourceIndexEntry>)newIndex).Add(newIe);
                byte[] value = PackedChunk(ie as ResourceIndexEntry);

                newIe.Chunkoffset = (uint)s.Position;
                w.Write(value);
                w.Flush();

                if (value.Length < newIe.Memsize)
                {
                    newIe.Compressed = 0xffff;
                    newIe.Filesize   = (uint)value.Length;
                }
                else
                {
                    newIe.Compressed = 0x0000;
                    newIe.Filesize   = newIe.Memsize;
                }
            }

            long indexpos = s.Position;

            newIndex.Save(w);
            SetIndexcount(w, newIndex.Count);
            SetIndexsize(w, newIndex.Size);
            SetIndexposition(w, (int)indexpos);
            s.Flush();
        }