コード例 #1
0
        public static void ImportProperty(PCCObject pcc, PCCObject importpcc, Property p, string className, System.IO.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);
                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":
                name2    = importpcc.getNameEntry(BitConverter.ToInt32(p.raw, 24));
                idxname2 = pcc.FindNameOrAdd(name2);
                m.Write(BitConverter.GetBytes(p.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 (p.Size == 8)
                {
                    m.Write(BitConverter.GetBytes(pcc.FindNameOrAdd(importpcc.getNameEntry(p.Value.IntValue))), 0, 4);
                    m.Write(new byte[4], 0, 4);
                }
                else
                {
                    m.WriteByte(p.raw[32]);
                }
                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;
                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);
                }
                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 == Type.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);
                UnrealObjectInfo.PropertyInfo info      = UnrealObjectInfo.getPropertyInfo(className, name, inStruct);
                UnrealObjectInfo.ArrayType    arrayType = UnrealObjectInfo.getArrayType(info);
                pos = 28;
                List <Property> AllProps = new List <Property>();

                if (arrayType == UnrealObjectInfo.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)))
                {
                    foreach (Property pp in AllProps)
                    {
                        ImportProperty(pcc, importpcc, pp, className, m, inStruct);
                    }
                }
                else if (arrayType == UnrealObjectInfo.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);
            }
        }
