public static PropertyCollection getDefaultStructValue(string className, bool stripTransients)
        {
            bool isImmutable = UnrealObjectInfo.IsImmutable(className, Mod.MEGame.ME2);

            if (Structs.ContainsKey(className))
            {
                ClassInfo info = Structs[className];
                try
                {
                    PropertyCollection structProps = new PropertyCollection();
                    ClassInfo          tempInfo    = info;
                    while (tempInfo != null)
                    {
                        foreach ((string propName, PropertyInfo propInfo) in tempInfo.properties)
                        {
                            if (stripTransients && propInfo.Transient)
                            {
                                continue;
                            }
                            if (getDefaultProperty(propName, propInfo, stripTransients, isImmutable) is UProperty uProp)
                            {
                                structProps.Add(uProp);
                            }
                        }
                        if (!Structs.TryGetValue(tempInfo.baseClass, out tempInfo))
                        {
                            tempInfo = null;
                        }
                    }
                    structProps.Add(new NoneProperty());

                    string filepath = Path.Combine(ME2Directory.gamePath, "BioGame", info.pccPath);
                    if (File.Exists(info.pccPath))
                    {
                        filepath = info.pccPath; //Used for dynamic lookup
                    }
                    if (File.Exists(filepath))
                    {
                        IMEPackage importPCC = MEPackageHandler.OpenMEPackage(filepath);

                        var                exportToRead = importPCC.getUExport(info.exportIndex);
                        byte[]             buff         = exportToRead.Data.Skip(0x30).ToArray();
                        PropertyCollection defaults     = PropertyCollection.ReadProps(exportToRead, new MemoryStream(buff), className);
                        foreach (var prop in defaults)
                        {
                            structProps.TryReplaceProp(prop);
                        }
                    }
                    return(structProps);
                }
                catch
                {
                    return(null);
                }
            }
            return(null);
        }
Esempio n. 2
0
 public StructProperty(string structType, bool isImmutable, params UProperty[] props) : base(null)
 {
     StructType  = structType;
     IsImmutable = isImmutable;
     PropType    = PropertyType.StructProperty;
     Properties  = new PropertyCollection();
     foreach (var prop in props)
     {
         Properties.Add(prop);
     }
 }
