Esempio n. 1
0
        public void TestCDOModification()
        {
            var tester = new UAsset(Path.Combine("TestManyAssets", "Astroneer", "Augment_BroadBrush.uasset"), UE4Version.VER_UE4_23);

            Assert.IsTrue(tester.VerifyBinaryEquality());

            NormalExport cdoExport = null;

            foreach (Export testExport in tester.Exports)
            {
                if (testExport.ObjectFlags.HasFlag(EObjectFlags.RF_ClassDefaultObject))
                {
                    cdoExport = (NormalExport)testExport;
                    break;
                }
            }
            Assert.IsNotNull(cdoExport);

            cdoExport["PickupActor"] = new ObjectPropertyData()
            {
                Value = FPackageIndex.FromRawIndex(0)
            };

            Assert.IsTrue(cdoExport["PickupActor"] is ObjectPropertyData);
            Assert.IsTrue(((ObjectPropertyData)cdoExport["PickupActor"]).Value.Index == 0);
        }
Esempio n. 2
0
        public static PropertyData TypeToClass(string type, string name, AssetReader asset, BinaryReader reader = null, long leng = 0, bool includeHeader = true)
        {
            //Debug.WriteLine(type);
            PropertyData data;

            switch (type)
            {
            case "BoolProperty":
                data = new BoolPropertyData(name, asset);
                break;

            case "Int8Property":
                data = new Int8PropertyData(name, asset);
                break;

            case "Int16Property":
                data = new Int16PropertyData(name, asset);
                break;

            case "IntProperty":
                data = new IntPropertyData(name, asset);
                break;

            case "Int64Property":
                data = new Int64PropertyData(name, asset);
                break;

            case "UInt16Property":
                data = new UInt16PropertyData(name, asset);
                break;

            case "UInt32Property":
                data = new UInt32PropertyData(name, asset);
                break;

            case "UInt64Property":
                data = new UInt64PropertyData(name, asset);
                break;

            case "FloatProperty":
                data = new FloatPropertyData(name, asset);
                break;

            case "TextProperty":
                data = new TextPropertyData(name, asset);
                break;

            case "StrProperty":
                data = new StrPropertyData(name, asset);
                break;

            case "ObjectProperty":
                data = new ObjectPropertyData(name, asset);
                break;

            case "EnumProperty":
                data = new EnumPropertyData(name, asset);
                break;

            case "ByteProperty":
                data = new BytePropertyData(name, asset);
                break;

            case "NameProperty":
                data = new NamePropertyData(name, asset);
                break;

            case "ArrayProperty":
                data = new ArrayPropertyData(name, asset);
                break;

            case "MapProperty":
                data = new MapPropertyData(name, asset);
                break;

            case "StructProperty":
                data = new StructPropertyData(name, asset);
                break;

            case "Guid":
                data = new GuidPropertyData(name, asset);
                break;

            case "LinearColor":
                data = new LinearColorPropertyData(name, asset);
                break;

            case "Color":
                data = new ColorPropertyData(name, asset);
                break;

            case "Vector":
                data = new VectorPropertyData(name, asset);
                break;

            case "Vector2D":
                data = new Vector2DPropertyData(name, asset);
                break;

            case "Box":
                data = new BoxPropertyData(name, asset);
                break;

            case "IntPoint":
                data = new IntPointPropertyData(name, asset);
                break;

            case "DateTime":
                data = new DateTimePropertyData(name, asset);
                break;

            case "Timespan":
                data = new TimespanPropertyData(name, asset);
                break;

            case "Rotator":
                data = new RotatorPropertyData(name, asset);
                break;

            case "Quat":
                data = new QuatPropertyData(name, asset);
                break;

            case "Vector4":
                data = new Vector4PropertyData(name, asset);
                break;

            case "SoftObjectProperty":
                data = new SoftObjectPropertyData(name, asset);
                break;

            case "MulticastDelegateProperty":
                data = new MulticastDelegatePropertyData(name, asset);
                break;

            default:
#if DEBUG
                Debug.WriteLine("Last type: " + lastType);
#endif
                if (reader == null)
                {
                    throw new FormatException("Unknown property type: " + type + " (on " + name + ")");
                }
                throw new FormatException("Unknown property type: " + type + " (on " + name + " at " + reader.BaseStream.Position + ")");
            }
#if DEBUG
            lastType = type;
#endif
            if (reader != null)
            {
                data.Read(reader, includeHeader, leng);
            }
            return(data);
        }
