Esempio n. 1
0
        public int GetPropertyStart()
        {
            IMEPackage pcc = FileRef;

            if ((ObjectFlags & (ulong)UnrealFlags.EObjectFlags.HasStack) != 0)
            {
                if (pcc.Game != MEGame.ME3)
                {
                    return(32);
                }
                return(30);
            }
            int result = 8;
            int test1  = BitConverter.ToInt32(_data, 4);
            int test2  = BitConverter.ToInt32(_data, 8);

            if (pcc.isName(test1) && test2 == 0)
            {
                result = 4;
            }
            if (pcc.isName(test1) && pcc.isName(test2) && test2 != 0)
            {
                result = 8;
            }
            return(result);
        }
Esempio n. 2
0
        private void ReadColors(PropertyReader.Property p, IMEPackage pcc)
        {
            int count = BitConverter.ToInt32(p.raw, 24);
            int start = 28;

            for (int i = 0; i < count; i++)
            {
                List <PropertyReader.Property> props = PropertyReader.ReadProp(pcc, p.raw, start);
                ColorOverride co = new ColorOverride();

                foreach (PropertyReader.Property sp in props)
                {
                    string propName = pcc.getNameEntry(sp.Name);
                    switch (propName)
                    {
                    case "nName":
                        int nameI = sp.Value.IntValue;
                        if (pcc.isName(nameI))
                        {
                            co.ParamName = pcc.Names[nameI];
                        }
                        break;

                    case "cValue":
                        co.Value = new LinearColor(sp);
                        break;

                    case "None":
                        break;
                    }
                }
                ColorOverrides.Add(co);
                start = props[props.Count - 1].offend;
            }
        }
Esempio n. 3
0
        public BoneOffset(List <PropertyReader.Property> props, IMEPackage pcc)
        {
            foreach (PropertyReader.Property p in props)
            {
                string propName = pcc.getNameEntry(p.Name);
                switch (propName)
                {
                case "nName":
                    int nameI = p.Value.IntValue;
                    if (pcc.isName(nameI))
                    {
                        BoneName = pcc.Names[nameI];
                    }
                    break;

                case "vPos":
                    Offset = new Vector(BitConverter.ToSingle(p.raw, p.raw.Length - 12),
                                        BitConverter.ToSingle(p.raw, p.raw.Length - 8),
                                        BitConverter.ToSingle(p.raw, p.raw.Length - 4));
                    break;

                case "None":
                    //
                    break;

                default:
                    Console.WriteLine("Prop name for BoneOffset is " + propName);
                    break;
                }
            }
        }
Esempio n. 4
0
        public BioFeature(List <PropertyReader.Property> props, IMEPackage pcc)
        {
            foreach (PropertyReader.Property p in props)
            {
                string propName = pcc.getNameEntry(p.Name);
                switch (propName)
                {
                case "sFeatureName":
                    int nameI = p.Value.IntValue;
                    if (pcc.isName(nameI - 1))
                    {
                        Name = pcc.Names[nameI - 1];
                    }
                    break;

                case "Offset":
                    Value = BitConverter.ToSingle(p.raw, p.raw.Length - 4);
                    break;

                case "None":
                    //
                    break;

                default:
                    Console.WriteLine("Prop name for Bioture is " + propName);
                    break;
                }
            }
        }
        public static int detectStart(IMEPackage pcc, byte[] raw, ulong flags)
        {
            if ((flags & (ulong)UnrealFlags.EObjectFlags.HasStack) != 0)
            {
                if (pcc.Game != MEGame.ME3)
                {
                    return(32);
                }
                return(30);
            }
            int result = 8;
            int test1  = BitConverter.ToInt32(raw, 4);
            int test2  = BitConverter.ToInt32(raw, 8);

            if (pcc.isName(test1) && test2 == 0)
            {
                result = 4;
            }
            if (pcc.isName(test1) && pcc.isName(test2) && test2 != 0)
            {
                result = 8;
            }
            return(result);
        }
        private void SerializeBones(SerializingContainer Container)
        {
            int count = 0;

            if (!Container.isLoading)
            {
                count = Bones.Count();
            }
            count = Container + count;
            if (Container.isLoading)
            {
                Bones = new List <BoneStruct>();
                for (int i = 0; i < count; i++)
                {
                    Bones.Add(new BoneStruct());
                }
            }
            for (int i = 0; i < count; i++)
            {
                BoneStruct b = Bones[i];
                b.Name          = Container + b.Name;
                b.Flags         = Container + b.Flags;
                b.Unk1          = Container + b.Unk1;
                b.Orientation.X = Container + b.Orientation.X;
                b.Orientation.Y = Container + b.Orientation.Y;
                b.Orientation.Z = Container + b.Orientation.Z;
                b.Orientation.W = Container + b.Orientation.W;
                b.Position.X    = Container + b.Position.X;
                b.Position.Y    = Container + b.Position.Y;
                b.Position.Z    = Container + b.Position.Z;
                b.NumChildren   = Container + b.NumChildren;
                b.Parent        = Container + b.Parent;
                if (Owner is ME3Package)
                {
                    b.BoneColor = Container + b.BoneColor;
                }

                b.BoneName = Owner.isName(b.Name) ? Owner.Names[b.Name] : "bone_" + b.Name;
                Bones[i]   = b;
            }
            SkeletonDepth = Container + SkeletonDepth;
        }
