public void ModifyItem(CapsResManifestItem item) { if (_Building != null) { var asset = _Building.Asset; string rootpath = "Assets/CapsRes/"; bool inPackage = false; if (asset.StartsWith("Assets/Mods/") || (inPackage = asset.StartsWith("Packages/"))) { int index; if (inPackage) { index = asset.IndexOf('/', "Packages/".Length); } else { index = asset.IndexOf('/', "Assets/Mods/".Length); } if (index > 0) { rootpath = asset.Substring(0, index) + "/CapsRes/"; } } var dist = _Building.Dist; if (string.IsNullOrEmpty(dist)) { rootpath += "atlas/"; } else { rootpath = rootpath + "dist/" + dist + "/atlas/"; } var newpath = rootpath + _Building.AtlasName; CapsResManifestNode newnode = item.Manifest.AddOrGetItem(newpath); var newitem = new CapsResManifestItem(newnode); newitem.Type = (int)CapsResManifestItemType.Redirect; newitem.BRef = item.BRef; newitem.Ref = item; newnode.Item = newitem; } }
public static IEnumerator GenerateBuildWorkAsync(Dictionary <string, CapsResBuildWork> result, IList <string> assets, IEditorWorkProgressShower winprog, IList <IResBuilderEx> runOnceExBuilder) { var logger = new EditorWorkProgressLogger() { Shower = winprog }; logger.Log("(Start) Generate Build Work."); if (winprog != null && AsyncWorkTimer.Check()) { yield return(null); } if (result == null) { logger.Log("(Error) You have to provide container to retrive the result."); yield break; } result.Clear(); if (assets == null) { logger.Log("(Option) Get All Assets."); assets = AssetDatabase.GetAllAssetPaths(); if (winprog != null && AsyncWorkTimer.Check()) { yield return(null); } } if (assets != null) { List <IResBuilderEx> allExBuilders = new List <IResBuilderEx>(ResBuilderEx); if (runOnceExBuilder != null) { allExBuilders.AddRange(runOnceExBuilder); } Dictionary <string, Dictionary <string, List <string> > > mod2build = new Dictionary <string, Dictionary <string, List <string> > >(); Dictionary <string, Dictionary <string, CapsResManifest> > mod2mani = new Dictionary <string, Dictionary <string, CapsResManifest> >(); for (int i = 0; i < assets.Count; ++i) { if (winprog != null && AsyncWorkTimer.Check()) { yield return(null); } var asset = assets[i]; logger.Log(asset); if (string.IsNullOrEmpty(asset)) { logger.Log("Empty Path."); continue; } if (System.IO.Directory.Exists(asset)) { logger.Log("Folder."); continue; } if (CapsResInfoEditor.IsAssetScript(asset)) { logger.Log("Script."); continue; } string mod = null; string opmod = null; string dist = null; string norm = asset; bool inPackage = false; if (asset.StartsWith("Assets/Mods/") || (inPackage = asset.StartsWith("Packages/"))) { string sub; if (inPackage) { sub = asset.Substring("Packages/".Length); } else { sub = asset.Substring("Assets/Mods/".Length); } var index = sub.IndexOf('/'); if (index < 0) { logger.Log("Cannot Parse Module."); continue; } mod = sub.Substring(0, index); if (inPackage) { mod = CapsModEditor.GetPackageModName(mod); } if (string.IsNullOrEmpty(mod)) { logger.Log("Empty Module."); continue; } sub = sub.Substring(index + 1); if (!sub.StartsWith("CapsRes/")) { logger.Log("Should Ignore This Asset."); continue; } var moddesc = ResManager.GetDistributeDesc(mod); bool isMainPackage = inPackage && !CapsModEditor.ShouldTreatPackageAsMod(CapsModEditor.GetPackageName(mod)); if (moddesc == null || moddesc.InMain || isMainPackage) { mod = ""; if (moddesc != null && moddesc.IsOptional && !isMainPackage) { opmod = moddesc.Mod; } } sub = sub.Substring("CapsRes/".Length); norm = sub; if (sub.StartsWith("dist/")) { sub = sub.Substring("dist/".Length); index = sub.IndexOf('/'); if (index > 0) { dist = sub.Substring(0, index); norm = sub.Substring(index + 1); } } } else { if (asset.StartsWith("Assets/CapsRes/")) { mod = ""; var sub = asset.Substring("Assets/CapsRes/".Length); norm = sub; if (sub.StartsWith("dist/")) { sub = sub.Substring("dist/".Length); var index = sub.IndexOf('/'); if (index > 0) { dist = sub.Substring(0, index); norm = sub.Substring(index + 1); } } } else { logger.Log("Should Ignore This Asset."); continue; } } if (string.IsNullOrEmpty(norm)) { logger.Log("Normallized Path Empty."); continue; } mod = mod ?? ""; dist = dist ?? ""; logger.Log("Mod " + mod + "; Dist " + dist + "; Norm " + norm); Dictionary <string, List <string> > builds; if (!mod2build.TryGetValue(mod, out builds)) { builds = new Dictionary <string, List <string> >(); mod2build[mod] = builds; } Dictionary <string, CapsResManifest> manis; if (!mod2mani.TryGetValue(opmod ?? mod, out manis)) { manis = new Dictionary <string, CapsResManifest>(); mod2mani[opmod ?? mod] = manis; } CapsResManifest mani; if (!manis.TryGetValue(dist, out mani)) { mani = new CapsResManifest(); mani.MFlag = opmod ?? mod; mani.DFlag = dist; if (opmod != null) { mani.InMain = true; } manis[dist] = mani; } string bundle = null; bool shouldWriteBRef = false; for (int j = 0; j < allExBuilders.Count; ++j) { bundle = allExBuilders[j].FormatBundleName(asset, opmod ?? mod, dist, norm); if (bundle != null) { break; } } if (bundle == null) { bundle = FormatBundleName(asset, opmod ?? mod, dist, norm); } else { shouldWriteBRef = true; } List <string> build; if (!builds.TryGetValue(bundle, out build)) { build = new List <string>(); builds[bundle] = build; } build.Add(asset); var node = mani.AddOrGetItem(asset); for (int j = 0; j < allExBuilders.Count; ++j) { if (allExBuilders[j].CreateItem(node)) { break; } } if (node.Item == null) { var item = new CapsResManifestItem(node); if (asset.EndsWith(".prefab")) { item.Type = (int)CapsResManifestItemType.Prefab; } else if (asset.EndsWith(".unity")) { item.Type = (int)CapsResManifestItemType.Scene; } else { item.Type = (int)CapsResManifestItemType.Normal; } if (shouldWriteBRef) { item.BRef = bundle; } node.Item = item; } for (int j = 0; j < allExBuilders.Count; ++j) { allExBuilders[j].ModifyItem(node.Item); } } if (winprog != null && AsyncWorkTimer.Check()) { yield return(null); } logger.Log("(Phase) Combine the final result."); foreach (var kvpbuild in mod2build) { var mod = kvpbuild.Key; var builds = kvpbuild.Value; CapsResBuildWork work = new CapsResBuildWork(); if (mod == "") { List <CapsResManifest> manis = new List <CapsResManifest>(mod2mani[mod].Values); foreach (var kvpmm in mod2mani) { if (!mod2build.ContainsKey(kvpmm.Key)) { manis.AddRange(kvpmm.Value.Values); } } work.Manifests = manis.ToArray(); } else { work.Manifests = mod2mani[mod].Values.ToArray(); } work.ABs = new AssetBundleBuild[builds.Count]; int index = 0; foreach (var kvpbundle in builds) { var bundleName = kvpbundle.Key; var bundleAssets = kvpbundle.Value; AssetBundleBuild build = new AssetBundleBuild(); build.assetBundleName = kvpbundle.Key; build.assetNames = kvpbundle.Value.ToArray(); for (int j = 0; j < allExBuilders.Count; ++j) { allExBuilders[j].GenerateBuildWork(bundleName, bundleAssets, ref build, work, index); } work.ABs[index++] = build; } result[mod] = work; } } logger.Log("(Done) Generate Build Work."); }
private static System.IO.Stream GetLuaStream(CapsResManifestItem item, out string location) { try { var rnode = item.Node; System.Text.StringBuilder sbpath = new System.Text.StringBuilder(); while (rnode.Parent != null) { if (sbpath.Length > 0) { sbpath.Insert(0, '/'); } sbpath.Insert(0, rnode.PPath); rnode = rnode.Parent; } var path = sbpath.ToString(); // load from update path var sptpath = ThreadSafeValues.UpdatePath + "/spt/" + path; if (PlatDependant.IsFileExist(sptpath)) { location = sptpath; return(PlatDependant.OpenRead(sptpath)); } // load from package if (ThreadSafeValues.AppStreamingAssetsPath.Contains("://")) { if (ThreadSafeValues.AppPlatform == RuntimePlatform.Android.ToString() && ResManager.LoadAssetsFromApk) { // Obb if (ResManager.LoadAssetsFromObb && ResManager.ObbZipArchive != null) { sptpath = "spt/" + path; int retryTimes = 10; 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 entry = za.GetEntry(sptpath); if (entry != null) { location = sptpath; return(entry.Open()); } } 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) { sptpath = "assets/spt/" + path; int retryTimes = 10; 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 entry = za.GetEntry(sptpath); if (entry != null) { location = sptpath; return(entry.Open()); } } 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 { sptpath = ThreadSafeValues.AppStreamingAssetsPath + "/spt/" + path; if (PlatDependant.IsFileExist(sptpath)) { location = sptpath; return(PlatDependant.OpenRead(sptpath)); } } } catch (Exception e) { PlatDependant.LogError(e); } location = ""; return(null); }
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(); } }
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); }
public void ModifyItem(CapsResManifestItem item) { if (_Building != null) { var node = item.Node; var asset = _Building.Asset; string rootpath = "Assets/CapsRes/"; bool inPackage = false; if (asset.StartsWith("Assets/Mods/") || (inPackage = asset.StartsWith("Packages/"))) { int index; if (inPackage) { index = asset.IndexOf('/', "Packages/".Length); } else { index = asset.IndexOf('/', "Assets/Mods/".Length); } if (index > 0) { rootpath = asset.Substring(0, index) + "/CapsRes/"; } } var dist = _Building.Dist; if (string.IsNullOrEmpty(dist)) { rootpath += "font/"; } else { rootpath = rootpath + "dist/" + dist + "/font/"; } var newpath = rootpath + node.PPath; CapsResManifestNode newnode = item.Manifest.AddOrGetItem(newpath); var newitem = new CapsResManifestItem(newnode); newitem.Type = (int)CapsResManifestItemType.Redirect; newitem.BRef = item.BRef; newitem.Ref = item; newnode.Item = newitem; if (_PHFontDescs.Contains(asset)) { newpath = rootpath + "placeholder"; newnode = item.Manifest.AddOrGetItem(newpath); if (newnode.Item == null) { newitem = new CapsResManifestItem(newnode); newitem.Type = (int)CapsResManifestItemType.Redirect; newitem.BRef = item.BRef; newitem.Ref = item; newnode.Item = newitem; } } else if (_ReplacementDescs.Contains(asset)) { newpath = rootpath + "replacement"; newnode = item.Manifest.AddOrGetItem(newpath); if (newnode.Item == null) { newitem = new CapsResManifestItem(newnode); newitem.Type = (int)CapsResManifestItemType.Redirect; newitem.BRef = item.BRef; newitem.Ref = item; newnode.Item = newitem; } } } }