private static void ParseManifest(string mod, string[] manibundlenames)
            {
                mod = mod ?? "";
                var lmod      = mod.ToLower();
                var umanipath = "res";

                if (mod != "")
                {
                    umanipath = "mod/" + mod + "/" + mod;
                }
                var mbinfo = LoadAssetBundle(umanipath, true);

                if (mbinfo != null)
                {
                    if (mbinfo.Bundle != null)
                    {
                        var umanis = mbinfo.Bundle.LoadAllAssets <AssetBundleManifest>();
                        if (umanis != null && umanis.Length > 0)
                        {
                            UnityManifests[mod] = Object.Instantiate <AssetBundleManifest>(umanis[0]);
                        }
                    }
                    mbinfo.AddRef();
                    mbinfo.Release();
                }

                var pre = "mani/m-" + lmod + "-";

                for (int j = 0; j < manibundlenames.Length; ++j)
                {
                    var bundle = manibundlenames[j];
                    if (bundle.StartsWith(pre) && bundle.EndsWith(".m.ab"))
                    {
                        var binfo = LoadAssetBundle(bundle);
                        if (binfo != null)
                        {
                            if (binfo.Bundle != null)
                            {
                                var dmanis = binfo.Bundle.LoadAllAssets <CapsResOnDiskManifest>();
                                if (dmanis != null)
                                {
                                    for (int k = 0; k < dmanis.Length; ++k)
                                    {
                                        var mani = CapsResManifest.Load(dmanis[k]);
                                        CollapsedManifest.MergeManifest(mani);
                                    }
                                }
                            }
                            binfo.AddRef();
                            binfo.Release();
                        }
                    }
                }
            }
        public void MergeManifest(CapsResManifest other)
        {
            if (other == null || other.Root == null || other.Root.Children == null)
            {
                return;
            }
            if (Root == null)
            {
                Root = new CapsResManifestNode(this);
            }
            CapsResManifestNode mynode = Root;
            CapsResManifestNode thnode;

            if (other.TryGetItem("Assets/CapsRes", out thnode))
            {
                MergeManifestNode(mynode, thnode, false);
            }
            //if (other.TryGetItem("Assets/CapsSpt", out thnode))
            //{
            //    MergeManifestNode(mynode, thnode);
            //}
            for (int i = 0; i < _MergeManifestModsRoots.Length; ++i)
            {
                if (other.TryGetItem(_MergeManifestModsRoots[i], out thnode))
                {
                    if (thnode.Children != null)
                    {
                        foreach (var kvpChild in thnode.Children)
                        {
                            var child = kvpChild.Value;
                            if (child.Children != null)
                            {
                                CapsResManifestNode thresnode;
                                if (child.Children.TryGetValue("CapsRes", out thresnode))
                                {
                                    MergeManifestNode(mynode, thresnode, false);
                                }
                                //if (child.Children.TryGetValue("CapsSpt", out thresnode))
                                //{
                                //    MergeManifestNode(mynode, thresnode);
                                //}
                            }
                        }
                    }
                }
            }
        }
        public static CapsResOnDiskManifest Save(CapsResManifest inmem)
        {
            if (inmem == null)
            {
                return(null);
            }
            CapsResOnDiskManifest rv = ScriptableObject.CreateInstance <CapsResOnDiskManifest>();

            rv.MFlag  = inmem.MFlag;
            rv.DFlag  = inmem.DFlag;
            rv.InMain = inmem.InMain;

            Dictionary <CapsResManifestItem, int> itemlines = new Dictionary <CapsResManifestItem, int>();
            Dictionary <CapsResOnDiskManifestItem, CapsResManifestItem> unknownRefItem = new Dictionary <CapsResOnDiskManifestItem, CapsResManifestItem>();
            Dictionary <string, int> bundlelines = new Dictionary <string, int>();
            List <string>            bundles     = new List <string>();

            bundles.Add("");
            List <CapsResOnDiskManifestNode>  assets   = new List <CapsResOnDiskManifestNode>();
            Action <CapsResManifestNode, int> SaveNode = null;

            SaveNode = (node, lvl) =>
            {
                var linen = assets.Count;
                var asset = new CapsResOnDiskManifestNode();
                asset.Level = lvl;
                asset.PPath = node.PPath;
                assets.Add(asset);
                if (node.Item != null)
                {
                    itemlines[node.Item] = linen;
                    CapsResOnDiskManifestItem item = new CapsResOnDiskManifestItem();
                    asset.Item = item;
                    item.Type  = node.Item.Type;
                    if (node.Item.BRef != null)
                    {
                        var bref = node.Item.BRef;
                        int brefline;
                        if (!bundlelines.TryGetValue(bref, out brefline))
                        {
                            brefline          = bundles.Count;
                            bundlelines[bref] = brefline;
                            bundles.Add(bref);
                        }
                        item.BRef = brefline;
                    }
                    if (node.Item.Ref != null)
                    {
                        var aref = node.Item.Ref;
                        int arefline;
                        if (itemlines.TryGetValue(aref, out arefline))
                        {
                            item.Ref = arefline;
                        }
                        else
                        {
                            unknownRefItem[item] = aref;
                        }
                    }
                    if (node.Item.ExInfo != null)
                    {
                        item.ExInfo = UnityEngine.Object.Instantiate <ScriptableObject>(node.Item.ExInfo);
                    }
                }
                if (node.Children != null)
                {
                    var values = node.Children.Values;
                    for (int i = 0; i < values.Count; ++i)
                    {
                        SaveNode(values[i], lvl + 1);
                    }
                }
            };

            if (inmem.Root != null)
            {
                SaveNode(inmem.Root, 0);
            }

            foreach (var kvpu in unknownRefItem)
            {
                int aref;
                if (itemlines.TryGetValue(kvpu.Value, out aref))
                {
                    kvpu.Key.Ref = aref;
                }
            }

            if (bundles.Count > 1)
            {
                rv.Bundles = bundles.ToArray();
            }
            if (assets.Count > 0)
            {
                rv.Assets = assets.ToArray();
            }

            return(rv);
        }
 public CapsResManifestNode(CapsResManifestNode parent, string ppath)
 {
     Parent   = parent;
     Manifest = parent.Manifest;
     PPath    = ppath;
 }
        public static CapsResManifest Load(CapsResOnDiskManifest ondisk)
        {
            if (ondisk == null)
            {
                return(null);
            }
            CapsResManifest rv = new CapsResManifest();

            rv.MFlag  = ondisk.MFlag;
            rv.DFlag  = ondisk.DFlag;
            rv.InMain = ondisk.InMain;

            if (ondisk.Assets != null && ondisk.Assets.Length > 0)
            {
                List <CapsResManifestNode> nodeStack = new List <CapsResManifestNode>();
                var parsedNodes = new CapsResManifestNode[ondisk.Assets.Length];
                for (int i = 0; i < ondisk.Assets.Length; ++i)
                {
                    var curDiskNode = ondisk.Assets[i];
                    var curlvl      = curDiskNode.Level;
                    if (nodeStack.Count > curlvl)
                    {
                        var removecnt = nodeStack.Count - curlvl;
                        nodeStack.RemoveRange(nodeStack.Count - removecnt, removecnt);
                    }
                    while (nodeStack.Count < curlvl)
                    {
                        // something goes wrong here.
                        nodeStack.Add(null);
                    }

                    CapsResManifestNode curNode;
                    if (curlvl == 0)
                    {
                        curNode = new CapsResManifestNode(rv);
                        rv.Root = curNode;
                        //curNode.PPath = curDiskNode.PPath;
                    }
                    else
                    {
                        var parNode = nodeStack[curlvl - 1];
                        var ppath   = curDiskNode.PPath;
                        curNode = new CapsResManifestNode(parNode, ppath);
                        if (parNode.Children == null)
                        {
                            parNode.Children = new SortedList <string, CapsResManifestNode>();
                        }
                        parNode.Children[ppath] = curNode;
                    }
                    nodeStack.Add(curNode);
                    parsedNodes[i] = curNode;

                    if (curDiskNode.Item != null && curDiskNode.Item.Type != 0)
                    {
                        var item = new CapsResManifestItem(curNode);
                        curNode.Item = item;
                        item.Type    = curDiskNode.Item.Type;
                        if (curDiskNode.Item.BRef > 0)
                        {
                            if (ondisk.Bundles != null && ondisk.Bundles.Length > curDiskNode.Item.BRef)
                            {
                                item.BRef = ondisk.Bundles[curDiskNode.Item.BRef];
                            }
                        }
                        if (curDiskNode.Item.ExInfo != null)
                        {
                            item.ExInfo = UnityEngine.Object.Instantiate <ScriptableObject>(curDiskNode.Item.ExInfo);
                        }
                    }
                }
                for (int i = 0; i < ondisk.Assets.Length; ++i)
                {
                    var curDiskNode = ondisk.Assets[i];
                    if (curDiskNode.Item != null && curDiskNode.Item.Type != 0 && curDiskNode.Item.Ref > 0)
                    {
                        parsedNodes[i].Item.Ref = parsedNodes[curDiskNode.Item.Ref].Item;
                    }
                }
            }

            rv.TrimExcess();

            return(rv);
        }
 public CapsResManifestNode(CapsResManifest manifest)
 {
     Manifest = manifest;
 }
 public CapsResManifestItem(CapsResManifestNode node)
 {
     Node     = node;
     Manifest = node.Manifest;
 }