public BundleList ReadBundleList(string listName)
        {
            List <SuperBundle> listOfBundles = new List <SuperBundle>();

            string[] compare = new string[] { "bundles", "chunks", "ebx", "res", "chunkMeta", "dbx" };

            if (!compare.Contains(listName))
            {
                throw new InvalidDataException("Unknown list type.");
            }

            int limit = Read7BitEncodedInt();

            long startPosition = BaseStream.Position;

            while (BaseStream.Position < startPosition + limit)
            {
                SuperBundle currentBundle = ReadTableOfContentsPayload();
                if (currentBundle != null)
                {
                    listOfBundles.Add(currentBundle);
                }
            }

            BundleList bundleList = new BundleList();

            bundleList.Name    = listName;
            bundleList.Bundles = listOfBundles;
            bundleList.Limit   = limit;

            return(bundleList);
        }
Пример #2
0
        public static Int32 Chunk(BinaryWriter writer, SuperBundle superBundle)
        {
            Int32  totalFileSize        = 0;
            UInt32 uncompressedFileSize = (UInt32) new FileInfo(superBundle.Changed).Length;

            using (BinaryReader changedFileReader = new BinaryReader(File.Open(superBundle.Changed, FileMode.Open)))
            {
                byte[] inBuffer;
                byte[] outBuffer = new byte[UInt16.MaxValue * 2];

                UInt32 maximalUncompressedChunkSize = UInt16.MaxValue + 1;

                for (UInt32 currentPosition = 0; currentPosition < uncompressedFileSize; currentPosition += maximalUncompressedChunkSize)
                {
                    UInt32 uncompressedChunkSize = uncompressedFileSize - currentPosition;
                    if (uncompressedChunkSize > maximalUncompressedChunkSize)
                    {
                        uncompressedChunkSize = maximalUncompressedChunkSize;
                    }

                    inBuffer = changedFileReader.ReadBytes((int)uncompressedChunkSize);

                    int compressedChunkSize = CompressionStrategy.Compress(inBuffer, outBuffer, (int)uncompressedChunkSize);

                    writer.WriteUInt32BE(uncompressedChunkSize);
                    totalFileSize += 8;

                    // store uncompressed
                    if (compressedChunkSize > uncompressedChunkSize)
                    {
                        writer.Write((byte)0);
                        writer.Write((byte)0x71);
                        writer.Write((UInt16)0);
                        writer.Write(inBuffer);
                        totalFileSize += (int)uncompressedChunkSize;
                    }
                    // store compressed
                    else
                    {
                        writer.Write(CompressionStrategy.CompressionSignature);
                        writer.Write((byte)0x70);
                        writer.WriteUInt16BE((UInt16)compressedChunkSize);
                        writer.Write(outBuffer, 0, compressedChunkSize);
                        totalFileSize += compressedChunkSize;
                    }
                }
            }

            return(totalFileSize);
        }
        public void ResolveNewFiles(string tableOfContentsName, string directory)
        {
            FileInfo[] files = new DirectoryInfo(directory).GetFiles("*", SearchOption.AllDirectories);
            foreach (FileInfo file in files)
            {
                string[] pathLayers = Regex.Split(file.FullName.Substring(directory.Length), "(?:(bundles)|(chunks)|(ebx)|(res)|(chunkMeta)|(dbx))\\\\").Select(substring => substring.Trim('\\').Replace('\\', '/')).Where(_ => !String.IsNullOrEmpty(_)).ToArray();

                BundleList bundleList = myTableOfContents.Payload.BundleCollections.SingleOrDefault(_ => _.Name == pathLayers[0]);
                if (bundleList != null)
                {
                    SuperBundle correspondingBundle = null;
                    // no indirection
                    if (pathLayers.Length == 2)
                    {
                        correspondingBundle = bundleList.Bundles.SingleOrDefault(bundle => ((byte[])bundle.Properties["id"].Value).SequenceEqual(Helpers.StringToByteArray(pathLayers[1])));
                    }
                    // indirection
                    else
                    {
                        IEnumerable <SuperBundle> superBundles = bundleList.Bundles
                                                                 .Where(bundle => (string)bundle.Properties["id"].Value == pathLayers[1].Replace("_Dq_", ":"));

                        if (superBundles != null)
                        {
                            BundleList indirectBundleList = superBundles.SelectMany(bundle => bundle.Indirection.BundleCollections
                                                                                    .Where(list => list.Name == pathLayers[2]))
                                                            .SingleOrDefault();

                            if (indirectBundleList != null)
                            {
                                correspondingBundle = indirectBundleList.Bundles
                                                      .SingleOrDefault(bundle => bundle.Properties.ContainsKey("name")
                                        ? (string)bundle.Properties["name"].Value == pathLayers[3]
                                        : ((byte[])bundle.Properties["id"].Value).SequenceEqual(Helpers.StringToByteArray(pathLayers[3])));
                            }
                        }
                    }
                    if (correspondingBundle != null)
                    {
                        correspondingBundle.Changed = file.FullName;
                    }
                }
            }
        }
        public SuperBundle ReadTableOfContentsPayload()
        {
            SuperBundle       superBundle = new SuperBundle();
            List <BundleList> bundleList  = new List <BundleList>();
            Dictionary <string, PropertyValue> properties = new Dictionary <string, PropertyValue>();

            superBundle.Properties        = properties;
            superBundle.BundleCollections = bundleList;

            byte currentInitialByte = ReadByte();

            if (currentInitialByte == 0)
            {
                return(null);
            }

            superBundle.InitialByte = currentInitialByte;
            superBundle.Limit       = Read7BitEncodedInt();
            long startPosition = BaseStream.Position;

            while (BaseStream.Position < startPosition + superBundle.Limit)
            {
                byte entryOpCode = ReadByte();

                if (entryOpCode == 0)
                {
                    return(superBundle);
                }

                string entryName = ReadNullTerminatedString();
                object value;

                switch (entryOpCode)
                {
                // list
                case 0x01:
                    bundleList.Add(ReadBundleList(entryName));
                    continue;

                // boolean
                case 0x06:
                    value = ReadByte() == 0x01;
                    break;

                // string
                case 0x07:
                    value = ReadString();
                    break;

                // 4-byte number
                case 0x08:
                    value = ReadInt32();
                    break;

                // 8-byte number
                case 0x09:
                    value = ReadInt64();
                    break;

                // 16 bytes hash
                case 0x0f:
                    value = ReadBytes(16);
                    break;

                // 20 bytes hash
                case 0x10:
                    value = ReadBytes(20);
                    break;

                // variable size blob
                case 0x02:
                case 0x13:
                    int blobSize = Read7BitEncodedInt();
                    value = ReadBytes(blobSize);
                    break;

                default:
                    throw new InvalidDataException("Unknown opcode.");
                }

                properties.Add(entryName, new PropertyValue(entryOpCode, value));
            }

            return(superBundle);
        }