Esempio n. 3
0
        public MemoryStream Bake(string[] newComponents, byte[] superRawData)
        {
            BinaryReader yReader = new BinaryReader(new MemoryStream(superRawData));
            AssetWriter  y       = new AssetWriter
            {
                WillStoreOriginalCopyInMemory = true, WillWriteSectionSix = true, data = new AssetReader()
            };

            y.data.Read(yReader);
            y.OriginalCopy = superRawData;

            int scsLocation = -1;
            int bgcLocation = -1;

            for (int i = 0; i < y.data.categories.Count; i++)
            {
                Category baseUs = y.data.categories[i];
                if (baseUs is NormalCategory us)
                {
                    switch (y.data.GetHeaderReference(y.data.GetLinkReference(us.ReferenceData.connection)))
                    {
                    case "SimpleConstructionScript":
                        scsLocation = i;
                        break;

                    case "BlueprintGeneratedClass":
                        bgcLocation = i;
                        break;
                    }
                }
            }
            if (scsLocation < 0)
            {
                throw new FormatException("Unable to find SimpleConstructionScript");
            }
            if (bgcLocation < 0)
            {
                throw new FormatException("Unable to find BlueprintGeneratedClass");
            }

            int objectPropertyLink = y.data.SearchForLink((ulong)y.data.SearchHeaderReference("/Script/CoreUObject"), (ulong)y.data.SearchHeaderReference("Class"), (ulong)y.data.SearchHeaderReference("ObjectProperty"));
            int scsNodeLink        = y.data.SearchForLink((ulong)y.data.SearchHeaderReference("/Script/CoreUObject"), (ulong)y.data.SearchHeaderReference("Class"), (ulong)y.data.SearchHeaderReference("SCS_Node"));

            byte[] noneRef = BitConverter.GetBytes((long)y.data.SearchHeaderReference("None"));

            y.data.AddHeaderReference("bAutoActivate");
            foreach (string componentPathRaw in newComponents)
            {
                CategoryReference refData1 = new CategoryReference(refData1B);
                CategoryReference refData2 = new CategoryReference(refData2B);
                CategoryReference refData3 = new CategoryReference(refData3B);

                string componentPath = componentPathRaw;
                string component     = Path.GetFileNameWithoutExtension(componentPathRaw);
                if (componentPathRaw.Contains("."))
                {
                    string[] tData = componentPathRaw.Split(new char[] { '.' });
                    componentPath = tData[0];
                    component     = tData[1].Remove(tData[1].Length - 2);
                }
                y.data.AddHeaderReference(componentPath);
                y.data.AddHeaderReference(component + "_C");

                Link newLink    = new Link("/Script/Engine", "BlueprintGeneratedClass", y.data.AddLink("/Script/CoreUObject", "Package", 0, componentPath).Index, component + "_C", y.data);
                int  bigNewLink = y.data.AddLink(newLink);
                refData2.connection = bigNewLink;
                refData2.typeIndex  = y.data.AddHeaderReference(component + "_GEN_VARIABLE");

                refData1.connection = objectPropertyLink;
                refData1.typeIndex  = y.data.AddHeaderReference(component);

                refData3.connection = scsNodeLink;
                refData3.typeIndex  = y.data.AddHeaderReference("SCS_Node");

                List <byte> rawData = new List <byte>();

                // Here we specify the raw data for our ObjectProperty category, including necessary flags and such
                rawData.AddRange(noneRef);
                rawData.AddRange(new byte[] {
                    0x00,
                    0x00,
                    0x00,
                    0x00,
                    0x01,
                    0x00,
                    0x00,
                    0x00,

                    0x04,
                    0x00,
                    0x00,
                    0x00,
                    0x04,
                    0x00,
                    0x00,
                    0x00,
                });
                rawData.AddRange(noneRef);
                rawData.Add((byte)0);
                rawData.AddRange(BitConverter.GetBytes((int)bigNewLink));

                refData1.link = bgcLocation + 1; // BlueprintGeneratedClass category
                refData2.link = bgcLocation + 1; // BlueprintGeneratedClass category
                refData3.link = scsLocation + 1;

                // Note that category links are set to one more than you'd think since categories in the category list index from 1 instead of 0

                // First we add the template category
                y.data.categories.Add(new NormalCategory(new List <PropertyData>
                {
                    new BoolPropertyData("bAutoActivate", y.data)
                    {
                        Value = true
                    }
                }, refData2, y.data, new byte[4] {
                    0, 0, 0, 0
                }));

                // Then the ObjectProperty category
                y.data.categories.Add(new RawCategory(rawData.ToArray(), refData1, y.data, new byte[0]));

                // Then the SCS_Node
                y.data.categories.Add(new NormalCategory(new List <PropertyData>
                {
                    new ObjectPropertyData("ComponentClass", y.data)
                    {
                        LinkValue = bigNewLink
                    },
                    new ObjectPropertyData("ComponentTemplate", y.data)
                    {
                        LinkValue = y.data.categories.Count - 1 // the first NormalCategory
                    },
                    new StructPropertyData("VariableGuid", y.data, "Guid")
                    {
                        Value = new List <PropertyData>
                        {
                            new GuidPropertyData("VariableGuid", y.data)
                            {
                                Value = Guid.NewGuid()
                            }
                        }
                    },
                    new NamePropertyData("InternalVariableName", y.data)
                    {
                        Value  = component,
                        Value2 = 0
                    }
                }, refData3, y.data, new byte[4] {
                    0, 0, 0, 0
                }));

                // We update the BlueprintGeneratedClass data to include our new ActorComponent
                ((BlueprintGeneratedClassCategory)y.data.categories[bgcLocation]).IndexData.Add(y.data.categories.Count - 1); // the RawCategory

                // Here we update the SimpleConstructionScript so that the parser constructs our new ActorComponent
                NormalCategory scsCategory = (NormalCategory)y.data.categories[scsLocation];
                for (int j = 0; j < scsCategory.Data.Count; j++)
                {
                    PropertyData bit = scsCategory.Data[j];
                    if (bit.Type.Equals("ArrayProperty"))
                    {
                        switch (bit.Name)
                        {
                        case "AllNodes":
                        case "RootNodes":
                            PropertyData[] ourArr  = ((ArrayPropertyData)bit).Value;
                            int            oldSize = ourArr.Length;
                            Array.Resize(ref ourArr, oldSize + 1);
                            refData3.garbage1 = oldSize + 2;
                            ourArr[oldSize]   = new ObjectPropertyData(bit.Name, y.data)
                            {
                                LinkValue = y.data.categories.Count     // the SCS_Node
                            };
                            ((ArrayPropertyData)bit).Value = ourArr;
                            break;
                        }
                    }
                }
            }

            return(y.WriteData(new BinaryReader(new MemoryStream(y.OriginalCopy))));
        }
