Example #1
0
        public static void TrashEntries(IMEPackage pcc, IEnumerable <IEntry> itemsToTrash)
        {
            ExportEntry trashTopLevel = pcc.Exports.FirstOrDefault(x => x.idxLink == 0 && x.ObjectName == UnrealPackageFile.TrashPackageName);
            ImportEntry packageImport = pcc.Imports.FirstOrDefault(x => x.GetFullPath == "Core.Package");

            if (packageImport == null)
            {
                ImportEntry coreImport = pcc.Imports.FirstOrDefault(x => x.GetFullPath == "Core");
                if (coreImport == null)
                {
                    //really small file
                    coreImport = new ImportEntry(pcc)
                    {
                        idxObjectName  = pcc.FindNameOrAdd("Core"),
                        idxClassName   = pcc.FindNameOrAdd("Package"),
                        idxLink        = 0,
                        idxPackageFile = pcc.FindNameOrAdd("Core")
                    };
                    pcc.addImport(coreImport);
                }

                //Package isn't an import, could be one of the 2DA files or other small ones
                packageImport = new ImportEntry(pcc)
                {
                    idxObjectName  = pcc.FindNameOrAdd("Package"),
                    idxClassName   = pcc.FindNameOrAdd("Class"),
                    idxLink        = coreImport.UIndex,
                    idxPackageFile = pcc.FindNameOrAdd("Core")
                };
                pcc.addImport(packageImport);
            }

            foreach (IEntry entry in itemsToTrash)
            {
                if (entry == trashTopLevel || entry.ObjectName == "Trash") //don't trash what's already been trashed
                {
                    continue;
                }
                trashTopLevel = TrashEntry(entry, trashTopLevel, packageImport.UIndex);
            }
            pcc.RemoveTrailingTrash();
        }
Example #2
0
        //if neccessary, will fill in parents as Package Imports (if the import you need has non-Package parents, don't use this method)
        public static IEntry getEntryOrAddImport(this IMEPackage pcc, string fullPath, string className = "Class", string packageFile = "Core")
        {
            if (string.IsNullOrEmpty(fullPath))
            {
                return(null);
            }

            //see if this import exists locally
            foreach (ImportEntry imp in pcc.Imports)
            {
                if (imp.GetFullPath == fullPath)
                {
                    return(imp);
                }
            }

            //see if this is an export and exists locally
            foreach (ExportEntry exp in pcc.Exports)
            {
                if (exp.GetFullPath == fullPath)
                {
                    return(exp);
                }
            }

            string[] pathParts = fullPath.Split('.');

            IEntry parent = pcc.getEntryOrAddImport(string.Join(".", pathParts.Take(pathParts.Length - 1)), "Package");

            var import = new ImportEntry(pcc)
            {
                idxLink        = parent?.UIndex ?? 0,
                idxClassName   = pcc.FindNameOrAdd(className),
                idxObjectName  = pcc.FindNameOrAdd(pathParts.Last()),
                idxPackageFile = pcc.FindNameOrAdd(packageFile)
            };

            pcc.addImport(import);
            return(import);
        }
