/// <summary> /// 삭제할 ZIP 파일 리스트에서 특정 파일을 제외합니다. /// </summary> /// <param name="path">제외하려는 TreeNode의 Name</param> /// <returns></returns> public override bool Delist(string path) { try { EntryTree.BeginUpdate(); foreach (var key in deZipper.Entries.ToList()) { if (key.Value.FullName.Contains(path)) { deZipper.Delist(key.Value.FullName); if (key.Value.Name.Equals("")) cDirs--; else cFiles--; } } TreeNode delNode = EntryTree.Nodes.Find(path, true)[0]; EntryTree.Nodes.Remove(delNode); EntryTree.EndUpdate(); return true; } catch { throw; } }
/// <summary> /// TreeView 컴포넌트에 파일 리스트를 출력합니다. /// </summary> public override void PrintList() { try { cDirs = 0; cFiles = 0; EntryTree.BeginUpdate(); EntryTree.Nodes.Clear(); List<string> dirList = new List<string>(); TreeNodeCollection branch = EntryTree.Nodes; foreach (KeyValuePair<string, ZipArchiveEntry> entry in deZipper.Entries) { string path = entry.Value.FullName; path = path.TrimEnd('/'); path = path.Remove(path.LastIndexOf('/') + 1); if (entry.Value.Name.Equals("")) // Folder { string name = entry.Value.FullName.Split('/')[entry.Value.FullName.Split('/').Length - 2]; dirList.Add(entry.Value.FullName); if (dirList.Contains(path)) branch.Find(path, true)[0].Nodes.Add(entry.Value.FullName, name, 1, 1); else branch.Add(entry.Value.FullName, name, 1, 1); cDirs++; } else // Files { if (dirList.Contains(path)) branch.Find(path, true)[0].Nodes.Add(entry.Value.FullName, entry.Value.Name); else branch.Add(entry.Value.FullName, entry.Value.Name); cFiles++; } } EntryTree.EndUpdate(); EntryTree.ExpandAll(); } catch { throw; } }
public static void TrashIncompatibleEntries(MEPackage pcc, MEGame oldGame, MEGame newGame) { var entries = new EntryTree(pcc); var oldClasses = UnrealObjectInfo.GetClasses(oldGame); var newClasses = UnrealObjectInfo.GetClasses(newGame); var classesToRemove = oldClasses.Keys.Except(newClasses.Keys).ToHashSet(); foreach (IEntry entry in entries) { if (classesToRemove.Contains(entry.ClassName) || (entry.ClassName == "Class" && classesToRemove.Contains(entry.ObjectName.Name)) || entry is ExportEntry exp && (exp.Archetype?.IsTrash() ?? false)) { TrashEntries(pcc, entries.FlattenTreeOf(entry.UIndex)); } } }
public static T CloneTree <T>(T entry) where T : IEntry { var objectMap = new Dictionary <IEntry, IEntry>(); T newRoot = CloneEntry(entry, objectMap); EntryTree tree = new EntryTree(entry.FileRef); cloneTreeRecursive(entry, newRoot); Relinker.RelinkAll(objectMap); return(newRoot); void cloneTreeRecursive(IEntry originalRootNode, IEntry newRootNode) { foreach (IEntry node in tree.GetDirectChildrenOf(originalRootNode.UIndex)) { IEntry newEntry = CloneEntry(node, objectMap); newEntry.Parent = newRootNode; cloneTreeRecursive(node, newEntry); } } }
public static IEntry cloneTree(IEntry entry) { var objectMap = new Dictionary <IEntry, IEntry>(); IEntry newRoot = cloneEntry(entry, objectMap); EntryTree tree = new EntryTree(entry.FileRef); cloneTreeRecursive(entry, newRoot); IMEPackage pcc = entry.FileRef; Relinker.RelinkAll(objectMap); return(newRoot); void cloneTreeRecursive(IEntry originalRootNode, IEntry newRootNode) { foreach (IEntry node in tree.GetDirectChildrenOf(originalRootNode.UIndex)) { IEntry newEntry = cloneEntry(node, objectMap); newEntry.Parent = newRootNode; cloneTreeRecursive(node, newEntry); } } }
/// <summary> /// Imports <paramref name="sourceEntry"/> (and possibly its children) to <paramref name="destPcc"/> in a manner defined by <paramref name="portingOption"/> /// If no <paramref name="relinkMap"/> is provided, method will create one /// </summary> /// <param name="portingOption"></param> /// <param name="sourceEntry"></param> /// <param name="destPcc"></param> /// <param name="targetLinkEntry">Can be null if cloning as a top-level entry</param> /// <param name="shouldRelink"></param> /// <param name="newEntry"></param> /// <param name="relinkMap"></param> /// <returns></returns> public static List <EntryStringPair> ImportAndRelinkEntries(PortingOption portingOption, IEntry sourceEntry, IMEPackage destPcc, IEntry targetLinkEntry, bool shouldRelink, out IEntry newEntry, Dictionary <IEntry, IEntry> relinkMap = null , Action <string> errorOccuredCallback = null) { relinkMap ??= new Dictionary <IEntry, IEntry>(); IMEPackage sourcePcc = sourceEntry.FileRef; EntryTree sourcePackageTree = new EntryTree(sourcePcc); if (portingOption == PortingOption.ReplaceSingular) { //replace data only if (sourceEntry is ExportEntry entry) { relinkMap.Add(entry, targetLinkEntry); ReplaceExportDataWithAnother(entry, targetLinkEntry as ExportEntry, errorOccuredCallback); } } RelinkerCache cache = null; if (portingOption == PortingOption.MergeTreeChildren || portingOption == PortingOption.ReplaceSingular) { newEntry = targetLinkEntry; //Root item is the one we just dropped. Use that as the root. } else { cache = new RelinkerCache(sourceEntry.FileRef, destPcc); int link = targetLinkEntry?.UIndex ?? 0; if (sourceEntry is ExportEntry sourceExport) { //importing an export newEntry = ImportExport(destPcc, sourceExport, link, portingOption == PortingOption.CloneAllDependencies, relinkMap, errorOccuredCallback, cache); } else { newEntry = GetOrAddCrossImportOrPackage(sourceEntry.FullPath, sourcePcc, destPcc, forcedLink: sourcePackageTree.NumChildrenOf(sourceEntry) == 0 ? link : (int?)null, objectMapping: relinkMap, relinkerCache: cache); } newEntry.idxLink = link; } //if this node has children if ((portingOption == PortingOption.CloneTreeAsChild || portingOption == PortingOption.MergeTreeChildren || portingOption == PortingOption.CloneAllDependencies) && sourcePackageTree.NumChildrenOf(sourceEntry) > 0) { importChildrenOf(sourceEntry, newEntry, cache); } List <EntryStringPair> relinkResults = null; if (shouldRelink) { relinkResults = Relinker.RelinkAll(relinkMap, portingOption == PortingOption.CloneAllDependencies, cache); } // Reindex - disabled for now as it causes issues //Dictionary<string, ExportEntry> itemsToReindex = new Dictionary<string, ExportEntry>(); //foreach (var v in relinkMap.Values) //{ // if (v is ExportEntry export && export.indexValue > 0) // { // itemsToReindex[export.FullPath] = export; // Match on full path. Not instanced full path! // } //} //foreach (var item in itemsToReindex) //{ // ReindexExportEntriesWithSamePath(item.Value); //} cache?.Dispose(); return(relinkResults); void importChildrenOf(IEntry sourceNode, IEntry newParent, RelinkerCache cache) { foreach (IEntry node in sourcePackageTree.GetDirectChildrenOf(sourceNode)) { if (portingOption == PortingOption.MergeTreeChildren) { //we must check to see if there is an item already matching what we are trying to port. //Todo: We may need to enhance target checking here as fullpath may not be reliable enough. Maybe have to do indexing, or something. IEntry sameObjInTarget = newParent.GetChildren().FirstOrDefault(x => node.FullPath == x.FullPath); if (sameObjInTarget != null) { relinkMap[node] = sameObjInTarget; //merge children to this node instead importChildrenOf(node, sameObjInTarget, cache); continue; } } IEntry entry; if (node is ExportEntry exportNode) { entry = ImportExport(destPcc, exportNode, newParent.UIndex, portingOption == PortingOption.CloneAllDependencies, relinkMap, errorOccuredCallback, cache); } else { entry = GetOrAddCrossImportOrPackage(node.FullPath, sourcePcc, destPcc, objectMapping: relinkMap, relinkerCache: cache); } entry.Parent = newParent; importChildrenOf(node, entry, cache); } } }
/// <summary> /// Imports <paramref name="sourceEntry"/> (and possibly its children) to <paramref name="destPcc"/> in a manner defined by <paramref name="portingOption"/> /// If no <paramref name="relinkMap"/> is provided, method will create one /// </summary> /// <param name="portingOption"></param> /// <param name="sourceEntry"></param> /// <param name="destPcc"></param> /// <param name="targetLinkEntry">Can be null if cloning as a top-level entry</param> /// <param name="shouldRelink"></param> /// <param name="newEntry"></param> /// <param name="relinkMap"></param> /// <returns></returns> public static List <string> ImportAndRelinkEntries(PortingOption portingOption, IEntry sourceEntry, IMEPackage destPcc, IEntry targetLinkEntry, bool shouldRelink, out IEntry newEntry, Dictionary <IEntry, IEntry> relinkMap = null) { relinkMap ??= new Dictionary <IEntry, IEntry>(); IMEPackage sourcePcc = sourceEntry.FileRef; EntryTree sourcePackageTree = new EntryTree(sourcePcc); if (portingOption == PortingOption.ReplaceSingular) { //replace data only if (sourceEntry is ExportEntry entry) { relinkMap.Add(entry, targetLinkEntry); ReplaceExportDataWithAnother(entry, targetLinkEntry as ExportEntry); } } if (portingOption == PortingOption.MergeTreeChildren || portingOption == PortingOption.ReplaceSingular) { newEntry = targetLinkEntry; //Root item is the one we just dropped. Use that as the root. } else { int link = targetLinkEntry?.UIndex ?? 0; if (sourceEntry is ExportEntry sourceExport) { //importing an export newEntry = ImportExport(destPcc, sourceExport, link, portingOption == PortingOption.CloneAllDependencies, relinkMap); } else { newEntry = GetOrAddCrossImportOrPackage(sourceEntry.FullPath, sourcePcc, destPcc, forcedLink: sourcePackageTree.NumChildrenOf(sourceEntry) == 0 ? link : (int?)null, objectMapping: relinkMap); } newEntry.idxLink = link; } //if this node has children if ((portingOption == PortingOption.CloneTreeAsChild || portingOption == PortingOption.MergeTreeChildren || portingOption == PortingOption.CloneAllDependencies) && sourcePackageTree.NumChildrenOf(sourceEntry) > 0) { importChildrenOf(sourceEntry, newEntry); } List <string> relinkResults = null; if (shouldRelink) { relinkResults = Relinker.RelinkAll(relinkMap, portingOption == PortingOption.CloneAllDependencies); } return(relinkResults); void importChildrenOf(IEntry sourceNode, IEntry newParent) { foreach (IEntry node in sourcePackageTree.GetDirectChildrenOf(sourceNode)) { if (portingOption == PortingOption.MergeTreeChildren) { //we must check to see if there is an item already matching what we are trying to port. //Todo: We may need to enhance target checking here as fullpath may not be reliable enough. Maybe have to do indexing, or something. IEntry sameObjInTarget = newParent.GetChildren().FirstOrDefault(x => node.FullPath == x.FullPath); if (sameObjInTarget != null) { relinkMap[node] = sameObjInTarget; //merge children to this node instead importChildrenOf(node, sameObjInTarget); continue; } } IEntry entry; if (node is ExportEntry exportNode) { entry = ImportExport(destPcc, exportNode, newParent.UIndex, portingOption == PortingOption.CloneAllDependencies, relinkMap); } else { entry = GetOrAddCrossImportOrPackage(node.FullPath, sourcePcc, destPcc, objectMapping: relinkMap); } entry.Parent = newParent; importChildrenOf(node, entry); } } }