private void Start()
        {
            LoadedOfficialTalkFiles = new List <TalkFile>();
            MERTalkFiles            = new List <TalkFile>();
            // Load the basegame TLKs
            var bgPath = MEDirectories.GetBioGamePath(MERFileSystem.Game);
            // ME2 specific - ignore ME2Randomizer TLKs, we do not want to modify those
            var tlkFiles = Directory.GetFiles(bgPath, "*.tlk", SearchOption.AllDirectories);

            foreach (var tlkFile in tlkFiles)
            {
                if (tlkFile.Contains("DLC_440")) // Change if our module number changes
                {
                    TalkFile tf = new TalkFile();
                    tf.LoadTlkData(tlkFile);
                    MERTalkFiles.Add(tf);
                    if (tlkFile.Contains("_INT"))
                    {
                        MERTalkFile = tf;
                    }
                    var fname = Path.GetFileNameWithoutExtension(tlkFile);
                    loadedLanguages.Add(fname.Substring(fname.LastIndexOf("_") + 1));
                }
                else
                {
                    TalkFile tf = new TalkFile();
                    tf.LoadTlkData(tlkFile);
                    LoadedOfficialTalkFiles.Add(tf);
                    var fname = Path.GetFileNameWithoutExtension(tlkFile);
                    loadedLanguages.Add(fname.Substring(fname.LastIndexOf("_") + 1));
                }
            }
        }
