예제 #1
0
        public Resource GetResource(uint resourceType, uint resourceGroup, ulong instance)
        {
            IResourceIndexEntry rie = _package.Find(x =>
                                                    x.ResourceType == resourceType && x.ResourceGroup == resourceGroup && x.Instance == instance);

            if (rie == null)
            {
                return(default(Resource));
            }

            return(GetResource(rie));
        }
예제 #2
0
        public static void AddFiles(IPackage package, List <string> sourceFilePaths)
        {
            List <TGIN> addedResourceKeys = new List <TGIN>();

            for (int sourceFilePathIndex = 0; sourceFilePathIndex < sourceFilePaths.Count; sourceFilePathIndex++)
            {
                string sourceInfoFilePath = sourceFilePaths[sourceFilePathIndex] + "." + SourceInfoFileExtension;

                TGIN targetResourceKeyTGIN = Path.GetFileName(sourceFilePaths[sourceFilePathIndex]);

                if (File.Exists(sourceInfoFilePath))
                {
                    try {
                        SourceInfo sourceInfo = (SourceInfo)Tools.ReadXML <SourceInfo>(sourceInfoFilePath);
                        targetResourceKeyTGIN = sourceInfo.ToTGIN();
                    } catch (Exception e) {
                        Console.Error.Write("Failed to read source info file.\n" + sourceInfoFilePath + "\n" + e.ToString());
                    }
                }

                AResourceKey targetResourceKey = targetResourceKeyTGIN;

                MemoryStream sourceStream       = new MemoryStream();
                BinaryWriter sourceStreamWriter = new BinaryWriter(sourceStream);

                using (BinaryReader sourceFileReader = new BinaryReader(new FileStream(sourceFilePaths[sourceFilePathIndex], FileMode.Open, FileAccess.Read))) {
                    sourceStreamWriter.Write(sourceFileReader.ReadBytes((int)sourceFileReader.BaseStream.Length));
                    sourceStreamWriter.Flush();
                }

                IResourceIndexEntry targetPreviousEntry = package.Find(targetResourceKey.Equals);

                while (targetPreviousEntry != null)
                {
                    package.DeleteResource(targetPreviousEntry);
                    targetPreviousEntry = package.Find(targetResourceKey.Equals);
                }

                IResourceIndexEntry targetEntry = package.AddResource(targetResourceKey, sourceStream, false);

                if (targetEntry == null)
                {
                    continue;
                }

                targetEntry.Compressed = 23106;
                addedResourceKeys.Add(targetResourceKeyTGIN);
            }

            GenerateNameMap(package, addedResourceKeys, null);
        }
예제 #3
0
파일: Form1.cs 프로젝트: yakoder/sims3tools
        string Compare(IPackage pkgA, IPackage pkgB, IResourceKey rk)
        {
            IResource left  = s3pi.WrapperDealer.WrapperDealer.GetResource(0, pkgA, pkgA.Find(x => x.CompareTo(rk) == 0), true);
            IResource right = s3pi.WrapperDealer.WrapperDealer.GetResource(0, pkgB, pkgB.Find(x => x.CompareTo(rk) == 0), true);

            return(left.AsBytes.CompareTo(right.AsBytes) == 0 ? "=" : "!");
        }
예제 #4
0
        protected static Dictionary <ulong, STBLImporter.Lookup> ReadTable(string prefix, string instance, IPackage package, bool addOtherKeys)
        {
            instance = prefix + instance.Substring(4);

            Dictionary <ulong, STBLImporter.Lookup> lookup = new Dictionary <ulong, STBLImporter.Lookup>();

            IResourceIndexEntry entry = package.Find(key => ((key.ResourceType == (uint)ResourceType.STBL) && (key["Instance"] == instance)));

            if (entry != null)
            {
                StblResource.StblResource resource = ResourceHandlers.CreateResource(entry, package) as StblResource.StblResource;

                foreach (KeyValuePair <ulong, string> element in resource)
                {
                    bool space = false;

                    string keyValue = element.Value;
                    if (prefix == "0x17")
                    {
                        if (keyValue.StartsWith("PackerSpace|"))
                        {
                            keyValue = keyValue.Replace("PackerSpace|", "");
                            space    = true;
                        }
                    }

                    if (!lookup.ContainsKey(element.Key))
                    {
                        STBLImporter.Lookup recent = new STBLImporter.Lookup(keyValue, keyValue, space);
                        lookup.Add(element.Key, recent);
                    }

                    if ((addOtherKeys) && (!HasSuffix(keyValue)))
                    {
                        foreach (string suffix in sSuffixes)
                        {
                            string value = keyValue + suffix;

                            ulong key = FNV64.GetHash(value);

                            if (lookup.ContainsKey(key))
                            {
                                continue;
                            }

                            STBLImporter.Lookup recent = new STBLImporter.Lookup(value, value, space);
                            lookup.Add(key, recent);
                        }
                    }
                }
            }

            return(lookup);
        }
