public static List<Property> ReadProp(ME2Explorer.PCCObject 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.ToInt32(raw, pos); //printbytes(raw, pos, 60); if (!pcc.isName(name)) return result; string t = pcc.GetName(name); if (t == "None") { p = new Property(); p.Name = t; p.TypeVal = Type.None; p.i = 0; p.offsetval = pos; p.Size = 20; p.Value = new PropertyValue(); p.raw = BitConverter.GetBytes((Int64)name); p.offend = pos + 20; result.Add(p); return result; } int type = (int)BitConverter.ToInt32(raw, pos + 8); int size = BitConverter.ToInt32(raw, pos + 16); int idx = BitConverter.ToInt32(raw, pos + 20); //Unused if (!pcc.isName(type) || size < 0 || size >= raw.Length) return result; string tp = pcc.GetName(type); switch (tp) { case "BoolProperty": p = new Property(); p.TypeVal = Type.BoolProperty; p.Name = t; p.Size = size; p.i = 0; v = new PropertyValue(); v.IntValue = BitConverter.ToInt32(raw, pos + 24); //Guess. I haven't seen a true boolproperty yet pos += 28; p.Value = v; break; case "NameProperty": p = new Property(); p.TypeVal = Type.NameProperty; p.Name = t; p.Size = size; p.i = 0; //pos += 32; v = new PropertyValue(); //int tempInt = BitConverter.ToInt32(raw, pos + 24); v.IntValue = BitConverter.ToInt32(raw, pos + 24); v.StringValue = pcc.GetName(v.IntValue); p.Value = v; pos += 32; //throw new NullReferenceException(); break; case "IntProperty": p = new Property(); p.TypeVal = Type.IntProperty; v = new PropertyValue(); v.IntValue = BitConverter.ToInt32(raw, pos + 24); p.Name = t; p.Size = size; p.i = 0; p.offsetval = pos + 24; pos += 28; p.Value = v; break; case "DelegateProperty": p = new Property(); p.Name = t; p.Size = size; p.TypeVal = Type.DelegateProperty; p.i = 0; p.offsetval = pos + 24; v = new PropertyValue(); v.IntValue = BitConverter.ToInt32(raw, pos + 28); v.len = size; v.Array = new List<PropertyValue>(); pos += 24; for (int i = 0; i < 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 = (int)BitConverter.ToInt64(raw, pos + 24); p = new Property(); p.Name = t; p.Size = size; p.TypeVal = Type.ArrayProperty; p.i = 0; p.offsetval = pos + 24; v = new PropertyValue(); v.IntValue = type; v.len = 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 = (int)BitConverter.ToInt32(raw, pos + 24); p = new Property(); p.Name = t; p.Size = size; p.TypeVal = Type.StrProperty; p.i = 0; p.offsetval = pos + 24; //count *= -1; v = new PropertyValue(); v.IntValue = type; v.len = count; pos += 28; string s = ""; for (int i = 0; i < count - 1; i++) { s += (char)raw[pos]; pos++; } pos++; v.StringValue = s; p.Value = v; break; case "StructProperty": sname = (int)BitConverter.ToInt64(raw, pos + 24); p = new Property(); p.Name = t; p.Size = size; p.TypeVal = Type.StructProperty; p.i = 0; p.offsetval = pos + 24; v = new PropertyValue(); v.IntValue = sname; v.StringValue = pcc.GetName(sname); v.len = size; v.Array = new List<PropertyValue>(); pos += 32; for (int i = 0; i < size; i += 4) { PropertyValue v2 = new PropertyValue(); //if (pos < raw.Length) // v2.IntValue = raw[pos]; //v.Array.Add(v2); //pos++; if (pos < raw.Length) v2.IntValue = BitConverter.ToInt32(raw, pos); v.Array.Add(v2); pos += 4; } p.Value = v; break; case "ByteProperty": //sname = (int)BitConverter.ToInt64(raw, pos + 24); sname = BitConverter.ToInt32(raw, pos + 24); p = new Property(); p.Name = t; p.Size = size; p.TypeVal = Type.ByteProperty; p.i = 0; p.offsetval = pos + 32; v = new PropertyValue(); v.StringValue = pcc.GetName(sname); v.IntValue = BitConverter.ToInt32(raw, pos + 28); v.String2 = pcc.GetName(v.IntValue); v.len = size; pos += 32; //v.IntValue = (int)BitConverter.ToInt64(raw, pos); //pos += size; p.Value = v; break; case "FloatProperty": sname = BitConverter.ToInt32(raw, pos + 24); p = new Property(); p.Name = t; p.Size = size; p.TypeVal = Type.FloatProperty; p.i = 0; p.offsetval = pos + 24; v = new PropertyValue(); v.FloatValue = BitConverter.ToSingle(raw, pos + 24); v.len = size; pos += 28; p.Value = v; break; default: p = new Property(); p.Name = t; p.TypeVal = getType(pcc, type); p.i = 0; p.Size = size; 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 int detectStart(ME2Explorer.PCCObject pcc, byte[] raw) { int result = 8; int test1 = BitConverter.ToInt32(raw, 4); if (test1 < 0) result = 30; else { 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; }