Esempio n. 7
0
        private void ReadTextures(PropertyReader.Property p, IMEPackage pcc)
        {
            int count = BitConverter.ToInt32(p.raw, 24);
            int start = 28;

            for (int i = 0; i < count; i++)
            {
                // read next 68 bytes
                List <PropertyReader.Property> props = PropertyReader.ReadProp(pcc, p.raw, start);
                TextureOverride to = new TextureOverride();

                foreach (PropertyReader.Property sp in props)
                {
                    string propName = pcc.getNameEntry(sp.Name);
                    switch (propName)
                    {
                    case "nName":
                        int nameI = sp.Value.IntValue;
                        if (pcc.isName(nameI))
                        {
                            to.ParamName = pcc.Names[nameI];
                        }
                        break;

                    case "m_pTexture":
                        int objTextIndex = sp.Value.IntValue;
                        if (pcc.isExport(objTextIndex - 1))
                        {
                            to.TextureName = pcc.Exports[objTextIndex - 1].ObjectName;
                        }
                        break;

                    case "None":
                        break;
                    }
                }
                TextureOverrides.Add(to);
                start = props[props.Count - 1].offend;
            }
        }
Esempio n. 8
0
        private void ReadScalars(PropertyReader.Property p, IMEPackage pcc)
        {
            int count = BitConverter.ToInt32(p.raw, 24);
            int start = 28;

            for (int i = 0; i < count; i++)
            {
                // read next 68 bytes
                List <PropertyReader.Property> props = PropertyReader.ReadProp(pcc, p.raw, start);
                ScalarOverride so = new ScalarOverride();

                foreach (PropertyReader.Property sp in props)
                {
                    string propName = pcc.getNameEntry(sp.Name);
                    switch (propName)
                    {
                    case "nName":
                        int nameI = sp.Value.IntValue;
                        if (pcc.isName(nameI))
                        {
                            so.ParamName = pcc.Names[nameI];
                        }
                        break;

                    case "sValue":
                        so.Value = BitConverter.ToSingle(sp.raw, sp.raw.Length - 4);
                        break;

                    case "None":
                        break;
                    }
                }
                ScalarOverrides.Add(so);
                start = props[props.Count - 1].offend;
            }
        }
        public static List <Property> ReadProp(IMEPackage pcc, byte[] raw, int start)
        {
            Property        p;
            PropertyValue   v;
            int             sname;
            List <Property> result = new List <Property>();
            int             pos    = start;

            if (raw.Length - pos < 8)
            {
                return(result);
            }
            //int name = (int)BitConverter.ToInt64(raw, pos);
            int name = (int)BitConverter.ToInt32(raw, pos);

            if (!pcc.isName(name))
            {
                return(result);
            }
            string t = pcc.getNameEntry(name);

            p      = new Property();
            p.Name = name;
            //Debug.WriteLine(t +" at "+start);
            if (t == "None")
            {
                p.TypeVal   = PropertyType.None;
                p.offsetval = pos;
                p.Size      = 8;
                p.Value     = new PropertyValue();
                p.raw       = BitConverter.GetBytes((long)name);
                p.offend    = pos + 8;
                result.Add(p);
                return(result);
            }
            //int type = (int)BitConverter.ToInt64(raw, pos + 8);
            int type = (int)BitConverter.ToInt32(raw, pos + 8);

            if (!pcc.isName(type))
            {
                return(result);
            }
            p.Size = BitConverter.ToInt32(raw, pos + 16);
            if (p.Size < 0 || p.Size >= raw.Length)
            {
                return(result);
            }
            string tp = pcc.getNameEntry(type);

            switch (tp)
            {
            case "DelegateProperty":
                p.TypeVal   = PropertyType.DelegateProperty;
                p.offsetval = pos + 24;
                v           = new PropertyValue();
                v.IntValue  = BitConverter.ToInt32(raw, pos + 28);
                v.len       = p.Size;
                v.Array     = new List <PropertyValue>();
                pos        += 24;
                for (int i = 0; i < p.Size; i++)
                {
                    PropertyValue v2 = new PropertyValue();
                    if (pos < raw.Length)
                    {
                        v2.IntValue = raw[pos];
                    }
                    v.Array.Add(v2);
                    pos++;
                }
                p.Value = v;
                break;

            case "ArrayProperty":
                int count = BitConverter.ToInt32(raw, pos + 24);
                p.TypeVal   = PropertyType.ArrayProperty;
                p.offsetval = pos + 24;
                v           = new PropertyValue();
                v.IntValue  = type;
                v.len       = p.Size - 4;
                count       = v.len;//TODO can be other objects too
                v.Array     = new List <PropertyValue>();
                pos        += 28;
                for (int i = 0; i < count; i++)
                {
                    PropertyValue v2 = new PropertyValue();
                    if (pos < raw.Length)
                    {
                        v2.IntValue = raw[pos];
                    }
                    v.Array.Add(v2);
                    pos++;
                }
                p.Value = v;
                break;

            case "StrProperty":
                count       = BitConverter.ToInt32(raw, pos + 24);
                p.TypeVal   = PropertyType.StrProperty;
                p.offsetval = pos + 24;
                v           = new PropertyValue();
                v.IntValue  = type;
                v.len       = count;
                pos        += 28;
                string s = "";
                if (count < 0)
                {
                    count *= -1;
                    for (int i = 1; i < count; i++)
                    {
                        s   += (char)raw[pos];
                        pos += 2;
                    }
                    pos += 2;
                }
                else if (count > 0)
                {
                    for (int i = 1; i < count; i++)
                    {
                        s += (char)raw[pos];
                        pos++;
                    }
                    pos++;
                }
                v.StringValue = s;
                p.Value       = v;
                break;

            case "StructProperty":
                sname       = BitConverter.ToInt32(raw, pos + 24);
                p.TypeVal   = PropertyType.StructProperty;
                p.offsetval = pos + 24;
                v           = new PropertyValue();
                v.IntValue  = sname;
                v.len       = p.Size;
                v.Array     = new List <PropertyValue>();
                pos        += 32;
                for (int i = 0; i < p.Size; i++)
                {
                    PropertyValue v2 = new PropertyValue();
                    if (pos < raw.Length)
                    {
                        v2.IntValue = raw[pos];
                    }
                    v.Array.Add(v2);
                    pos++;
                }
                p.Value = v;
                break;

            case "BioMask4Property":
                p.TypeVal   = PropertyType.ByteProperty;
                p.offsetval = pos + 24;
                v           = new PropertyValue();
                v.len       = p.Size;
                pos        += 24;
                v.IntValue  = raw[pos];
                pos        += p.Size;
                p.Value     = v;
                break;

            case "ByteProperty":
                sname     = BitConverter.ToInt32(raw, pos + 24);
                p.TypeVal = PropertyType.ByteProperty;
                v         = new PropertyValue();
                v.len     = p.Size;
                if (pcc.Game == MEGame.ME3 || pcc.Game == MEGame.UDK)
                {
                    p.offsetval   = pos + 32;
                    v.StringValue = pcc.getNameEntry(sname);
                    pos          += 32;
                    if (p.Size == 8)
                    {
                        v.IntValue = BitConverter.ToInt32(raw, pos);
                    }
                    else
                    {
                        v.IntValue = raw[pos];
                    }
                    pos += p.Size;
                }
                else
                {
                    p.offsetval = pos + 24;
                    if (p.Size != 1)
                    {
                        v.StringValue = pcc.getNameEntry(sname);
                        v.IntValue    = sname;
                        pos          += 32;
                    }
                    else
                    {
                        v.StringValue = "";
                        v.IntValue    = raw[pos + 24];
                        pos          += 25;
                    }
                }
                p.Value = v;
                break;

            case "FloatProperty":
                sname        = BitConverter.ToInt32(raw, pos + 24);
                p.TypeVal    = PropertyType.FloatProperty;
                p.offsetval  = pos + 24;
                v            = new PropertyValue();
                v.FloatValue = BitConverter.ToSingle(raw, pos + 24);
                v.len        = p.Size;
                pos         += 28;
                p.Value      = v;
                break;

            case "BoolProperty":
                p           = new Property();
                p.Name      = name;
                p.TypeVal   = PropertyType.BoolProperty;
                p.offsetval = pos + 24;
                v           = new PropertyValue();
                v.IntValue  = raw[pos + 24];
                if (pcc.Game == MEGame.ME3 || pcc.Game == MEGame.UDK)     //THIS NEEDS TESTED!!! From when merging UDK
                {
                    v.len = 1;
                }
                else
                {
                    v.len = 4;
                }
                pos    += v.len + 24;
                p.Value = v;
                break;

            default:
                p.TypeVal   = getType(pcc, type);
                p.offsetval = pos + 24;
                p.Value     = ReadValue(pcc, raw, pos + 24, type);
                pos        += p.Value.len + 24;
                break;
            }
            p.raw    = new byte[pos - start];
            p.offend = pos;
            if (pos < raw.Length)
            {
                for (int i = 0; i < pos - start; i++)
                {
                    p.raw[i] = raw[start + i];
                }
            }
            result.Add(p);
            if (pos != start)
            {
                result.AddRange(ReadProp(pcc, raw, pos));
            }
            return(result);
        }
