public ME2BioConversation(ME2Package Pcc, int Index) { pcc = Pcc; MyIndex = Index; Memory = pcc.Exports[Index].Data; ReadData(); }
public TreeNode ToTree(int MyIndex, ME2Package pcc) { string s = ""; if (Text.Length != 0) { s = Text.Substring(0, Text.Length - 1); } TreeNode res = new TreeNode(MyIndex + " : " + s + " " + ME2TalkFiles.findDataById(refText)); TreeNode t = new TreeNode("Entry List"); for (int i = 0; i < EntryList.Count; i++) { t.Nodes.Add(i + " : " + EntryList[i]); } res.Nodes.Add(t); res.Nodes.Add("Listener Index : " + ListenerIndex); res.Nodes.Add("Unskippable : " + Unskippable); res.Nodes.Add("ReplyType : " + pcc.getNameEntry(ReplyTypeValue)); res.Nodes.Add("Text : " + Text); res.Nodes.Add("refText : " + refText + " " + ME2TalkFiles.findDataById(refText, true)); res.Nodes.Add("ConditionalFunc : " + ConditionalFunc); res.Nodes.Add("ConditionalParam : " + ConditionalParam); res.Nodes.Add("StateTransition : " + StateTransition); res.Nodes.Add("StateTransitionParam : " + StateTransitionParam); res.Nodes.Add("ExportID : " + ExportID); res.Nodes.Add("ScriptIndex : " + ScriptIndex); res.Nodes.Add("CameraIntimacy : " + CameraIntimacy); res.Nodes.Add("FireConditional : " + FireConditional); res.Nodes.Add("Ambient : " + Ambient); res.Nodes.Add("NonTextline : " + NonTextLine); res.Nodes.Add("IgnoreBodyGestures : " + IgnoreBodyGestures); res.Nodes.Add("GUIStyle : " + pcc.getNameEntry(GUIStyleValue)); return(res); }
private void openToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog d = new OpenFileDialog(); d.Filter = "*.pcc|*.pcc"; if (d.ShowDialog() == DialogResult.OK) { try { pcc = MEPackageHandler.OpenME2Package(d.FileName); Objects = new List <int>(); IReadOnlyList <IExportEntry> Exports = pcc.Exports; for (int i = 0; i < Exports.Count; i++) { if (Exports[i].ClassName == "FaceFXAnimSet") { Objects.Add(i); } } ListRefresh(); } catch (Exception ex) { MessageBox.Show("Error:\n" + ex.Message); } } }
public TreeNode ToTree(int MyIndex, ME2Package pcc) { string s = ""; if (Text.Length != 0) { s = Text.Substring(0, Text.Length - 1); } TreeNode res = new TreeNode(MyIndex + " : " + s + " " + ME2TalkFiles.findDataById(refText)); TreeNode t = new TreeNode("Reply List"); for (int i = 0; i < ReplyList.Count; i++) { EntryListReplyListStruct e = ReplyList[i]; string par = e.Paraphrase; if (par.Length != 0 && par[par.Length - 1] == '\0') { par = par.Substring(0, par.Length - 1); } t.Nodes.Add(i + " : " + par + " " + e.refParaphrase + " " + ME2TalkFiles.findDataById(e.refParaphrase) + " " + e.Index + " " + pcc.getNameEntry(e.CategoryValue)); } res.Nodes.Add(t); TreeNode t2 = new TreeNode("Speaker List"); for (int i = 0; i < SpeakerList.Count; i++) { t2.Nodes.Add(i + " : " + SpeakerList[i]); } res.Nodes.Add(t2); res.Nodes.Add("SpeakerIndex : " + SpeakerIndex); res.Nodes.Add("ListenerIndex : " + ListenerIndex); res.Nodes.Add("ConditionalFunc : " + ConditionalFunc); res.Nodes.Add("ConditionalParam : " + ConditionalParam); res.Nodes.Add("StateTransition : " + StateTransition); res.Nodes.Add("StateTransitionParam : " + StateTransitionParam); res.Nodes.Add("ExportID : " + ExportID); res.Nodes.Add("ScriptIndex : " + ScriptIndex); res.Nodes.Add("CameraIntimacy : " + CameraIntimacy); res.Nodes.Add("Skippable : " + Skippable); res.Nodes.Add("FireConditional : " + FireConditional); res.Nodes.Add("Ambient : " + Ambient); res.Nodes.Add("NonTextline : " + NonTextline); res.Nodes.Add("IgnoreBodyGestures : " + IgnoreBodyGestures); res.Nodes.Add("Text : " + Text); res.Nodes.Add("refText : " + refText + " " + ME2TalkFiles.findDataById(refText, true)); res.Nodes.Add("GUIStyle : " + pcc.getNameEntry(GUIStyleValue)); return(res); }
private static void generateEnumValues(int index, ME2Package pcc) { string enumName = pcc.Exports[index].ObjectName; if (!Enums.ContainsKey(enumName)) { List <string> values = new List <string>(); byte[] buff = pcc.Exports[index].Data; int count = BitConverter.ToInt32(buff, 20); for (int i = 0; i < count; i++) { values.Add(pcc.Names[BitConverter.ToInt32(buff, 24 + i * 8)]); } Enums.Add(enumName, values); } }
private static void generateEnumValues(int index, ME2Package pcc, Dictionary <string, List <NameReference> > NewEnums = null) { var enumTable = NewEnums ?? Enums; string enumName = pcc.Exports[index].ObjectName; if (!enumTable.ContainsKey(enumName)) { var values = new List <NameReference>(); byte[] buff = pcc.Exports[index].Data; int count = BitConverter.ToInt32(buff, 20); for (int i = 0; i < count; i++) { int enumValIndex = 24 + i * 8; values.Add(new NameReference(pcc.Names[BitConverter.ToInt32(buff, enumValIndex)], BitConverter.ToInt32(buff, enumValIndex + 4))); } enumTable.Add(enumName, values); } }
private static ClassInfo generateClassInfo(int index, ME2Package pcc) { ClassInfo info = new ClassInfo { baseClass = pcc.Exports[index].ClassParent, exportIndex = index }; if (pcc.FileName.Contains("BioGame")) { info.pccPath = new string(pcc.FileName.Skip(pcc.FileName.LastIndexOf("BioGame") + 8).ToArray()); } else { info.pccPath = pcc.FileName; //used for dynamic resolution of files outside the game directory. } foreach (IExportEntry entry in pcc.Exports) { if (entry.idxLink - 1 == index && entry.ClassName != "ScriptStruct" && entry.ClassName != "Enum" && entry.ClassName != "Function" && entry.ClassName != "Const" && entry.ClassName != "State") { //Skip if property is transient (only used during execution, will never be in game files) if (/*(BitConverter.ToUInt64(entry.Data, 24) & 0x0000000000002000) == 0 &&*/ !info.properties.ContainsKey(entry.ObjectName)) { PropertyInfo p = getProperty(pcc, entry); if (p != null) { info.properties.Add(entry.ObjectName, p); } } //else //{ // //Debug.WriteLine("Skipping property due to flag: " + entry.ObjectName); //} } } return(info); }
private static ClassInfo generateClassInfo(int index, ME2Package pcc) { ClassInfo info = new ClassInfo(); info.baseClass = pcc.Exports[index].ClassParent; foreach (ME2ExportEntry entry in pcc.Exports) { if (entry.idxLink - 1 == index && entry.ClassName != "ScriptStruct" && entry.ClassName != "Enum" && entry.ClassName != "Function" && entry.ClassName != "Const" && entry.ClassName != "State") { //Skip if property is transient (only used during execution, will never be in game files) if ((BitConverter.ToUInt64(entry.Data, 24) & 0x0000000000002000) == 0 && !info.properties.ContainsKey(entry.ObjectName)) { PropertyInfo p = getProperty(pcc, entry); if (p != null) { info.properties.Add(entry.ObjectName, p); } } } } return(info); }
private static PropertyInfo getProperty(ME2Package pcc, IExportEntry entry) { PropertyInfo p = new PropertyInfo(); switch (entry.ClassName) { case "IntProperty": p.type = PropertyType.IntProperty; break; case "StringRefProperty": p.type = PropertyType.StringRefProperty; break; case "FloatProperty": p.type = PropertyType.FloatProperty; break; case "BoolProperty": p.type = PropertyType.BoolProperty; break; case "StrProperty": p.type = PropertyType.StrProperty; break; case "NameProperty": p.type = PropertyType.NameProperty; break; case "DelegateProperty": p.type = PropertyType.DelegateProperty; break; case "ObjectProperty": p.type = PropertyType.ObjectProperty; p.reference = pcc.getObjectName(BitConverter.ToInt32(entry.Data, entry.Data.Length - 4)); break; case "StructProperty": p.type = PropertyType.StructProperty; p.reference = pcc.getObjectName(BitConverter.ToInt32(entry.Data, entry.Data.Length - 4)); break; case "BioMask4Property": case "ByteProperty": p.type = PropertyType.ByteProperty; p.reference = pcc.getObjectName(BitConverter.ToInt32(entry.Data, entry.Data.Length - 4)); break; case "ArrayProperty": p.type = PropertyType.ArrayProperty; PropertyInfo arrayTypeProp = getProperty(pcc, pcc.Exports[BitConverter.ToInt32(entry.Data, 44) - 1]); if (arrayTypeProp != null) { switch (arrayTypeProp.type) { case PropertyType.ObjectProperty: case PropertyType.StructProperty: case PropertyType.ArrayProperty: p.reference = arrayTypeProp.reference; break; case PropertyType.ByteProperty: if (arrayTypeProp.reference == "") { p.reference = arrayTypeProp.type.ToString(); } else { p.reference = arrayTypeProp.reference; } break; case PropertyType.IntProperty: case PropertyType.FloatProperty: case PropertyType.NameProperty: case PropertyType.BoolProperty: case PropertyType.StrProperty: case PropertyType.StringRefProperty: case PropertyType.DelegateProperty: p.reference = arrayTypeProp.type.ToString(); break; case PropertyType.None: case PropertyType.Unknown: default: System.Diagnostics.Debugger.Break(); p = null; break; } } else { p = null; } break; case "ClassProperty": case "InterfaceProperty": case "ComponentProperty": default: p = null; break; } return(p); }
//call this method to regenerate ME2ObjectInfo.json //Takes a long time (10 minutes maybe?). Application will be completely unresponsive during that time. public static void generateInfo() { var NewClasses = new Dictionary <string, ClassInfo>(); var NewStructs = new Dictionary <string, ClassInfo>(); var NewEnums = new Dictionary <string, List <NameReference> >(); string path = ME2Directory.gamePath; string[] files = Directory.GetFiles(path, "*.pcc", SearchOption.AllDirectories); foreach (string file in files) { if (file.ToLower().EndsWith(".pcc") /* && file.Contains("Engine")*/) { using (ME2Package pcc = MEPackageHandler.OpenME2Package(file)) { IReadOnlyList <IExportEntry> Exports = pcc.Exports; for (int j = 0; j < Exports.Count; j++) { IExportEntry exportEntry = Exports[j]; if (exportEntry.ClassName == "Enum") { generateEnumValues(j, pcc, NewEnums); } else if (exportEntry.ClassName == "Class") { string objectName = exportEntry.ObjectName; if (!NewClasses.ContainsKey(objectName)) { NewClasses.Add(objectName, generateClassInfo(j, pcc)); } } else if (exportEntry.ClassName == "ScriptStruct") { string objectName = exportEntry.ObjectName; if (!NewStructs.ContainsKey(objectName)) { NewStructs.Add(objectName, generateClassInfo(j, pcc)); } } } Debug.WriteLine("Releasing " + pcc.FileName); } } } //CUSTOM ADDITIONS ClassInfo info = new ClassInfo { baseClass = "Texture2D", exportIndex = 0, pccPath = "ME3Explorer_CustomNativeAdditions" }; try { NewClasses.Add("LightMapTexture2D", info); } catch (Exception) { } //SFXPhysicalMaterialDecals missing items ClassInfo sfxpmd = Classes["SFXPhysicalMaterialDecals"]; string[] decalComponentArrays = { "HeavyPistol", "AutoPistol", "HandCannon", "SMG", "Shotgun", "HeavyShotgun", "FlakGun", "AssaultRifle", "Needler", "Machinegun", "SniperRifle", "AntiMatRifle", "MassCannon", "ParticleBeam" }; foreach (string decal in decalComponentArrays) { sfxpmd.properties[decal] = new PropertyInfo { type = PropertyType.ArrayProperty, reference = "DecalComponent" }; } ClassInfo sfxweapon = Classes["SFXWeapon"]; sfxpmd.properties["InstantHitDamageTypes"] = new PropertyInfo { type = PropertyType.ArrayProperty, reference = "Class" }; File.WriteAllText(jsonPath, JsonConvert.SerializeObject(new { Classes = NewClasses, Structs = NewStructs, Enums = NewEnums }, Formatting.Indented)); MessageBox.Show("Done"); }
public static PropertyCollection getDefaultStructValue(string className, bool stripTransients = true) { if (Structs.ContainsKey(className)) { bool immutable = UnrealObjectInfo.isImmutable(className, MEGame.ME2); ClassInfo info = Structs[className]; try { if (info.pccPath != "ME3Explorer_CustomNativeAdditions") { string filepath = (Path.Combine(ME2Directory.gamePath, @"BioGame\" + info.pccPath)); if (File.Exists(info.pccPath)) { filepath = info.pccPath; //Used for dynamic lookup } using (ME2Package importPCC = MEPackageHandler.OpenME2Package(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 { var exportToRead = importPCC.Exports[info.exportIndex]; buff = exportToRead.Data.Skip(0x30).ToArray(); } PropertyCollection props = PropertyCollection.ReadProps(importPCC, new MemoryStream(buff), className); if (stripTransients) { var toRemove = new List <UProperty>(); foreach (var prop in props) { //remove transient props if (info.properties.TryGetValue(prop.Name, out PropertyInfo propInfo)) { if (propInfo.transient) { toRemove.Add(prop); } } //if (!info.properties.ContainsKey(prop.Name) && info.baseClass == "Class") //{ // toRemove.Add(prop); //} } foreach (var prop in toRemove) { Debug.WriteLine($"ME2: Get Default Struct value ({className}) - removing transient prop: {prop.Name}"); props.Remove(prop); } } return(props); } } } catch { return(null); } } return(null); }