Example #3
0
        /// <summary>
        /// Adds an import from the importingPCC to the destinationPCC with the specified importFullName, or returns the existing one if it can be found.
        /// This method will look at importingPCC's import upstream chain and check for the most downstream one's existence in destinationPCC,
        /// including if none can be founc (in which case the entire upstream is copied). It will then create new imports to match the remaining
        /// downstream ones and return the originally named import, however now located in destinationPCC.
        /// </summary>
        /// <param name="importFullName">GetFullPath() of an import from ImportingPCC</param>
        /// <param name="importingPCC">PCC to import imports from</param>
        /// <param name="destinationPCC">PCC to add imports to</param>
        /// <returns></returns>
        private ImportEntry getOrAddCrossImport(string importFullName, IMEPackage importingPCC, IMEPackage destinationPCC, int?forcedLinkIdx = null)
        {
            //This code is kind of ugly, sorry.

            //see if this import exists locally
            foreach (ImportEntry imp in destinationPCC.Imports)
            {
                if (imp.GetFullPath == importFullName)
                {
                    return(imp);
                }
            }

            //Import doesn't exist, so we're gonna need to add it
            //But first we need to figure out what needs to be added upstream as links
            //Search upstream until we find something, or we can't get any more upstreams
            ImportEntry mostdownstreamimport = null;

            string[] importParts = importFullName.Split('.');

            if (!forcedLinkIdx.HasValue)
            {
                List <int> upstreamLinks = new List <int>(); //0 = top level, 1 = next level... n = what we wanted to import
                int        upstreamCount = 1;

                ImportEntry upstreamImport = null;
                //get number of required upstream imports that do not yet exist
                while (upstreamCount < importParts.Count())
                {
                    string upstream = String.Join(".", importParts, 0, importParts.Count() - upstreamCount);
                    foreach (ImportEntry imp in destinationPCC.Imports)
                    {
                        if (imp.GetFullPath == upstream)
                        {
                            upstreamImport = imp;
                            break;
                        }
                    }

                    if (upstreamImport != null)
                    {
                        //We found an upsteam import that already exists
                        break;
                    }
                    upstreamCount++;
                }

                IExportEntry donorUpstreamExport = null;
                if (upstreamImport == null)
                {
                    //We have to import the entire upstream chain
                    string      fullobjectname      = importParts[0];
                    ImportEntry donorTopLevelImport = null;
                    foreach (ImportEntry imp in importingPCC.Imports) //importing side info we will move to our dest pcc
                    {
                        if (imp.GetFullPath == fullobjectname)
                        {
                            donorTopLevelImport = imp;
                            break;
                        }
                    }

                    if (donorTopLevelImport == null)
                    {
                        //This is issue KinkoJiro had. It is aborting relinking at this step. Will need to find a way to
                        //work with exports as parents for imports which will block it.
                        //Update: This has been partially implemented.
                        Debug.WriteLine("No upstream import was found in the source file. It's probably an export: " + importFullName);
                        foreach (IExportEntry exp in destinationPCC.Exports) //importing side info we will move to our dest pcc
                        {
                            //Console.WriteLine(exp.GetFullPath);
                            if (exp.GetFullPath == fullobjectname)
                            {
                                // = imp;
                                //We will need to find a way to cross map this as this will block cross import mapping unless these exports already exist.
                                Debug.WriteLine("FOUND UPSTREAM, AS EXPORT!");
                                KFreonLib.Debugging.DebugOutput.StartDebugger("Package Editor Relinker");
                                KFreonLib.Debugging.DebugOutput.PrintLn("Error: Upstream item that is required is an export in the pcc to import from: " + fullobjectname);
                                donorUpstreamExport = exp;
                                upstreamCount--; //level 1 now from the top down
                                                 //Create new import with this as higher IDK
                                break;
                            }
                        }
                        if (donorUpstreamExport == null)
                        {
                            Debug.WriteLine("An error has occured. Could not find an upstream import or export for relinking: " + fullobjectname + " from " + pcc.FileName);
                            return(null);
                        }
                    }

                    if (donorUpstreamExport == null)
                    {
                        //Create new toplevel import and set that as the most downstream one. (top = bottom at this point)
                        int downstreamPackageFile = destinationPCC.FindNameOrAdd(Path.GetFileNameWithoutExtension(donorTopLevelImport.PackageFile));
                        int downstreamClassName   = destinationPCC.FindNameOrAdd(donorTopLevelImport.ClassName);
                        int downstreamName        = destinationPCC.FindNameOrAdd(fullobjectname);

                        mostdownstreamimport = new ImportEntry(destinationPCC);
                        // mostdownstreamimport.idxLink = downstreamLinkIdx; ??
                        mostdownstreamimport.idxClassName   = downstreamClassName;
                        mostdownstreamimport.idxObjectName  = downstreamName;
                        mostdownstreamimport.idxPackageFile = downstreamPackageFile;
                        destinationPCC.addImport(mostdownstreamimport); //Add new top level downstream import
                        upstreamImport = mostdownstreamimport;
                        upstreamCount--;                                //level 1 now from the top down
                                                                        //return null;
                    }
                }

                //Have an upstream import, now we need to add downstream imports.
                while (upstreamCount > 0)
                {
                    upstreamCount--;
                    string      fullobjectname = String.Join(".", importParts, 0, importParts.Count() - upstreamCount);
                    ImportEntry donorImport    = null;

                    //Get or create names for creating import and get upstream linkIdx
                    int downstreamName = destinationPCC.FindNameOrAdd(importParts[importParts.Count() - upstreamCount - 1]);
                    foreach (ImportEntry imp in importingPCC.Imports) //importing side info we will move to our dest pcc
                    {
                        if (imp.GetFullPath == fullobjectname)
                        {
                            donorImport = imp;
                            break;
                        }
                    }
                    if (donorImport == null)
                    {
                        throw new Exception("No suitable upstream import was found for porting - this may be an export in the source file that is referenced as a parent or dependency. You should import this object and its parents first. " + fullobjectname + "(as part of " + importFullName + ")");
                    }

                    int downstreamPackageFile = destinationPCC.FindNameOrAdd(Path.GetFileNameWithoutExtension(donorImport.PackageFile));
                    int downstreamClassName   = destinationPCC.FindNameOrAdd(donorImport.ClassName);

                    mostdownstreamimport                = new ImportEntry(destinationPCC);
                    mostdownstreamimport.idxLink        = donorUpstreamExport == null ? upstreamImport.UIndex : donorUpstreamExport.UIndex;
                    mostdownstreamimport.idxClassName   = downstreamClassName;
                    mostdownstreamimport.idxObjectName  = downstreamName;
                    mostdownstreamimport.idxPackageFile = downstreamPackageFile;
                    destinationPCC.addImport(mostdownstreamimport);
                    upstreamImport = mostdownstreamimport;
                }
            }
            else
            {
                //get importing import
                ImportEntry importingImport = importingPCC.Imports.FirstOrDefault(x => x.GetFullPath == importFullName); //this shouldn't be null
                mostdownstreamimport                = new ImportEntry(destinationPCC);
                mostdownstreamimport.idxLink        = forcedLinkIdx.Value;
                mostdownstreamimport.idxClassName   = destinationPCC.FindNameOrAdd(importingImport.ClassName);
                mostdownstreamimport.idxObjectName  = destinationPCC.FindNameOrAdd(importingImport.ObjectName);
                mostdownstreamimport.idxPackageFile = destinationPCC.FindNameOrAdd(Path.GetFileNameWithoutExtension(importingImport.PackageFile));
                destinationPCC.addImport(mostdownstreamimport);
            }
            return(mostdownstreamimport);
        }