예제 #5
0
        public static IResource CreateKeyResource(IPackage package)
        {
            IResourceIndexEntry key = package.Find(value => value.ResourceType == (uint)ResourceType._KEY);

            if (key == null)
            {
                return(null);
            }
            else
            {
                return(ResourceHandlers.CreateResource(key, package));
            }
        }
예제 #6
0
        public static void RemoveFiles(IPackage package, List <string> fileNames)
        {
            List <TGIN> removedResourceKeys = new List <TGIN>();

            for (int fileNameIndex = 0; fileNameIndex < fileNames.Count; fileNameIndex++)
            {
                TGIN         targetResourceKeyTGIN = fileNames[fileNameIndex];
                AResourceKey targetResourceKey     = targetResourceKeyTGIN;

                IResourceIndexEntry targetPreviousEntry = package.Find(targetResourceKey.Equals);

                while (targetPreviousEntry != null)
                {
                    package.DeleteResource(targetPreviousEntry);
                    targetPreviousEntry = package.Find(targetResourceKey.Equals);
                }

                removedResourceKeys.Add(targetResourceKeyTGIN);
            }

            GenerateNameMap(package, null, removedResourceKeys);
        }
예제 #7
0
        protected static Dictionary<ulong, STBLImporter.Lookup> ReadTable(string prefix, string instance, IPackage package, bool addOtherKeys)
        {
            instance = prefix + instance.Substring(4);

            Dictionary<ulong, STBLImporter.Lookup> lookup = new Dictionary<ulong, STBLImporter.Lookup>();

            IResourceIndexEntry entry = package.Find(key => ((key.ResourceType == (uint)ResourceType.STBL) && (key["Instance"] == instance)));
            if (entry != null)
            {
                StblResource.StblResource resource = ResourceHandlers.CreateResource(entry, package) as StblResource.StblResource;

                foreach (KeyValuePair<ulong,string> element in resource)
                {
                    bool space = false;

                    string keyValue = element.Value;
                    if (prefix == "0x17")
                    {
                        if (keyValue.StartsWith("PackerSpace|"))
                        {
                            keyValue = keyValue.Replace("PackerSpace|", "");
                            space = true;
                        }
                    }

                    if (!lookup.ContainsKey(element.Key))
                    {
                        STBLImporter.Lookup recent = new STBLImporter.Lookup(keyValue, keyValue, space);
                        lookup.Add(element.Key, recent);
                    }

                    if ((addOtherKeys) && (!HasSuffix(keyValue)))
                    {
                        foreach (string suffix in sSuffixes)
                        {
                            string value = keyValue + suffix;

                            ulong key = FNV64.GetHash(value);

                            if (lookup.ContainsKey(key)) continue;

                            STBLImporter.Lookup recent = new STBLImporter.Lookup(value, value, space);
                            lookup.Add(key, recent);
                        }
                    }
                }
            }

            return lookup;
        }
예제 #8
0
        private void UnParse(Stream s)
        {
            BinaryReader binaryReader = new BinaryReader(s);

            binaryReader.ReadInt32();
            StringBuilder stringBuilder = new StringBuilder();

            int num1 = checked (binaryReader.ReadInt32() - 1);
            int num2 = 0;

            while (num2 <= num1)
            {
                short num3 = binaryReader.ReadInt16();
                stringBuilder.Append((char)num3);
                checked { ++num2; }
            }

            stringBuilder.Append(' ');
            int num4 = checked (binaryReader.ReadInt32() - 1);
            int num5 = 0;

            while (num5 <= num4)
            {
                short num3 = binaryReader.ReadInt16();
                stringBuilder.Append((char)num3);
                checked { ++num5; }
            }

            WorldName = stringBuilder.ToString();
            binaryReader.ReadInt32();

            IPackage pkg = Package.OpenPackage(nhdPath);

            ImgInstance = binaryReader.ReadUInt64();
            IResourceIndexEntry rie = pkg.Find(entry => (long)entry.Instance == (long)ImgInstance & entry.ResourceType == 1802339198U);

            if (rie != null)
            {
                FamilyIcon = new Bitmap(S3PI.WrapperDealer.GetResource(pkg, rie).Stream);
            }
            else
            {
                FamilyIcon = App.GetResource <DrawingImage>("UnknownIcon");
            }

            binaryReader.ReadUInt64();
        }
