Beispiel #1
0
        public IResourceIndexEntry Add(IResourceKey rk)
        {
            ResourceIndexEntry rc = new ResourceIndexEntry(new Int32[Hdrsize], new Int32[numFields - Hdrsize]);

            rc.ResourceType   = rk.ResourceType;
            rc.ResourceGroup  = rk.ResourceGroup;
            rc.Instance       = rk.Instance;
            rc.Chunkoffset    = 0xffffffff;
            rc.Unknown2       = 1;
            rc.ResourceStream = null;

            base.Add(rc);
            return(rc);
        }
        private byte[] packedChunk(ResourceIndexEntry ie)
        {
            byte[] chunk = null;
            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(String.Format("packedChunk, dirty resource - T: 0x{0:X}, G: 0x{1:X}, I: 0x{2:X}: Length expected: 0x{3:X}, read: 0x{4:X}",
                                                                  ie.ResourceType, ie.ResourceGroup, ie.Instance, ie.Memsize, chunk.Length));
                    }
                }

                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(String.Format("Clean resource with undefined \"current package\" - T: 0x{0:X}, G: 0x{1:X}, I: 0x{2:X}",
                                                                          ie.ResourceType, ie.ResourceGroup, ie.Instance));
                    }
                }
                packageStream.Position = ie.Chunkoffset;
                chunk = (new BinaryReader(packageStream)).ReadBytes((int)ie.Filesize);
                if (checking)
                {
                    if (chunk.Length != (int)ie.Filesize)
                    {
                        throw new OverflowException(String.Format("packedChunk, clean resource - T: 0x{0:X}, G: 0x{1:X}, I: 0x{2:X}: Length expected: 0x{3:X}, read: 0x{4:X}",
                                                                  ie.ResourceType, ie.ResourceGroup, ie.Instance, ie.Filesize, chunk.Length));
                    }
                }
            }
            return(chunk);
        }
        // Required by API, not user tools

        /// <summary>
        /// Required internally by s3pi - <b>not</b> for use in user tools.
        /// Please use <c>WrapperDealer.GetResource(int, IPackage, IResourceIndexEntry)</c> instead.
        /// </summary>
        /// <param name="rc">IResourceIndexEntry of resource</param>
        /// <returns>The resource data (uncompressed, if necessary)</returns>
        /// <remarks>Used by WrapperDealer to get the data for a resource.</remarks>
        public override Stream GetResource(IResourceIndexEntry rc)
        {
            ResourceIndexEntry rie = rc as ResourceIndexEntry;

            if (rie == null)
            {
                return(null);
            }
            if (rie.ResourceStream != null)
            {
                return(rie.ResourceStream);
            }

            if (rc.Chunkoffset == 0xffffffff)
            {
                return(null);
            }
            packageStream.Position = rc.Chunkoffset;

            byte[] data = null;
            if (rc.Filesize == 1 && rc.Memsize == 0xFFFFFFFF)
            {
                return(null);                                             //{ data = new byte[0]; }
            }
            else if (rc.Filesize == rc.Memsize)
            {
                data = (new BinaryReader(packageStream)).ReadBytes((int)rc.Filesize);
            }
            else
            {
                data = Compression.UncompressStream(packageStream, (int)rc.Filesize, (int)rc.Memsize);
            }

            MemoryStream ms = new MemoryStream();

            ms.Write(data, 0, data.Length);
            ms.Position = 0;
            return(ms);
        }
Beispiel #4
0
        private byte[] packedChunk(ResourceIndexEntry ie)
        {
            byte[] chunk = null;
            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(String.Format("packedChunk, dirty resource - T: 0x{0:X}, G: 0x{1:X}, I: 0x{2:X}: Length expected: 0x{3:X}, read: 0x{4:X}",
                            ie.ResourceType, ie.ResourceGroup, ie.Instance, ie.Memsize, chunk.Length));

                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(String.Format("Clean resource with undefined \"current package\" - T: 0x{0:X}, G: 0x{1:X}, I: 0x{2:X}",
                            ie.ResourceType, ie.ResourceGroup, ie.Instance));
                packageStream.Position = ie.Chunkoffset;
                chunk = (new BinaryReader(packageStream)).ReadBytes((int)ie.Filesize);
                if (checking) if (chunk.Length != (int)ie.Filesize)
                        throw new OverflowException(String.Format("packedChunk, clean resource - T: 0x{0:X}, G: 0x{1:X}, I: 0x{2:X}: Length expected: 0x{3:X}, read: 0x{4:X}",
                            ie.ResourceType, ie.ResourceGroup, ie.Instance, ie.Filesize, chunk.Length));
            }
            return chunk;
        }
        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>();

            this.Index.ForEach(x =>
            {
                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);

            foreach (IResourceIndexEntry ie in this.Index)
            {
                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)
                {
                    // Move to TS4
                    //newIE.Compressed = 0xffff;
                    newIE.Compressed = 0x5A42;
                    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);
            setUnused4(w, unused4);
            s.Flush();
        }