static PropertyValue ReadValue(IMEPackage pcc, byte[] raw, int start, int type) { PropertyValue v = new PropertyValue(); switch (pcc.getNameEntry(type)) { case "IntProperty": case "ObjectProperty": case "StringRefProperty": v.IntValue = BitConverter.ToInt32(raw, start); v.len = 4; break; case "NameProperty": v.IntValue = BitConverter.ToInt32(raw, start); var nameRef = new NameReference(); nameRef.Name = pcc.getNameEntry(v.IntValue); nameRef.count = BitConverter.ToInt32(raw, start + 4); if (nameRef.count > 0) { nameRef.Name += "_" + (nameRef.count - 1); } v.NameValue = nameRef; v.StringValue = nameRef.Name; v.len = 8; break; } return(v); }
private int ClassParser_ReadImplementsTable(IMEPackage importpcc, IExportEntry exp, List <string> relinkFailedReport, ref byte[] data, int offset) { if (importpcc.Game == MEGame.ME3) { int interfaceCount = BitConverter.ToInt32(data, offset); offset += 4; for (int i = 0; i < interfaceCount; i++) { int interfaceIndex = BitConverter.ToInt32(data, offset); int mapped; bool isMapped = crossPCCObjectMap.TryGetValue(interfaceIndex, out mapped); if (isMapped) { mapped = me3ExpIndexingToUnreal(mapped, interfaceIndex < 0); //if the value is 0, it would have an error anyways. WriteMem(offset, data, BitConverter.GetBytes(mapped)); } else { relinkFailedReport.Add("Binary Class Interface Index[" + i + "] could not be remapped during porting: " + interfaceIndex + " is not in the mapping tree"); } offset += 4; //propertypointer interfaceIndex = BitConverter.ToInt32(data, offset); isMapped = crossPCCObjectMap.TryGetValue(interfaceIndex, out mapped); if (isMapped) { mapped = me3ExpIndexingToUnreal(mapped, interfaceIndex < 0); //if the value is 0, it would have an error anyways. WriteMem(offset, data, BitConverter.GetBytes(mapped)); } else { relinkFailedReport.Add("Binary Class Interface Index[" + i + "] could not be remapped during porting: " + interfaceIndex + " is not in the mapping tree"); } offset += 4; } } else { int interfaceTableName = BitConverter.ToInt32(data, offset); //???? NameReference importingName = importpcc.getNameEntry(interfaceTableName); int interfaceName = exp.FileRef.FindNameOrAdd(importingName); WriteMem(offset, data, BitConverter.GetBytes(interfaceName)); offset += 8; int interfaceCount = BitConverter.ToInt32(data, offset); offset += 4; for (int i = 0; i < interfaceCount; i++) { int interfaceNameIndex = BitConverter.ToInt32(data, offset); importingName = importpcc.getNameEntry(interfaceNameIndex); interfaceName = exp.FileRef.FindNameOrAdd(importingName); WriteMem(offset, data, BitConverter.GetBytes(interfaceName)); offset += 8; } } return(offset); }
public static string PropertyToText(Property p, IMEPackage pcc) { string s = ""; s = "Name: " + pcc.getNameEntry(p.Name); s += " Type: " + TypeToString((int)p.TypeVal); s += " Size: " + p.Size; switch (p.TypeVal) { case PropertyType.StructProperty: s += " \"" + pcc.getNameEntry(p.Value.IntValue) + "\" with " + p.Value.Array.Count + " bytes"; break; case PropertyType.IntProperty: case PropertyType.ObjectProperty: case PropertyType.StringRefProperty: s += " Value: " + p.Value.IntValue; break; case PropertyType.BoolProperty: s += " Value: " + (p.raw[24] == 1); break; case PropertyType.FloatProperty: s += " Value: " + p.Value.FloatValue; break; case PropertyType.NameProperty: s += " " + pcc.getNameEntry(p.Value.IntValue); break; case PropertyType.ByteProperty: s += " Value: \"" + p.Value.StringValue + "\" with \"" + pcc.getNameEntry(p.Value.IntValue) + "\""; break; case PropertyType.ArrayProperty: s += " bytes"; //Value: " + p.Value.Array.Count.ToString() + " Elements"; break; case PropertyType.StrProperty: if (p.Value.StringValue.Length == 0) { break; } s += " Value: " + p.Value.StringValue; break; } return(s); }
public void ReadProperties() { props = PropertyReader.getPropList(pcc.Exports[index]); Textures = new List <TextureParam>(); for (int i = 0; i < props.Count(); i++) { string name = pcc.getNameEntry(props[i].Name); switch (name) { case "TextureParameterValues": ReadTextureParams(props[i].raw); break; } } }
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 MaterialOverrides(IMEPackage pcc, int index) { byte[] data = pcc.Exports[index].Data; List <PropertyReader.Property> props = PropertyReader.getPropList(pcc.Exports[index]); foreach (PropertyReader.Property p in props) { string propName = pcc.getNameEntry(p.Name); switch (propName) { case "m_aTextureOverrides": ReadTextures(p, pcc); break; case "m_aColorOverrides": ReadColors(p, pcc); break; case "m_aScalarOverrides": ReadScalars(p, pcc); break; case "None": break; } } }
static PropertyType getType(IMEPackage pcc, int type) { switch (pcc.getNameEntry(type)) { case "None": return(PropertyType.None); case "StructProperty": return(PropertyType.StructProperty); case "IntProperty": return(PropertyType.IntProperty); case "FloatProperty": return(PropertyType.FloatProperty); case "ObjectProperty": return(PropertyType.ObjectProperty); case "NameProperty": return(PropertyType.NameProperty); case "BoolProperty": return(PropertyType.BoolProperty); case "ByteProperty": return(PropertyType.ByteProperty); case "ArrayProperty": return(PropertyType.ArrayProperty); case "DelegateProperty": return(PropertyType.DelegateProperty); case "StrProperty": return(PropertyType.StrProperty); case "StringRefProperty": return(PropertyType.StringRefProperty); default: return(PropertyType.Unknown); } }
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 NameProperty(MemoryStream stream, IMEPackage pcc, NameReference?name = null) : base(name) { NameReference nameRef = new NameReference(); nameRef.Name = pcc.getNameEntry(stream.ReadValueS32()); nameRef.count = stream.ReadValueS32(); Value = nameRef; PropType = PropertyType.NameProperty; }
public EnumProperty(MemoryStream stream, IMEPackage pcc, NameReference enumType, NameReference?name = null) : base(name) { EnumType = enumType; NameReference enumVal = new NameReference(); enumVal.Name = pcc.getNameEntry(stream.ReadValueS32()); enumVal.count = stream.ReadValueS32(); Value = enumVal; PropType = PropertyType.ByteProperty; }
public DelegateProperty(MemoryStream stream, IMEPackage pcc, NameReference?name = null) : base(name) { unk = stream.ReadValueS32(); NameReference val = new NameReference(); val.Name = pcc.getNameEntry(stream.ReadValueS32()); val.count = stream.ReadValueS32(); Value = val; PropType = PropertyType.DelegateProperty; }
public NameProperty(MemoryStream stream, IMEPackage pcc, NameReference?name = null) : base(name) { Offset = stream.Position; NameTableIndex = stream.ReadValueS32(); NameReference nameRef = new NameReference { Name = pcc.getNameEntry(NameTableIndex), Number = stream.ReadValueS32() }; Value = nameRef; PropType = PropertyType.NameProperty; }
public static Property getPropOrNull(IMEPackage pcc, byte[] data, int start, string propName) { List <Property> props = ReadProp(pcc, data, start); foreach (Property prop in props) { if (pcc.getNameEntry(prop.Name) == propName) { return(prop); } } return(null); }
static PropertyValue ReadValue(IMEPackage pcc, byte[] raw, int start, int type) { PropertyValue v = new PropertyValue(); switch (pcc.getNameEntry(type)) { case "IntProperty": case "ObjectProperty": case "StringRefProperty": v.IntValue = BitConverter.ToInt32(raw, start); v.len = 4; break; case "NameProperty": v.IntValue = BitConverter.ToInt32(raw, start); v.NameValue = new NameReference(pcc.getNameEntry(v.IntValue), BitConverter.ToInt32(raw, start + 4)); v.StringValue = v.NameValue.InstancedString; v.len = 8; break; } return(v); }
private PropertyInfo GetPropertyInfo(int propName) { switch (pcc.Game) { case MEGame.ME1: return(ME1UnrealObjectInfo.getPropertyInfo(className, pcc.getNameEntry(propName))); case MEGame.ME2: return(ME2UnrealObjectInfo.getPropertyInfo(className, pcc.getNameEntry(propName))); case MEGame.ME3: return(ME3UnrealObjectInfo.getPropertyInfo(className, pcc.getNameEntry(propName))); } return(null); }
public EnumProperty(MemoryStream stream, IMEPackage pcc, NameReference enumType, NameReference?name = null) : base(name) { Offset = stream.Position; EnumType = enumType; NameReference enumVal = new NameReference { Name = pcc.getNameEntry(stream.ReadValueS32()), Number = stream.ReadValueS32() }; Value = enumVal; EnumValues = UnrealObjectInfo.GetEnumValues(pcc.Game, enumType, true); PropType = PropertyType.ByteProperty; }
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 InterpCurve(IMEPackage _pcc, PropertyReader.Property p) { pcc = _pcc; Curves = new ObservableCollection<Curve>(); Name = pcc.getNameEntry(p.Name); curveType = (CurveType)Enum.Parse(typeof(CurveType), pcc.getNameEntry(p.Value.IntValue)); float InVal = 0f; CurveMode InterpMode = CurveMode.CIM_Linear; var points = PropertyReader.ReadStructArrayProp(pcc, PropertyReader.getPropOrNull(pcc, p.raw, 32, "Points")); switch (curveType) { case CurveType.InterpCurveQuat: throw new NotImplementedException($"InterpCurveQuat has not been implemented yet."); case CurveType.InterpCurveFloat: float OutVal = 0f; float ArriveTangent = 0f; float LeaveTangent = 0f; LinkedList<CurvePoint> vals = new LinkedList<CurvePoint>(); foreach (var point in points) { foreach (var prop in point) { switch (pcc.getNameEntry(prop.Name)) { case "InVal": InVal = BitConverter.ToSingle(prop.raw, 24); break; case "OutVal": OutVal = BitConverter.ToSingle(prop.raw, 24); break; case "ArriveTangent": ArriveTangent = BitConverter.ToSingle(prop.raw, 24); break; case "LeaveTangent": LeaveTangent = BitConverter.ToSingle(prop.raw, 24); break; case "InterpMode": InterpMode = (CurveMode)Enum.Parse(typeof(CurveMode), pcc.getNameEntry(prop.Value.IntValue)); break; default: break; } } vals.AddLast(new CurvePoint(InVal, OutVal, ArriveTangent, LeaveTangent, InterpMode)); } Curves.Add(new Curve("X", vals)); break; case CurveType.InterpCurveVector: Vector OutValVec = new Vector(0, 0, 0); Vector ArriveTangentVec = new Vector(0, 0, 0); Vector LeaveTangentVec = new Vector(0, 0, 0); LinkedList<CurvePoint> x = new LinkedList<CurvePoint>(); LinkedList<CurvePoint> y = new LinkedList<CurvePoint>(); LinkedList<CurvePoint> z = new LinkedList<CurvePoint>(); foreach (var point in points) { foreach (var prop in point) { switch (pcc.getNameEntry(prop.Name)) { case "InVal": InVal = BitConverter.ToSingle(prop.raw, 24); break; case "OutVal": OutValVec = GetVector(prop); break; case "ArriveTangent": ArriveTangentVec = GetVector(prop); break; case "LeaveTangent": LeaveTangentVec = GetVector(prop); break; case "InterpMode": InterpMode = (CurveMode)Enum.Parse(typeof(CurveMode), pcc.getNameEntry(prop.Value.IntValue)); break; default: break; } } x.AddLast(new CurvePoint(InVal, OutValVec.X, ArriveTangentVec.X, LeaveTangentVec.X, InterpMode)); y.AddLast(new CurvePoint(InVal, OutValVec.Y, ArriveTangentVec.Y, LeaveTangentVec.Y, InterpMode)); z.AddLast(new CurvePoint(InVal, OutValVec.Z, ArriveTangentVec.Z, LeaveTangentVec.Z, InterpMode)); } if (Name == "EulerTrack") { Curves.Add(new Curve("Roll", x)); Curves.Add(new Curve("Pitch", y)); Curves.Add(new Curve("Yaw", z)); } else { Curves.Add(new Curve("X", x)); Curves.Add(new Curve("Y", y)); Curves.Add(new Curve("Z", z)); } break; case CurveType.InterpCurveVector2D: throw new NotImplementedException($"InterpCurveVector2D has not been implemented yet."); case CurveType.InterpCurveTwoVectors: throw new NotImplementedException($"InterpCurveTwoVectors has not been implemented yet."); case CurveType.InterpCurveLinearColor: throw new NotImplementedException($"InterpCurveLinearColor has not been implemented yet."); default: break; } foreach (var curve in Curves) { curve.SharedValueChanged += Curve_SharedValueChanged; curve.ListModified += Curve_ListModified; } }
public Bio2DA(IExportEntry export) { Console.WriteLine("Loading " + export.ObjectName); this.export = export; IMEPackage pcc = export.FileRef; byte[] data = export.Data; RowNames = new List <string>(); if (export.ClassName == "Bio2DA") { string rowLabelsVar = "m_sRowLabel"; var properties = export.GetProperties(); var props = export.GetProperty <ArrayProperty <NameProperty> >(rowLabelsVar); if (props != null) { foreach (NameProperty n in props) { RowNames.Add(n.ToString()); } } else { Console.WriteLine("Unable to find row names property!"); Debugger.Break(); return; } } else { string rowLabelsVar = "m_lstRowNumbers"; //Bio2DANumberedRows var props = export.GetProperty <ArrayProperty <IntProperty> >(rowLabelsVar); if (props != null) { foreach (IntProperty n in props) { RowNames.Add(n.Value.ToString()); } } else { Console.WriteLine("Unable to find row names property!"); Debugger.Break(); return; } } //Get Columns ColumnNames = new List <string>(); int colcount = BitConverter.ToInt32(data, data.Length - 4); int currentcoloffset = 0; while (colcount >= 0) { currentcoloffset += 4; int colindex = BitConverter.ToInt32(data, data.Length - currentcoloffset); currentcoloffset += 8; //names in this case don't use nameindex values. int nameindex = BitConverter.ToInt32(data, data.Length - currentcoloffset); string name = pcc.getNameEntry(nameindex); ColumnNames.Insert(0, name); colcount--; } Cells = new Bio2DACell[RowNames.Count(), ColumnNames.Count()]; currentcoloffset += 4; //column count. int infilecolcount = BitConverter.ToInt32(data, data.Length - currentcoloffset); //start of binary data int binstartoffset = export.propsEnd(); //arrayheader + nonenamesize + number of items in this list int curroffset = binstartoffset; int cellcount = BitConverter.ToInt32(data, curroffset); if (cellcount > 0) { curroffset += 4; for (int rowindex = 0; rowindex < RowNames.Count(); rowindex++) { for (int colindex = 0; colindex < ColumnNames.Count() && curroffset < data.Length - currentcoloffset; colindex++) { byte dataType = 255; dataType = data[curroffset]; curroffset++; int dataSize = dataType == Bio2DACell.TYPE_NAME ? 8 : 4; byte[] celldata = new byte[dataSize]; Buffer.BlockCopy(data, curroffset, celldata, 0, dataSize); Bio2DACell cell = new Bio2DACell(pcc, curroffset, dataType, celldata); Cells[rowindex, colindex] = cell; curroffset += dataSize; } } CellCount = RowNames.Count() * ColumnNames.Count(); } else { IsIndexed = true; curroffset += 4; //theres a 0 here for some reason cellcount = BitConverter.ToInt32(data, curroffset); curroffset += 4; //curroffset += 4; while (CellCount < cellcount) { int index = BitConverter.ToInt32(data, curroffset); int row = index / ColumnNames.Count(); int col = index % ColumnNames.Count(); curroffset += 4; byte dataType = data[curroffset]; int dataSize = dataType == Bio2DACell.TYPE_NAME ? 8 : 4; curroffset++; byte[] celldata = new byte[dataSize]; Buffer.BlockCopy(data, curroffset, celldata, 0, dataSize); Bio2DACell cell = new Bio2DACell(pcc, curroffset, dataType, celldata); Cells[row, col] = cell; CellCount++; curroffset += dataSize; } } Console.WriteLine("Finished loading " + export.ObjectName); }
public int GetPropertyEnd() { int pos = 0x00; try { byte[] data = Owner.Exports[MyIndex].Data; int test = BitConverter.ToInt32(data, 8); if (test == 0) { pos = 0x04; } else { pos = 0x08; } if ((Flags & 0x02000000) != 0) { pos = 0x1A; } while (true) { int idxname = BitConverter.ToInt32(data, pos); if (Owner.getNameEntry(idxname) == "None" || Owner.getNameEntry(idxname) == "") { break; } int idxtype = BitConverter.ToInt32(data, pos + 8); int size = BitConverter.ToInt32(data, pos + 16); if (size == 0) { size = 1; //boolean fix } if (Owner.getNameEntry(idxtype) == "StructProperty") { size += 8; } if (Owner.getNameEntry(idxtype) == "ByteProperty") { size += 8; } pos += 24 + size; if (pos > data.Length) { pos -= 24 + size; break; } } } catch (Exception e) { MessageBox.Show(e.ToString()); } return(pos + 8); }
public static void ImportProperty(IMEPackage pcc, IMEPackage importpcc, Property p, string className, MemoryStream m, bool inStruct = false) { string name = importpcc.getNameEntry(p.Name); int idxname = pcc.FindNameOrAdd(name); m.Write(BitConverter.GetBytes(idxname), 0, 4); m.Write(new byte[4], 0, 4); if (name == "None") return; string type = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 8)); int idxtype = pcc.FindNameOrAdd(type); m.Write(BitConverter.GetBytes(idxtype), 0, 4); m.Write(new byte[4], 0, 4); string name2; int idxname2; int size, count, pos; List<Property> Props; switch (type) { case "IntProperty": case "FloatProperty": case "ObjectProperty": case "StringRefProperty": m.Write(BitConverter.GetBytes(4), 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(p.Value.IntValue), 0, 4); break; case "NameProperty": m.Write(BitConverter.GetBytes(8), 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(importpcc.getNameEntry(p.Value.IntValue))), 0, 4); //preserve index or whatever the second part of a namereference is m.Write(p.raw, 28, 4); break; case "BoolProperty": m.Write(new byte[8], 0, 8); m.WriteByte((byte)p.Value.IntValue); if (pcc.Game != MEGame.ME3) { m.Write(new byte[3], 0, 3); } break; case "BioMask4Property": m.Write(BitConverter.GetBytes(p.Size), 0, 4); m.Write(new byte[4], 0, 4); m.WriteByte((byte)p.Value.IntValue); break; case "ByteProperty": m.Write(BitConverter.GetBytes(p.Size), 0, 4); m.Write(new byte[4], 0, 4); if (pcc.Game == MEGame.ME3) { name2 = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 24)); idxname2 = pcc.FindNameOrAdd(name2); m.Write(BitConverter.GetBytes(idxname2), 0, 4); m.Write(new byte[4], 0, 4); } if (p.Size != 1) { m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(importpcc.getNameEntry(p.Value.IntValue))), 0, 4); m.Write(new byte[4], 0, 4); } else { m.WriteByte(Convert.ToByte(p.Value.IntValue)); } break; case "DelegateProperty": size = BitConverter.ToInt32(p.raw, 16); if (size == 0xC) { name2 = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 28)); idxname2 = pcc.FindNameOrAdd(name2); m.Write(BitConverter.GetBytes(0xC), 0, 4); m.Write(new byte[4], 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(idxname2), 0, 4); m.Write(new byte[4], 0, 4); } else { m.Write(BitConverter.GetBytes(size), 0, 4); m.Write(new byte[4], 0, 4); for (int i = 0; i < size; i++) m.WriteByte(p.raw[24 + i]); } break; case "StrProperty": name2 = p.Value.StringValue + '\0'; if (p.Value.len < 0) { m.Write(BitConverter.GetBytes(4 + name2.Length * 2), 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(-name2.Length), 0, 4); foreach (char c in name2) { m.WriteByte((byte)c); m.WriteByte(0); } } else { m.Write(BitConverter.GetBytes(4 + name2.Length), 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(name2.Length), 0, 4); foreach (char c in name2) { m.WriteByte((byte)c); } } break; case "StructProperty": size = BitConverter.ToInt32(p.raw, 16); name2 = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 24)); idxname2 = pcc.FindNameOrAdd(name2); pos = 32; Props = new List<Property>(); try { Props = ReadProp(importpcc, p.raw, pos); } catch (Exception) { } m.Write(BitConverter.GetBytes(size), 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(idxname2), 0, 4); m.Write(new byte[4], 0, 4); if (Props.Count == 0 || Props[0].TypeVal == PropertyType.Unknown) { for (int i = 0; i < size; i++) m.WriteByte(p.raw[32 + i]); } else { foreach (Property pp in Props) ImportProperty(pcc, importpcc, pp, className, m, inStruct); } break; case "ArrayProperty": size = BitConverter.ToInt32(p.raw, 16); count = BitConverter.ToInt32(p.raw, 24); PropertyInfo info = ME3UnrealObjectInfo.getPropertyInfo(className, name, inStruct); ArrayType arrayType = ME3UnrealObjectInfo.getArrayType(info); pos = 28; List<Property> AllProps = new List<Property>(); if (arrayType == ArrayType.Struct) { for (int i = 0; i < count; i++) { Props = new List<Property>(); try { Props = ReadProp(importpcc, p.raw, pos); } catch (Exception) { } AllProps.AddRange(Props); if (Props.Count != 0) { pos = Props[Props.Count - 1].offend; } } } m.Write(BitConverter.GetBytes(size), 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(count), 0, 4); if (AllProps.Count != 0 && (info == null || !ME3UnrealObjectInfo.isImmutable(info.reference))) { foreach (Property pp in AllProps) ImportProperty(pcc, importpcc, pp, className, m, inStruct); } else if (arrayType == ArrayType.Name) { for (int i = 0; i < count; i++) { string s = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 28 + i * 8)); m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(s)), 0, 4); //preserve index or whatever the second part of a namereference is m.Write(p.raw, 32 + i * 8, 4); } } else { m.Write(p.raw, 28, size - 4); } break; default: throw new Exception(type); } }
public static CustomProperty PropertyToGrid(Property p, IMEPackage pcc) { string cat = p.TypeVal.ToString(); CustomProperty pg; NameProp pp; switch (p.TypeVal) { case PropertyType.BoolProperty: pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, (p.Value.IntValue == 1), typeof(bool), false, true); break; case PropertyType.FloatProperty: pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, p.Value.FloatValue, typeof(float), false, true); break; case PropertyType.ByteProperty: if (p.Size != 8) { pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, (byte)p.Value.IntValue, typeof(byte), false, true); } else { pp = new NameProp(); pp.name = pcc.getNameEntry(p.Value.IntValue); pp.nameindex = p.Value.IntValue; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, pp, typeof(NameProp), false, true); } break; case PropertyType.NameProperty: pp = new NameProp(); pp.name = pcc.getNameEntry(p.Value.IntValue); pp.nameindex = p.Value.IntValue; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, pp, typeof(NameProp), false, true); break; case PropertyType.ObjectProperty: ObjectProp ppo = new ObjectProp(); ppo.objectName = pcc.getObjectName(p.Value.IntValue); ppo.index = p.Value.IntValue; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, ppo, typeof(ObjectProp), false, true); break; case PropertyType.StrProperty: pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, p.Value.StringValue, typeof(string), false, true); break; case PropertyType.ArrayProperty: pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, BitConverter.ToInt32(p.raw, 24) + " elements", typeof(string), false, true); break; case PropertyType.StructProperty: string structType = pcc.getNameEntry(p.Value.IntValue); switch (structType) { case "Color": System.Drawing.Color color = System.Drawing.Color.FromArgb(BitConverter.ToInt32(p.raw, 32)); ColorProp cp = new ColorProp { name = structType, nameindex = p.Value.IntValue, Alpha = color.A, Red = color.R, Green = color.G, Blue = color.B }; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, cp, typeof(ColorProp), false, true); break; case "Vector": VectorProp vp = new VectorProp { name = structType, nameindex = p.Value.IntValue, X = BitConverter.ToSingle(p.raw, 32), Y = BitConverter.ToSingle(p.raw, 36), Z = BitConverter.ToSingle(p.raw, 40) }; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, vp, typeof(VectorProp), false, true); break; case "Rotator": RotatorProp rp = new RotatorProp { name = structType, nameindex = p.Value.IntValue, Pitch = BitConverter.ToInt32(p.raw, 32).ToDegrees(), Yaw = BitConverter.ToInt32(p.raw, 36).ToDegrees(), Roll = BitConverter.ToInt32(p.raw, 40).ToDegrees() }; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, rp, typeof(RotatorProp), false, true); break; case "LinearColor": LinearColorProp lcp = new LinearColorProp { name = structType, nameindex = p.Value.IntValue, Red = BitConverter.ToSingle(p.raw, 32), Green = BitConverter.ToSingle(p.raw, 36), Blue = BitConverter.ToSingle(p.raw, 40), Alpha = BitConverter.ToSingle(p.raw, 44) }; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, lcp, typeof(VectorProp), false, true); break; default: byte[] buf = new byte[p.Value.Array.Count()]; for (int i = 0; i < p.Value.Array.Count(); i++) { buf[i] = (byte)p.Value.Array[i].IntValue; } List <int> buf2 = new List <int>(); for (int i = 0; i < p.Value.Array.Count() / 4; i++) { buf2.Add(BitConverter.ToInt32(buf, i * 4)); } StructProp ppp = new StructProp { name = structType, nameindex = p.Value.IntValue, data = buf2.ToArray() }; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, ppp, typeof(StructProp), false, true); break; } break; default: pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, p.Value.IntValue, typeof(int), false, true); break; } return(pg); }
private int ClassParser_RelinkComponentsTable(IMEPackage importpcc, IExportEntry exp, List <string> relinkFailedReport, ref byte[] data, int offset) { if (importpcc.Game == MEGame.ME3) { int componentTableNameIndex = BitConverter.ToInt32(data, offset); int componentTableIndex = BitConverter.ToInt32(data, offset + 4); NameReference importingName = importpcc.getNameEntry(componentTableNameIndex); int newComponentTableName = exp.FileRef.FindNameOrAdd(importingName); WriteMem(offset, data, BitConverter.GetBytes(newComponentTableName)); offset += 8; int componentTableCount = BitConverter.ToInt32(data, offset); offset += 4; for (int i = 0; i < componentTableCount; i++) { int nameTableIndex = BitConverter.ToInt32(data, offset); int nameIndex = BitConverter.ToInt32(data, offset + 4); importingName = importpcc.getNameEntry(nameTableIndex); int componentName = exp.FileRef.FindNameOrAdd(importingName); WriteMem(offset, data, BitConverter.GetBytes(componentName)); offset += 8; int componentObjectIndex = BitConverter.ToInt32(data, offset); int mapped; bool isMapped = crossPCCObjectMap.TryGetValue(componentObjectIndex, out mapped); if (isMapped) { mapped = me3ExpIndexingToUnreal(mapped, componentObjectIndex < 0); //if the value is 0, it would have an error anyways. WriteMem(offset, data, BitConverter.GetBytes(mapped)); } else { if (componentObjectIndex < 0) { ImportEntry componentObjectImport = importpcc.Imports[Math.Abs(unrealIndexToME3ExpIndexing(componentObjectIndex))]; ImportEntry newComponentObjectImport = getOrAddCrossImport(componentObjectImport.GetFullPath, importpcc, exp.FileRef); WriteMem(offset, data, BitConverter.GetBytes(newComponentObjectImport.UIndex)); } else if (componentObjectIndex > 0) //we do not remap on 0 here in binary land { relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: Component[" + i + "] could not be remapped during porting: " + componentObjectIndex + " is not in the mapping tree"); } } offset += 4; } } else { int componentTableCount = BitConverter.ToInt32(data, offset); offset += 4; for (int i = 0; i < componentTableCount; i++) { int nameTableIndex = BitConverter.ToInt32(data, offset); int nameIndex = BitConverter.ToInt32(data, offset + 4); offset += 8; int componentObjectIndex = BitConverter.ToInt32(data, offset); if (componentObjectIndex != 0) { int mapped; bool isMapped = crossPCCObjectMap.TryGetValue(componentObjectIndex, out mapped); if (isMapped) { mapped = me3ExpIndexingToUnreal(mapped, componentObjectIndex < 0); //if the value is 0, it would have an error anyways. WriteMem(offset, data, BitConverter.GetBytes(mapped)); } else { if (componentObjectIndex < 0) { ImportEntry componentObjectImport = importpcc.Imports[Math.Abs(unrealIndexToME3ExpIndexing(componentObjectIndex))]; ImportEntry newComponentObjectImport = getOrAddCrossImport(componentObjectImport.GetFullPath, importpcc, exp.FileRef); WriteMem(offset, data, BitConverter.GetBytes(newComponentObjectImport.UIndex)); } else { relinkFailedReport.Add("Binary Class Component[" + i + "] could not be remapped during porting: " + componentObjectIndex + " is not in the mapping tree"); } } } offset += 4; } } return(offset); }
public static Property getPropOrNull(IMEPackage pcc, byte[] data, int start, string propName) { List<Property> props = ReadProp(pcc, data, start); foreach (Property prop in props) { if (pcc.getNameEntry(prop.Name) == propName) { return prop; } } return null; }
private bool importExport(IMEPackage importpcc, int n, int link) { IExportEntry ex = importpcc.getExport(n); IExportEntry nex = null; switch (pcc.Game) { case MEGame.ME1: nex = new ME1ExportEntry(pcc as ME1Package); break; case MEGame.ME2: nex = new ME2ExportEntry(pcc as ME2Package); break; case MEGame.ME3: nex = new ME3ExportEntry(pcc as ME3Package); break; } byte[] idata = ex.Data; PropertyCollection props = ex.GetProperties(); int start = ex.GetPropertyStart(); int end = props.endOffset; MemoryStream res = new MemoryStream(); if ((importpcc.getExport(n).ObjectFlags & (ulong)UnrealFlags.EObjectFlags.HasStack) != 0) { byte[] stackdummy = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //Lets hope for the best :D 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,}; if (pcc.Game != MEGame.ME3) { stackdummy = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,}; } res.Write(stackdummy, 0, stackdummy.Length); } else { res.Write(new byte[start], 0, start); } //store copy of names list in case something goes wrong List<string> names = pcc.Names.ToList(); try { props.WriteTo(res, pcc); } catch (Exception exception) { //restore namelist pcc.setNames(names); MessageBox.Show("Error occured while trying to import " + ex.ObjectName + " : " + exception.Message); return false; } if (importpcc.Game == MEGame.ME3 && importpcc.getObjectName(ex.idxClass) == "SkeletalMesh") { SkeletalMesh skl = new SkeletalMesh(importpcc as ME3Package, n); SkeletalMesh.BoneStruct bone; for (int i = 0; i < skl.Bones.Count; i++) { bone = skl.Bones[i]; string s = importpcc.getNameEntry(bone.Name); bone.Name = pcc.FindNameOrAdd(s); skl.Bones[i] = bone; } SkeletalMesh.TailNamesStruct tailName; for (int i = 0; i < skl.TailNames.Count; i++) { tailName = skl.TailNames[i]; string s = importpcc.getNameEntry(tailName.Name); tailName.Name = pcc.FindNameOrAdd(s); skl.TailNames[i] = tailName; } SerializingContainer container = new SerializingContainer(res); container.isLoading = false; skl.Serialize(container); } else { res.Write(idata, end, idata.Length - end); } nex.setHeader((byte[])ex.header.Clone()); nex.Data = res.ToArray(); nex.idxObjectName = pcc.FindNameOrAdd(importpcc.getNameEntry(ex.idxObjectName)); nex.idxLink = link; nex.idxArchtype = nex.idxClass = nex.idxClassParent = 0; pcc.addExport(nex); return true; }
private void importImport(IMEPackage importpcc, int n, int link) { ImportEntry imp = importpcc.getImport(n); ImportEntry nimp = new ImportEntry(pcc, imp.header); nimp.idxLink = link; nimp.idxClassName = pcc.FindNameOrAdd(importpcc.getNameEntry(imp.idxClassName)); nimp.idxObjectName = pcc.FindNameOrAdd(importpcc.getNameEntry(imp.idxObjectName)); nimp.idxPackageFile = pcc.FindNameOrAdd(importpcc.getNameEntry(imp.idxPackageFile)); pcc.addImport(nimp); }
public static string PropertyToText(Property p, IMEPackage pcc) { string s = ""; s = "Name: " + pcc.getNameEntry(p.Name); s += " Type: " + TypeToString((int)p.TypeVal); s += " Size: " + p.Size; switch (p.TypeVal) { case PropertyType.StructProperty: s += " \"" + pcc.getNameEntry (p.Value.IntValue) + "\" with " + p.Value.Array.Count + " bytes"; break; case PropertyType.IntProperty: case PropertyType.ObjectProperty: case PropertyType.StringRefProperty : s += " Value: " + p.Value.IntValue; break; case PropertyType.BoolProperty: s += " Value: " + (p.raw[24] == 1); break; case PropertyType.FloatProperty: s += " Value: " + p.Value.FloatValue; break; case PropertyType.NameProperty: s += " " + pcc.getNameEntry(p.Value.IntValue); break; case PropertyType.ByteProperty: s += " Value: \"" + p.Value.StringValue + "\" with \"" + pcc.getNameEntry(p.Value.IntValue) + "\""; break; case PropertyType.ArrayProperty: s += " bytes"; //Value: " + p.Value.Array.Count.ToString() + " Elements"; break; case PropertyType.StrProperty: if (p.Value.StringValue.Length == 0) break; s += " Value: " + p.Value.StringValue; break; } return s; }
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 void propGridPropertyValueChanged(PropertyValueChangedEventArgs e, int n, IMEPackage pcc) { string name = e.ChangedItem.Label; GridItem parent = e.ChangedItem.Parent; //if (parent != null) name = parent.Label; if (parent.Label == "data") { GridItem parent2 = parent.Parent; if (parent2 != null) name = parent2.Label; } Type parentVal = null; if (parent.Value != null) { parentVal = parent.Value.GetType(); } if (name == "nameindex" || name == "index" || parentVal == typeof(ColorProp) || parentVal == typeof(VectorProp) || parentVal == typeof(Unreal.RotatorProp) || parentVal == typeof(Unreal.LinearColorProp)) { name = parent.Label; } IExportEntry ent = pcc.getExport(n); byte[] data = ent.Data; List<PropertyReader.Property> p = PropertyReader.getPropList(ent); int m = -1; for (int i = 0; i < p.Count; i++) if (pcc.getNameEntry(p[i].Name) == name) m = i; if (m == -1) return; byte[] buff2; switch (p[m].TypeVal) { case PropertyType.BoolProperty: byte res = 0; if ((bool)e.ChangedItem.Value == true) res = 1; data[p[m].offsetval] = res; break; case PropertyType.FloatProperty: buff2 = BitConverter.GetBytes((float)e.ChangedItem.Value); for (int i = 0; i < 4; i++) data[p[m].offsetval + i] = buff2[i]; break; case PropertyType.IntProperty: case PropertyType.StringRefProperty: int newv = Convert.ToInt32(e.ChangedItem.Value); int oldv = Convert.ToInt32(e.OldValue); buff2 = BitConverter.GetBytes(newv); for (int i = 0; i < 4; i++) data[p[m].offsetval + i] = buff2[i]; break; case PropertyType.StrProperty: string s = Convert.ToString(e.ChangedItem.Value); int stringMultiplier = 1; int oldLength = BitConverter.ToInt32(data, p[m].offsetval); if (oldLength < 0) { stringMultiplier = 2; oldLength *= -2; } int oldSize = 4 + oldLength; List<byte> stringBuff = new List<byte>(s.Length * stringMultiplier); if (stringMultiplier == 2) { for (int j = 0; j < s.Length; j++) { stringBuff.AddRange(BitConverter.GetBytes(s[j])); } stringBuff.Add(0); } else { for (int j = 0; j < s.Length; j++) { stringBuff.Add(BitConverter.GetBytes(s[j])[0]); } } stringBuff.Add(0); buff2 = BitConverter.GetBytes((s.Length + 1) * stringMultiplier + 4); for (int j = 0; j < 4; j++) data[p[m].offsetval - 8 + j] = buff2[j]; buff2 = BitConverter.GetBytes((s.Length + 1) * stringMultiplier == 1 ? 1 : -1); for (int j = 0; j < 4; j++) data[p[m].offsetval + j] = buff2[j]; buff2 = new byte[data.Length - oldLength + stringBuff.Count]; int startLength = p[m].offsetval + 4; int startLength2 = startLength + oldLength; for (int i = 0; i < startLength; i++) { buff2[i] = data[i]; } for (int i = 0; i < stringBuff.Count; i++) { buff2[i + startLength] = stringBuff[i]; } startLength += stringBuff.Count; for (int i = 0; i < data.Length - startLength2; i++) { buff2[i + startLength] = data[i + startLength2]; } data = buff2; break; case PropertyType.StructProperty: if (e.ChangedItem.Label != "nameindex" && parentVal == typeof(ColorProp)) { switch (e.ChangedItem.Label) { case "Alpha": data[p[m].offsetval + 11] = Convert.ToByte(e.ChangedItem.Value); break; case "Red": data[p[m].offsetval + 10] = Convert.ToByte(e.ChangedItem.Value); break; case "Green": data[p[m].offsetval + 9] = Convert.ToByte(e.ChangedItem.Value); break; case "Blue": data[p[m].offsetval + 8] = Convert.ToByte(e.ChangedItem.Value); break; default: break; } } else if (e.ChangedItem.Label != "nameindex" && parentVal == typeof(VectorProp)) { int offset = 0; switch (e.ChangedItem.Label) { case "X": offset = 8; break; case "Y": offset = 12; break; case "Z": offset = 16; break; default: break; } if (offset != 0) { buff2 = BitConverter.GetBytes(Convert.ToSingle(e.ChangedItem.Value)); for (int i = 0; i < 4; i++) data[p[m].offsetval + offset + i] = buff2[i]; } } else if (e.ChangedItem.Label != "nameindex" && parentVal == typeof(Unreal.RotatorProp)) { int offset = 0; switch (e.ChangedItem.Label) { case "Pitch": offset = 8; break; case "Yaw": offset = 12; break; case "Roll": offset = 16; break; default: break; } if (offset != 0) { int val = Convert.ToInt32(Convert.ToSingle(e.ChangedItem.Value) * 65536f / 360f); buff2 = BitConverter.GetBytes(val); for (int i = 0; i < 4; i++) data[p[m].offsetval + offset + i] = buff2[i]; } } else if (e.ChangedItem.Label != "nameindex" && parentVal == typeof(Unreal.LinearColorProp)) { int offset = 0; switch (e.ChangedItem.Label) { case "Red": offset = 8; break; case "Green": offset = 12; break; case "Blue": offset = 16; break; case "Alpha": offset = 20; break; default: break; } if (offset != 0) { buff2 = BitConverter.GetBytes(Convert.ToSingle(e.ChangedItem.Value)); for (int i = 0; i < 4; i++) data[p[m].offsetval + offset + i] = buff2[i]; } } else if (e.ChangedItem.Value is int) { int val = Convert.ToInt32(e.ChangedItem.Value); if (e.ChangedItem.Label == "nameindex") { int val1 = Convert.ToInt32(e.ChangedItem.Value); buff2 = BitConverter.GetBytes(val1); for (int i = 0; i < 4; i++) data[p[m].offsetval + i] = buff2[i]; } else { string sidx = e.ChangedItem.Label.Replace("[", ""); sidx = sidx.Replace("]", ""); int index = Convert.ToInt32(sidx); buff2 = BitConverter.GetBytes(val); for (int i = 0; i < 4; i++) data[p[m].offsetval + i + index * 4 + 8] = buff2[i]; } } break; case PropertyType.ByteProperty: case PropertyType.NameProperty: if (e.ChangedItem.Value is int) { int val = Convert.ToInt32(e.ChangedItem.Value); buff2 = BitConverter.GetBytes(val); for (int i = 0; i < 4; i++) data[p[m].offsetval + i] = buff2[i]; } break; case PropertyType.ObjectProperty: if (e.ChangedItem.Value is int) { int val = Convert.ToInt32(e.ChangedItem.Value); buff2 = BitConverter.GetBytes(val); for (int i = 0; i < 4; i++) data[p[m].offsetval + i] = buff2[i]; } break; default: return; } ent.Data = data; }
/// <summary> /// Attempts to relink unreal binary data to object pointers if they are part of the clone tree. /// It's gonna be an ugly mess. /// </summary> /// <param name="importpcc">PCC being imported from</param> private List <string> relinkBinaryObjects(IMEPackage importpcc) { List <string> relinkFailedReport = new List <string>(); foreach (KeyValuePair <int, int> entry in crossPCCObjectMap) { if (entry.Key > 0) { IExportEntry exp = pcc.getExport(entry.Value); byte[] binarydata = exp.getBinaryData(); if (binarydata.Length > 0) { //has binary data //This is temporary until I find a more permanent style for relinking binary try { switch (exp.ClassName) { case "WwiseEvent": { int count = BitConverter.ToInt32(binarydata, 0); for (int i = 0; i < count; i++) { int originalValue = BitConverter.ToInt32(binarydata, 4 + (i * 4)); int currentObjectRef = unrealIndexToME3ExpIndexing(originalValue); //count + i * intsize int mapped; bool isMapped = crossPCCObjectMap.TryGetValue(currentObjectRef, out mapped); if (isMapped) { mapped = me3ExpIndexingToUnreal(mapped, originalValue < 0); //if the value is 0, it would have an error anyways. Debug.WriteLine("Binary relink hit for WwiseEvent Export " + exp.UIndex + " 0x" + (4 + (i * 4)).ToString("X6") + " " + originalValue + " -> " + (mapped + 1)); WriteMem(4 + (i * 4), binarydata, BitConverter.GetBytes(mapped)); int newValue = BitConverter.ToInt32(binarydata, 4 + (i * 4)); Debug.WriteLine(originalValue + " -> " + newValue); } else { Debug.WriteLine("Binary relink missed WwiseEvent Export " + exp.UIndex + " 0x" + (4 + (i * 4)).ToString("X6") + " " + originalValue); relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: WwiseEvent referenced WwiseStream " + originalValue + " is not in the mapping tree and could not be relinked"); } } exp.setBinaryData(binarydata); } break; case "Class": { if (exp.FileRef.Game != importpcc.Game) { //Cannot relink against a different game. continue; } IExportEntry importingExp = importpcc.getExport(entry.Key); if (importingExp.ClassName != "Class") { continue; //the class was not actually set, so this is not really class. } //This is going to be pretty ugly try { byte[] newdata = importpcc.Exports[entry.Key].Data; //may need to rewrite first unreal header byte[] data = importpcc.Exports[entry.Key].Data; int offset = 0; int unrealExportIndex = BitConverter.ToInt32(data, offset); offset += 4; int superclassIndex = BitConverter.ToInt32(data, offset); if (superclassIndex < 0) { //its an import ImportEntry superclassImportEntry = importpcc.Imports[Math.Abs(unrealIndexToME3ExpIndexing(superclassIndex))]; ImportEntry newSuperclassValue = getOrAddCrossImport(superclassImportEntry.GetFullPath, importpcc, exp.FileRef); WriteMem(offset, newdata, BitConverter.GetBytes(newSuperclassValue.UIndex)); } else { relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: Superclass is an export in the source package and was not relinked."); } int unknown1 = BitConverter.ToInt32(data, offset); offset += 4; int classObjTree = BitConverter.ToInt32(data, offset); //Don't know if I need to do this. offset += 4; //I am not sure what these mean. However if Pt1&2 are 33/25, the following bytes that follow are extended. int headerUnknown1 = BitConverter.ToInt32(data, offset); Int64 ignoreMask = BitConverter.ToInt64(data, offset); offset += 8; Int16 labelOffset = BitConverter.ToInt16(data, offset); offset += 2; int skipAmount = 0x6; //Find end of script block. Seems to be 10 FF's. while (offset + skipAmount + 10 < data.Length) { //Debug.WriteLine("Cheecking at 0x"+(offset + skipAmount + 10).ToString("X4")); bool isEnd = true; for (int i = 0; i < 10; i++) { byte b = data[offset + skipAmount + i]; if (b != 0xFF) { isEnd = false; break; } } if (isEnd) { break; } else { skipAmount++; } } int offsetEnd = offset + skipAmount + 10; offset += skipAmount + 10; //heuristic to find end of script uint stateMask = BitConverter.ToUInt32(data, offset); offset += 4; int localFunctionsTableCount = BitConverter.ToInt32(data, offset); offset += 4; bool isMapped; for (int i = 0; i < localFunctionsTableCount; i++) { int nameTableIndex = BitConverter.ToInt32(data, offset); int nameIndex = BitConverter.ToInt32(data, offset + 4); NameReference importingName = importpcc.getNameEntry(nameTableIndex); int newFuncName = exp.FileRef.FindNameOrAdd(importingName); WriteMem(offset, newdata, BitConverter.GetBytes(newFuncName)); offset += 8; int functionObjectIndex = unrealIndexToME3ExpIndexing(BitConverter.ToInt32(data, offset)); int mapped; isMapped = crossPCCObjectMap.TryGetValue(functionObjectIndex, out mapped); if (isMapped) { mapped = me3ExpIndexingToUnreal(mapped, functionObjectIndex < 0); //if the value is 0, it would have an error anyways. WriteMem(offset, newdata, BitConverter.GetBytes(mapped)); } else { relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: Local function[" + i + "] could not be remapped during porting: " + functionObjectIndex + " is not in the mapping tree and could not be relinked"); } offset += 4; } int classMask = BitConverter.ToInt32(data, offset); offset += 4; if (importpcc.Game != MEGame.ME3) { offset += 1; //seems to be a blank byte here } int coreReference = BitConverter.ToInt32(data, offset); if (coreReference < 0) { //its an import ImportEntry outerclassReferenceImport = importpcc.Imports[Math.Abs(unrealIndexToME3ExpIndexing(coreReference))]; ImportEntry outerclassNewImport = getOrAddCrossImport(outerclassReferenceImport.GetFullPath, importpcc, exp.FileRef); WriteMem(offset, newdata, BitConverter.GetBytes(outerclassNewImport.UIndex)); } else { relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: Outerclass is an export in the original package, not relinked."); } offset += 4; if (importpcc.Game == MEGame.ME3) { offset = ClassParser_RelinkComponentsTable(importpcc, exp, relinkFailedReport, ref newdata, offset); offset = ClassParser_ReadImplementsTable(importpcc, exp, relinkFailedReport, ref newdata, offset); int postComponentsNoneNameIndex = BitConverter.ToInt32(data, offset); int postComponentNoneIndex = BitConverter.ToInt32(data, offset + 4); string postCompName = importpcc.getNameEntry(postComponentsNoneNameIndex); //This appears to be unused in ME3, it is always None it seems. int newFuncName = exp.FileRef.FindNameOrAdd(postCompName); WriteMem(offset, newdata, BitConverter.GetBytes(newFuncName)); offset += 8; int unknown4 = BitConverter.ToInt32(data, offset); offset += 4; } else { offset = ClassParser_ReadImplementsTable(importpcc, exp, relinkFailedReport, ref data, offset); offset = ClassParser_RelinkComponentsTable(importpcc, exp, relinkFailedReport, ref data, offset); int me12unknownend1 = BitConverter.ToInt32(data, offset); offset += 4; int me12unknownend2 = BitConverter.ToInt32(data, offset); offset += 4; } int defaultsClassLink = unrealIndexToME3ExpIndexing(BitConverter.ToInt32(data, offset)); int defClassLink; isMapped = crossPCCObjectMap.TryGetValue(defaultsClassLink, out defClassLink); if (isMapped) { defClassLink = me3ExpIndexingToUnreal(defClassLink, defaultsClassLink < 0); //if the value is 0, it would have an error anyways. WriteMem(offset, newdata, BitConverter.GetBytes(defClassLink)); } else { relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: DefaultsClassLink cannot be currently automatically relinked by Binary Relinker. Please manually set this in Binary Editor"); } offset += 4; if (importpcc.Game == MEGame.ME3) { int functionsTableCount = BitConverter.ToInt32(data, offset); offset += 4; for (int i = 0; i < functionsTableCount; i++) { int functionsTableIndex = unrealIndexToME3ExpIndexing(BitConverter.ToInt32(data, offset)); int mapped; isMapped = crossPCCObjectMap.TryGetValue(functionsTableIndex, out mapped); if (isMapped) { mapped = me3ExpIndexingToUnreal(mapped, functionsTableIndex < 0); //if the value is 0, it would have an error anyways. WriteMem(offset, newdata, BitConverter.GetBytes(mapped)); } else { if (functionsTableIndex < 0) { ImportEntry functionObjIndex = importpcc.Imports[Math.Abs(functionsTableIndex)]; ImportEntry newFunctionObjIndex = getOrAddCrossImport(functionObjIndex.GetFullPath, importpcc, exp.FileRef); WriteMem(offset, newdata, BitConverter.GetBytes(newFunctionObjIndex.UIndex)); } else { relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: Full Functions List function[" + i + "] could not be remapped during porting: " + functionsTableIndex + " is not in the mapping tree and could not be relinked"); } } offset += 4; } } exp.Data = newdata; } catch (Exception ex) { relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relink error: Exception relinking: " + ex.Message); } } break; default: continue; } } catch (Exception e) { relinkFailedReport.Add(exp.Index + " " + exp.GetFullPath + " binary relinking failed: " + e.Message); } //Run an interpreter pass over it - we will find objectleafnodes and attempt to update the same offset in the destination file. //BinaryInterpreter binaryrelinkInterpreter = new ME3Explorer.BinaryInterpreter(importpcc, importpcc.Exports[entry.Key], pcc, pcc.Exports[entry.Value], crossPCCObjectMapping); } } } return(relinkFailedReport); }
static PropertyType getType(IMEPackage pcc, int type) { switch (pcc.getNameEntry(type)) { case "None": return PropertyType.None; case "StructProperty": return PropertyType.StructProperty; case "IntProperty": return PropertyType.IntProperty; case "FloatProperty": return PropertyType.FloatProperty; case "ObjectProperty": return PropertyType.ObjectProperty; case "NameProperty": return PropertyType.NameProperty; case "BoolProperty": return PropertyType.BoolProperty; case "ByteProperty": return PropertyType.ByteProperty; case "ArrayProperty": return PropertyType.ArrayProperty; case "DelegateProperty": return PropertyType.DelegateProperty; case "StrProperty": return PropertyType.StrProperty; case "StringRefProperty": return PropertyType.StringRefProperty; default: return PropertyType.Unknown; } }
public InterpCurve(IMEPackage _pcc, PropertyReader.Property p) { pcc = _pcc; Curves = new ObservableCollection <Curve>(); Name = pcc.getNameEntry(p.Name); curveType = (CurveType)Enum.Parse(typeof(CurveType), pcc.getNameEntry(p.Value.IntValue)); float InVal = 0f; CurveMode InterpMode = CurveMode.CIM_Linear; var points = PropertyReader.ReadStructArrayProp(pcc, PropertyReader.getPropOrNull(pcc, p.raw, 32, "Points")); switch (curveType) { case CurveType.InterpCurveQuat: throw new NotImplementedException($"InterpCurveQuat has not been implemented yet."); case CurveType.InterpCurveFloat: float OutVal = 0f; float ArriveTangent = 0f; float LeaveTangent = 0f; LinkedList <CurvePoint> vals = new LinkedList <CurvePoint>(); foreach (var point in points) { foreach (var prop in point) { switch (pcc.getNameEntry(prop.Name)) { case "InVal": InVal = BitConverter.ToSingle(prop.raw, 24); break; case "OutVal": OutVal = BitConverter.ToSingle(prop.raw, 24); break; case "ArriveTangent": ArriveTangent = BitConverter.ToSingle(prop.raw, 24); break; case "LeaveTangent": LeaveTangent = BitConverter.ToSingle(prop.raw, 24); break; case "InterpMode": InterpMode = (CurveMode)Enum.Parse(typeof(CurveMode), pcc.getNameEntry(prop.Value.IntValue)); break; default: break; } } vals.AddLast(new CurvePoint(InVal, OutVal, ArriveTangent, LeaveTangent, InterpMode)); } Curves.Add(new Curve("X", vals)); break; case CurveType.InterpCurveVector: Vector OutValVec = new Vector(0, 0, 0); Vector ArriveTangentVec = new Vector(0, 0, 0); Vector LeaveTangentVec = new Vector(0, 0, 0); LinkedList <CurvePoint> x = new LinkedList <CurvePoint>(); LinkedList <CurvePoint> y = new LinkedList <CurvePoint>(); LinkedList <CurvePoint> z = new LinkedList <CurvePoint>(); foreach (var point in points) { foreach (var prop in point) { switch (pcc.getNameEntry(prop.Name)) { case "InVal": InVal = BitConverter.ToSingle(prop.raw, 24); break; case "OutVal": OutValVec = GetVector(prop); break; case "ArriveTangent": ArriveTangentVec = GetVector(prop); break; case "LeaveTangent": LeaveTangentVec = GetVector(prop); break; case "InterpMode": InterpMode = (CurveMode)Enum.Parse(typeof(CurveMode), pcc.getNameEntry(prop.Value.IntValue)); break; default: break; } } x.AddLast(new CurvePoint(InVal, OutValVec.X, ArriveTangentVec.X, LeaveTangentVec.X, InterpMode)); y.AddLast(new CurvePoint(InVal, OutValVec.Y, ArriveTangentVec.Y, LeaveTangentVec.Y, InterpMode)); z.AddLast(new CurvePoint(InVal, OutValVec.Z, ArriveTangentVec.Z, LeaveTangentVec.Z, InterpMode)); } if (Name == "EulerTrack") { Curves.Add(new Curve("Roll", x)); Curves.Add(new Curve("Pitch", y)); Curves.Add(new Curve("Yaw", z)); } else { Curves.Add(new Curve("X", x)); Curves.Add(new Curve("Y", y)); Curves.Add(new Curve("Z", z)); } break; case CurveType.InterpCurveVector2D: throw new NotImplementedException($"InterpCurveVector2D has not been implemented yet."); case CurveType.InterpCurveTwoVectors: throw new NotImplementedException($"InterpCurveTwoVectors has not been implemented yet."); case CurveType.InterpCurveLinearColor: throw new NotImplementedException($"InterpCurveLinearColor has not been implemented yet."); default: break; } foreach (var curve in Curves) { curve.SharedValueChanged += Curve_SharedValueChanged; curve.ListModified += Curve_ListModified; } }
public static void ImportProperty(IMEPackage pcc, IMEPackage importpcc, Property p, string className, MemoryStream m, bool inStruct = false) { string name = importpcc.getNameEntry(p.Name); int idxname = pcc.FindNameOrAdd(name); m.Write(BitConverter.GetBytes(idxname), 0, 4); m.Write(new byte[4], 0, 4); if (name == "None") { return; } string type = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 8)); int idxtype = pcc.FindNameOrAdd(type); m.Write(BitConverter.GetBytes(idxtype), 0, 4); m.Write(new byte[4], 0, 4); string name2; int idxname2; int size, count, pos; List <Property> Props; switch (type) { case "IntProperty": case "FloatProperty": case "ObjectProperty": case "StringRefProperty": m.Write(BitConverter.GetBytes(4), 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(p.Value.IntValue), 0, 4); break; case "NameProperty": m.Write(BitConverter.GetBytes(8), 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(importpcc.getNameEntry(p.Value.IntValue))), 0, 4); //preserve index or whatever the second part of a namereference is m.Write(p.raw, 28, 4); break; case "BoolProperty": m.Write(new byte[8], 0, 8); m.WriteByte((byte)p.Value.IntValue); if (pcc.Game != MEGame.ME3) { m.Write(new byte[3], 0, 3); } break; case "BioMask4Property": m.Write(BitConverter.GetBytes(p.Size), 0, 4); m.Write(new byte[4], 0, 4); m.WriteByte((byte)p.Value.IntValue); break; case "ByteProperty": m.Write(BitConverter.GetBytes(p.Size), 0, 4); m.Write(new byte[4], 0, 4); if (pcc.Game == MEGame.ME3) { name2 = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 24)); idxname2 = pcc.FindNameOrAdd(name2); m.Write(BitConverter.GetBytes(idxname2), 0, 4); m.Write(new byte[4], 0, 4); } if (p.Size != 1) { m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(importpcc.getNameEntry(p.Value.IntValue))), 0, 4); m.Write(new byte[4], 0, 4); } else { m.WriteByte(Convert.ToByte(p.Value.IntValue)); } break; case "DelegateProperty": size = BitConverter.ToInt32(p.raw, 16); if (size == 0xC) { name2 = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 28)); idxname2 = pcc.FindNameOrAdd(name2); m.Write(BitConverter.GetBytes(0xC), 0, 4); m.Write(new byte[4], 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(idxname2), 0, 4); m.Write(new byte[4], 0, 4); } else { m.Write(BitConverter.GetBytes(size), 0, 4); m.Write(new byte[4], 0, 4); for (int i = 0; i < size; i++) { m.WriteByte(p.raw[24 + i]); } } break; case "StrProperty": name2 = p.Value.StringValue; if (p.Value.StringValue.Length > 0) { name2 += '\0'; } if (p.Value.len < 0) { //unicode m.Write(BitConverter.GetBytes(4 + name2.Length * 2), 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(-name2.Length), 0, 4); foreach (char c in name2) { m.WriteByte((byte)c); m.WriteByte(0); } } else { //ascii m.Write(BitConverter.GetBytes(4 + name2.Length), 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(name2.Length), 0, 4); foreach (char c in name2) { m.WriteByte((byte)c); } } break; case "StructProperty": size = BitConverter.ToInt32(p.raw, 16); name2 = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 24)); idxname2 = pcc.FindNameOrAdd(name2); pos = 32; Props = new List <Property>(); try { Props = ReadProp(importpcc, p.raw, pos); } catch (Exception) { } m.Write(BitConverter.GetBytes(size), 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(idxname2), 0, 4); m.Write(new byte[4], 0, 4); if (Props.Count == 0 || Props[0].TypeVal == PropertyType.Unknown) { for (int i = 0; i < size; i++) { m.WriteByte(p.raw[32 + i]); } } else { foreach (Property pp in Props) { ImportProperty(pcc, importpcc, pp, className, m, inStruct); } } break; case "ArrayProperty": size = BitConverter.ToInt32(p.raw, 16); count = BitConverter.ToInt32(p.raw, 24); PropertyInfo info = ME3UnrealObjectInfo.getPropertyInfo(className, name, inStruct); ArrayType arrayType = ME3UnrealObjectInfo.getArrayType(info); pos = 28; List <Property> AllProps = new List <Property>(); if (arrayType == ArrayType.Struct) { for (int i = 0; i < count; i++) { Props = new List <Property>(); try { Props = ReadProp(importpcc, p.raw, pos); } catch (Exception) { } AllProps.AddRange(Props); if (Props.Count != 0) { pos = Props[Props.Count - 1].offend; } } } m.Write(BitConverter.GetBytes(size), 0, 4); m.Write(new byte[4], 0, 4); m.Write(BitConverter.GetBytes(count), 0, 4); if (AllProps.Count != 0 && (info == null || !UnrealObjectInfo.isImmutable(info.reference, pcc.Game))) { foreach (Property pp in AllProps) { ImportProperty(pcc, importpcc, pp, className, m, inStruct); } } else if (arrayType == ArrayType.Name) { for (int i = 0; i < count; i++) { string s = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 28 + i * 8)); m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(s)), 0, 4); //preserve index or whatever the second part of a namereference is m.Write(p.raw, 32 + i * 8, 4); } } else { m.Write(p.raw, 28, size - 4); } break; default: throw new Exception(type); } }
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 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 CustomProperty PropertyToGrid(Property p, IMEPackage pcc) { string cat = p.TypeVal.ToString(); CustomProperty pg; NameProp pp; switch (p.TypeVal) { case PropertyType.BoolProperty: pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, (p.Value.IntValue == 1), typeof(bool), false, true); break; case PropertyType.FloatProperty: pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, p.Value.FloatValue, typeof(float), false, true); break; case PropertyType.ByteProperty: if (p.Size != 8) { pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, (byte)p.Value.IntValue, typeof(byte), false, true); } else { pp = new NameProp(); pp.name = pcc.getNameEntry(p.Value.IntValue); pp.nameindex = p.Value.IntValue; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, pp, typeof(NameProp), false, true); } break; case PropertyType.NameProperty: pp = new NameProp(); pp.name = pcc.getNameEntry(p.Value.IntValue); pp.nameindex = p.Value.IntValue; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, pp, typeof(NameProp), false, true); break; case PropertyType.ObjectProperty: ObjectProp ppo = new ObjectProp(); ppo.objectName = pcc.getObjectName(p.Value.IntValue); ppo.index = p.Value.IntValue; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, ppo, typeof(ObjectProp), false, true); break; case PropertyType.StrProperty: pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, p.Value.StringValue, typeof(string), false, true); break; case PropertyType.ArrayProperty: pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, BitConverter.ToInt32(p.raw, 24) + " elements", typeof(string), false, true); break; case PropertyType.StructProperty: string structType = pcc.getNameEntry(p.Value.IntValue); if (structType == "Color") { ColorProp cp = new ColorProp(); cp.name = structType; cp.nameindex = p.Value.IntValue; System.Drawing.Color color = System.Drawing.Color.FromArgb(BitConverter.ToInt32(p.raw, 32)); cp.Alpha = color.A; cp.Red = color.R; cp.Green = color.G; cp.Blue = color.B; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, cp, typeof(ColorProp), false, true); } else if (structType == "Vector") { VectorProp vp = new VectorProp(); vp.name = structType; vp.nameindex = p.Value.IntValue; vp.X = BitConverter.ToSingle(p.raw, 32); vp.Y = BitConverter.ToSingle(p.raw, 36); vp.Z = BitConverter.ToSingle(p.raw, 40); pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, vp, typeof(VectorProp), false, true); } else if (structType == "Rotator") { RotatorProp rp = new RotatorProp(); rp.name = structType; rp.nameindex = p.Value.IntValue; rp.Pitch = BitConverter.ToInt32(p.raw, 32) * 360f / 65536f; rp.Yaw = BitConverter.ToInt32(p.raw, 36) * 360f / 65536f; rp.Roll = BitConverter.ToInt32(p.raw, 40) * 360f / 65536f; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, rp, typeof(RotatorProp), false, true); } else if (structType == "LinearColor") { LinearColorProp lcp = new LinearColorProp(); lcp.name = structType; lcp.nameindex = p.Value.IntValue; lcp.Red = BitConverter.ToSingle(p.raw, 32); lcp.Green = BitConverter.ToSingle(p.raw, 36); lcp.Blue = BitConverter.ToSingle(p.raw, 40); lcp.Alpha = BitConverter.ToSingle(p.raw, 44); pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, lcp, typeof(VectorProp), false, true); } else { StructProp ppp = new StructProp(); ppp.name = structType; ppp.nameindex = p.Value.IntValue; byte[] buf = new byte[p.Value.Array.Count()]; for (int i = 0; i < p.Value.Array.Count(); i++) { buf[i] = (byte)p.Value.Array[i].IntValue; } List <int> buf2 = new List <int>(); for (int i = 0; i < p.Value.Array.Count() / 4; i++) { buf2.Add(BitConverter.ToInt32(buf, i * 4)); } ppp.data = buf2.ToArray(); pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, ppp, typeof(StructProp), false, true); } break; default: pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, p.Value.IntValue, typeof(int), false, true); break; } return(pg); }
static PropertyValue ReadValue(IMEPackage pcc, byte[] raw, int start, int type) { PropertyValue v = new PropertyValue(); switch (pcc.getNameEntry(type)) { case "IntProperty": case "ObjectProperty": case "StringRefProperty": v.IntValue = BitConverter.ToInt32(raw, start); v.len = 4; break; case "NameProperty": v.IntValue = BitConverter.ToInt32(raw, start); var nameRef = new NameReference(); nameRef.Name = pcc.getNameEntry(v.IntValue); nameRef.count = BitConverter.ToInt32(raw, start + 4); if (nameRef.count > 0) nameRef.Name += "_" + (nameRef.count - 1); v.NameValue = nameRef; v.StringValue = nameRef.Name; v.len = 8; break; } return v; }
public static NameReference ReadNameReference(this Stream stream, IMEPackage pcc) { return(new NameReference(pcc.getNameEntry(stream.ReadInt32()), stream.ReadInt32())); }
public static CustomProperty PropertyToGrid(Property p, IMEPackage pcc) { string cat = p.TypeVal.ToString(); CustomProperty pg; NameProp pp; switch (p.TypeVal) { case PropertyType.BoolProperty : pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, (p.Value.IntValue == 1), typeof(bool), false, true); break; case PropertyType.FloatProperty: pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, p.Value.FloatValue, typeof(float), false, true); break; case PropertyType.ByteProperty: if (p.Size != 8) { pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, (byte)p.Value.IntValue, typeof(byte), false, true); } else { pp = new NameProp(); pp.name = pcc.getNameEntry(p.Value.IntValue); pp.nameindex = p.Value.IntValue; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, pp, typeof(NameProp), false, true); } break; case PropertyType.NameProperty: pp = new NameProp(); pp.name = pcc.getNameEntry(p.Value.IntValue); pp.nameindex = p.Value.IntValue; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, pp, typeof(NameProp), false, true); break; case PropertyType.ObjectProperty: ObjectProp ppo = new ObjectProp(); ppo.objectName = pcc.getObjectName(p.Value.IntValue); ppo.index = p.Value.IntValue; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, ppo, typeof(ObjectProp), false, true); break; case PropertyType.StrProperty: pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, p.Value.StringValue, typeof(string), false, true); break; case PropertyType.ArrayProperty: pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, BitConverter.ToInt32(p.raw,24) + " elements", typeof(string), false, true); break; case PropertyType.StructProperty: string structType = pcc.getNameEntry(p.Value.IntValue); if(structType == "Color") { ColorProp cp = new ColorProp(); cp.name = structType; cp.nameindex = p.Value.IntValue; System.Drawing.Color color = System.Drawing.Color.FromArgb(BitConverter.ToInt32(p.raw, 32)); cp.Alpha = color.A; cp.Red = color.R; cp.Green = color.G; cp.Blue = color.B; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, cp, typeof(ColorProp), false, true); } else if (structType == "Vector") { VectorProp vp = new VectorProp(); vp.name = structType; vp.nameindex = p.Value.IntValue; vp.X = BitConverter.ToSingle(p.raw, 32); vp.Y = BitConverter.ToSingle(p.raw, 36); vp.Z = BitConverter.ToSingle(p.raw, 40); pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, vp, typeof(VectorProp), false, true); } else if (structType == "Rotator") { RotatorProp rp = new RotatorProp(); rp.name = structType; rp.nameindex = p.Value.IntValue; rp.Pitch = BitConverter.ToInt32(p.raw, 32) * 360f / 65536f; rp.Yaw = BitConverter.ToInt32(p.raw, 36) * 360f / 65536f; rp.Roll = BitConverter.ToInt32(p.raw, 40) * 360f / 65536f; pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, rp, typeof(RotatorProp), false, true); } else if (structType == "LinearColor") { LinearColorProp lcp = new LinearColorProp(); lcp.name = structType; lcp.nameindex = p.Value.IntValue; lcp.Red = BitConverter.ToSingle(p.raw, 32); lcp.Green = BitConverter.ToSingle(p.raw, 36); lcp.Blue = BitConverter.ToSingle(p.raw, 40); lcp.Alpha = BitConverter.ToSingle(p.raw, 44); pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, lcp, typeof(VectorProp), false, true); } else { StructProp ppp = new StructProp(); ppp.name = structType; ppp.nameindex = p.Value.IntValue; byte[] buf = new byte[p.Value.Array.Count()]; for (int i = 0; i < p.Value.Array.Count(); i++) buf[i] = (byte)p.Value.Array[i].IntValue; List<int> buf2 = new List<int>(); for (int i = 0; i < p.Value.Array.Count() / 4; i++) buf2.Add(BitConverter.ToInt32(buf ,i * 4)); ppp.data = buf2.ToArray(); pg = new CustomProperty(pcc.getNameEntry(p.Name), cat, ppp, typeof(StructProp), false, true); } break; default: pg = new CustomProperty(pcc.getNameEntry(p.Name),cat,p.Value.IntValue,typeof(int),false,true); break; } return pg; }