예제 #9
0
        public PackageMetadata GetMetadata(IPackage package)
        {
            #region Preconditions

            if (package == null)
            {
                throw new ArgumentNullException(nameof(package));
            }

            #endregion

            var metadataFile = package.Find("package.json");

            if (metadataFile == null)
            {
                throw new Exception("Missing /package.json");
            }

            return(PackageMetadata.Parse(metadataFile.OpenAsync().Result));
        }
예제 #10
0
        private void exportResourceToPackage(IPackage tgtpkg, IResourceIndexEntry srcrie, bool replace)
        {
            IResourceIndexEntry rie = tgtpkg.Find(x => ((IResourceKey)srcrie).Equals(x));
            if (rie != null)
            {
                if (!replace) return;
                tgtpkg.DeleteResource(rie);
            }

            rie = tgtpkg.AddResource(srcrie, null, true);
            if (rie == null) return;
            rie.Compressed = srcrie.Compressed;

            IResource srcres = s4pi.WrapperDealer.WrapperDealer.GetResource(0, CurrentPackage, srcrie, true);//Don't need wrapper
            tgtpkg.ReplaceResource(rie, srcres);
        }
예제 #11
0
        public static IResource CreateKeyResource(IPackage package)
        {
            IResourceIndexEntry key = package.Find(value => value.ResourceType == (uint)ResourceType._KEY);

            if (key == null)
            {
                return null;
            }
            else
            {
                return ResourceHandlers.CreateResource(key, package);
            }
        }
예제 #12
0
        private void Search_Click(object sender, EventArgs e)
        {
            string instanceStr = Instance.Text;
            string groupStr    = Group.Text;

            ulong instance = 0;

            try
            {
                instance = Convert.ToUInt64(instanceStr, 16);
            }
            catch
            {
                MessageBox.Show("Format of Instance is invalid.");
                return;
            }

            uint group = 0;

            if (!string.IsNullOrEmpty(groupStr))
            {
                try
                {
                    group = Convert.ToUInt32(groupStr, 16);
                }
                catch
                {
                    MessageBox.Show("Format of Group is invalid.");
                    return;
                }
            }

            string[] files = Directory.GetFiles(Folder.Text, "*.package", SearchOption.AllDirectories);
            if (files == null)
            {
                return;
            }

            Application.UseWaitCursor = true;

            try
            {
                MainForm.Log("Searching: " + Folder.Text, false);
                MainForm.Log("Instance: " + instanceStr, false);

                if (!string.IsNullOrEmpty(groupStr))
                {
                    MainForm.Log("Group: " + groupStr, false);
                }

                bool success = false;

                foreach (string file in files)
                {
                    IPackage package = null;

                    try
                    {
                        package = Package.OpenPackage(0, file, false);
                    }
                    catch
                    { }

                    if (package == null)
                    {
                        MainForm.Log("Unable to open " + file, true);
                    }
                    else if (string.IsNullOrEmpty(groupStr))
                    {
                        if (package.Find(value => (value.Instance == instance)) != null)
                        {
                            MainForm.Log("Match Found: " + file, true);
                            success = true;
                        }
                    }
                    else
                    {
                        if (package.Find(value => ((value.Instance == instance) && (value.ResourceGroup == group))) != null)
                        {
                            MainForm.Log("Match Found: " + file, true);
                            success = true;
                        }
                    }
                }

                if (!success)
                {
                    MainForm.Log("No Matches Found.", true);
                }

                MainForm.ExportLog("PackageSearch.log");
            }
            finally
            {
                Application.UseWaitCursor = false;
            }
        }