Esempio n. 3
0
        public static PropertyCollection ReadSpecialStruct(IMEPackage pcc, MemoryStream stream, string structType, int size)
        {
            PropertyCollection props = new PropertyCollection();

            if (pcc.Game == MEGame.ME3)
            {
                if (ME3UnrealObjectInfo.Structs.ContainsKey(structType))
                {
                    PropertyCollection defaultProps;
                    //memoize
                    if (defaultStructValues.ContainsKey(structType))
                    {
                        defaultProps = defaultStructValues[structType];
                    }
                    else
                    {
                        defaultProps = ME3UnrealObjectInfo.getDefaultStructValue(structType);
                        if (defaultProps == null)
                        {
                            props.Add(new UnknownProperty(stream, size));
                            return(props);
                        }
                        defaultStructValues.Add(structType, defaultProps);
                    }
                    for (int i = 0; i < defaultProps.Count; i++)
                    {
                        UProperty uProperty = ReadSpecialStructProp(pcc, stream, defaultProps[i], structType);
                        if (uProperty.PropType != PropertyType.None)
                        {
                            props.Add(uProperty);
                        }
                    }
                    return(props);
                }
            }
            //TODO: implement getDefaultClassValue() for ME1 and ME2 so this isn't needed
            if (structType == "Rotator")
            {
                string[] labels = { "Pitch", "Yaw", "Roll" };
                for (int i = 0; i < 3; i++)
                {
                    props.Add(new IntProperty(stream, labels[i]));
                }
            }
            else if (structType == "Vector2d" || structType == "RwVector2")
            {
                string[] labels = { "X", "Y" };
                for (int i = 0; i < 2; i++)
                {
                    props.Add(new FloatProperty(stream, labels[i]));
                }
            }
            else if (structType == "Vector" || structType == "RwVector3")
            {
                string[] labels = { "X", "Y", "Z" };
                for (int i = 0; i < 3; i++)
                {
                    props.Add(new FloatProperty(stream, labels[i]));
                }
            }
            else if (structType == "Color")
            {
                string[] labels = { "B", "G", "R", "A" };
                for (int i = 0; i < 4; i++)
                {
                    props.Add(new ByteProperty(stream, labels[i]));
                }
            }
            else if (structType == "LinearColor")
            {
                string[] labels = { "R", "G", "B", "A" };
                for (int i = 0; i < 4; i++)
                {
                    props.Add(new FloatProperty(stream, labels[i]));
                }
            }
            //uses EndsWith to support RwQuat, RwVector4, and RwPlane
            else if (structType.EndsWith("Quat") || structType.EndsWith("Vector4") || structType.EndsWith("Plane"))
            {
                string[] labels = { "X", "Y", "Z", "W" };
                for (int i = 0; i < 4; i++)
                {
                    props.Add(new FloatProperty(stream, labels[i]));
                }
            }
            else if (structType == "TwoVectors")
            {
                string[] labels = { "X", "Y", "Z", "X", "Y", "Z" };
                for (int i = 0; i < 6; i++)
                {
                    props.Add(new FloatProperty(stream, labels[i]));
                }
            }
            else if (structType == "Matrix" || structType == "RwMatrix44")
            {
                string[] labels  = { "X Plane", "Y Plane", "Z Plane", "W Plane" };
                string[] labels2 = { "X", "Y", "Z", "W" };
                for (int i = 0; i < 4; i++)
                {
                    PropertyCollection structProps = new PropertyCollection();
                    for (int j = 0; j < 4; j++)
                    {
                        structProps.Add(new FloatProperty(stream, labels2[j]));
                    }
                    props.Add(new StructProperty("Plane", structProps, labels[i], true));
                }
            }
            else if (structType == "Guid")
            {
                string[] labels = { "A", "B", "C", "D" };
                for (int i = 0; i < 4; i++)
                {
                    props.Add(new IntProperty(stream, labels[i]));
                }
            }
            else if (structType == "IntPoint")
            {
                string[] labels = { "X", "Y" };
                for (int i = 0; i < 2; i++)
                {
                    props.Add(new IntProperty(stream, labels[i]));
                }
            }
            else if (structType == "Box" || structType == "BioRwBox")
            {
                string[] labels  = { "Min", "Max" };
                string[] labels2 = { "X", "Y", "Z" };
                for (int i = 0; i < 2; i++)
                {
                    PropertyCollection structProps = new PropertyCollection();
                    for (int j = 0; j < 3; j++)
                    {
                        structProps.Add(new FloatProperty(stream, labels2[j]));
                    }
                    props.Add(new StructProperty("Vector", structProps, labels[i], true));
                }
                props.Add(new ByteProperty(stream, "IsValid"));
            }
            else
            {
                props.Add(new UnknownProperty(stream, size));
            }
            return(props);
        }