Esempio n. 4
0
        /*
         *  Game plan:
         *  1. Find the Level category
         *  2. Find the link with the Property SceneComponent
         *  3. Dig into the vanilla pak and the mod pak, try to find the connecting actor, add its nodes in the SimpleConstructionScript under BlueprintCreatedComponents (garbage1 = 0 no problem)
         *  4. Create the SceneComponent (garbage1 = 0), no RelativeLocation or UCSModifiedProperties, CreationMethod = EComponentCreationMethod::SimpleConstructionScript, bNetAddressable = 1
         *  5. Create the new Actor_C category, set its Linkage to the Level category, set the garbage1 to 0 (maybe random number idk), DefaultSceneRoot & RootComponent = the matching SceneComponent
         */

        public MemoryStream Bake(string[] newComponents, string[] newTrailheads, byte[] superRawData)
        {
            BinaryReader yReader = new BinaryReader(new MemoryStream(superRawData));
            AssetWriter  y       = new AssetWriter
            {
                WillStoreOriginalCopyInMemory = true, WillWriteSectionSix = true, data = new AssetReader()
            };

            y.data.Read(yReader);
            y.OriginalCopy = superRawData;

            // Missions
            if (newTrailheads.Length > 0)
            {
                for (int cat = 0; cat < y.data.categories.Count; cat++)
                {
                    if (y.data.categories[cat] is NormalCategory normalCat)
                    {
                        if (y.data.GetHeaderReference(y.data.GetLinkReference(normalCat.ReferenceData.connection)) != "AstroSettings")
                        {
                            continue;
                        }

                        for (int i = 0; i < normalCat.Data.Count; i++)
                        {
                            if (normalCat.Data[i].Name == "MissionData" && normalCat.Data[i] is ArrayPropertyData arrDat && arrDat.ArrayType == "ObjectProperty")
                            {
                                y.data.AddHeaderReference("AstroMissionDataAsset");

                                PropertyData[] usArrData = arrDat.Value;
                                int            oldLen    = usArrData.Length;
                                Array.Resize(ref usArrData, usArrData.Length + newTrailheads.Length);
                                for (int j = 0; j < newTrailheads.Length; j++)
                                {
                                    string realName      = newTrailheads[j];
                                    string softClassName = Path.GetFileNameWithoutExtension(realName);

                                    y.data.AddHeaderReference(realName);
                                    y.data.AddHeaderReference(softClassName);
                                    Link newLink    = new Link("/Script/Astro", "AstroMissionDataAsset", y.data.AddLink("/Script/CoreUObject", "Package", 0, realName).Index, softClassName, y.data);
                                    int  bigNewLink = y.data.AddLink(newLink);

                                    usArrData[oldLen + j] = new ObjectPropertyData(arrDat.Name, y.data)
                                    {
                                        LinkValue = bigNewLink
                                    };
                                }
                                arrDat.Value = usArrData;
                                break;
                            }
                        }
                        break;
                    }
                }
            }

            if (newComponents.Length == 0)
            {
                return(y.WriteData(new BinaryReader(new MemoryStream(y.OriginalCopy))));
            }

            LevelCategory levelCategory = null;
            int           levelLocation = -1;

            for (int i = 0; i < y.data.categories.Count; i++)
            {
                Category baseUs = y.data.categories[i];
                if (baseUs is LevelCategory levelUs)
                {
                    levelCategory = levelUs;
                    levelLocation = i;
                    break;
                }
            }
            if (levelLocation < 0)
            {
                throw new FormatException("Unable to find Level category");
            }

            // Preliminary header reference additions
            y.data.AddHeaderReference("bHidden");
            y.data.AddHeaderReference("bNetAddressable");
            y.data.AddHeaderReference("CreationMethod");
            y.data.AddHeaderReference("EComponentCreationMethod");
            y.data.AddHeaderReference("EComponentCreationMethod::SimpleConstructionScript");
            y.data.AddHeaderReference("BlueprintCreatedComponents");
            y.data.AddHeaderReference("AttachParent");
            y.data.AddHeaderReference("RootComponent");

            foreach (string componentPathRaw in newComponents)
            {
                CategoryReference refData1      = new CategoryReference(refData1B);
                string            componentPath = componentPathRaw;
                string            component     = Path.GetFileNameWithoutExtension(componentPathRaw);
                if (componentPathRaw.Contains("."))
                {
                    string[] tData = componentPathRaw.Split(new char[] { '.' });
                    componentPath = tData[0];
                    component     = tData[1].Remove(tData[1].Length - 2);
                }
                y.data.AddHeaderReference(componentPath);
                y.data.AddHeaderReference(component + "_C");

                Link newLink    = new Link("/Script/Engine", "BlueprintGeneratedClass", y.data.AddLink("/Script/CoreUObject", "Package", 0, componentPath).Index, component + "_C", y.data);
                int  bigNewLink = y.data.AddLink(newLink);
                refData1.connection = bigNewLink;
                refData1.typeIndex  = y.data.AddHeaderReference(component);

                // Note that category links are set to one more than you'd think since categories in the category list index from 1 instead of 0

                refData1.garbage1 = 0;
                refData1.link     = levelLocation + 1; // Level category

                // First we see if we can find the actual asset it's referring to
                List <SCS_Node> allBlueprintCreatedComponents = new List <SCS_Node>();
                byte[]          foundData = ParentIntegrator.SearchInAllPaksForPath(componentPath.ConvertGamePathToAbsolutePath(), Extractor);
                if (foundData != null && foundData.Length > 0)
                {
                    // If we can find the asset, then we read the asset and hop straight to the SimpleConstructionScript
                    AssetReader foundDataReader = new AssetReader();
                    foundDataReader.Read(new BinaryReader(new MemoryStream(foundData)), null, null);

                    int scsLocation = -1;
                    for (int i = 0; i < foundDataReader.categories.Count; i++)
                    {
                        Category foundCategory = foundDataReader.categories[i];
                        if (foundCategory is NormalCategory normalFoundCategory)
                        {
                            string nm = foundDataReader.GetHeaderReference(foundDataReader.GetLinkReference(normalFoundCategory.ReferenceData.connection));
                            switch (nm)
                            {
                            case "SimpleConstructionScript":
                                scsLocation = i;
                                break;
                            }
                        }
                    }

                    if (scsLocation >= 0)
                    {
                        List <int>     knownNodeCategories = new List <int>();
                        NormalCategory scsCategory         = (NormalCategory)foundDataReader.categories[scsLocation];
                        for (int j = 0; j < scsCategory.Data.Count; j++)
                        {
                            PropertyData bit = scsCategory.Data[j];
                            if (bit is ArrayPropertyData arrBit && arrBit.ArrayType == "ObjectProperty" && bit.Name == "AllNodes")
                            {
                                foreach (ObjectPropertyData objProp in arrBit.Value)
                                {
                                    if (objProp.LinkValue > 0)
                                    {
                                        knownNodeCategories.Add(objProp.LinkValue);
                                    }
                                }
                            }
                        }

                        Dictionary <int, int> knownParents = new Dictionary <int, int>();
                        foreach (int knownNodeCategory in knownNodeCategories)
                        {
                            Category knownCat = foundDataReader.categories[knownNodeCategory - 1];
                            string   nm       = foundDataReader.GetHeaderReference(foundDataReader.GetLinkReference(knownCat.ReferenceData.connection));
                            if (nm != "SCS_Node")
                            {
                                continue;
                            }
                            if (knownCat is NormalCategory knownNormalCat)
                            {
                                SCS_Node newSCS = new SCS_Node();
                                newSCS.InternalVariableName = "Unknown";
                                newSCS.OriginalCategory     = knownNodeCategory;
                                Link knownTypeLink1 = null;
                                Link knownTypeLink2 = null;

                                foreach (PropertyData knownNormalCatProp in knownNormalCat.Data)
                                {
                                    switch (knownNormalCatProp.Name)
                                    {
                                    case "InternalVariableName":
                                        if (knownNormalCatProp is NamePropertyData)
                                        {
                                            newSCS.InternalVariableName = ((NamePropertyData)knownNormalCatProp).Value;
                                        }
                                        break;

                                    case "ComponentClass":
                                        if (knownNormalCatProp is ObjectPropertyData)
                                        {
                                            knownTypeLink1 = ((ObjectPropertyData)knownNormalCatProp).Value;
                                        }
                                        knownTypeLink2 = foundDataReader.GetLinkAt(knownTypeLink1.Linkage);
                                        break;

                                    case "ChildNodes":
                                        if (knownNormalCatProp is ArrayPropertyData arrData2 && arrData2.ArrayType == "ObjectProperty")
                                        {
                                            foreach (ObjectPropertyData knownNormalCatPropChildren in arrData2.Value)
                                            {
                                                knownParents.Add(knownNormalCatPropChildren.LinkValue, knownNodeCategory);
                                            }
                                        }
                                        break;
                                    }
                                }

                                if (knownTypeLink1 != null && knownTypeLink2 != null)
                                {
                                    Link prospectiveLink2 = new Link();
                                    prospectiveLink2.Base     = (ulong)y.data.AddHeaderReference(foundDataReader.GetHeaderReference((int)knownTypeLink2.Base));
                                    prospectiveLink2.Class    = (ulong)y.data.AddHeaderReference(foundDataReader.GetHeaderReference((int)knownTypeLink2.Class));
                                    prospectiveLink2.Linkage  = knownTypeLink2.Linkage;
                                    prospectiveLink2.Property = (ulong)y.data.AddHeaderReference(foundDataReader.GetHeaderReference((int)knownTypeLink2.Property));

                                    int addedLink = y.data.SearchForLink(prospectiveLink2.Base, prospectiveLink2.Class, prospectiveLink2.Linkage, prospectiveLink2.Property);
                                    if (addedLink >= 0)
                                    {
                                        addedLink = y.data.AddLink(prospectiveLink2);
                                    }

                                    Link prospectiveLink1 = new Link();
                                    prospectiveLink1.Base     = (ulong)y.data.AddHeaderReference(foundDataReader.GetHeaderReference((int)knownTypeLink1.Base));
                                    prospectiveLink1.Class    = (ulong)y.data.AddHeaderReference(foundDataReader.GetHeaderReference((int)knownTypeLink1.Class));
                                    prospectiveLink1.Property = (ulong)y.data.AddHeaderReference(foundDataReader.GetHeaderReference((int)knownTypeLink1.Property));
                                    prospectiveLink1.Linkage  = addedLink;

                                    int newTypeLink = y.data.SearchForLink(prospectiveLink1.Base, prospectiveLink1.Class, prospectiveLink1.Linkage, prospectiveLink1.Property);
                                    if (newTypeLink >= 0)
                                    {
                                        newTypeLink = y.data.AddLink(prospectiveLink1);
                                    }
                                    newSCS.TypeLink = newTypeLink;
                                }

                                allBlueprintCreatedComponents.Add(newSCS);
                            }
                        }

                        foreach (SCS_Node node in allBlueprintCreatedComponents)
                        {
                            if (knownParents.ContainsKey(node.OriginalCategory))
                            {
                                node.AttachParent = knownParents[node.OriginalCategory];
                            }
                        }
                    }
                }

                // Then we add all our child components
                int templateCategoryPointer = y.data.categories.Count + allBlueprintCreatedComponents.Count + 1;

                List <ObjectPropertyData> BlueprintCreatedComponentsSerializedList = new List <ObjectPropertyData>();
                List <ObjectPropertyData> AttachParentDueForCorrection             = new List <ObjectPropertyData>();
                Dictionary <string, int>  NodeNameToCatIndex = new Dictionary <string, int>();
                Dictionary <int, int>     OldCatToNewCat     = new Dictionary <int, int>();
                foreach (SCS_Node blueprintCreatedComponent in allBlueprintCreatedComponents)
                {
                    CategoryReference refData2 = new CategoryReference(refData2B);

                    refData2.connection = blueprintCreatedComponent.TypeLink;
                    refData2.typeIndex  = y.data.AddHeaderReference(blueprintCreatedComponent.InternalVariableName);
                    refData2.garbage1   = 0;                       // unknown if this needs to be randomized or something
                    refData2.link       = templateCategoryPointer; // Template category

                    var determinedPropData = new List <PropertyData>
                    {
                        new BoolPropertyData("bNetAddressable", y.data)
                        {
                            Value = true,
                        },
                        new EnumPropertyData("CreationMethod", y.data)
                        {
                            EnumType = "EComponentCreationMethod",
                            Value    = "EComponentCreationMethod::SimpleConstructionScript"
                        }
                    };

                    if (blueprintCreatedComponent.AttachParent >= 0)
                    {
                        var nextOPD = new ObjectPropertyData("AttachParent", y.data)
                        {
                            LinkValue = blueprintCreatedComponent.AttachParent
                        };
                        AttachParentDueForCorrection.Add(nextOPD);
                        determinedPropData.Add(nextOPD);
                    }

                    y.data.categories.Add(new NormalCategory(determinedPropData, refData2, y.data, new byte[4] {
                        0, 0, 0, 0
                    }));
                    BlueprintCreatedComponentsSerializedList.Add(new ObjectPropertyData("BlueprintCreatedComponents", y.data)
                    {
                        LinkValue = y.data.categories.Count
                    });
                    NodeNameToCatIndex.Add(blueprintCreatedComponent.InternalVariableName, y.data.categories.Count);
                    OldCatToNewCat.Add(blueprintCreatedComponent.OriginalCategory, y.data.categories.Count);

                    y.data.AddLink(new Link((ulong)y.data.AddHeaderReference("/Script/Engine"), y.data.GetLinkAt(blueprintCreatedComponent.TypeLink).Property, refData1.connection, (ulong)y.data.AddHeaderReference(blueprintCreatedComponent.InternalVariableName + "_GEN_VARIABLE")));
                }

                foreach (ObjectPropertyData attachParentCorrecting in AttachParentDueForCorrection)
                {
                    attachParentCorrecting.LinkValue = OldCatToNewCat[attachParentCorrecting.LinkValue];
                }

                // Then we add the template category
                var templateDeterminedPropData = new List <PropertyData>
                {
                    new BoolPropertyData("bHidden", y.data)
                    {
                        Value = true
                    },
                    new ArrayPropertyData("BlueprintCreatedComponents", y.data)
                    {
                        ArrayType = "ObjectProperty",
                        Value     = BlueprintCreatedComponentsSerializedList.ToArray()
                    }
                };

                foreach (KeyValuePair <string, int> entry in NodeNameToCatIndex)
                {
                    if (entry.Key == "DefaultSceneRoot")
                    {
                        templateDeterminedPropData.Add(new ObjectPropertyData("RootComponent", y.data)
                        {
                            LinkValue = entry.Value
                        });
                    }
                    templateDeterminedPropData.Add(new ObjectPropertyData(entry.Key, y.data)
                    {
                        LinkValue = entry.Value
                    });
                }

                y.data.categories.Add(new NormalCategory(templateDeterminedPropData, refData1, y.data, new byte[4] {
                    0, 0, 0, 0
                }));

                // Add the template category to the level category
                levelCategory.IndexData.Add(y.data.categories.Count);
            }

            return(y.WriteData(new BinaryReader(new MemoryStream(y.OriginalCopy))));
        }