예제 #13
0
        private void CompareFiles_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(LeftText.Text))
            {
                System.Windows.Forms.MessageBox.Show("The Left File has not been selected.", "Compare", MessageBoxButtons.OK);
                return;
            }
            else if (string.IsNullOrEmpty(RightText.Text))
            {
                System.Windows.Forms.MessageBox.Show("The Right File has not been selected.", "Compare", MessageBoxButtons.OK);
                return;
            }
            else if (string.IsNullOrEmpty(ResultsText.Text))
            {
                System.Windows.Forms.MessageBox.Show("The Results File has not been selected.", "Compare", MessageBoxButtons.OK);
                return;
            }

            IPackage leftPackage = Package.OpenPackage(0, LeftText.Text);

            if (leftPackage == null)
            {
                System.Windows.Forms.MessageBox.Show("The Left File could not be opened.", "Compare", MessageBoxButtons.OK);
                return;
            }

            IPackage rightPackage = Package.OpenPackage(0, RightText.Text);

            if (rightPackage == null)
            {
                System.Windows.Forms.MessageBox.Show("The Right File could not be opened.", "Compare", MessageBoxButtons.OK);

                Package.ClosePackage(0, leftPackage);
                return;
            }

            IPackage resultsPackage = Package.NewPackage(0);

            if (resultsPackage == null)
            {
                System.Windows.Forms.MessageBox.Show("The Right File could not be opened.", "Compare", MessageBoxButtons.OK);

                Package.ClosePackage(0, leftPackage);
                Package.ClosePackage(0, rightPackage);
                return;
            }

            try
            {
                UseWaitCursor = true;

                NameMapResource.NameMapResource keyResource = null;

                IResourceIndexEntry leftKey = leftPackage.Find(key => key.ResourceType == (uint)ResourceType._KEY);
                if (leftKey != null)
                {
                    NameMapResource.NameMapResource leftResource = ResourceHandlers.CreateResource(leftKey, leftPackage) as NameMapResource.NameMapResource;

                    IResourceIndexEntry keyEntry = resultsPackage.AddResource(new AResource.TGIBlock(0, null, leftKey.ResourceType, leftKey.ResourceGroup, leftKey.Instance), leftResource.Stream, false);
                    if (keyEntry != null)
                    {
                        keyResource = ResourceHandlers.CreateResource(keyEntry, resultsPackage) as NameMapResource.NameMapResource;
                    }
                }

                IResourceIndexEntry rightKey = rightPackage.Find(key => key.ResourceType == (uint)ResourceType._KEY);
                if (rightKey != null)
                {
                    NameMapResource.NameMapResource rightResource = ResourceHandlers.CreateResource(rightKey, rightPackage) as NameMapResource.NameMapResource;

                    if (keyResource == null)
                    {
                        IResourceIndexEntry keyEntry = resultsPackage.AddResource(new AResource.TGIBlock(0, null, rightKey.ResourceType, rightKey.ResourceGroup, rightKey.Instance), rightResource.Stream, false);
                        if (keyEntry != null)
                        {
                            keyResource = ResourceHandlers.CreateResource(keyEntry, resultsPackage) as NameMapResource.NameMapResource;
                        }
                    }
                    else
                    {
                        foreach (KeyValuePair <ulong, string> element in rightResource)
                        {
                            if (keyResource.ContainsKey(element.Key))
                            {
                                continue;
                            }

                            keyResource.Add(element.Key, element.Value);
                        }
                    }
                }

                IList <IResourceIndexEntry> leftList = leftPackage.FindAll(value => { return(true); });
                foreach (IResourceIndexEntry left in leftList)
                {
                    ResourceType type = (ResourceType)left.ResourceType;

                    bool test = false;
                    switch (type)
                    {
                    case ResourceType._XML:
                    case ResourceType.ITUN:
                        test = true;
                        break;
                    }

                    if (!test)
                    {
                        continue;
                    }

                    IResourceIndexEntry right = rightPackage.Find(value => { return((value.Instance == left.Instance) && (value.ResourceGroup == left.ResourceGroup) && (value.ResourceType == left.ResourceType)); });
                    if (right == null)
                    {
                        if (CheckCopyMissing.Checked)
                        {
                            TextResource.TextResource leftResource = ResourceHandlers.CreateResource(left, leftPackage) as TextResource.TextResource;

                            resultsPackage.AddResource(new AResource.TGIBlock(0, null, left.ResourceType, left.ResourceGroup, left.Instance), leftResource.Stream, false);
                        }
                    }
                    else
                    {
                        TextResource.TextResource leftResource = ResourceHandlers.CreateResource(left, leftPackage) as TextResource.TextResource;

                        StreamReader leftReader = leftResource.TextFileReader as StreamReader;
                        leftReader.BaseStream.Position = 0;
                        string leftText = leftReader.ReadToEnd();

                        TextResource.TextResource rightResource = ResourceHandlers.CreateResource(right, rightPackage) as TextResource.TextResource;

                        StreamReader rightReader = rightResource.TextFileReader as StreamReader;
                        rightReader.BaseStream.Position = 0;
                        string rightText = rightReader.ReadToEnd();

                        if (!leftText.Equals(rightText))
                        {
                            resultsPackage.AddResource(new AResource.TGIBlock(0, null, left.ResourceType, left.ResourceGroup, left.Instance), leftResource.Stream, false);
                        }
                    }
                }

                IList <IResourceIndexEntry> rightList = rightPackage.FindAll(value => { return(true); });
                foreach (IResourceIndexEntry right in rightList)
                {
                    ResourceType type = (ResourceType)right.ResourceType;

                    bool test = false;
                    switch (type)
                    {
                    case ResourceType._XML:
                    case ResourceType.ITUN:
                        test = true;
                        break;
                    }

                    if (!test)
                    {
                        continue;
                    }

                    IResourceIndexEntry left = rightPackage.Find(value => { return((value.Instance == right.Instance) && (value.ResourceGroup == right.ResourceGroup) && (value.ResourceType == right.ResourceType)); });
                    if (left == null)
                    {
                        if (CheckCopyMissing.Checked)
                        {
                            TextResource.TextResource rightResource = ResourceHandlers.CreateResource(right, rightPackage) as TextResource.TextResource;

                            resultsPackage.AddResource(new AResource.TGIBlock(0, null, right.ResourceType, right.ResourceGroup, right.Instance), rightResource.Stream, false);
                        }
                    }
                }

                resultsPackage.SaveAs(ResultsText.Text);
            }
            finally
            {
                Package.ClosePackage(0, leftPackage);
                Package.ClosePackage(0, rightPackage);
                Package.ClosePackage(0, resultsPackage);

                UseWaitCursor = false;
            }

            System.Windows.Forms.MessageBox.Show("Complete.", "Compare", MessageBoxButtons.OK);
        }
