private static void LoadRuntimeManifest(TaskProgress progress) { try { var maniPath = ThreadSafeValues.UpdatePath + "/spt/manifest.m.txt"; if (PlatDependant.IsFileExist(maniPath)) { _RuntimeRawManifest = LoadManifest(maniPath); } else { CapsResManifest mani = new CapsResManifest(); // load from update path var sptfolder = ThreadSafeValues.UpdatePath + "/spt/"; try { var files = PlatDependant.GetAllFiles(sptfolder); if (files != null && files.Length > 0) { for (int i = 0; i < files.Length; ++i) { var file = files[i]; var part = file.Substring(sptfolder.Length).Replace('\\', '/'); var node = mani.AddOrGetItem(part); if (node.Item == null) { CapsResManifestItem item; item = new CapsResManifestItem(node); node.Item = item; } } } } catch (Exception e) { PlatDependant.LogError(e); } // load from package if (ThreadSafeValues.AppStreamingAssetsPath.Contains("://")) { if (ThreadSafeValues.AppPlatform == RuntimePlatform.Android.ToString() && ResManager.LoadAssetsFromApk) { // Obb if (ResManager.LoadAssetsFromObb && ResManager.ObbZipArchive != null) { sptfolder = "spt/"; int retryTimes = 10; int entryindex = 0; for (int i = 0; i < retryTimes; ++i) { Exception error = null; do { ZipArchive za = ResManager.ObbZipArchive; if (za == null) { PlatDependant.LogError("Obb Archive Cannot be read."); break; } try { var entries = za.Entries; while (entryindex < entries.Count) { var entry = entries[entryindex]; var fullname = entry.FullName; if (fullname.StartsWith(sptfolder)) { var part = fullname.Substring(sptfolder.Length); var node = mani.AddOrGetItem(part); if (node.Item == null) { CapsResManifestItem item; item = new CapsResManifestItem(node); node.Item = item; } } ++entryindex; } } catch (Exception e) { error = e; break; } } while (false); if (error != null) { if (i == retryTimes - 1) { PlatDependant.LogError(error); } else { PlatDependant.LogError(error); PlatDependant.LogInfo("Need Retry " + i); } } else { break; } } } // Apk //if (true) { sptfolder = "assets/spt/"; int retryTimes = 10; int entryindex = 0; for (int i = 0; i < retryTimes; ++i) { Exception error = null; do { ZipArchive za = ResManager.AndroidApkZipArchive; if (za == null) { PlatDependant.LogError("Apk Archive Cannot be read."); break; } try { var entries = za.Entries; while (entryindex < entries.Count) { var entry = entries[entryindex]; var fullname = entry.FullName; if (fullname.StartsWith(sptfolder)) { var part = fullname.Substring(sptfolder.Length); var node = mani.AddOrGetItem(part); if (node.Item == null) { CapsResManifestItem item; item = new CapsResManifestItem(node); node.Item = item; } } ++entryindex; } } catch (Exception e) { error = e; break; } } while (false); if (error != null) { if (i == retryTimes - 1) { PlatDependant.LogError(error); } else { PlatDependant.LogError(error); PlatDependant.LogInfo("Need Retry " + i); } } else { break; } } } } } else { sptfolder = ThreadSafeValues.AppStreamingAssetsPath + "/spt/"; try { var files = PlatDependant.GetAllFiles(sptfolder); if (files != null && files.Length > 0) { for (int i = 0; i < files.Length; ++i) { var file = files[i]; var part = file.Substring(sptfolder.Length).Replace('\\', '/'); var node = mani.AddOrGetItem(part); if (node.Item == null) { CapsResManifestItem item; item = new CapsResManifestItem(node); node.Item = item; } } } } catch (Exception e) { PlatDependant.LogError(e); } } mani.TrimExcess(); _RuntimeRawManifest = mani; _RuntimeManifestReady.Set(); SaveManifest(mani, maniPath); } } finally { _RuntimeManifestReady.Set(); _RuntimeManifestTaskIdle.Set(); } }
// This will judge whether a mod is optional, so this should be called in UnityMain thread. private static CapsResManifest MergeAndCollapseRuntimeManifest(CapsResManifest rawmani) { var root = rawmani.Root; var rmani = new CapsResManifest(); if (root != null) { rmani.Root = new CapsResManifestNode(rmani); CapsResManifestNode tmpNode = new CapsResManifestNode(rawmani); CapsResManifestNode archNode = null; if (root.Children != null) { tmpNode.Children = new SortedList <string, CapsResManifestNode>(); for (int i = 0; i < root.Children.Count; ++i) { var child = root.Children.Values[i]; if (child.PPath == "mod") { continue; } else if (child.PPath == "@64") { if (Environment.Is64BitProcess) { archNode = child; } continue; } else if (child.PPath == "@32") { if (!Environment.Is64BitProcess) { archNode = child; } continue; } tmpNode.Children[child.PPath] = child; } } // merge - no mod CapsResManifest.MergeManifestNode(rmani.Root, tmpNode, true); // merge - no mod on arch if (archNode != null) { tmpNode = new CapsResManifestNode(rawmani); if (archNode.Children != null) { tmpNode.Children = new SortedList <string, CapsResManifestNode>(); for (int i = 0; i < archNode.Children.Count; ++i) { var child = archNode.Children.Values[i]; if (child.PPath == "mod") { continue; } tmpNode.Children[child.PPath] = child; } } CapsResManifest.MergeManifestNode(rmani.Root, tmpNode, true); } // merge - mod MergeRuntimeManifestInMod(rmani, root); // merge - mod on arch if (archNode != null) { MergeRuntimeManifestInMod(rmani, archNode); } // Collapse var flags = ResManager.GetValidDistributeFlags(); rmani.CollapseManifest(flags); rmani.TrimExcess(); } return(rmani); }
public static CapsResManifest LoadManifest(string file) { CapsResManifest mani = new CapsResManifest(); if (PlatDependant.IsFileExist(file)) { using (var sr = PlatDependant.OpenReadText(file)) { if (sr != null) { List <CapsResManifestNode> nodeStack = new List <CapsResManifestNode>(); var root = new CapsResManifestNode(mani); mani.Root = root; nodeStack.Add(root); int nxtChar = -1; while ((nxtChar = sr.Peek()) > 0) { int lvl = 0; while (nxtChar == '*') { sr.Read(); ++lvl; nxtChar = sr.Peek(); } string ppath = sr.ReadLine(); if (string.IsNullOrEmpty(ppath)) { continue; } if (nodeStack.Count > lvl) { var last = nodeStack[nodeStack.Count - 1]; if (last.Children == null || last.Children.Count <= 0) { CapsResManifestItem item; item = new CapsResManifestItem(last); last.Item = item; } nodeStack.RemoveRange(lvl, nodeStack.Count - lvl); } { var last = nodeStack[nodeStack.Count - 1]; if (last.Children == null) { last.Children = new SortedList <string, CapsResManifestNode>(); } var child = new CapsResManifestNode(last, ppath); last.Children[ppath] = child; nodeStack.Add(child); } } if (nodeStack.Count > 1) { var last = nodeStack[nodeStack.Count - 1]; CapsResManifestItem item; item = new CapsResManifestItem(last); last.Item = item; } mani.TrimExcess(); } } } return(mani); }