Esempio n. 10
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);
        }
Esempio n. 11
0
 public static int detectStart(IMEPackage pcc, byte[] raw, ulong flags)
 {
     if ((flags & (ulong)UnrealFlags.EObjectFlags.HasStack) != 0)
     {
         if (pcc.Game != MEGame.ME3)
         {
             return 32; 
         }
         return 30;
     }
     int result = 8;
     int test1 = BitConverter.ToInt32(raw, 4);
     int test2 = BitConverter.ToInt32(raw, 8);
     if (pcc.isName(test1) && test2 == 0)
         result = 4;
     if (pcc.isName(test1) && pcc.isName(test2) && test2 != 0)
         result = 8;    
     return result;
 }
Esempio n. 12
0
        public static List<Property> ReadProp(IMEPackage pcc, byte[] raw, int start)
        {
            Property p;
            PropertyValue v;
            int sname;
            List<Property> result = new List<Property>();
            int pos = start;
            if(raw.Length - pos < 8)
                return result;
            int name = (int)BitConverter.ToInt64(raw, pos);
            if (!pcc.isName(name))
                return result;
            string t = pcc.getNameEntry(name);
            p = new Property();
            p.Name = name;
            if (t == "None")
            {
                p.TypeVal = PropertyType.None;         
                p.offsetval = pos;
                p.Size = 8;
                p.Value = new PropertyValue();
                p.raw = BitConverter.GetBytes((long)name);
                p.offend = pos + 8;
                result.Add(p);
                return result;
            }
            int type = (int)BitConverter.ToInt64(raw, pos + 8);            
            p.Size = BitConverter.ToInt32(raw, pos + 16);
            if (!pcc.isName(type) || p.Size < 0 || p.Size >= raw.Length)
                return result;
            string tp = pcc.getNameEntry(type);
            switch (tp)
            {

                case "DelegateProperty":
                    p.TypeVal = PropertyType.DelegateProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.IntValue = BitConverter.ToInt32(raw, pos + 28);
                    v.len = p.Size;
                    v.Array = new List<PropertyValue>();
                    pos += 24;
                    for (int i = 0; i < p.Size; i++)
                    {
                        PropertyValue v2 = new PropertyValue();
                        if(pos < raw.Length)
                            v2.IntValue = raw[pos];
                        v.Array.Add(v2);
                        pos++;
                    }
                    p.Value = v;
                    break;
                case "ArrayProperty":
                    int count = BitConverter.ToInt32(raw, pos + 24);
                    p.TypeVal = PropertyType.ArrayProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.IntValue = type;
                    v.len = p.Size - 4;
                    count = v.len;//TODO can be other objects too
                    v.Array = new List<PropertyValue>();
                    pos += 28;
                    for (int i = 0; i < count; i++)
                    {
                        PropertyValue v2 = new PropertyValue();
                        if(pos < raw.Length)
                            v2.IntValue = raw[pos];
                        v.Array.Add(v2);
                        pos ++;
                    }
                    p.Value = v;
                    break;
                case "StrProperty":
                    count = BitConverter.ToInt32(raw, pos + 24);
                    p.TypeVal = PropertyType.StrProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.IntValue = type;
                    v.len = count;
                    pos += 28;
                    string s = "";
                    if (count < 0)
                    {
                        count *= -1;
                        for (int i = 1; i < count; i++)
                        {
                            s += (char)raw[pos];
                            pos += 2;
                        }
                        pos += 2;
                    }
                    else if (count > 0)
                    {
                        for (int i = 1; i < count; i++)
                        {
                            s += (char)raw[pos];
                            pos++;
                        }
                        pos++;
                    }
                    v.StringValue = s;
                    p.Value = v;
                    break;
                case "StructProperty":
                    sname = BitConverter.ToInt32(raw, pos + 24);
                    p.TypeVal = PropertyType.StructProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.IntValue = sname;
                    v.len = p.Size;
                    v.Array = new List<PropertyValue>();
                    pos += 32;
                    for (int i = 0; i < p.Size; i++)
                    {
                        PropertyValue v2 = new PropertyValue();
                        if (pos < raw.Length)
                            v2.IntValue = raw[pos];
                        v.Array.Add(v2);
                        pos++;
                    }
                    p.Value = v;
                    break;
                case "BioMask4Property":
                    p.TypeVal = PropertyType.ByteProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.len = p.Size;
                    pos += 24;
                    v.IntValue = raw[pos];
                    pos += p.Size;
                    p.Value = v;
                    break;
                case "ByteProperty":
                    sname = BitConverter.ToInt32(raw, pos + 24);
                    p.TypeVal = PropertyType.ByteProperty;
                    v = new PropertyValue();
                    v.len = p.Size;
                    if (pcc.Game == MEGame.ME3)
                    {
                        p.offsetval = pos + 32;
                        v.StringValue = pcc.getNameEntry(sname);
                        pos += 32;
                        if (p.Size == 8)
                        {
                            v.IntValue = BitConverter.ToInt32(raw, pos);
                        }
                        else
                        {
                            v.IntValue = raw[pos];
                        }
                        pos += p.Size;
                    }
                    else
                    {
                        p.offsetval = pos + 24;
                        if (p.Size != 1)
                        {
                            v.StringValue = pcc.getNameEntry(sname);
                            v.IntValue = sname;
                            pos += 32;
                        }
                        else
                        {
                            v.StringValue = "";
                            v.IntValue = raw[pos + 24];
                            pos += 25;
                        }
                    }
                    p.Value = v;
                    break;
                case "FloatProperty":
                    sname = BitConverter.ToInt32(raw, pos + 24);
                    p.TypeVal = PropertyType.FloatProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.FloatValue = BitConverter.ToSingle(raw, pos + 24);
                    v.len = p.Size;
                    pos += 28;
                    p.Value = v;
                    break;
                case "BoolProperty":
                    p = new Property();
                    p.Name = name;
                    p.TypeVal = PropertyType.BoolProperty;
                    p.offsetval = pos + 24;
                    v = new PropertyValue();
                    v.IntValue = raw[pos + 24];
                    if (pcc.Game == MEGame.ME3)
                    {
                        v.len = 1; 
                    }
                    else
                    {
                        v.len = 4;
                    }
                    pos += v.len + 24;
                    p.Value = v;
                    break;
                default:
                    p.TypeVal = getType(pcc,type);
                    p.offsetval = pos + 24;
                    p.Value = ReadValue(pcc, raw, pos + 24, type);
                    pos += p.Value.len + 24;
                    break;
            }
            p.raw = new byte[pos - start];
            p.offend = pos;
            if(pos < raw.Length)
                for (int i = 0; i < pos - start; i++) 
                    p.raw[i] = raw[start + i];
            result.Add(p);            
            if(pos!=start) result.AddRange(ReadProp(pcc, raw, pos));
            return result;
        }
        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);
        }