//call this method to regenerate ME2ObjectInfo.json
        //Takes a long time (10 minutes maybe?). Application will be completely unresponsive during that time.
        public static void generateInfo()
        {
            var NewClasses         = new Dictionary <string, ClassInfo>();
            var NewStructs         = new Dictionary <string, ClassInfo>();
            var NewEnums           = new Dictionary <string, List <NameReference> >();
            var NewSequenceObjects = new Dictionary <string, SequenceObjectInfo>();

            foreach (string filePath in MELoadedFiles.GetOfficialFiles(MEGame.ME2))
            {
                if (Path.GetExtension(filePath) == ".pcc")
                {
                    using IMEPackage pcc = MEPackageHandler.OpenME2Package(filePath);
                    for (int j = 1; j <= pcc.ExportCount; j++)
                    {
                        ExportEntry exportEntry = pcc.GetUExport(j);
                        string      className   = exportEntry.ClassName;
                        if (className == "Enum")
                        {
                            generateEnumValues(exportEntry, NewEnums);
                        }
                        else if (className == "Class")
                        {
                            string objectName = exportEntry.ObjectName;
                            if (!NewClasses.ContainsKey(objectName))
                            {
                                NewClasses.Add(objectName, generateClassInfo(exportEntry));
                            }
                        }
                        else if (className == "ScriptStruct")
                        {
                            string objectName = exportEntry.ObjectName;
                            if (!NewStructs.ContainsKey(objectName))
                            {
                                NewStructs.Add(objectName, generateClassInfo(exportEntry, isStruct: true));
                            }
                        }
                        else if (exportEntry.IsOrInheritsFrom("SequenceObject"))
                        {
                            if (!NewSequenceObjects.TryGetValue(className, out SequenceObjectInfo seqObjInfo))
                            {
                                seqObjInfo = new SequenceObjectInfo();
                                NewSequenceObjects.Add(className, seqObjInfo);
                            }

                            int objInstanceVersion = exportEntry.GetProperty <IntProperty>("ObjInstanceVersion");
                            if (objInstanceVersion > seqObjInfo.ObjInstanceVersion)
                            {
                                seqObjInfo.ObjInstanceVersion = objInstanceVersion;
                            }
                        }
                    }
                    //Debug.WriteLine("Releasing " + pcc.FileName);
                }
            }

            //CUSTOM ADDITIONS
            try
            {
                NewClasses.Add("LightMapTexture2D", new ClassInfo
                {
                    baseClass   = "Texture2D",
                    exportIndex = 0,
                    pccPath     = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName
                });

                NewClasses["StaticMesh"] = new ClassInfo
                {
                    baseClass   = "Object",
                    exportIndex = 0,
                    pccPath     = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName,
                    properties  =
                    {
                        new KeyValuePair <string, PropertyInfo>("UseSimpleRigidBodyCollision", new PropertyInfo(PropertyType.BoolProperty)),
                        new KeyValuePair <string, PropertyInfo>("UseSimpleLineCollision",      new PropertyInfo(PropertyType.BoolProperty)),
                        new KeyValuePair <string, PropertyInfo>("UseSimpleBoxCollision",       new PropertyInfo(PropertyType.BoolProperty)),
                        new KeyValuePair <string, PropertyInfo>("UseFullPrecisionUVs",         new PropertyInfo(PropertyType.BoolProperty)),
                        new KeyValuePair <string, PropertyInfo>("BodySetup",                   new PropertyInfo(PropertyType.ObjectProperty, "RB_BodySetup")),
                        new KeyValuePair <string, PropertyInfo>("LODDistanceRatio",            new PropertyInfo(PropertyType.FloatProperty)),
                        new KeyValuePair <string, PropertyInfo>("LightMapCoordinateIndex",     new PropertyInfo(PropertyType.IntProperty)),
                        new KeyValuePair <string, PropertyInfo>("LightMapResolution",          new PropertyInfo(PropertyType.IntProperty)),
                    }
                };
            }
            catch (Exception)
            {
            }

            //SFXPhysicalMaterialDecals missing items
            ClassInfo sfxpmd = NewClasses["SFXPhysicalMaterialDecals"];

            string[] decalComponentArrays = { "HeavyPistol", "AutoPistol", "HandCannon", "SMG", "Shotgun", "HeavyShotgun", "FlakGun", "AssaultRifle", "Needler", "Machinegun", "SniperRifle", "AntiMatRifle", "MassCannon", "ParticleBeam" };
            foreach (string decal in decalComponentArrays)
            {
                sfxpmd.properties.Add(decal, new PropertyInfo(PropertyType.ArrayProperty, "DecalComponent"));
            }

            NewClasses["SFXWeapon"].properties.Add("InstantHitDamageTypes", new PropertyInfo(PropertyType.ArrayProperty, "Class"));

            File.WriteAllText(jsonPath, JsonConvert.SerializeObject(new { SequenceObjects = NewSequenceObjects, Classes = NewClasses, Structs = NewStructs, Enums = NewEnums }, Formatting.Indented));
        }
        //call this method to regenerate ME1ObjectInfo.json
        //Takes a long time (10 to 20 minutes maybe?). Application will be completely unresponsive during that time.
        public static void generateInfo()
        {
            Classes         = new Dictionary <string, ClassInfo>();
            Structs         = new Dictionary <string, ClassInfo>();
            Enums           = new Dictionary <string, List <NameReference> >();
            SequenceObjects = new Dictionary <string, SequenceObjectInfo>();
            foreach (string file in MELoadedFiles.GetOfficialFiles(MEGame.ME1))
            {
                if (Path.GetExtension(file) == ".upk" || Path.GetExtension(file) == ".sfm" || Path.GetExtension(file) == ".u")
                {
                    Debug.WriteLine($"File: {file}");
                    using IMEPackage pcc = MEPackageHandler.OpenME1Package(file);
                    for (int j = 1; j <= pcc.ExportCount; j++)
                    {
                        ExportEntry exportEntry = pcc.GetUExport(j);
                        string      className   = exportEntry.ClassName;
                        if (className == "Enum")
                        {
                            generateEnumValues(exportEntry);
                        }
                        else if (className == "Class")
                        {
                            string objectName = exportEntry.ObjectName;
                            Debug.WriteLine($"Generating information for {objectName}");
                            if (!Classes.ContainsKey(objectName))
                            {
                                Classes.Add(objectName, generateClassInfo(exportEntry));
                            }
                        }
                        else if (className == "ScriptStruct")
                        {
                            string objectName = exportEntry.ObjectName;
                            if (!Structs.ContainsKey(exportEntry.ObjectName))
                            {
                                Structs.Add(objectName, generateClassInfo(exportEntry, isStruct: true));
                            }
                        }
                        else if (exportEntry.IsOrInheritsFrom("SequenceObject"))
                        {
                            if (!SequenceObjects.TryGetValue(className, out SequenceObjectInfo seqObjInfo))
                            {
                                seqObjInfo = new SequenceObjectInfo();
                                SequenceObjects.Add(className, seqObjInfo);
                            }

                            int objInstanceVersion = exportEntry.GetProperty <IntProperty>("ObjInstanceVersion");
                            if (objInstanceVersion > seqObjInfo.ObjInstanceVersion)
                            {
                                seqObjInfo.ObjInstanceVersion = objInstanceVersion;
                            }
                        }
                    }
                }
            }

            //CUSTOM ADDITIONS
            Classes["LightMapTexture2D"] = new ClassInfo
            {
                baseClass   = "Texture2D",
                exportIndex = 0,
                pccPath     = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName
            };

            Classes["StaticMesh"] = new ClassInfo
            {
                baseClass   = "Object",
                exportIndex = 0,
                pccPath     = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName,
                properties  =
                {
                    new KeyValuePair <string, PropertyInfo>("UseSimpleRigidBodyCollision",   new PropertyInfo(PropertyType.BoolProperty)),
                    new KeyValuePair <string, PropertyInfo>("UseSimpleLineCollision",        new PropertyInfo(PropertyType.BoolProperty)),
                    new KeyValuePair <string, PropertyInfo>("UseSimpleBoxCollision",         new PropertyInfo(PropertyType.BoolProperty)),
                    new KeyValuePair <string, PropertyInfo>("ForceDoubleSidedShadowVolumes", new PropertyInfo(PropertyType.BoolProperty)),
                    new KeyValuePair <string, PropertyInfo>("BodySetup",                     new PropertyInfo(PropertyType.ObjectProperty, "RB_BodySetup")),
                    new KeyValuePair <string, PropertyInfo>("LODDistanceRatio",              new PropertyInfo(PropertyType.FloatProperty)),
                    new KeyValuePair <string, PropertyInfo>("LightMapCoordinateIndex",       new PropertyInfo(PropertyType.IntProperty)),
                    new KeyValuePair <string, PropertyInfo>("LightMapResolution",            new PropertyInfo(PropertyType.IntProperty)),
                    new KeyValuePair <string, PropertyInfo>("SoundCue",                      new PropertyInfo(PropertyType.ObjectProperty, "SoundCue")),
                }
            };


            File.WriteAllText(jsonPath, JsonConvert.SerializeObject(new { SequenceObjects, Classes, Structs, Enums }, Formatting.Indented));
        }