コード例 #2
0
 public void GenerateTree(TreeNode localRoot, List <PropHeader> headersList)
 {
     foreach (PropHeader header in headersList)
     {
         if (readerpos > memory.Length)
         {
             throw new IndexOutOfRangeException(": tried to read past bounds of Export Data");
         }
         nodeType type = getType(pcc.getNameEntry(header.type));
         if (type != nodeType.ArrayProperty && type != nodeType.StructProperty)
         {
             localRoot.Nodes.Add(GenerateNode(header));
         }
         else
         {
             if (type == nodeType.ArrayProperty)
             {
                 TreeNode t           = GenerateNode(header);
                 int      arrayLength = BitConverter.ToInt32(memory, header.offset + 24);
                 readerpos = header.offset + 28;
                 int tmp = readerpos;
                 UnrealObjectInfo.ArrayType arrayType;
                 try
                 {
                     arrayType = UnrealObjectInfo.getArrayType(className, pcc.getNameEntry(header.name));
                 }
                 catch (Exception)
                 {
                     arrayType = UnrealObjectInfo.ArrayType.Int;
                 }
                 if (arrayType == UnrealObjectInfo.ArrayType.Struct)
                 {
                     UnrealObjectInfo.PropertyInfo info = UnrealObjectInfo.getPropertyInfo(className, pcc.getNameEntry(header.name));
                     t.Text = t.Text.Insert(t.Text.IndexOf("Size: ") - 2, $"({info.reference})");
                     for (int i = 0; i < arrayLength; i++)
                     {
                         readerpos = tmp;
                         int pos = tmp;
                         List <PropHeader> arrayListPropHeaders = ReadHeadersTillNone();
                         tmp = readerpos;
                         TreeNode n = new TreeNode(i.ToString());
                         n.Tag  = nodeType.ArrayLeafStruct;
                         n.Name = (-pos).ToString();
                         t.Nodes.Add(n);
                         n = t.LastNode;
                         if (info != null && (UnrealObjectInfo.isImmutable(info.reference) || arrayListPropHeaders.Count == 0))
                         {
                             readerpos = pos;
                             GenerateSpecialStruct(n, info.reference, header.size / arrayLength);
                             tmp = readerpos;
                         }
                         else if (arrayListPropHeaders.Count > 0)
                         {
                             GenerateTree(n, arrayListPropHeaders);
                         }
                         else
                         {
                             throw new Exception($"at position {readerpos.ToString("X4")}. Could not read element {i} of ArrayProperty {pcc.getNameEntry(header.name)}");
                         }
                         t.LastNode.Remove();
                         t.Nodes.Add(n);
                     }
                     localRoot.Nodes.Add(t);
                 }
                 else
                 {
                     t.Text = t.Text.Insert(t.Text.IndexOf("Size: ") - 2, $"({arrayType.ToString()})");
                     int count = 0;
                     int pos;
                     for (int i = 0; i < (header.size - 4); count++)
                     {
                         pos = header.offset + 28 + i;
                         if (pos > memory.Length)
                         {
                             throw new Exception(": tried to read past bounds of Export Data");
                         }
                         int      val  = BitConverter.ToInt32(memory, pos);
                         string   s    = pos.ToString("X4") + "|" + count + ": ";
                         TreeNode node = new TreeNode();
                         node.Name = pos.ToString();
                         if (arrayType == UnrealObjectInfo.ArrayType.Object)
                         {
                             node.Tag = nodeType.ArrayLeafObject;
                             int value = val;
                             if (value == 0)
                             {
                                 //invalid
                                 s += "Null [" + value + "] ";
                             }
                             else
                             {
                                 bool isImport = value < 0;
                                 if (isImport)
                                 {
                                     value = -value;
                                 }
                                 value--; //0-indexed
                                 if (isImport)
                                 {
                                     if (pcc.Imports.Count > value)
                                     {
                                         s += pcc.Imports[value].PackageFullName + "." + pcc.Imports[value].ObjectName + " [IMPORT " + value + "]";
                                     }
                                     else
                                     {
                                         s += "Index not in import list [" + value + "]";
                                     }
                                 }
                                 else
                                 {
                                     if (pcc.Exports.Count > value)
                                     {
                                         s += pcc.Exports[value].PackageFullName + "." + pcc.Exports[value].ObjectName + " [EXPORT " + value + "]";
                                     }
                                     else
                                     {
                                         s += "Index not in export list [" + value + "]";
                                     }
                                 }
                             }
                             i += 4;
                         }
                         else if (arrayType == UnrealObjectInfo.ArrayType.Name || arrayType == UnrealObjectInfo.ArrayType.Enum)
                         {
                             node.Tag = arrayType == UnrealObjectInfo.ArrayType.Name ? nodeType.ArrayLeafName : nodeType.ArrayLeafEnum;
                             int value = val;
                             if (value < 0)
                             {
                                 s += "Invalid Name Index [" + value + "]";
                             }
                             else
                             {
                                 if (pcc.Names.Count > value)
                                 {
                                     s += $"\"{pcc.Names[value]}\"_{BitConverter.ToInt32(memory, pos + 4)}[NAMEINDEX {value}]";
                                 }
                                 else
                                 {
                                     s += "Index not in name list [" + value + "]";
                                 }
                             }
                             i += 8;
                         }
                         else if (arrayType == UnrealObjectInfo.ArrayType.Float)
                         {
                             node.Tag = nodeType.ArrayLeafFloat;
                             s       += BitConverter.ToSingle(memory, pos).ToString("0.0######");
                             i       += 4;
                         }
                         else if (arrayType == UnrealObjectInfo.ArrayType.Byte)
                         {
                             node.Tag = nodeType.ArrayLeafByte;
                             s       += "(byte)" + memory[pos];
                             i       += 1;
                         }
                         else if (arrayType == UnrealObjectInfo.ArrayType.Bool)
                         {
                             node.Tag = nodeType.ArrayLeafBool;
                             s       += BitConverter.ToBoolean(memory, pos);
                             i       += 1;
                         }
                         else if (arrayType == UnrealObjectInfo.ArrayType.String)
                         {
                             node.Tag = nodeType.ArrayLeafString;
                             int sPos = pos + 4;
                             s += "\"";
                             int len = val > 0 ? val : -val;
                             for (int j = 1; j < len; j++)
                             {
                                 s    += BitConverter.ToChar(memory, sPos);
                                 sPos += 2;
                             }
                             s += "\"";
                             i += (len * 2) + 4;
                         }
                         else
                         {
                             node.Tag = nodeType.ArrayLeafInt;
                             s       += val.ToString();
                             i       += 4;
                         }
                         node.Text = s;
                         t.Nodes.Add(node);
                     }
                     localRoot.Nodes.Add(t);
                 }
             }
             if (type == nodeType.StructProperty)
             {
                 TreeNode t = GenerateNode(header);
                 readerpos = header.offset + 32;
                 List <PropHeader> ll = ReadHeadersTillNone();
                 if (ll.Count != 0)
                 {
                     GenerateTree(t, ll);
                 }
                 else
                 {
                     string structType = pcc.getNameEntry(BitConverter.ToInt32(memory, header.offset + 24));
                     GenerateSpecialStruct(t, structType, header.size);
                 }
                 localRoot.Nodes.Add(t);
             }
         }
     }
 }