Esempio n. 4
0
        public static PropertyCollection ReadProps(IMEPackage pcc, MemoryStream stream, string typeName, bool includeNoneProperty = false)
        {
            //Uncomment this for debugging property engine

            /*DebugOutput.StartDebugger("Property Engine ReadProps() for "+typeName);
             * if (pcc.FileName == "C:\\Users\\Dev\\Downloads\\ME2_Placeables.upk")
             * {
             * //Debugger.Break();
             * }*/
            PropertyCollection props = new PropertyCollection();
            long startPosition       = stream.Position;

            while (stream.Position + 8 <= stream.Length)
            {
                int nameIdx = stream.ReadValueS32();
                if (!pcc.isName(nameIdx))
                {
                    stream.Seek(-4, SeekOrigin.Current);
                    break;
                }
                string name = pcc.getNameEntry(nameIdx);
                if (name == "None")
                {
                    props.Add(new NoneProperty(stream, "None"));
                    stream.Seek(4, SeekOrigin.Current);
                    break;
                }
                NameReference nameRef = new NameReference {
                    Name = name, Number = stream.ReadValueS32()
                };
                int typeIdx = stream.ReadValueS32();
                stream.Seek(4, SeekOrigin.Current);
                int size = stream.ReadValueS32();
                if (!pcc.isName(typeIdx) || size < 0 || size > stream.Length - stream.Position)
                {
                    stream.Seek(-16, SeekOrigin.Current);
                    break;
                }
                stream.Seek(4, SeekOrigin.Current);
                PropertyType type;
                string       namev = pcc.getNameEntry(typeIdx);
                if (Enum.IsDefined(typeof(PropertyType), namev))
                {
                    Enum.TryParse(namev, out type);
                }
                else
                {
                    type = PropertyType.Unknown;
                }
                switch (type)
                {
                case PropertyType.StructProperty:
                    string structType = pcc.getNameEntry(stream.ReadValueS32());
                    stream.Seek(4, SeekOrigin.Current);
                    if (ME3UnrealObjectInfo.isImmutable(structType))
                    {
                        PropertyCollection structProps = ReadSpecialStruct(pcc, stream, structType, size);
                        var structprop = new StructProperty(structType, structProps, nameRef, true);
                        structprop.Offset = stream.Position - 4;
                        props.Add(structprop);
                    }
                    else
                    {
                        PropertyCollection structProps = ReadProps(pcc, stream, structType, includeNoneProperty);
                        var structprop = new StructProperty(structType, structProps, nameRef);
                        structprop.Offset = stream.Position - 4;
                        props.Add(structprop);
                    }
                    break;

                case PropertyType.IntProperty:
                    props.Add(new IntProperty(stream, nameRef));
                    break;

                case PropertyType.FloatProperty:
                    props.Add(new FloatProperty(stream, nameRef));
                    break;

                case PropertyType.ObjectProperty:
                    props.Add(new ObjectProperty(stream, nameRef));
                    break;

                case PropertyType.NameProperty:
                    props.Add(new NameProperty(stream, pcc, nameRef));
                    break;

                case PropertyType.BoolProperty:
                    props.Add(new BoolProperty(stream, pcc.Game, nameRef));
                    break;

                case PropertyType.BioMask4Property:
                    props.Add(new BioMask4Property(stream, nameRef));
                    break;

                case PropertyType.ByteProperty:
                {
                    if (size != 1)
                    {
                        NameReference enumType = new NameReference();
                        if (pcc.Game == MEGame.ME3)
                        {
                            enumType.Name   = pcc.getNameEntry(stream.ReadValueS32());
                            enumType.Number = stream.ReadValueS32();
                        }
                        else
                        {
                            enumType.Name = UnrealObjectInfo.GetEnumType(pcc.Game, name, typeName);
                        }
                        props.Add(new EnumProperty(stream, pcc, enumType, nameRef));
                    }
                    else
                    {
                        if (pcc.Game == MEGame.ME3)
                        {
                            stream.Seek(8, SeekOrigin.Current);
                        }
                        props.Add(new ByteProperty(stream, nameRef));
                    }
                }
                break;

                case PropertyType.ArrayProperty:
                {
                    props.Add(ReadArrayProperty(stream, pcc, typeName, nameRef));
                }
                break;

                case PropertyType.StrProperty:
                {
                    props.Add(new StrProperty(stream, nameRef));
                }
                break;

                case PropertyType.StringRefProperty:
                    props.Add(new StringRefProperty(stream, nameRef));
                    break;

                case PropertyType.DelegateProperty:
                    props.Add(new DelegateProperty(stream, pcc, nameRef));
                    break;

                case PropertyType.Unknown:
                {
                    props.Add(new UnknownProperty(stream, size, pcc.getNameEntry(typeIdx), nameRef));
                }
                break;

                case PropertyType.None:
                    if (includeNoneProperty)
                    {
                        props.Add(new NoneProperty(stream, "None"));
                    }
                    break;

                default:
                    break;
                }
            }
            if (props.Count > 0)
            {
                //error reading props.
                if (props[props.Count - 1].PropType != PropertyType.None)
                {
                    stream.Seek(startPosition, SeekOrigin.Begin);
                    return(new PropertyCollection {
                        endOffset = (int)stream.Position
                    });
                }
                //remove None Property
                if (!includeNoneProperty)
                {
                    props.RemoveAt(props.Count - 1);
                }
            }
            props.endOffset = (int)stream.Position;
            return(props);
        }
        public static PropertyCollection ReadProps(IMEPackage pcc, MemoryStream stream, string typeName)
        {
            PropertyCollection props = new PropertyCollection();
            long startPosition       = stream.Position;

            while (stream.Position + 8 <= stream.Length)
            {
                int nameIdx = stream.ReadValueS32();
                if (!pcc.isName(nameIdx))
                {
                    stream.Seek(-4, SeekOrigin.Current);
                    break;
                }
                string name = pcc.getNameEntry(nameIdx);
                if (name == "None")
                {
                    props.Add(new NoneProperty {
                        PropType = PropertyType.None
                    });
                    stream.Seek(4, SeekOrigin.Current);
                    break;
                }
                NameReference nameRef = new NameReference {
                    Name = name, count = stream.ReadValueS32()
                };
                int typeIdx = stream.ReadValueS32();
                stream.Seek(4, SeekOrigin.Current);
                int size = stream.ReadValueS32();
                if (!pcc.isName(typeIdx) || size < 0 || size > stream.Length - stream.Position)
                {
                    stream.Seek(-16, SeekOrigin.Current);
                    break;
                }
                stream.Seek(4, SeekOrigin.Current);
                PropertyType type;
                if (!Enum.TryParse(pcc.getNameEntry(typeIdx), out type))
                {
                    type = PropertyType.Unknown;
                }
                switch (type)
                {
                case PropertyType.StructProperty:
                    string structType = pcc.getNameEntry(stream.ReadValueS32());
                    stream.Seek(4, SeekOrigin.Current);
                    if (ME3UnrealObjectInfo.isImmutable(structType))
                    {
                        PropertyCollection structProps = ReadSpecialStruct(pcc, stream, structType, size);
                        props.Add(new StructProperty(structType, structProps, nameRef, true));
                    }
                    else
                    {
                        PropertyCollection structProps = ReadProps(pcc, stream, structType);
                        props.Add(new StructProperty(structType, structProps, nameRef));
                    }
                    break;

                case PropertyType.IntProperty:
                    props.Add(new IntProperty(stream, nameRef));
                    break;

                case PropertyType.FloatProperty:
                    props.Add(new FloatProperty(stream, nameRef));
                    break;

                case PropertyType.ObjectProperty:
                    props.Add(new ObjectProperty(stream, nameRef));
                    break;

                case PropertyType.NameProperty:
                    props.Add(new NameProperty(stream, pcc, nameRef));
                    break;

                case PropertyType.BoolProperty:
                    props.Add(new BoolProperty(stream, pcc.Game, nameRef));
                    break;

                case PropertyType.BioMask4Property:
                    props.Add(new BioMask4Property(stream, nameRef));
                    break;

                case PropertyType.ByteProperty:
                {
                    if (size != 1)
                    {
                        NameReference enumType = new NameReference();
                        if (pcc.Game == MEGame.ME3)
                        {
                            enumType.Name  = pcc.getNameEntry(stream.ReadValueS32());
                            enumType.count = stream.ReadValueS32();
                        }
                        else
                        {
                            enumType.Name = UnrealObjectInfo.GetEnumType(pcc.Game, name, typeName);
                        }
                        props.Add(new EnumProperty(stream, pcc, enumType, nameRef));
                    }
                    else
                    {
                        if (pcc.Game == MEGame.ME3)
                        {
                            stream.Seek(8, SeekOrigin.Current);
                        }
                        props.Add(new ByteProperty(stream, nameRef));
                    }
                }
                break;

                case PropertyType.ArrayProperty:
                {
                    props.Add(ReadArrayProperty(stream, pcc, typeName, nameRef));
                }
                break;

                case PropertyType.StrProperty:
                {
                    props.Add(new StrProperty(stream, nameRef));
                }
                break;

                case PropertyType.StringRefProperty:
                    props.Add(new StringRefProperty(stream, nameRef));
                    break;

                case PropertyType.DelegateProperty:
                    props.Add(new DelegateProperty(stream, pcc, nameRef));
                    break;

                case PropertyType.Unknown:
                {
                    props.Add(new UnknownProperty(stream, size, pcc.getNameEntry(typeIdx), nameRef));
                }
                break;

                case PropertyType.None:
                default:
                    break;
                }
            }
            if (props.Count > 0)
            {
                if (props[props.Count - 1].PropType != PropertyType.None)
                {
                    stream.Seek(startPosition, SeekOrigin.Begin);
                    return(new PropertyCollection {
                        endOffset = (int)stream.Position
                    });
                }
                //remove None Property
                props.RemoveAt(props.Count - 1);
            }
            props.endOffset = (int)stream.Position;
            return(props);
        }