Пример #5
0
        public void Write(SuperBundle bundle)
        {
            if (bundle == null)
            {
                return;
            }

            Write(bundle.InitialByte);
            Write7BitEncodedInt(bundle.Limit);

            foreach (BundleList bundleList in bundle.BundleCollections)
            {
                Write(bundleList);
            }

            foreach (var property in bundle.Properties)
            {
                object value = property.Value.Value;
                Write(property.Value.Opcode);
                WriteNullTerminatedString(property.Key);

                switch (property.Value.Opcode)
                {
                // boolean
                case 0x06:
                    Write((bool)value ? (byte)1 : (byte)0);
                    break;

                // string
                case 0x07:
                    WriteNullTerminatedStringWithLEB128Prefix((string)value);
                    break;

                // 4-byte number
                case 0x08:
                    Write((Int32)value);
                    break;

                // 8-byte number
                case 0x09:
                    Write((Int64)value);
                    break;

                // 16 or 20 bytes hash
                case 0x0f:
                case 0x10:
                    Write((byte[])value);
                    break;

                // variable size blob
                case 0x02:
                case 0x13:
                    Write7BitEncodedInt(((byte[])value).Length);
                    Write((byte[])value);
                    break;

                default:
                    throw new InvalidDataException("Unknown opcode.");
                }
            }

            Write((byte)0);
        }