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); }
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; } }
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; } } }
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; }
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; } }
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); }
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 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; }
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); }