public static byte[] getDefaultClassValue(ME3Package pcc, string className, bool fullProps = false) { if (Structs.ContainsKey(className)) { bool immutable = UnrealObjectInfo.isImmutable(className, MEGame.ME3); ClassInfo info = Structs[className]; try { string filepath = (Path.Combine(ME3Directory.gamePath, @"BIOGame\" + info.pccPath)); if (File.Exists(info.pccPath)) { filepath = info.pccPath; //Used for dynamic lookup } using (ME3Package importPCC = MEPackageHandler.OpenME3Package(filepath)) { byte[] buff; //Plane and CoverReference inherit from other structs, meaning they don't have default values (who knows why) //thus, I have hardcoded what those default values should be if (className == "Plane") { buff = PlaneDefault; } else if (className == "CoverReference") { buff = CoverReferenceDefault; } else { buff = importPCC.Exports[info.exportIndex].Data.Skip(0x24).ToArray(); } List <PropertyReader.Property> Props = PropertyReader.ReadProp(importPCC, buff, 0); MemoryStream m = new MemoryStream(); foreach (PropertyReader.Property p in Props) { string propName = importPCC.getNameEntry(p.Name); //check if property is transient, if so, skip (neither of the structs that inherit have transient props) if (info.properties.ContainsKey(propName) || propName == "None" || info.baseClass != "Class") { if (immutable && !fullProps) { PropertyReader.ImportImmutableProperty(pcc, importPCC, p, className, m, true); } else { PropertyReader.ImportProperty(pcc, importPCC, p, className, m, true); } } } return(m.ToArray()); } } catch (Exception) { return(null); } } else if (Classes.ContainsKey(className)) { ClassInfo info = Structs[className]; try { string filepath = (Path.Combine(ME3Directory.gamePath, @"BIOGame\" + info.pccPath)); if (File.Exists(info.pccPath)) { filepath = info.pccPath; //Used for dynamic lookup } using (ME3Package importPCC = MEPackageHandler.OpenME3Package(filepath)) { IExportEntry entry = pcc.Exports[info.exportIndex + 1]; List <PropertyReader.Property> Props = PropertyReader.getPropList(entry); MemoryStream m = new MemoryStream(entry.DataSize - 4); foreach (PropertyReader.Property p in Props) { if (!info.properties.ContainsKey(importPCC.getNameEntry(p.Name))) { //property is transient continue; } PropertyReader.ImportProperty(pcc, importPCC, p, className, m); } return(m.ToArray()); } } catch (Exception) { return(null); } } return(null); }
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.ToSingle(e.ChangedItem.Value).ToUnrealRotationUnits(); 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; }