public static List <ClassInfo> GetCommonObjects(MEGame game)
 {
     return(new List <string>
     {
         "Sequence",
         "SeqAct_Interp",
         "InterpData",
         "BioSeqAct_EndCurrentConvNode",
         "BioSeqEvt_ConvNode",
         "BioSeqVar_ObjectFindByTag",
         "SeqVar_Object",
         "SeqAct_ActivateRemoteEvent",
         "SeqEvent_SequenceActivated",
         "SeqAct_Delay",
         "SeqAct_Gate",
         "BioSeqAct_PMCheckState",
         "BioSeqAct_PMExecuteTransition",
         "SeqAct_FinishSequence"
     }.Select(className => UnrealObjectInfo.GetClassOrStructInfo(game, className)).NonNull().ToList());
 }
 public bool TryGetPropInfo(string name, Mod.MEGame game, out PropertyInfo propInfo) =>
 properties.TryGetValue(name, out propInfo) || (UnrealObjectInfo.GetClassOrStructInfo(game, baseClass)?.TryGetPropInfo(name, game, out propInfo) ?? false);
Exemple #3
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, string className, MEGame game) => GetSequenceObjectDefaults(pcc, UnrealObjectInfo.GetClassOrStructInfo(game, className));
        public static PropertyCollection RemoveIncompatibleProperties(IMEPackage sourcePcc, PropertyCollection props, string typeName, MEGame newGame)
        {
            var infoProps = UnrealObjectInfo.GetAllProperties(newGame, typeName);

            var newProps = new PropertyCollection();

            foreach (UProperty prop in props)
            {
                if (infoProps.ContainsKey(prop.Name))
                {
                    switch (prop)
                    {
                    case ArrayProperty <DelegateProperty> adp:
                        //don't think these exist? if they do, delete them
                        break;

                    case ArrayProperty <EnumProperty> aep:
                        if (UnrealObjectInfo.GetEnumValues(newGame, aep.Reference) is List <NameReference> enumValues)
                        {
                            foreach (EnumProperty enumProperty in aep)
                            {
                                if (!enumValues.Contains(enumProperty.Value))
                                {
                                    enumProperty.Value = enumValues.First();     //hope that the first value is a reasonable default
                                }
                            }
                            newProps.Add(aep);
                        }
                        break;

                    case ArrayProperty <ObjectProperty> asp:
                        for (int i = asp.Count - 1; i >= 0; i--)
                        {
                            if (asp[i].Value == 0 || sourcePcc.getEntry(asp[i].Value) is IEntry entry && !entry.GetFullPath.StartsWith(UnrealPackageFile.TrashPackageName))
                            {
                                continue;
                            }
                            //delete if it references a trashed entry or if value is invalid
                            asp.RemoveAt(i);
                        }
                        newProps.Add(asp);
                        break;

                    case ArrayProperty <StructProperty> asp:
                        if (UnrealObjectInfo.GetStructs(newGame).ContainsKey(asp.Reference))
                        {
                            if (HasIncompatibleImmutabilities(asp.Reference, out bool newImmutability))
                            {
                                break;
                            }
                            foreach (StructProperty structProperty in asp)
                            {
                                structProperty.Properties  = RemoveIncompatibleProperties(sourcePcc, structProperty.Properties, structProperty.StructType, newGame);
                                structProperty.IsImmutable = newImmutability;
                            }
                            newProps.Add(asp);
                        }
                        break;

                    case DelegateProperty delegateProperty:
                        //script related, so just delete it.
                        break;

                    case EnumProperty enumProperty:
                        if (UnrealObjectInfo.GetEnumValues(newGame, enumProperty.EnumType) is List <NameReference> values)
                        {
                            if (!values.Contains(enumProperty.Value))
                            {
                                enumProperty.Value = values.First();     //hope that the first value is a reasonable default
                            }
                            newProps.Add(enumProperty);
                        }
                        break;

                    case ObjectProperty objectProperty:
                    {
                        if (objectProperty.Value == 0 || sourcePcc.getEntry(objectProperty.Value) is IEntry entry && !entry.GetFullPath.StartsWith(UnrealPackageFile.TrashPackageName))
                        {
                            newProps.Add(objectProperty);
                        }
                        break;
                    }

                    case StructProperty structProperty:
                        string structType = structProperty.StructType;
                        if (UnrealObjectInfo.GetStructs(newGame).ContainsKey(structType))
                        {
                            if (HasIncompatibleImmutabilities(structType, out bool newImmutability))
                            {
                                break;
                            }
                            structProperty.Properties  = RemoveIncompatibleProperties(sourcePcc, structProperty.Properties, structType, newGame);
                            structProperty.IsImmutable = newImmutability;
                            newProps.Add(structProperty);
                        }
                        break;

                    default:
                        newProps.Add(prop);
                        break;
                    }
                }
            }

            return(newProps);

            bool HasIncompatibleImmutabilities(string structType, out bool newImmutability)
            {
                bool sourceIsImmutable = UnrealObjectInfo.IsImmutable(structType, sourcePcc.Game);

                newImmutability = UnrealObjectInfo.IsImmutable(structType, newGame);

                if (sourceIsImmutable && newImmutability && !UnrealObjectInfo.GetClassOrStructInfo(sourcePcc.Game, structType).properties
                    .SequenceEqual(UnrealObjectInfo.GetClassOrStructInfo(newGame, structType).properties))
                {
                    //both immutable, but have different properties
                    return(true);
                }

                if (!sourceIsImmutable && newImmutability)
                {
                    //can't easily guarantee it will have have all neccesary properties
                    return(true);
                }

                return(false);
            }
        }