Beispiel #2
0
        public static IEntry EnsureClassIsInFile(IMEPackage pcc, string className)
        {
            //check to see class is already in file
            foreach (ImportEntry import in pcc.Imports)
            {
                if (import.IsClass && import.ObjectName == className)
                {
                    return(import);
                }
            }
            foreach (ExportEntry export in pcc.Exports)
            {
                if (export.IsClass && export.ObjectName == className)
                {
                    return(export);
                }
            }

            ClassInfo info = UnrealObjectInfo.GetClassOrStructInfo(pcc.Game, className);

            //backup some package state so we can undo changes if something goes wrong
            int           exportCount    = pcc.ExportCount;
            int           importCount    = pcc.ImportCount;
            List <string> nameListBackup = pcc.Names.ToList();

            try
            {
                if (EntryImporter.IsSafeToImportFrom(info.pccPath, pcc.Game))
                {
                    string package = Path.GetFileNameWithoutExtension(info.pccPath);
                    return(pcc.getEntryOrAddImport($"{package}.{className}"));
                }

                //It's a class that's defined locally in every file that uses it.
                Stream loadStream = null;
                if (info.pccPath == UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName)
                {
                    loadStream = Utilities.GetCustomAppResourceStream(pcc.Game);
                    //string resourceFilePath = App.CustomResourceFilePath(pcc.Game);
                    //if (File.Exists(resourceFilePath))
                    //{
                    //    sourceFilePath = resourceFilePath;
                    //}
                }
                else
                {
                    string testPath = Path.Combine(MEDirectories.GetBioGamePath(pcc.Game), info.pccPath);
                    if (File.Exists(testPath))
                    {
                        loadStream = new MemoryStream(File.ReadAllBytes(testPath));
                    }
                    else if (pcc.Game == MEGame.ME1)
                    {
                        testPath = Path.Combine(ME1Directory.DefaultGamePath, info.pccPath);
                        if (File.Exists(testPath))
                        {
                            loadStream = new MemoryStream(File.ReadAllBytes(testPath));
                        }
                    }
                }

                if (loadStream == null)
                {
                    //can't find file to import from. This may occur if user does not have game or neccesary dlc installed
                    return(null);
                }

                using IMEPackage sourcePackage = MEPackageHandler.OpenMEPackageFromStream(loadStream);

                if (!sourcePackage.IsUExport(info.exportIndex))
                {
                    return(null); //not sure how this would happen
                }

                ExportEntry sourceClassExport = sourcePackage.GetUExport(info.exportIndex);

                if (sourceClassExport.ObjectName != className)
                {
                    return(null);
                }

                //Will make sure that, if the class is in a package, that package will exist in pcc
                IEntry parent = EntryImporter.GetOrAddCrossImportOrPackage(sourceClassExport.ParentFullPath, sourcePackage, pcc);

                var relinkResults = EntryImporter.ImportAndRelinkEntries(EntryImporter.PortingOption.CloneAllDependencies, sourceClassExport, pcc, parent, true, out IEntry result);
                if (relinkResults?.Count > 0)
                {
                    ListDialog ld = new ListDialog(relinkResults, "Relink report", "The following items failed to relink.", null);
                    ld.Show();
                }
                return(result);
            }
            catch (Exception e)
            {
                //remove added entries
                var entriesToRemove = new List <IEntry>();
                for (int i = exportCount; i < pcc.Exports.Count; i++)
                {
                    entriesToRemove.Add(pcc.Exports[i]);
                }
                for (int i = importCount; i < pcc.Imports.Count; i++)
                {
                    entriesToRemove.Add(pcc.Imports[i]);
                }
                EntryPruner.TrashEntries(pcc, entriesToRemove);
                pcc.restoreNames(nameListBackup);
                return(null);
            }
        }
        public static PropertyCollection GetSequenceObjectDefaults(IMEPackage pcc, ClassInfo info)
        {
            MEGame             game     = pcc.Game;
            PropertyCollection defaults = new PropertyCollection();

            if (info.ClassName == "Sequence")
            {
                defaults.Add(new ArrayProperty <ObjectProperty>("SequenceObjects"));
            }
            else if (!info.IsA(SequenceVariableName, game))
            {
                ArrayProperty <StructProperty> varLinksProp   = null;
                ArrayProperty <StructProperty> outLinksProp   = null;
                ArrayProperty <StructProperty> eventLinksProp = null;
                ArrayProperty <StructProperty> inLinksProp    = null;
                Dictionary <string, ClassInfo> classes        = UnrealObjectInfo.GetClasses(game);
                try
                {
                    ClassInfo classInfo = info;
                    while (classInfo != null && (varLinksProp is null || outLinksProp is null || eventLinksProp is null || game == MEGame.ME1 && inLinksProp is null))
                    {
                        string filepath   = Path.Combine(MEDirectories.GetBioGamePath(game), classInfo.pccPath);
                        Stream loadStream = null;
                        if (File.Exists(classInfo.pccPath))
                        {
                            loadStream = new MemoryStream(File.ReadAllBytes(classInfo.pccPath));
                        }
                        else if (classInfo.pccPath == UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName)
                        {
                            loadStream = Utilities.GetCustomAppResourceStream(game);
                        }
                        else if (File.Exists(filepath))
                        {
                            loadStream = new MemoryStream(File.ReadAllBytes(filepath));
                        }
                        else if (game == MEGame.ME1)
                        {
                            filepath = Path.Combine(ME1Directory.DefaultGamePath, classInfo.pccPath); //for files from ME1 DLC
                            if (File.Exists(filepath))
                            {
                                loadStream = new MemoryStream(File.ReadAllBytes(filepath));
                            }
                        }
                        if (loadStream != null)
                        {
                            using IMEPackage importPCC = MEPackageHandler.OpenMEPackageFromStream(loadStream);
                            ExportEntry classExport   = importPCC.GetUExport(classInfo.exportIndex);
                            UClass      classBin      = ObjectBinary.From <UClass>(classExport);
                            ExportEntry classDefaults = importPCC.GetUExport(classBin.Defaults);

                            foreach (var prop in classDefaults.GetProperties())
                            {
                                if (varLinksProp == null && prop.Name == "VariableLinks" && prop is ArrayProperty <StructProperty> vlp)
                                {
                                    varLinksProp = vlp;
                                    //relink ExpectedType
                                    foreach (StructProperty varLink in varLinksProp)
                                    {
                                        if (varLink.GetProp <ObjectProperty>("ExpectedType") is ObjectProperty expectedTypeProp &&
                                            importPCC.TryGetEntry(expectedTypeProp.Value, out IEntry expectedVar) &&
                                            EntryImporterExtended.EnsureClassIsInFile(pcc, expectedVar.ObjectName) is IEntry portedExpectedVar)
                                        {
                                            expectedTypeProp.Value = portedExpectedVar.UIndex;
                                        }
                                    }
                                }
                                if (outLinksProp == null && prop.Name == "OutputLinks" && prop is ArrayProperty <StructProperty> olp)
                                {
                                    outLinksProp = olp;
                                }

                                if (eventLinksProp == null && prop.Name == "EventLinks" && prop is ArrayProperty <StructProperty> elp)
                                {
                                    eventLinksProp = elp;
                                    //relink ExpectedType
                                    foreach (StructProperty eventLink in eventLinksProp)
                                    {
                                        if (eventLink.GetProp <ObjectProperty>("ExpectedType") is ObjectProperty expectedTypeProp &&
                                            importPCC.TryGetEntry(expectedTypeProp.Value, out IEntry expectedVar) &&
                                            EntryImporterExtended.EnsureClassIsInFile(pcc, expectedVar.ObjectName) is IEntry portedExpectedVar)
                                        {
                                            expectedTypeProp.Value = portedExpectedVar.UIndex;
                                        }
                                    }
                                }

                                if (game == MEGame.ME1 && inLinksProp is null && prop.Name == "InputLinks" && prop is ArrayProperty <StructProperty> ilp)
                                {
                                    inLinksProp = ilp;
                                }
                            }
                        }
                        classes.TryGetValue(classInfo.baseClass, out classInfo);
                    }
                }
                catch
                {
                    // ignored
                }
                if (varLinksProp != null)
                {
                    defaults.Add(varLinksProp);
                }
                if (outLinksProp != null)
                {
                    defaults.Add(outLinksProp);
                }
                if (eventLinksProp != null)
                {
                    defaults.Add(eventLinksProp);
                }
                if (inLinksProp != null)
                {
                    defaults.Add(inLinksProp);
                }

                //remove links if empty
                if (defaults.GetProp <ArrayProperty <StructProperty> >("OutputLinks") is { } outLinks&& outLinks.IsEmpty())
                {
                    defaults.Remove(outLinks);
                }
                if (defaults.GetProp <ArrayProperty <StructProperty> >("VariableLinks") is { } varLinks&& varLinks.IsEmpty())
                {
                    defaults.Remove(varLinks);
                }
                if (defaults.GetProp <ArrayProperty <StructProperty> >("EventLinks") is { } eventLinks&& eventLinks.IsEmpty())
                {
                    defaults.Remove(eventLinks);
                }
                if (defaults.GetProp <ArrayProperty <StructProperty> >("InputLinks") is { } inputLinks&& inputLinks.IsEmpty())
                {
                    defaults.Remove(inputLinks);
                }
            }

            int objInstanceVersion = UnrealObjectInfo.getSequenceObjectInfo(game, info.ClassName)?.ObjInstanceVersion ?? 1;

            defaults.Add(new IntProperty(objInstanceVersion, "ObjInstanceVersion"));

            return(defaults);
        }
Beispiel #4
0
 public static string GetBioGamePath(GameTarget target) => MEDirectories.GetBioGamePath(target.Game, target.TargetPath);