Example #4
0
        public static IEntry GetEntryOrAddImport(IMEPackage Pcc, string importFullName)
        {
            //foreach (ImportEntry imp in Pcc.Imports)
            //{
            //    if (imp.GetFullPath == importFullName)
            //    {
            //        return imp;
            //    }
            //}

            var fullPathMappingList = new List <(string fullpath, IEntry entry)>();

            foreach (ImportEntry imp in Pcc.Imports)
            {
                fullPathMappingList.Add((imp.GetFullPath, imp));
            }
            foreach (ExportEntry exp in Pcc.Exports)
            {
                fullPathMappingList.Add((exp.GetFullPath, exp));
            }

            var directMapping = fullPathMappingList.Where(x => x.fullpath == importFullName).ToList();

            if (directMapping.Count == 1)
            {
                return(directMapping[0].entry);                          //direct single match
            }
            //Find an upstream entry to attach our import to (we can't add exports)
            string[] importParts   = importFullName.Split('.');
            int      upstreamCount = 1;

            IEntry upstreamEntryToAttachTo = null;
            string upstreamfullpath;

            while (upstreamCount < importParts.Length)
            {
                upstreamfullpath = string.Join(".", importParts, 0, importParts.Length - upstreamCount);
                var upstreammatchinglist = fullPathMappingList.Where(x => x.fullpath == upstreamfullpath).ToList();
                if (upstreammatchinglist.Where(x => x.entry is ExportEntry).HasExactly(1) || upstreammatchinglist.Where(x => x.entry is ImportEntry).HasExactly(1))
                {
                    upstreamEntryToAttachTo = upstreammatchinglist[0].entry;
                    break;
                }

                /*if (upstreamEntryToAttachTo != null)
                 * {
                 *  break;
                 * }*/
                upstreamCount++;
            }

            //upstreamImport = Pcc.Imports.FirstOrDefault(x => x.GetFullPath == upstream);



            //Check if this is an export instead

            /* itemAsImport = Pcc.Exports.FirstOrDefault(x => x.GetFullPath == importFullName && x.indexValue == 0);
             * if (itemAsImport != null)
             * {
             *  return itemAsImport;
             * }*/

            //Import doesn't exist, so we're gonna need to add it
            //But first we need to figure out what needs to be added.
            //string[] importParts = importFullName.Split('.');
            //List<int> upstreamLinks = new List<int>(); //0 = top level, 1 = next level... n = what we wanted to import

            /*ImportEntry upstreamImport = null;
             * string upstream = null;
             * while (upstreamCount < importParts.Count())
             * {
             *  upstreamfullpath = string.Join(".", importParts, 0, importParts.Count() - upstreamCount);
             *  upstreamImport = Pcc.Imports.FirstOrDefault(x => x.GetFullPath == upstreamfullpath);
             *
             *  if (upstreamImport != null)
             *  {
             *      break;
             *  }
             *  upstreamCount++;
             * }*/

            if (upstreamEntryToAttachTo == null)
            {
                //There is nothing we can attach to.
                Debug.WriteLine("cannot find a top level item to attach to for " + importFullName);
                return(null);
            }

            //Have an upstream import, now we need to add downstream imports.
            ImportEntry mostdownstreamimport = null;

            while (upstreamCount > 0)
            {
                upstreamCount--;
                string fullobjectname = String.Join(".", importParts, 0, importParts.Length - upstreamCount);
                Dictionary <string, string> importdbinfo = ImportClassDB[fullobjectname];

                int downstreamName = Pcc.FindNameOrAdd(importParts[importParts.Length - upstreamCount - 1]);
                Debug.WriteLine(Pcc.Names[downstreamName]);
                int downstreamLinkIdx = upstreamEntryToAttachTo.UIndex;
                Debug.WriteLine(upstreamEntryToAttachTo.GetFullPath);

                int    downstreamPackageName = Pcc.FindNameOrAdd(importdbinfo["packagefile"]);
                string downstreamClassName   = importdbinfo["fullclasspath"];
                int    lastPeriodIndex       = downstreamClassName.LastIndexOf(".");
                if (lastPeriodIndex > 0)
                {
                    downstreamClassName = importdbinfo["fullclasspath"].Substring(lastPeriodIndex + 1);
                }

                int downstreamClassNameIdx = Pcc.FindNameOrAdd(downstreamClassName);
                Debug.WriteLine("Finding name " + downstreamClassName);
                //ImportEntry classImport = getOrAddImport();
                //int downstreamClass = 0;
                //if (classImport != null) {
                //    downstreamClass = classImport.UIndex; //no recursion pls
                //} else
                //{
                //    throw new Exception("No class was found for importing");
                //}

                mostdownstreamimport = new ImportEntry(Pcc)
                {
                    idxLink        = downstreamLinkIdx,
                    idxClassName   = downstreamClassNameIdx,
                    idxObjectName  = downstreamName,
                    idxPackageFile = downstreamPackageName
                };
                Pcc.addImport(mostdownstreamimport);
                upstreamEntryToAttachTo = mostdownstreamimport;
            }
            return(mostdownstreamimport);
        }
