Esempio n. 1
0
        public void Load()
        {
            var sw = Stopwatch.StartNew();

            while (true)
            {
                using (var texReader = new BinaryReader(File.OpenRead(_textureFile)))
                {
                    Byte[] IsCompressed = texReader.ReadBytes(2);
                    if (BitConverter.ToString(IsCompressed) == "53-43")
                    {
                        texReader.BaseStream.Seek(26, SeekOrigin.Begin);
                        DialogResult result =
                            MessageBox.Show("The tool detected that you have load a compressed file.\nWould you like to decompress and load it?\nPlease note,Choosing to decompressed will override the compressed file with a new one",
                                            "SC File Is Compresed", MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button2);

                        if (result == DialogResult.Yes)
                        {
                            string IsSc = BitConverter.ToString(texReader.ReadBytes(2));
                            texReader.Close();
                            if (IsSc == "53-43")
                            {
                                Lzham.DecompressSc(_textureFile);
                            }
                            else
                            {
                                Lzma.Decompress(_textureFile);
                            }
                            continue;
                        }
                        break;
                    }

                    Console.WriteLine(texReader.BaseStream.Length);
                    texReader.BaseStream.Seek(0, SeekOrigin.Begin);
                    while (true)
                    {
                        long texoffset  = texReader.BaseStream.Position;
                        var  packetId   = texReader.ReadByte();
                        var  packetSize = texReader.ReadUInt32();
                        if (packetSize > 0)
                        {
                            var tex = new Texture(this);
                            tex.SetOffset(texoffset);
                            tex.Read(packetId, packetSize, texReader);
                            this._textures.Add(tex);
                            if (texReader.BaseStream.Position != texReader.BaseStream.Length)
                            {
                                continue;
                            }
                        }
                        _eofTexOffset = texoffset;
                        break;
                    }
                }
                break;
            }

            while (true)
            {
                using (var reader = new BinaryReader(File.OpenRead(_infoFile)))
                {
                    Byte[] IsCompressed = reader.ReadBytes(2);
                    Console.WriteLine(BitConverter.ToString(IsCompressed) == "53-43");
                    if (BitConverter.ToString(IsCompressed) == "53-43")
                    {
                        reader.BaseStream.Seek(26, SeekOrigin.Begin);
                        DialogResult result = MessageBox.Show("The tool detected that you have load a compressed file.\nWould you like to decompress and load it?\nPlease note,Choosing to decompressed will override the compressed file with a new one",
                                                              @"SC File Is Compresed", MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button2);

                        if (result == DialogResult.Yes)
                        {
                            string IsSc = BitConverter.ToString(reader.ReadBytes(2));
                            reader.Close();
                            if (IsSc == "53-43")
                            {
                                Lzham.DecompressSc(_infoFile);
                            }
                            else
                            {
                                Lzma.Decompress(_infoFile);
                            }
                            continue;
                        }
                        break;
                    }

                    reader.BaseStream.Seek(0, SeekOrigin.Begin);
                    var shapeCount          = reader.ReadUInt16(); // a1 + 8
                    var movieClipCount      = reader.ReadUInt16(); // a1 + 12
                    var textureCount        = reader.ReadUInt16(); // a1 + 16
                    var textFieldCount      = reader.ReadUInt16(); // a1 + 24
                    var matrixCount         = reader.ReadUInt16(); // a1 + 28
                    var colorTransformCount = reader.ReadUInt16(); // a1 + 32

                    int colorTransfromID = 0;

#if DEBUG
                    Console.WriteLine(@"ShapeCount: " + shapeCount);
                    Console.WriteLine(@"MovieClipCount: " + movieClipCount);
                    Console.WriteLine(@"TextureCount: " + textureCount);
                    Console.WriteLine(@"TextFieldCount: " + textFieldCount);
                    Console.WriteLine(@"Matrix2x3Count: " + matrixCount);
                    Console.WriteLine(@"ColorTransformCount: " + colorTransformCount);
#endif
                    // 5 useless bytes, not even used by Supercell
                    reader.ReadByte();   // 1 octet
                    reader.ReadUInt16(); // 2 octets
                    reader.ReadUInt16(); // 2 octets

                    _exportStartOffset = reader.BaseStream.Position;
                    _exportCount       = reader.ReadUInt16(); // a1 + 20
                    Console.WriteLine(@"ExportCount: " + _exportCount);

                    // Reads the Export IDs.
                    for (int i = 0; i < _exportCount; i++)
                    {
                        var export = new Export(this);
                        export.SetId(reader.ReadUInt16());
                        _exports.Add(export);
                    }

                    // Reads the Export names.
                    for (int i = 0; i < _exportCount; i++)
                    {
                        var nameLength = reader.ReadByte();
                        var name       = Encoding.UTF8.GetString(reader.ReadBytes(nameLength));
                        var export     = (Export)_exports[i];
                        export.SetExportName(name);
                    }

                    while (reader.BaseStream.Position != reader.BaseStream.Length)
                    {
                        long offset = reader.BaseStream.Position;

                        var datatag = reader.ReadByte();
                        var tag     = datatag.ToString("X2"); //Block type
                        var tagSize = reader.ReadUInt32();    //Size in bytes
#if DEBUG
                        //Console.WriteLine("dataBlockTag: " + tag);
                        //Console.WriteLine("dataBlockSize: " + tagSize);
#endif
                        switch (tag)
                        {
                        default:
                            //Console.WriteLine("dataBlockTag: " + tag);
                            //Console.WriteLine("dataBlockSize: " + tagSize);
                            var defaultDataBlockContent = reader.ReadBytes(Convert.ToInt32(tagSize));
                            defaultDataBlockContent = null;
                            break;

                        case "00":
                            _eofOffset = offset;
                            foreach (ScObject t in _exports)
                            {
                                int index = _movieClips.FindIndex(movie => movie.Id == t.Id);
                                if (index != -1)
                                {
                                    ((Export)t).SetDataObject((MovieClip)_movieClips[index]);
                                }
                            }
                            break;

                        case "01":
                        case "18":
                            if (tagSize > 6)
                            {
                                var texture = new Texture(this);
                                texture.SetOffset(offset);
                                texture.Read(UInt32.Parse(tag), tagSize, reader);
                                //_eofTexOffset = reader.BaseStream.Position;
                                this._textures.Add(texture);
                            }
                            else
                            {
                                var pixelFormat = reader.ReadByte();
                                var width       = reader.ReadUInt16();
                                var height      = reader.ReadUInt16();

                                Console.WriteLine("pixelFormat: " + pixelFormat);
                                Console.WriteLine("width: " + width);
                                Console.WriteLine("height: " + height);
                            }
                            break;

                        case "02":
                        case "12":
                            var shape = new Shape(this);
                            shape.SetOffset(offset);
                            shape.Read(reader, tag);
                            this._shapes.Add(shape);
                            break;

                        case "03":
                        case "0C":
                            var movieClip = new MovieClip(this, datatag);
                            movieClip.SetOffset(offset);
                            movieClip.Read(reader, tag);
                            _movieClips.Add(movieClip);
                            break;

                        case "08":
                            float[] Points = new float[6];
                            for (int Index = 0; Index < 6; Index++)
                            {
                                Points[Index] = reader.ReadInt32();
                            }
                            Matrix _Matrix = new Matrix(Points[0] / 1024, Points[1] / 1024, Points[2] / 1024,
                                                        Points[3] / 1024, Points[4] / -20, Points[5] / -20);
                            this._matrixs.Add(_Matrix);
                            //Console.WriteLine("\t matrixVal: " + Points[0] / 1024 + "\n\t matrixVal: " + Points[1] / 1024 + "\n\t matrixVal: " + Points[2] / 1024 + "\n\t matrixVal: " + Points[3] / 1024 + "\n\t matrixVal: " + Points[4] / -20 + "\n\t matrixVal: " + Points[5] / -20);
                            break;

                        case "09":
                            var ra = reader.ReadByte();
                            var ga = reader.ReadByte();
                            var ba = reader.ReadByte();
                            var am = reader.ReadByte();
                            var rm = reader.ReadByte();
                            var gm = reader.ReadByte();
                            var bm = reader.ReadByte();
                            this._colors.Add(new Tuple <Color, byte, Color>(Color.FromArgb(ra, ga, ba), am, Color.FromArgb(rm, gm, bm)));
                            //int id = this._colors.Count - 1;
                            //Console.WriteLine("\t -ct-" + id + "--ColorA: rgb(" + this._colors[id].Item1.R + "," + this._colors[id].Item1.G + "," + this._colors[id].Item1.B + ") & " + this._colors[id].Item2 + " & rgb(" + this._colors[id].Item3.R + "," + this._colors[id].Item3.G + "," + this._colors[id].Item3.B + ")");
                            break;
                        }
                    }

                    sw.Stop();
                    Program.Interface.Text = $@"Royale Editor :  {Path.GetFileNameWithoutExtension(_textureFile)}";
                    Program.Interface.Update();
                    Console.WriteLine(@"SC File loading finished in {0}ms", sw.Elapsed.TotalMilliseconds);
                }
                break;
            }
        }
