public MemoryStream Bake2(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 brandNewLink = y.data.AddLink(new Link((ulong)y.data.AddHeaderReference("/Script/Engine"), (ulong)y.data.AddHeaderReference("BlueprintGeneratedClass"), y.data.AddLink(new Link((ulong)y.data.AddHeaderReference("/Script/CoreUObject"), (ulong)y.data.AddHeaderReference("Package"), 0, (ulong)y.data.AddHeaderReference("/Game/Integrator/IntegratorStatics_BP"))), (ulong)y.data.AddHeaderReference("IntegratorStatics_BP_C"))); NormalCategory cat1 = y.data.categories[0] as NormalCategory; if (cat1 == null) { return(null); } cat1.Data = new List <PropertyData>() { new StrPropertyData("IntegratorVersion", y.data) { Value = IntegratorUtils.CurrentVersion.ToString(), Encoding = Encoding.ASCII }, new BoolPropertyData("RefuseMismatchedConnections", y.data) { Value = ParentIntegrator.RefuseMismatchedConnections }, new ObjectPropertyData("NativeClass", y.data) { LinkValue = brandNewLink } }; return(y.WriteData(new BinaryReader(new MemoryStream(y.OriginalCopy)))); }
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)))); }
/* * 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)))); }
public MemoryStream Bake(Metadata[] allMods, List <string> optionalModIDs, 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; DataTableCategory targetCategory = null; foreach (Category cat in y.data.categories) { if (cat is DataTableCategory) { targetCategory = (DataTableCategory)cat; break; } } List <DataTableEntry> tab = targetCategory.Data2.Table; string[] columns = tab[0].Data.Value.Select(x => x.Name).ToArray(); Dictionary <string, int> DuplicateIndexLookup = new Dictionary <string, int>(); List <DataTableEntry> newTable = new List <DataTableEntry>(); foreach (Metadata mod in allMods) { if (mod == null) { continue; } y.data.AddHeaderReference(mod.ModID); string codedSyncMode = "SyncMode::NewEnumerator0"; switch (mod.Sync) { case SyncMode.None: codedSyncMode = "SyncMode::NewEnumerator0"; break; case SyncMode.ServerOnly: codedSyncMode = "SyncMode::NewEnumerator1"; break; case SyncMode.ClientOnly: codedSyncMode = "SyncMode::NewEnumerator2"; break; case SyncMode.ServerAndClient: codedSyncMode = "SyncMode::NewEnumerator3"; break; } List <PropertyData> rows = new List <PropertyData>(); rows.Add(new StrPropertyData(columns[0], y.data) { Value = mod.Name ?? "", Encoding = Encoding.ASCII }); rows.Add(new StrPropertyData(columns[1], y.data) { Value = mod.Author ?? "", Encoding = Encoding.ASCII }); rows.Add(new StrPropertyData(columns[2], y.data) { Value = mod.Description ?? "", Encoding = Encoding.ASCII }); rows.Add(new StrPropertyData(columns[3], y.data) { Value = mod.ModVersion?.ToString() ?? "", Encoding = Encoding.ASCII }); rows.Add(new StrPropertyData(columns[4], y.data) { Value = mod.AstroBuild?.ToString() ?? "", Encoding = Encoding.ASCII }); rows.Add(new BytePropertyData(columns[5], y.data) { ByteType = BytePropertyType.Long, EnumType = y.data.AddHeaderReference("SyncMode"), Value = y.data.AddHeaderReference(codedSyncMode) }); rows.Add(new StrPropertyData(columns[6], y.data) { Value = mod.Homepage ?? "", Encoding = Encoding.ASCII }); rows.Add(new BoolPropertyData(columns[7], y.data) { Value = optionalModIDs.Contains(mod.ModID), }); if (!DuplicateIndexLookup.ContainsKey(mod.ModID)) { DuplicateIndexLookup[mod.ModID] = 0; } newTable.Add(new DataTableEntry(new StructPropertyData(mod.ModID, y.data) { StructType = tab[0].Data.StructType, Value = rows }, DuplicateIndexLookup[mod.ModID])); DuplicateIndexLookup[mod.ModID]++; } targetCategory.Data2.Table = newTable; return(y.WriteData(new BinaryReader(new MemoryStream(y.OriginalCopy)))); }
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)))); }