public TreeNode GenerateNode(PropHeader p) { string s = p.offset.ToString("X4") + ": "; s += "Name: \"" + pcc.getNameEntry(p.name) + "\" "; s += "Type: \"" + pcc.getNameEntry(p.type) + "\" "; s += "Size: " + p.size.ToString() + " Value: "; nodeType propertyType = getType(pcc.getNameEntry(p.type)); int idx; byte val; switch (propertyType) { case nodeType.IntProperty: idx = BitConverter.ToInt32(memory, p.offset + 24); s += idx.ToString(); break; case nodeType.ObjectProperty: idx = BitConverter.ToInt32(memory, p.offset + 24); s += idx.ToString() + " (" + pcc.getObjectName(idx) + ")"; break; case nodeType.StrProperty: int count = BitConverter.ToInt32(memory, p.offset + 24); s += "\""; for (int i = 0; i < count * -1 - 1; i++) { s += (char)memory[p.offset + 28 + i * 2]; } s += "\""; break; case nodeType.BoolProperty: val = memory[p.offset + 24]; s += (val == 1).ToString(); break; case nodeType.FloatProperty: float f = BitConverter.ToSingle(memory, p.offset + 24); s += f.ToString("0.0######"); break; case nodeType.NameProperty: idx = BitConverter.ToInt32(memory, p.offset + 24); s += "\"" + pcc.getNameEntry(idx) + "\"_" + BitConverter.ToInt32(memory, p.offset + 28); break; case nodeType.StructProperty: idx = BitConverter.ToInt32(memory, p.offset + 24); s += "\"" + pcc.getNameEntry(idx) + "\""; break; case nodeType.ByteProperty: if (p.size == 1) { val = memory[p.offset + 32]; s += val.ToString(); } else { idx = BitConverter.ToInt32(memory, p.offset + 24); int idx2 = BitConverter.ToInt32(memory, p.offset + 32); s += "\"" + pcc.getNameEntry(idx) + "\",\"" + pcc.getNameEntry(idx2) + "\""; } break; case nodeType.ArrayProperty: idx = BitConverter.ToInt32(memory, p.offset + 24); s += idx.ToString() + "(count)"; break; case nodeType.StringRefProperty: idx = BitConverter.ToInt32(memory, p.offset + 24); s += "#" + idx.ToString() + ": "; s += TalkFiles.tlkList.Count == 0 ? "(.tlk not loaded)" : TalkFiles.findDataById(idx); break; } TreeNode ret = new TreeNode(s); ret.Tag = propertyType; ret.Name = p.offset.ToString(); return(ret); }
private int GenerateSpecialStructProp(TreeNode t, string s, int pos, PropertyReader.Property prop) { if (pos > memory.Length) { throw new Exception(": tried to read past bounds of Export Data"); } int n; TreeNode node; UnrealObjectInfo.PropertyInfo propInfo; switch (prop.TypeVal) { case PropertyReader.Type.FloatProperty: s += BitConverter.ToSingle(memory, pos).ToString("0.0######"); node = new TreeNode(s); node.Name = pos.ToString(); node.Tag = nodeType.StructLeafFloat; t.Nodes.Add(node); pos += 4; break; case PropertyReader.Type.IntProperty: s += BitConverter.ToInt32(memory, pos).ToString(); node = new TreeNode(s); node.Name = pos.ToString(); node.Tag = nodeType.StructLeafInt; t.Nodes.Add(node); pos += 4; break; case PropertyReader.Type.ObjectProperty: n = BitConverter.ToInt32(memory, pos); s += n + " (" + pcc.getObjectName(n) + ")"; node = new TreeNode(s); node.Name = pos.ToString(); node.Tag = nodeType.StructLeafObject; t.Nodes.Add(node); pos += 4; break; case PropertyReader.Type.StringRefProperty: n = BitConverter.ToInt32(memory, pos); s += "#" + n + ": "; s += TalkFiles.tlkList.Count == 0 ? "(.tlk not loaded)" : TalkFiles.findDataById(n); node = new TreeNode(s); node.Name = pos.ToString(); node.Tag = nodeType.StructLeafInt; t.Nodes.Add(node); pos += 4; break; case PropertyReader.Type.NameProperty: n = BitConverter.ToInt32(memory, pos); pos += 4; s += "\"" + pcc.getNameEntry(n) + "\"_" + BitConverter.ToInt32(memory, pos); node = new TreeNode(s); node.Name = pos.ToString(); node.Tag = nodeType.StructLeafName; t.Nodes.Add(node); pos += 4; break; case PropertyReader.Type.BoolProperty: s += (memory[pos] > 0).ToString(); node = new TreeNode(s); node.Name = pos.ToString(); node.Tag = nodeType.StructLeafBool; t.Nodes.Add(node); pos += 1; break; case PropertyReader.Type.ByteProperty: if (prop.Size != 1) { string enumName = UnrealObjectInfo.getPropertyInfo(className, pcc.getNameEntry(prop.Name))?.reference; if (enumName != null) { s += "\"" + enumName + "\", "; } s += "\"" + pcc.getNameEntry(BitConverter.ToInt32(memory, pos)) + "\""; node = new TreeNode(s); node.Name = pos.ToString(); node.Tag = nodeType.StructLeafEnum; t.Nodes.Add(node); pos += 8; } else { s += "(byte)" + memory[pos].ToString(); node = new TreeNode(s); node.Name = pos.ToString(); node.Tag = nodeType.StructLeafByte; t.Nodes.Add(node); pos += 1; } break; case PropertyReader.Type.StrProperty: n = BitConverter.ToInt32(memory, pos); pos += 4; s += "\""; for (int i = 0; i < n - 1; i++) { s += (char)memory[pos + i * 2]; } s += "\""; node = new TreeNode(s); node.Name = pos.ToString(); node.Tag = nodeType.StructLeafStr; t.Nodes.Add(node); pos += n * 2; break; case PropertyReader.Type.ArrayProperty: n = BitConverter.ToInt32(memory, pos); s += n + " elements"; node = new TreeNode(s); node.Name = pos.ToString(); node.Tag = nodeType.StructLeafArray; pos += 4; propInfo = UnrealObjectInfo.getPropertyInfo(className, pcc.getNameEntry(prop.Name)); UnrealObjectInfo.ArrayType arrayType = UnrealObjectInfo.getArrayType(propInfo); TreeNode node2; string s2; for (int i = 0; i < n; i++) { if (arrayType == UnrealObjectInfo.ArrayType.Struct) { readerpos = pos; node2 = new TreeNode(i + ": (" + propInfo.reference + ")"); node2.Name = (-pos).ToString(); node2.Tag = nodeType.StructLeafStruct; GenerateSpecialStruct(node2, propInfo.reference, 0); node.Nodes.Add(node2); pos = readerpos; } else { s2 = ""; PropertyReader.Type type = PropertyReader.Type.None; int size = 0; switch (arrayType) { case UnrealObjectInfo.ArrayType.Object: type = PropertyReader.Type.ObjectProperty; break; case UnrealObjectInfo.ArrayType.Name: type = PropertyReader.Type.NameProperty; break; case UnrealObjectInfo.ArrayType.Byte: type = PropertyReader.Type.ByteProperty; size = 1; break; case UnrealObjectInfo.ArrayType.Enum: type = PropertyReader.Type.ByteProperty; break; case UnrealObjectInfo.ArrayType.Bool: type = PropertyReader.Type.BoolProperty; break; case UnrealObjectInfo.ArrayType.String: type = PropertyReader.Type.StrProperty; break; case UnrealObjectInfo.ArrayType.Float: type = PropertyReader.Type.FloatProperty; break; case UnrealObjectInfo.ArrayType.Int: type = PropertyReader.Type.IntProperty; break; } pos = GenerateSpecialStructProp(node, s2, pos, new PropertyReader.Property { TypeVal = type, Size = size }); } } t.Nodes.Add(node); break; case PropertyReader.Type.StructProperty: propInfo = UnrealObjectInfo.getPropertyInfo(className, pcc.getNameEntry(prop.Name)); s += propInfo.reference; node = new TreeNode(s); node.Name = (-pos).ToString(); node.Tag = nodeType.StructLeafStruct; readerpos = pos; GenerateSpecialStruct(node, propInfo.reference, 0); pos = readerpos; t.Nodes.Add(node); break; case PropertyReader.Type.DelegateProperty: throw new NotImplementedException($"at position {pos.ToString("X4")}: cannot read Delegate property of Immutable struct"); case PropertyReader.Type.Unknown: throw new NotImplementedException($"at position {pos.ToString("X4")}: cannot read Unkown property of Immutable struct"); case PropertyReader.Type.None: default: break; } return(pos); }