예제 #14
0
파일: Form1.cs 프로젝트: dd-dk/sims3tools
        string Compare(IPackage pkgA, IPackage pkgB, IResourceKey rk)
        {
            IResource left = s3pi.WrapperDealer.WrapperDealer.GetResource(0, pkgA, pkgA.Find(x => x.CompareTo(rk) == 0), true);
            IResource right = s3pi.WrapperDealer.WrapperDealer.GetResource(0, pkgB, pkgB.Find(x => x.CompareTo(rk) == 0), true);

            return left.AsBytes.CompareTo(right.AsBytes) == 0 ? "=" : "!";
        }
예제 #15
0
        public static void GenerateNameMap(IPackage package, List <TGIN> addedResourceKeys, List <TGIN> removedResourceKeys)
        {
            AResourceKey nameMapKey = new TGIBlock(0, null, 23462796u, 0u, 0uL);

            IResourceIndexEntry nameMapEntry = package.Find(nameMapKey.Equals);

            if (nameMapEntry == null)
            {
                nameMapEntry = package.AddResource(nameMapKey, null, false);
            }

            if (nameMapEntry != null)
            {
                NameMapResource.NameMapResource nameMapResource = (NameMapResource.NameMapResource)WrapperDealer.GetResource(0, package, nameMapEntry);

                if (nameMapResource == null || !typeof(IDictionary <ulong, string>).IsAssignableFrom(nameMapResource.GetType()))
                {
                    package.DeleteResource(nameMapEntry);
                    nameMapEntry    = package.AddResource(nameMapKey, null, false);
                    nameMapResource = (NameMapResource.NameMapResource)WrapperDealer.GetResource(0, package, nameMapEntry);
                }

                if (removedResourceKeys != null)
                {
                    for (int removedResourceKeyIndex = 0; removedResourceKeyIndex < removedResourceKeys.Count; removedResourceKeyIndex++)
                    {
                        if (nameMapResource.Contains(removedResourceKeys[removedResourceKeyIndex].ResInstance))
                        {
                            nameMapResource.Remove(removedResourceKeys[removedResourceKeyIndex].ResInstance);
                        }
                    }
                }

                if (addedResourceKeys != null)
                {
                    for (int addedResourceKeyIndex = 0; addedResourceKeyIndex < addedResourceKeys.Count; addedResourceKeyIndex++)
                    {
                        if (addedResourceKeys[addedResourceKeyIndex].ResName == null)
                        {
                            continue;
                        }

                        if (nameMapResource.Contains(addedResourceKeys[addedResourceKeyIndex].ResInstance))
                        {
                            nameMapResource[addedResourceKeys[addedResourceKeyIndex].ResInstance] = addedResourceKeys[addedResourceKeyIndex].ResName;
                        }
                        else
                        {
                            nameMapResource.Add(addedResourceKeys[addedResourceKeyIndex].ResInstance, addedResourceKeys[addedResourceKeyIndex].ResName);
                        }
                    }
                }

                List <KeyValuePair <ulong, string> > orderedNameMapResource = nameMapResource.ToList();
                orderedNameMapResource.Sort((pair1, pair2) => pair1.Value.CompareTo(pair2.Value));

                nameMapResource.Clear();

                for (int orderedNameMapResourceIndex = 0; orderedNameMapResourceIndex < orderedNameMapResource.Count; orderedNameMapResourceIndex++)
                {
                    nameMapResource.Add(orderedNameMapResource[orderedNameMapResourceIndex].Key, orderedNameMapResource[orderedNameMapResourceIndex].Value);
                }

                package.ReplaceResource(nameMapEntry, nameMapResource);
            }
        }