Example #5
0
        /// <summary>
        /// Adds an import from the importingPCC to the destinationPCC with the specified importFullName, or returns the existing one if it can be found.
        /// This will add parent imports and packages as neccesary
        /// </summary>
        /// <param name="importFullName">GetFullPath() of an import from ImportingPCC</param>
        /// <param name="importingPCC">PCC to import imports from</param>
        /// <param name="destinationPCC">PCC to add imports to</param>
        /// <param name="forcedLink">force this as parent</param>
        /// <returns></returns>
        public static IEntry getOrAddCrossImportOrPackage(string importFullName, IMEPackage importingPCC, IMEPackage destinationPCC, int?forcedLink = null)
        {
            if (string.IsNullOrEmpty(importFullName))
            {
                return(null);
            }

            //see if this import exists locally
            foreach (ImportEntry imp in destinationPCC.Imports)
            {
                if (imp.GetFullPath == importFullName)
                {
                    return(imp);
                }
            }

            //see if this is an export Package and exists locally
            foreach (ExportEntry exp in destinationPCC.Exports)
            {
                if (exp.ClassName == "Package" && exp.GetFullPath == importFullName)
                {
                    return(exp);
                }
            }

            if (forcedLink is int link)
            {
                ImportEntry importingImport = importingPCC.Imports.First(x => x.GetFullPath == importFullName); //this shouldn't be null
                var         newImport       = new ImportEntry(destinationPCC)
                {
                    idxLink        = link,
                    idxClassName   = destinationPCC.FindNameOrAdd(importingImport.ClassName),
                    idxObjectName  = destinationPCC.FindNameOrAdd(importingImport.ObjectName),
                    idxPackageFile = destinationPCC.FindNameOrAdd(importingImport.PackageFile)
                };
                destinationPCC.addImport(newImport);
                return(newImport);
            }

            string[] importParts = importFullName.Split('.');

            //recursively ensure parent package exists. when importParts.Length == 1, this will return null
            IEntry parent = getOrAddCrossImportOrPackage(string.Join(".", importParts.Take(importParts.Length - 1)), importingPCC, destinationPCC);


            foreach (ImportEntry imp in importingPCC.Imports)
            {
                if (imp.GetFullPath == importFullName)
                {
                    var import = new ImportEntry(destinationPCC)
                    {
                        idxLink        = parent?.UIndex ?? 0,
                        idxClassName   = destinationPCC.FindNameOrAdd(imp.ClassName),
                        idxObjectName  = destinationPCC.FindNameOrAdd(imp.ObjectName),
                        idxPackageFile = destinationPCC.FindNameOrAdd(imp.PackageFile)
                    };
                    destinationPCC.addImport(import);
                    return(import);
                }
            }

            foreach (ExportEntry exp in importingPCC.Exports)
            {
                if (exp.ClassName == "Package" && exp.GetFullPath == importFullName)
                {
                    importExport(destinationPCC, exp, parent?.UIndex ?? 0, out ExportEntry package);
                    return(package);
                }
            }

            throw new Exception($"Unable to add {importFullName} to file! Could not find it!");
        }