public async Task <List <Resources.ResourceInfo> > UnPackAssets(string packageAbsFile, string targetAbsPath) { List <Resources.ResourceInfo> retList = new List <Resources.ResourceInfo>(20); EditorCommon.FileSystemWatcherProcess.Enable = false; targetAbsPath = targetAbsPath.Replace("\\", "/").TrimEnd('/') + "/"; mNameManager.ClearMapper(); EngineNS.CEngine.Instance.FileManager.ClearPackageRNameCache(); // unzip var tempPath = EngineNS.CEngine.Instance.FileManager.Root + Guid.NewGuid().ToString() + "/"; if (EngineNS.CEngine.Instance.FileManager.DirectoryExists(tempPath)) { EngineNS.CEngine.Instance.FileManager.DeleteDirectory(tempPath, true); } EngineNS.CEngine.Instance.FileManager.CreateDirectory(tempPath); System.IO.File.SetAttributes(tempPath, System.IO.FileAttributes.Hidden); System.IO.Compression.ZipFile.ExtractToDirectory(packageAbsFile, tempPath); var srcContentTempPath = (tempPath + "Content/").Replace("\\", "/").ToLower(); var srcEditorContentTempPath = (tempPath + "EditContent/").Replace("\\", "/").ToLower(); var srcEngineContentTempPath = (tempPath + "EngineContent/").Replace("\\", "/").ToLower(); MessageBox.enMessageBoxResult chooseResult = MessageBox.enMessageBoxResult.Cancel; // EditorContent和EngineContent的对象直接复制 if (EngineNS.CEngine.Instance.FileManager.DirectoryExists(srcEditorContentTempPath)) { var files = EngineNS.CEngine.Instance.FileManager.GetFiles(srcEditorContentTempPath, "*", System.IO.SearchOption.AllDirectories); for (int i = 0; i < files.Count; i++) { var file = files[0].Replace("\\", "/").ToLower(); var tagFile = file.Replace(srcEditorContentTempPath, EngineNS.CEngine.Instance.FileManager.EditorContent); switch (chooseResult) { case MessageBox.enMessageBoxResult.YesAll: EngineNS.CEngine.Instance.FileManager.CopyFile(file, tagFile, true); break; case MessageBox.enMessageBoxResult.NoAll: EngineNS.CEngine.Instance.FileManager.CopyFile(file, tagFile, false); break; default: if (EngineNS.CEngine.Instance.FileManager.FileExists(tagFile)) { chooseResult = EditorCommon.MessageBox.Show($"文件{tagFile}与包中文件重名,是否覆盖?", MessageBox.enMessageBoxButton.Yes_YesAll_No_NoAll); switch (chooseResult) { case MessageBox.enMessageBoxResult.Yes: EngineNS.CEngine.Instance.FileManager.CopyFile(file, tagFile, true); break; } } break; } } } if (EngineNS.CEngine.Instance.FileManager.DirectoryExists(srcEngineContentTempPath)) { var files = EngineNS.CEngine.Instance.FileManager.GetFiles(srcEngineContentTempPath, "*", System.IO.SearchOption.AllDirectories); for (int i = 0; i < files.Count; i++) { var file = files[0].Replace("\\", "/").ToLower(); var tagFile = file.Replace(srcEngineContentTempPath, EngineNS.CEngine.Instance.FileManager.EngineContent); switch (chooseResult) { case MessageBox.enMessageBoxResult.YesAll: EngineNS.CEngine.Instance.FileManager.CopyFile(file, tagFile, true); break; case MessageBox.enMessageBoxResult.NoAll: if (!EngineNS.CEngine.Instance.FileManager.FileExists(tagFile)) { EngineNS.CEngine.Instance.FileManager.CopyFile(file, tagFile, false); } break; default: if (EngineNS.CEngine.Instance.FileManager.FileExists(tagFile)) { chooseResult = EditorCommon.MessageBox.Show($"文件{tagFile}与包中文件重名,是否覆盖?", MessageBox.enMessageBoxButton.Yes_YesAll_No_NoAll); switch (chooseResult) { case MessageBox.enMessageBoxResult.Yes: EngineNS.CEngine.Instance.FileManager.CopyFile(file, tagFile, true); break; } } break; } } } // Content中放入目标目录 if (EngineNS.CEngine.Instance.FileManager.DirectoryExists(srcContentTempPath)) { // 读取RName表 var xmlHolder = EngineNS.IO.XmlHolder.LoadXML(tempPath + "RNames.xml"); var rNameDataNode = xmlHolder.RootNode.FindNode("RNameData"); Dictionary <int, RNameData> rNameDataDic = new Dictionary <int, RNameData>(); Dictionary <string, RNameData> rNameDataPathDic = new Dictionary <string, RNameData>(); if (rNameDataNode != null) { var cNodes = rNameDataNode.GetNodes(); foreach (var cNode in cNodes) { var data = new RNameData(); var idxAtt = cNode.FindAttrib("Index"); if (idxAtt != null) { data.Index = System.Convert.ToInt32(idxAtt.Value); } var nameAtt = cNode.FindAttrib("Name"); if (nameAtt != null) { data.Name = nameAtt.Value; } var rtAtt = cNode.FindAttrib("RNameType"); if (rtAtt != null) { data.RNameType = EngineNS.Rtti.RttiHelper.EnumTryParse <EngineNS.RName.enRNameType>(rtAtt.Value); } var pathAtt = cNode.FindAttrib("PackagePath"); if (pathAtt != null) { data.PackagePath = pathAtt.Value; } rNameDataDic.Add(data.Index, data); rNameDataPathDic.Add(data.PackagePath, data); } } // RName填充,将RName中路径填充为Package目录 var rNameDataDicEnum = rNameDataDic.GetEnumerator(); while (rNameDataDicEnum.MoveNext()) { var rName = EngineNS.RName.GetRName(rNameDataDicEnum.Current.Key); rName.RNameType = EngineNS.RName.enRNameType.Package; rName.Name = tempPath + EngineNS.RName.GetRootFolderName(rNameDataDicEnum.Current.Value.RNameType) + rNameDataDicEnum.Current.Value.PackagePath; } // Shader目录直接拷贝 if (EngineNS.CEngine.Instance.FileManager.DirectoryExists(srcContentTempPath + "shaders")) { EngineNS.CEngine.Instance.FileManager.CopyDirectory(srcContentTempPath + "shaders", EngineNS.CEngine.Instance.FileManager.ProjectContent + "shaders"); } var relPath = EngineNS.CEngine.Instance.FileManager._GetRelativePathFromAbsPath(targetAbsPath, EngineNS.CEngine.Instance.FileManager.ProjectContent); // 全部加载, var files = EngineNS.CEngine.Instance.FileManager.GetFiles(srcContentTempPath, "*.rinfo", System.IO.SearchOption.AllDirectories); List <PackageResData> mLoadedResInfoDatas = new List <PackageResData>(files.Count); for (int i = 0; i < files.Count; i++) { var file = files[i].Replace("\\", "/"); var resInfo = await EditorCommon.Resources.ResourceInfoManager.Instance.CreateResourceInfoFromFile(file, null); var rnm = mNameManager.GetRNameIndex(resInfo.ResourceName); if (rnm == null) { continue; } var loadData = new EditorCommon.Assets.AssetsPakage.LoadResourceData() { ObjType = null, RNameMapper = rnm, }; await resInfo.AssetsOption_LoadResource(loadData); var pkResData = new PackageResData() { ResInfo = resInfo, RNM = rnm, }; mLoadedResInfoDatas.Add(pkResData); } // 填充rname,将RName中路径填充为Content目录,这里需要保证在之前全部加载完成,否则可能导致加载到目标目录的文件,而目标目录的文件是有可能还没导入 foreach (var cache in EngineNS.CEngine.Instance.FileManager.PackageRNameCache.Values) { RNameData data; if (rNameDataDic.TryGetValue(cache.NameIndexInPakage, out data)) { cache.RNameType = data.RNameType; if (cache.RNameType == EngineNS.RName.enRNameType.Game) { cache.Name = relPath + data.Name; } else { cache.Name = data.Name; } } } // 全部存入目标文件夹 foreach (var resInfoData in mLoadedResInfoDatas) { var resInfo = resInfoData.ResInfo; var tempTagPath = resInfo.ResourceName.Address.Replace(srcContentTempPath, ""); string tagFile = targetAbsPath + tempTagPath; RNameData tempData; if (rNameDataPathDic.TryGetValue(tempTagPath, out tempData)) { tagFile = targetAbsPath + tempData.Name; } EngineNS.CEngine.Instance.FileManager.MergePackageRNameCacheToRNameManager(); var saveData = new SaveResourceData() { TargetAbsFileName = tagFile, ResObject = resInfoData.RNM.ResObject, SrcAbsFileName = resInfo.ResourceName.Address, }; await resInfo.AssetsOption_SaveResource(saveData); var tempResInfo = await EditorCommon.Resources.ResourceInfoManager.Instance.CreateResourceInfoFromFile(tagFile + EditorCommon.Program.ResourceInfoExt, null); await EngineNS.CEngine.Instance.GameEditorInstance.RefreshResourceInfoReferenceDictionary(tempResInfo); retList.Add(tempResInfo); } } EngineNS.CEngine.Instance.FileManager.DeleteDirectory(tempPath, true); //EditorCommon.MessageBox.Show("导入完成"); EditorCommon.FileSystemWatcherProcess.Enable = true; return(retList); }
async Task <string> SaveToPackage(string rootPath, float totalProgress, Action <float, string> progressReport) { string rootFolder = ""; var delta = totalProgress / mNameManager.NameMapper.Count; using (var iter = mNameManager.NameMapper.Values.GetEnumerator()) { while (iter.MoveNext()) { progressReport?.Invoke(mProgress, $"正在导出到包 {iter.Current.Name.Name}"); //if (iter.Current.ResObject == null) // continue; if (iter.Current.ResObject is ShaderEnvData) { // ShaderEnv 直接拷贝 var tagFile = rootPath + iter.Current.Name.GetNameWithRootFolder(); EngineNS.CEngine.Instance.FileManager.CopyFile(iter.Current.Name.Address, tagFile, true); } else { Resources.ResourceInfo rInfo; if (!mResInfoDic.TryGetValue(iter.Current.Name, out rInfo)) { rInfo = await EditorCommon.Resources.ResourceInfoManager.Instance.CreateResourceInfoFromResource(iter.Current.Name.Address); if (rInfo == null) { EngineNS.Profiler.Log.WriteLine(EngineNS.Profiler.ELogTag.Warning, "资源丢失", $"找不到资源{iter.Current.Name.Address}"); continue; } mResInfoDic.Add(iter.Current.Name, rInfo); } var saveData = new SaveResourceData() { TargetAbsFileName = rootPath + iter.Current.Name.GetNameWithRootFolder(), SrcAbsFileName = iter.Current.Name.Address, ResObject = iter.Current.ResObject, //RNameMapper = iter.Current, }; await rInfo.AssetsOption_SaveResource(saveData); // 计算公共目录根 if (rInfo.ResourceName.RNameType == EngineNS.RName.enRNameType.Game) { var path = EngineNS.CEngine.Instance.FileManager.GetPathFromFullName(rInfo.ResourceName.Address); if (rootFolder == "" || rootFolder.Contains(path)) { rootFolder = path; } else { // 获取公共目录 var splitRootFolder = rootFolder.TrimEnd('/').Split('/'); var splitPath = path.TrimEnd('/').Split('/'); rootFolder = ""; var minLen = System.Math.Min(splitRootFolder.Length, splitPath.Length); for (int i = 0; i < minLen; i++) { if (string.Equals(splitRootFolder[i], splitPath[i], StringComparison.OrdinalIgnoreCase)) { rootFolder += splitRootFolder[i] + "/"; } else if (i == 0) { throw new InvalidOperationException("没有找到公共父目录"); } else { break; } } } } } mProgress += delta; } } return(rootFolder); }