예제 #16
0
        public async Task <WebLibrary> DeployAsync(IPackage package, RevisionSource source, int publisherId)
        {
            #region Preconditions

            if (package == null)
            {
                throw new ArgumentNullException(nameof(package));
            }

            #endregion

            var metadata = GetMetadata(package);

            var version = metadata.Version;

            // var existing = await registry.GetAsync(registry.Lookup(metadata.Name), metadata.Version);

            // if (existing != null) throw new PublishingConflict(existing);

            var mainPath = metadata.Main;

            var bowerFile = package.Find("bower.json");

            if (bowerFile != null)
            {
                try
                {
                    var bowerFileStream = await bowerFile.OpenAsync().ConfigureAwait(false);

                    var bower = PackageMetadata.Parse(bowerFileStream);

                    if (bower.Main != null)
                    {
                        mainPath = bower.Main;
                    }
                }
                catch { }
            }

            if (mainPath == null)
            {
                throw new Exception("A main property found in package.json or bower.json.");
            }

            var mainFile = package.Find(mainPath);

            if (mainFile == null)
            {
                throw new Exception($"The main file '{mainPath}' was not found");
            }

            var mainText = await mainFile.ReadAllTextAsync().ConfigureAwait(false);

            if (mainText.Length == 0)
            {
                throw new Exception($"{mainPath} is empty");
            }

            var mainBlobStream = new MemoryStream(Encoding.UTF8.GetBytes(mainText));

            var mainName = mainPath.Split('/').Last();

            if (!mainName.EndsWith(".js"))
            {
                throw new Exception($"Must end with js. was {mainName}");
            }

            var mainBlob = new Blob(
                key: $"libs/{metadata.Name}/{version}/{mainName}",
                stream: mainBlobStream,
                properties: new BlobProperties {
                ContentType = "application/javascript"
            }
                );

            var mainHash = Hash.ComputeSHA256(mainBlobStream);

            // Push to CDN
            await bucket.PutAsync(mainBlob).ConfigureAwait(false);

            if (metadata.Files != null)
            {
                // TODO: Copy over everything from files[] (excluding main)
                foreach (var fileName in metadata.Files)
                {
                    var fn = fileName;

                    if (fn.StartsWith("./"))
                    {
                        fn = fileName.Substring(2);
                    }

                    if (fn == mainPath)
                    {
                        continue;
                    }

                    var asset = package.Find(fn);

                    var format = asset.Key.Split('.').Last();

                    var n = asset.Key.Split('/').Last();

                    var ms = new MemoryStream();

                    using (var data = await asset.OpenAsync().ConfigureAwait(false))
                    {
                        data.CopyTo(ms);

                        ms.Position = 0;
                    }

                    var blob = new Blob(
                        key: $"libs/{metadata.Name}/{version}/{n}",
                        stream: ms,
                        properties: new BlobProperties {
                        ContentType = GetMime(format)
                    }
                        );

                    await bucket.PutAsync(blob).ConfigureAwait(false);
                }
            }

            var release = new WebLibrary(metadata.Name, version)
            {
                MainName   = mainName,
                MainSha256 = mainHash,
                Source     = source.ToString()
            };

            return(release);
        }