Esempio n. 2
0
 public uint Finish()
 {
     handle = IntPtr.Zero;
     return(Lzham.DecompressDeinit(handle));
 }
Esempio n. 3
0
        public static LoadError LoadFromStream(Stream stream, out Cnk0 cnk0)
        {
            if (stream == null)
            {
                cnk0 = null;
                return(LoadError.NullStream);
            }

            BinaryReader binaryReader = new BinaryReader(stream);

            //header
            char[] magic = binaryReader.ReadChars(4);

            if (magic[0] != 'C' ||
                magic[1] != 'N' ||
                magic[2] != 'K' ||
                magic[3] != '0')
            {
                cnk0 = null;
                return(LoadError.BadHeader);
            }

            int version = binaryReader.ReadInt32();

            if (version != VERSION)
            {
                cnk0 = null;
                return(LoadError.VersionMismatch);
            }

            uint uncompressedSize = binaryReader.ReadUInt32();
            uint compressedSize   = binaryReader.ReadUInt32();

            byte[] inputBuffer = binaryReader.ReadBytes((int)compressedSize);

            binaryReader.Close();

            byte[] outputBuffer = new byte[uncompressedSize];

            Lzham.ZStream zStream = new Lzham.ZStream();
            Lzham.ZInflateInit2(zStream, 20);
            zStream.AvailableInputBytes  = compressedSize;
            zStream.AvailableOutputBytes = uncompressedSize;

            GCHandle inputBufferGCHandle  = GCHandle.Alloc(inputBuffer, GCHandleType.Pinned);
            GCHandle outputBufferGCHandle = GCHandle.Alloc(outputBuffer, GCHandleType.Pinned);

            zStream.NextInputByte  = inputBufferGCHandle.AddrOfPinnedObject();
            zStream.NextOutputByte = outputBufferGCHandle.AddrOfPinnedObject();

            Lzham.ZInflate(zStream, (int)Lzham.ZFlush.Finish);
            Lzham.ZInflateEnd(zStream);

            inputBufferGCHandle.Free();
            outputBufferGCHandle.Free();

            MemoryStream memoryStream = new MemoryStream(outputBuffer);

            binaryReader = new BinaryReader(memoryStream);

            cnk0 = new Cnk0();

            //tiles
            uint tileCount = binaryReader.ReadUInt32();

            cnk0.Tiles = new Tile[tileCount];

            for (uint i = 0; i < tileCount; ++i)
            {
                Tile tile;

                if (Tile.LoadFromStream(memoryStream, out tile) != Tile.LoadError.None)
                {
                    cnk0 = null;
                    return(LoadError.BadTile);
                }

                cnk0.Tiles[i] = tile;
            }

            //unknown block
            uint unknown0 = binaryReader.ReadUInt32();
            uint unknown1 = binaryReader.ReadUInt32();

            binaryReader.BaseStream.Seek(unknown1 * 4, SeekOrigin.Current);

            //indices
            uint indexCount = binaryReader.ReadUInt32();

            cnk0.Indices = new ushort[indexCount];

            for (int i = 0; i < indexCount; ++i)
            {
                cnk0.Indices[i] = binaryReader.ReadUInt16();
            }

            //vertices
            uint vertexCount = binaryReader.ReadUInt32();

            cnk0.Vertices = new Vertex[vertexCount];

            for (int i = 0; i < vertexCount; ++i)
            {
                Vertex vertex;

                if (Vertex.LoadFromStream(binaryReader.BaseStream, out vertex) != Vertex.LoadError.None)
                {
                    cnk0 = null;
                    return(LoadError.BadVertex);
                }

                cnk0.Vertices[i] = vertex;
            }

            //render batches
            uint renderBatchCount = binaryReader.ReadUInt32();

            cnk0.RenderBatches = new RenderBatch[renderBatchCount];

            for (uint i = 0; i < renderBatchCount; ++i)
            {
                RenderBatch renderBatch;
                if (RenderBatch.LoadFromStream(binaryReader.BaseStream, out renderBatch) != RenderBatch.LoadError.None)
                {
                    cnk0 = null;
                    return(LoadError.BadRenderBatch);
                }

                cnk0.RenderBatches[i] = renderBatch;
            }

            binaryReader.Close();

            return(LoadError.None);
        }
