コード例 #1
0
        private static void GetStreamingAssetsInfoFromJar(string apkPath, List <string> paths, List <PartInfo> parts)
        {
            using (var stream = File.OpenRead(apkPath))
                using (var reader = new BinaryReader(stream))
                {
                    if (!stream.CanRead)
                    {
                        throw new ArgumentException();
                    }
                    if (!stream.CanSeek)
                    {
                        throw new ArgumentException();
                    }

                    long expectedNumberOfEntries;
                    long centralDirectoryStart;
                    ZipArchiveUtils.ReadEndOfCentralDirectory(stream, reader, out expectedNumberOfEntries, out centralDirectoryStart);

                    try
                    {
                        stream.Seek(centralDirectoryStart, SeekOrigin.Begin);

                        long numberOfEntries = 0;

                        ZipCentralDirectoryFileHeader header;

                        const int    prefixLength = 7;
                        const string prefix       = "assets/";
                        const string assetsPrefix = "assets/bin/";
                        Debug.Assert(prefixLength == prefix.Length);

                        while (ZipCentralDirectoryFileHeader.TryReadBlock(reader, out header))
                        {
                            if (header.CompressedSize != header.UncompressedSize)
                            {
                                // we only want uncompressed files
                            }
                            else
                            {
                                var fileName = Encoding.UTF8.GetString(header.Filename);
                                if (fileName.StartsWith(prefix))
                                {
                                    // ignore normal assets...
                                    if (fileName.StartsWith(assetsPrefix))
                                    {
                                        // Note: if you put bin directory in your StreamingAssets you will get false negative here
                                    }
                                    else
                                    {
                                        var relativePath = fileName.Substring(prefixLength - 1);
                                        var entry        = new PartInfo()
                                        {
                                            crc32  = header.Crc32,
                                            offset = header.RelativeOffsetOfLocalHeader, // this offset will need fixing later on
                                            size   = header.UncompressedSize
                                        };

                                        var index = paths.BinarySearch(relativePath, StringComparer.OrdinalIgnoreCase);
                                        if (index >= 0)
                                        {
                                            throw new System.InvalidOperationException("Paths duplicate! " + fileName);
                                        }

                                        paths.Insert(~index, relativePath);
                                        parts.Insert(~index, entry);
                                    }
                                }
                            }

                            numberOfEntries++;
                        }

                        if (numberOfEntries != expectedNumberOfEntries)
                        {
                            throw new ZipArchiveException("Number of entries does not match");
                        }
                    }
                    catch (EndOfStreamException ex)
                    {
                        throw new ZipArchiveException("CentralDirectoryInvalid", ex);
                    }

                    // now fix offsets
                    for (int i = 0; i < parts.Count; ++i)
                    {
                        var entry = parts[i];
                        stream.Seek(entry.offset, SeekOrigin.Begin);

                        if (!ZipLocalFileHeader.TrySkipBlock(reader))
                        {
                            throw new ZipArchiveException("Local file header corrupt");
                        }

                        entry.offset = stream.Position;

                        parts[i] = entry;
                    }
                }
        }
コード例 #2
0
        private static void GetStreamingAssetsInfoFromJar(string apkPath, List <string> paths, List <PartInfo> parts)
        {
            using (var stream = File.OpenRead(apkPath))
                using (var reader = new BinaryReader(stream))
                {
                    if (!stream.CanRead)
                    {
                        throw new ArgumentException();
                    }
                    if (!stream.CanSeek)
                    {
                        throw new ArgumentException();
                    }

                    long expectedNumberOfEntries;
                    long centralDirectoryStart;
                    ZipArchiveUtils.ReadEndOfCentralDirectory(stream, reader, out expectedNumberOfEntries, out centralDirectoryStart);

                    try
                    {
                        stream.Seek(centralDirectoryStart, SeekOrigin.Begin);

                        long numberOfEntries = 0;

                        ZipCentralDirectoryFileHeader header;

                        const int    prefixLength = 7;
                        const string prefix       = "assets/";
                        const string assetsPrefix = "assets/bin/";
                        Debug.Assert(prefixLength == prefix.Length);

                        while (ZipCentralDirectoryFileHeader.TryReadBlock(reader, out header))
                        {
                            if (header.CompressedSize != header.UncompressedSize)
                            {
#if UNITY_ASSERTIONS
                                var fileName = Encoding.UTF8.GetString(header.Filename);
                                if (fileName.StartsWith(prefix) && !fileName.StartsWith(assetsPrefix))
                                {
                                    bool isStreamingAsset = true;
                                    AndroidIsCompressedFileStreamingAsset(fileName, ref isStreamingAsset);
                                    if (isStreamingAsset)
                                    {
                                        Debug.LogAssertionFormat("BetterStreamingAssets: file {0} is where Streaming Assets are put, but is compressed. " +
                                                                 "If this is a App Bundle build, see README for a possible workaround. " +
                                                                 "If this file is not a Streaming Asset (has been on purpose by hand or by another plug-in), implement " +
                                                                 "BetterStreamingAssets.AndroidIsCompressedFileStreamingAsset partial method to prevent this message from appearing again. ",
                                                                 fileName);
                                    }
                                }
#endif
                                // we only want uncompressed files
                            }
                            else
                            {
                                var fileName = Encoding.UTF8.GetString(header.Filename);

                                if (fileName.EndsWith("/"))
                                {
                                    // there's some strangeness when it comes to OBB: directories are listed as files
                                    // simply ignoring them should be enough
                                    Debug.Assert(header.UncompressedSize == 0);
                                }
                                else if (fileName.StartsWith(prefix))
                                {
                                    // ignore normal assets...
                                    if (fileName.StartsWith(assetsPrefix))
                                    {
                                        // Note: if you put bin directory in your StreamingAssets you will get false negative here
                                    }
                                    else
                                    {
                                        var relativePath = fileName.Substring(prefixLength - 1);
                                        var entry        = new PartInfo()
                                        {
                                            crc32  = header.Crc32,
                                            offset = header.RelativeOffsetOfLocalHeader, // this offset will need fixing later on
                                            size   = header.UncompressedSize
                                        };

                                        var index = paths.BinarySearch(relativePath, StringComparer.OrdinalIgnoreCase);
                                        if (index >= 0)
                                        {
                                            throw new System.InvalidOperationException("Paths duplicate! " + fileName);
                                        }

                                        paths.Insert(~index, relativePath);
                                        parts.Insert(~index, entry);
                                    }
                                }
                            }

                            numberOfEntries++;
                        }

                        if (numberOfEntries != expectedNumberOfEntries)
                        {
                            throw new ZipArchiveException("Number of entries does not match");
                        }
                    }
                    catch (EndOfStreamException ex)
                    {
                        throw new ZipArchiveException("CentralDirectoryInvalid", ex);
                    }

                    // now fix offsets
                    for (int i = 0; i < parts.Count; ++i)
                    {
                        var entry = parts[i];
                        stream.Seek(entry.offset, SeekOrigin.Begin);

                        if (!ZipLocalFileHeader.TrySkipBlock(reader))
                        {
                            throw new ZipArchiveException("Local file header corrupt");
                        }

                        entry.offset = stream.Position;

                        parts[i] = entry;
                    }
                }
        }