Esempio n. 5
0
        public MemoryStream Bake(Dictionary <string, List <string> > newItems, byte[] superRawData)
        {
            BinaryReader yReader = new BinaryReader(new MemoryStream(superRawData));
            AssetWriter  y       = new AssetWriter
            {
                WillStoreOriginalCopyInMemory = true, WillWriteSectionSix = true, data = new AssetReader()
            };

            y.data.Read(yReader);
            y.OriginalCopy = superRawData;

            // Find some categories
            Dictionary <string, List <ArrayPropertyData> > itemTypesProperty = new Dictionary <string, List <ArrayPropertyData> >();

            for (int cat = 0; cat < y.data.categories.Count; cat++)
            {
                if (y.data.categories[cat] is NormalCategory normalCat)
                {
                    for (int i = 0; i < normalCat.Data.Count; i++)
                    {
                        foreach (KeyValuePair <string, List <string> > entry in newItems)
                        {
                            string arrName = entry.Key;
                            if (entry.Key.Contains('.'))
                            {
                                string[] tData   = entry.Key.Split(new char[] { '.' });
                                string   catName = tData[0].ToLower();
                                arrName = tData[1];
                                if (y.data.GetHeaderReference(y.data.GetLinkReference(normalCat.ReferenceData.connection)).ToLower() != catName)
                                {
                                    continue;
                                }
                            }

                            if (normalCat.Data[i].Name.Equals(arrName) && normalCat.Data[i] is ArrayPropertyData)
                            {
                                if (!itemTypesProperty.ContainsKey(entry.Key))
                                {
                                    itemTypesProperty.Add(entry.Key, new List <ArrayPropertyData>());
                                }
                                itemTypesProperty[entry.Key].Add((ArrayPropertyData)normalCat.Data[i]);
                            }
                        }
                    }
                }
            }

            foreach (KeyValuePair <string, List <string> > itemPaths in newItems)
            {
                if (!itemTypesProperty.ContainsKey(itemPaths.Key))
                {
                    continue;
                }
                foreach (string itemPath in itemPaths.Value)
                {
                    string realName      = itemPath;
                    string className     = Path.GetFileNameWithoutExtension(itemPath) + "_C";
                    string softClassName = Path.GetFileNameWithoutExtension(itemPath);
                    if (itemPath.Contains("."))
                    {
                        string[] tData = itemPath.Split(new char[] { '.' });
                        realName      = tData[0];
                        className     = tData[1];
                        softClassName = tData[1];
                    }

                    int bigNewLink = 0;

                    for (int prop = 0; prop < itemTypesProperty[itemPaths.Key].Count; prop++)
                    {
                        ArrayPropertyData currentItemTypesProperty = itemTypesProperty[itemPaths.Key][prop];
                        PropertyData[]    usArrData = currentItemTypesProperty.Value;
                        int oldLen = usArrData.Length;
                        Array.Resize(ref usArrData, oldLen + 1);
                        switch (currentItemTypesProperty.ArrayType)
                        {
                        case "ObjectProperty":
                            if (bigNewLink >= 0)
                            {
                                y.data.AddHeaderReference(realName);
                                y.data.AddHeaderReference(className);
                                Link newLink = new Link("/Script/Engine", "BlueprintGeneratedClass", y.data.AddLink("/Script/CoreUObject", "Package", 0, realName).Index, className, y.data);
                                bigNewLink = y.data.AddLink(newLink);
                            }

                            usArrData[oldLen] = new ObjectPropertyData(currentItemTypesProperty.Name, y.data)
                            {
                                LinkValue = bigNewLink
                            };
                            itemTypesProperty[itemPaths.Key][prop].Value = usArrData;
                            break;

                        case "SoftObjectProperty":
                            y.data.AddHeaderReference(realName);
                            y.data.AddHeaderReference(realName + "." + softClassName);
                            usArrData[oldLen] = new SoftObjectPropertyData(currentItemTypesProperty.Name, y.data)
                            {
                                Value  = realName + "." + softClassName,
                                Value2 = 0
                            };
                            itemTypesProperty[itemPaths.Key][prop].Value = usArrData;
                            break;
                        }
                    }
                }
            }

            return(y.WriteData(new BinaryReader(new MemoryStream(y.OriginalCopy))));
        }