Esempio n. 4
0
        /// <summary>
        /// Reads the entry from the VPK package.
        /// </summary>
        /// <param name="entry">Package entry.</param>
        /// <param name="progressReporter">Progress report callback.</param>
        /// <param name="validateCrc">If true, CRC32 will be calculated and verified for read data.</param>
        /// <returns>Output buffer.</returns>
        public async Task <Memory <byte> > ReadEntryAsync(PackageEntry entry, IProgress <int> progressReporter, bool validateCrc = true)
        {
            DecompressState decompressState = null;
            var             parameters      = new DecompressParameters();

            parameters.DictSizeLog2 = 20;

            var blockReadBuffer = new Memory <byte>(new byte[MAX_ENTRY_CHUNK_SIZE]);
            var outputBuffer    = new Memory <byte>(new byte[entry.SmallData.Length + entry.TotalLength]);
            var outputOffset    = 0;

            if (entry.SmallData.Length > 0)
            {
                entry.SmallData.CopyTo(outputBuffer);
                outputOffset += entry.SmallData.Length;
            }

            if (entry.TotalCompressedLength < entry.TotalLength)
            {
                decompressState = Lzham.DecompressInit(parameters);
            }

            if (entry.TotalLength > 0)
            {
                Stream fs = null;
                ushort currentArchiveIndex = 0x7FFF;

                try
                {
                    foreach (var chunk in entry.Chunks)
                    {
                        var streamOffset = chunk.Offset;

                        if (currentArchiveIndex != chunk.ArchiveIndex)
                        {
                            currentArchiveIndex = chunk.ArchiveIndex;
                            fs?.Close();
                        }

                        if (chunk.ArchiveIndex != 0x7FFF)
                        {
                            if (currentArchiveIndex != chunk.ArchiveIndex)
                            {
                                currentArchiveIndex = chunk.ArchiveIndex;
                                fs?.Close();
                            }

                            if (!IsDirVPK)
                            {
                                throw new InvalidOperationException("Given VPK is not a _dir, but entry is referencing an external archive.");
                            }

                            var vpkDirectory = Path.GetDirectoryName(FileName);
                            var vpkName      = Path.GetFileName(FileName);

                            foreach (var prefix in VPK_PREFIXES)
                            {
                                if (vpkName.StartsWith(prefix))
                                {
                                    vpkName = vpkName.Substring(prefix.Length);
                                    break;
                                }
                            }

                            var fileName = Path.Combine(vpkDirectory, $"{vpkName}_{chunk.ArchiveIndex:D3}.vpk");

                            fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                        }
                        else
                        {
                            fs = Reader.BaseStream;

                            streamOffset += HeaderSize + TreeSize;
                        }

                        fs.Seek(streamOffset, SeekOrigin.Begin);
                        var readBuffer = blockReadBuffer.Slice(0, (int)chunk.CompressedLength);
                        var bytesRead  = await fs.ReadAsync(readBuffer);

                        if (bytesRead != chunk.CompressedLength)
                        {
                            throw new InvalidOperationException($"Attempted to read {chunk.CompressedLength} bytes, got {bytesRead.ToString()}.");
                        }

                        if (chunk.CompressedLength < chunk.Length)
                        {
                            var decompressedSpan = outputBuffer.Slice(outputOffset);
                            var decompressResult = Lzham.DecompressMemory(parameters, readBuffer, ref decompressedSpan);

                            if (decompressResult != DecompressStatus.Success)
                            {
                                throw new InvalidOperationException($"Error attempting to decompress: {decompressResult.ToString()}");
                            }

                            outputOffset += (int)chunk.Length;
                        }
                        else
                        {
                            readBuffer.CopyTo(outputBuffer.Slice(outputOffset));

                            outputOffset += bytesRead;
                        }

                        if (progressReporter != null)
                        {
                            progressReporter.Report(outputOffset);
                        }
                    }
                }
                finally
                {
                    if (currentArchiveIndex != 0x7FFF)
                    {
                        fs?.Close();
                    }
                }
            }

            if (validateCrc && entry.CRC32 != Crc32.Compute(outputBuffer))
            {
                throw new InvalidDataException("CRC32 mismatch for read data.");
            }

            if (decompressState != null)
            {
                var deinitResult = Lzham.DecompressDeinit(decompressState);

                if (deinitResult >= DecompressStatus.FirstFailureCode)
                {
                    throw new InvalidOperationException($"Error attempting to deinitialize compressor: {deinitResult.ToString()}");
                }
            }

            return(outputBuffer);
        }