public void Should_UnwrapPrimitiveTypes(object primitive) { dynamic wrapped = primitive.AsDynamic(); object unwrapped = DynamicHelper.Unwrap(wrapped); Assert.Equal(unwrapped, primitive); }
public void Should_UnwrapStructs() { var @struct = Guid.NewGuid(); var wrapped = @struct.AsDynamic(); object unwrapped = DynamicHelper.Unwrap(wrapped); Assert.Equal(unwrapped, @struct); }
public void Should_UnwrapObjects() { object obj = new object(); dynamic wrapped = obj.AsDynamic(); object unwrapped = DynamicHelper.Unwrap(wrapped); Assert.Same(unwrapped, obj); }
public static void Postfix(object __instance) { var @dynamic = __instance.AsDynamic(); if ((bool)DynamicHelper.Unwrap(@dynamic._isSaving)) { return; } Task.Delay(1000).Wait(); if (LoadContextPatch1.PostfixUsed) { InformationManager.ShowInquiry( new InquiryData( new TextObject("{=gJtTUYkm}Module missing", null).ToString(), new TextObject("{=ld2gh1uF}The save file is loaded without a module that contains custom saved data. Ignore the data and proceed anyway?", null).ToString(), true, true, new TextObject("{=aeouhelq}Yes", null).ToString(), new TextObject("{=8OkPHu4f}No", null).ToString(), () => { if (SavedGameVMPatch2.UserRequestedSaveLoading == true) { LoadContextPatch1.PostfixUsed = false; // reset flag so StartGame will trigger. @dynamic.StartGame(SavedGameVMPatch2.LoadResult); // Flags will be reset by Prefix } }, () => { // Reset all flags LoadContextPatch1.PostfixUsed = false; SavedGameVMPatch2.UserRequestedSaveLoading = false; SavedGameVMPatch2.LoadResult = null; }, ""), false); } }
public static void Prefix(object __instance) { var @dynamic = __instance.AsDynamic(); foreach (object objectLoadData in @dynamic._childStructs.Values) { var objectLoadDataDynamic = objectLoadData.AsDynamic(); objectLoadDataDynamic.FillObject(); } for (var i = 0; i < (int)DynamicHelper.Unwrap(@dynamic._elementCount); i++) { switch (Convert.ToInt32(DynamicHelper.Unwrap(@dynamic._containerType))) { case 1: // List { var list = (IList)DynamicHelper.Unwrap(@dynamic.Target); if (!IsNull(list)) // bmountney: Added test for NULL { var value = ((IList)DynamicHelper.Unwrap(@dynamic._values))[i].AsDynamic(); if (Convert.ToInt32(DynamicHelper.Unwrap(value.SavedMemberType)) == 4) // CustomStruct { var objectLoadData = ((IDictionary)DynamicHelper.Unwrap(@dynamic._childStructs))[(int)DynamicHelper.Unwrap(value.Data)].AsDynamic(); value.SetCustomStructData(DynamicHelper.Unwrap(objectLoadData.Target)); } object valueData = DynamicHelper.Unwrap(value.GetDataToUse()); // PATCH if (IsNull(valueData)) { continue; } // PATCH try // bmountney: Added try...catch { list.Add(valueData); } catch (System.ArgumentException) { } } break; } case 2: // Dictionary { var dictionary = (IDictionary)DynamicHelper.Unwrap(@dynamic.Target); if (!IsNull(dictionary)) // bmountney: Added test for NULL { var key = ((IList)DynamicHelper.Unwrap(@dynamic._keys))[i].AsDynamic(); var value = ((IList)DynamicHelper.Unwrap(@dynamic._values))[i].AsDynamic(); if (Convert.ToInt32(DynamicHelper.Unwrap(key.SavedMemberType)) == 4) // CustomStruct { var objectLoadData = ((IDictionary)DynamicHelper.Unwrap(@dynamic._childStructs))[(int)DynamicHelper.Unwrap(key.Data)].AsDynamic(); key.SetCustomStructData(DynamicHelper.Unwrap(objectLoadData.Target)); } if (Convert.ToInt32(DynamicHelper.Unwrap(value.SavedMemberType)) == 4) // CustomStruct { var objectLoadData = ((IDictionary)DynamicHelper.Unwrap(@dynamic._childStructs))[(int)DynamicHelper.Unwrap(value.Data)].AsDynamic(); value.SetCustomStructData(DynamicHelper.Unwrap(objectLoadData.Target)); } object keyData = DynamicHelper.Unwrap(key.GetDataToUse()); object valueData = DynamicHelper.Unwrap(value.GetDataToUse()); if (!IsNull(keyData) && !IsNull(valueData)) { dictionary.Add(keyData, valueData); } } break; } case 3: // Array { var array = (Array)DynamicHelper.Unwrap(@dynamic.Target); if (!IsNull(array)) // bmountney: Added test for NULL (I didn't encounter a save that needed this test, but added it to be safe) { var value = ((IList)DynamicHelper.Unwrap(@dynamic._values))[i].AsDynamic(); if (Convert.ToInt32(DynamicHelper.Unwrap(value.SavedMemberType)) == 4) // CustomStruct { var objectLoadData = ((IDictionary)DynamicHelper.Unwrap(@dynamic._childStructs))[(int)DynamicHelper.Unwrap(value.Data)].AsDynamic(); value.SetCustomStructData(DynamicHelper.Unwrap(objectLoadData.Target)); } var valueData = DynamicHelper.Unwrap(value.GetDataToUse()); if (!IsNull(valueData)) { array.SetValue(valueData, i); } } break; } case 4: // Queue { var collection = (ICollection)DynamicHelper.Unwrap(@dynamic.Target); if (!IsNull(collection)) // bmountney: Added test for NULL (I didn't encounter a save that needed this test, but added it to be safe) { var value = ((IList)DynamicHelper.Unwrap(@dynamic._values))[i].AsDynamic(); if (Convert.ToInt32(DynamicHelper.Unwrap(value.SavedMemberType)) == 4) // CustomStruct { var objectLoadData = ((IDictionary)DynamicHelper.Unwrap(@dynamic._childStructs))[(int)DynamicHelper.Unwrap(value.Data)].AsDynamic(); value.SetCustomStructData(DynamicHelper.Unwrap(objectLoadData.Target)); } var valueData = DynamicHelper.Unwrap(value.GetDataToUse()); if (!IsNull(valueData)) { collection.GetType().GetMethod("Enqueue").Invoke(collection, new object[] { valueData }); } } break; } } } }
public static void Postfix(object __instance, ref bool __result, LoadData loadData) { // If the save is loaded withou any problem by vanilla if (__result) { PostfixUsed = false; return; } try { var @dynamic = __instance.AsDynamic(); using (new PerformanceTestBlock("LoadContext::Load Headers")) { using (new PerformanceTestBlock("LoadContext::Load And Create Header")) { var archiveDeserializer = Activator.CreateInstance(GetType("ArchiveDeserializer")).AsDynamic(); archiveDeserializer.LoadFrom(loadData.GameData.Header); var headerRootFolder = archiveDeserializer.RootFolder; BinaryReader binaryReader = headerRootFolder.GetEntry(Activator.CreateInstance(GetType("EntryId"), new object[] { -1, Enum.ToObject(GetType("SaveEntryExtension"), 0x7) })).GetBinaryReader(); @dynamic._objectCount = binaryReader.ReadInt(); @dynamic._stringCount = binaryReader.ReadInt(); @dynamic._containerCount = binaryReader.ReadInt(); @dynamic._objectHeaderLoadDatas = Activator.CreateInstance(GetType("Load.ObjectHeaderLoadData[]"), new object[] { (int)DynamicHelper.Unwrap(@dynamic._objectCount) }); @dynamic._containerHeaderLoadDatas = Activator.CreateInstance(GetType("Load.ContainerHeaderLoadData[]"), new object[] { (int)DynamicHelper.Unwrap(@dynamic._containerCount) }); @dynamic._strings = new string[(int)DynamicHelper.Unwrap(@dynamic._stringCount)]; Parallel.For(0, (int)DynamicHelper.Unwrap(@dynamic._objectCount), (int i) => { var objectHeaderLoadData = Activator.CreateInstance(GetType("Load.ObjectHeaderLoadData"), new object[] { __instance, i }).AsDynamic(); var childFolder = headerRootFolder.GetChildFolder(Activator.CreateInstance(GetType("FolderId"), new object[] { i, Enum.ToObject(GetType("SaveFolderExtension"), 0x1) })); objectHeaderLoadData.InitialieReaders(DynamicHelper.Unwrap(childFolder)); ((IList)DynamicHelper.Unwrap(@dynamic._objectHeaderLoadDatas))[i] = DynamicHelper.Unwrap(objectHeaderLoadData); }); Parallel.For(0, (int)DynamicHelper.Unwrap(@dynamic._containerCount), (int i) => { var containerHeaderLoadData = Activator.CreateInstance(GetType("Load.ContainerHeaderLoadData"), new object[] { __instance, i }).AsDynamic(); var childFolder = headerRootFolder.GetChildFolder(Activator.CreateInstance(GetType("FolderId"), new object[] { i, Enum.ToObject(GetType("SaveFolderExtension"), 0x3) })); containerHeaderLoadData.InitialieReaders(DynamicHelper.Unwrap(childFolder)); ((IList)DynamicHelper.Unwrap(@dynamic._containerHeaderLoadDatas))[i] = DynamicHelper.Unwrap(containerHeaderLoadData); }); } using (new PerformanceTestBlock("LoadContext::Create Objects")) { #if REMOVE_INVALID // PATCH var set1 = new HashSet <object>(); var set2 = new HashSet <object>(); // PATCH #endif foreach (object objectHeaderLoadData in @dynamic._objectHeaderLoadDatas) { var objectHeaderLoadDataDynamic = objectHeaderLoadData.AsDynamic(); objectHeaderLoadDataDynamic.CreateObject(); if (objectHeaderLoadDataDynamic.Id == 0) { @dynamic.RootObject = DynamicHelper.Unwrap(objectHeaderLoadDataDynamic.Target); } #if REMOVE_INVALID // PATCH if (objectHeaderLoadDataDynamic.TypeDefinition == null) { set1.Add(objectHeaderLoadData); } // PATCH #endif } foreach (object containerHeaderLoadData in @dynamic._containerHeaderLoadDatas) { var containerHeaderLoadDataDynamic = containerHeaderLoadData.AsDynamic(); if (containerHeaderLoadDataDynamic.GetObjectTypeDefinition()) { containerHeaderLoadDataDynamic.CreateObject(); } #if REMOVE_INVALID // PATCH if (containerHeaderLoadDataDynamic.TypeDefinition == null) { set2.Add(containerHeaderLoadData); } // PATCH #endif } #if REMOVE_INVALID // PATCH foreach (var item in set1) { ((IList)DynamicHelper.Unwrap(@dynamic._objectHeaderLoadDatas)).Remove(item); } @dynamic._objectCount -= set1.Count; foreach (var item in set2) { ((IList)DynamicHelper.Unwrap(@dynamic._containerHeaderLoadDatas)).Remove(item); } @dynamic._containerCount -= set2.Count; // PATCH #endif } } GC.Collect(); GC.WaitForPendingFinalizers(); using (new PerformanceTestBlock("LoadContext::Load Strings")) { var archiveDeserializer2 = Activator.CreateInstance(GetType("ArchiveDeserializer")).AsDynamic(); archiveDeserializer2.LoadFrom(loadData.GameData.Strings); for (var j = 0; j < (int)@dynamic._stringCount; j++) { var method = GetType("Load.LoadContext").GetMethod("LoadString", BindingFlags.NonPublic | BindingFlags.Static); ((IList)DynamicHelper.Unwrap(@dynamic._strings))[j] = (string)method.Invoke(null, new object[] { DynamicHelper.Unwrap(archiveDeserializer2), j }); } } GC.Collect(); GC.WaitForPendingFinalizers(); using (new PerformanceTestBlock("LoadContext::Load Object Datas")) { Parallel.For(0, (int)DynamicHelper.Unwrap(@dynamic._objectCount), (int i) => { var archiveDeserializer2 = Activator.CreateInstance(GetType("ArchiveDeserializer")).AsDynamic(); archiveDeserializer2.LoadFrom(loadData.GameData.ObjectData[i]); var rootFolder = archiveDeserializer2.RootFolder; var objectLoadData = Activator.CreateInstance(GetType("Load.ObjectLoadData"), new object[] { ((IList)DynamicHelper.Unwrap(@dynamic._objectHeaderLoadDatas))[i] }).AsDynamic(); var childFolder = rootFolder.GetChildFolder(Activator.CreateInstance(GetType("FolderId"), new object[] { i, Enum.ToObject(GetType("SaveFolderExtension"), 0x1) })); #if SKIP_INVALID // PATCH if (objectLoadData.TypeDefinition == null) { objectLoadData.Id = -1; return; } // PATCH #endif objectLoadData.InitialieReaders(DynamicHelper.Unwrap(childFolder)); objectLoadData.FillCreatedObject(); objectLoadData.Read(); objectLoadData.FillObject(); }); } using (new PerformanceTestBlock("LoadContext::Load Container Datas")) { Parallel.For(0, (int)DynamicHelper.Unwrap(@dynamic._containerCount), (int i) => { var binaryArchive = loadData.GameData.ContainerData[i]; var archiveDeserializer3 = Activator.CreateInstance(GetType("ArchiveDeserializer")).AsDynamic(); archiveDeserializer3.LoadFrom(binaryArchive); var rootFolder = archiveDeserializer3.RootFolder; var containerLoadData = Activator.CreateInstance(GetType("Load.ContainerLoadData"), new object[] { ((IList)@dynamic._containerHeaderLoadDatas.RealObject)[i] }).AsDynamic(); var childFolder = rootFolder.GetChildFolder(Activator.CreateInstance(GetType("FolderId"), new object[] { i, Enum.ToObject(GetType("SaveFolderExtension"), 0x3) })); #if SKIP_INVALID // PATCH if (containerLoadData.TypeDefinition == null) { containerLoadData.Id = -1; return; } // PATCH #endif containerLoadData.InitialieReaders(DynamicHelper.Unwrap(childFolder)); containerLoadData.FillCreatedObject(); containerLoadData.Read(); ContainerLoadDataPatch1.Prefix(DynamicHelper.Unwrap(containerLoadData)); }); } using (new PerformanceTestBlock("LoadContext::Callbacks")) { foreach (object objectHeaderLoadData2 in @dynamic._objectHeaderLoadDatas) { var objectHeaderLoadData2Dynamic = objectHeaderLoadData2.AsDynamic(); // PATCH if (objectHeaderLoadData2Dynamic.TypeDefinition == null) { continue; } // PATCH foreach (MethodInfo methodInfo in objectHeaderLoadData2Dynamic.TypeDefinition.InitializationCallbacks) { methodInfo.Invoke(DynamicHelper.Unwrap(objectHeaderLoadData2Dynamic.Target), new object[] { loadData.MetaData }); } } } GC.Collect(); GC.WaitForPendingFinalizers(); __result = true; PostfixUsed = true; } catch { __result = false; PostfixUsed = false; } }
public static void Prefix(object __instance) { var @dynamic = __instance.AsDynamic(); foreach (object objectLoadData in @dynamic._childStructs.Values) { var objectLoadDataDynamic = objectLoadData.AsDynamic(); objectLoadDataDynamic.FillObject(); } for (var i = 0; i < (int)DynamicHelper.Unwrap(@dynamic._elementCount); i++) { switch (Convert.ToInt32(DynamicHelper.Unwrap(@dynamic._containerType))) { case 1: // List { var list = (IList)DynamicHelper.Unwrap(@dynamic.Target); var value = ((IList)DynamicHelper.Unwrap(@dynamic._values))[i].AsDynamic(); if (Convert.ToInt32(DynamicHelper.Unwrap(value.SavedMemberType)) == 4) // CustomStruct { var objectLoadData = ((IDictionary)DynamicHelper.Unwrap(@dynamic._childStructs))[(int)DynamicHelper.Unwrap(value.Data)].AsDynamic(); value.SetCustomStructData(DynamicHelper.Unwrap(objectLoadData.Target)); } object valueData = DynamicHelper.Unwrap(value.GetDataToUse()); // PATCH if (valueData == null) { continue; } // PATCH list.Add(valueData); break; } case 2: // Dictionary { var dictionary = (IDictionary)DynamicHelper.Unwrap(@dynamic.Target); var key = ((IList)DynamicHelper.Unwrap(@dynamic._keys))[i].AsDynamic(); var value = ((IList)DynamicHelper.Unwrap(@dynamic._values))[i].AsDynamic(); if (Convert.ToInt32(DynamicHelper.Unwrap(key.SavedMemberType)) == 4) // CustomStruct { var objectLoadData = ((IDictionary)DynamicHelper.Unwrap(@dynamic._childStructs))[(int)DynamicHelper.Unwrap(key.Data)].AsDynamic(); key.SetCustomStructData(DynamicHelper.Unwrap(objectLoadData.Target)); } if (Convert.ToInt32(DynamicHelper.Unwrap(value.SavedMemberType)) == 4) // CustomStruct { var objectLoadData = ((IDictionary)DynamicHelper.Unwrap(@dynamic._childStructs))[(int)DynamicHelper.Unwrap(value.Data)].AsDynamic(); value.SetCustomStructData(DynamicHelper.Unwrap(objectLoadData.Target)); } object keyData = DynamicHelper.Unwrap(key.GetDataToUse()); object valueData = DynamicHelper.Unwrap(value.GetDataToUse()); dictionary.Add(keyData, valueData); break; } case 3: // Array { var array = (Array)DynamicHelper.Unwrap(@dynamic.Target); var value = ((IList)DynamicHelper.Unwrap(@dynamic._values))[i].AsDynamic(); if (Convert.ToInt32(DynamicHelper.Unwrap(value.SavedMemberType)) == 4) // CustomStruct { var objectLoadData = ((IDictionary)DynamicHelper.Unwrap(@dynamic._childStructs))[(int)DynamicHelper.Unwrap(value.Data)].AsDynamic(); value.SetCustomStructData(DynamicHelper.Unwrap(objectLoadData.Target)); } var valueData = DynamicHelper.Unwrap(value.GetDataToUse()); array.SetValue(valueData, i); break; } case 4: // Queue { var collection = (ICollection)DynamicHelper.Unwrap(@dynamic.Target); var value = ((IList)DynamicHelper.Unwrap(@dynamic._values))[i].AsDynamic(); if (Convert.ToInt32(DynamicHelper.Unwrap(value.SavedMemberType)) == 4) // CustomStruct { var objectLoadData = ((IDictionary)DynamicHelper.Unwrap(@dynamic._childStructs))[(int)DynamicHelper.Unwrap(value.Data)].AsDynamic(); value.SetCustomStructData(DynamicHelper.Unwrap(objectLoadData.Target)); } var valueData = DynamicHelper.Unwrap(value.GetDataToUse()); collection.GetType().GetMethod("Enqueue").Invoke(collection, new object[] { valueData }); break; } } } }
public static void Postfix(object __instance, ref bool __result, LoadData loadData) { // If the save is loaded withou any problem by vanilla if (__result) { PostfixUsed = false; return; } try { var @dynamic = __instance.AsDynamic(); using (new PerformanceTestBlock("LoadContext::Load Headers")) { using (new PerformanceTestBlock("LoadContext::Load And Create Header")) { var archiveDeserializer = Activator.CreateInstance(GetType("ArchiveDeserializer")).AsDynamic(); archiveDeserializer.LoadFrom(loadData.GameData.Header); var headerRootFolder = archiveDeserializer.RootFolder; BinaryReader binaryReader = headerRootFolder.GetEntry(Activator.CreateInstance(GetType("EntryId"), new object[] { -1, Enum.ToObject(GetType("SaveEntryExtension"), 0x7) })).GetBinaryReader(); @dynamic._objectCount = binaryReader.ReadInt(); @dynamic._stringCount = binaryReader.ReadInt(); @dynamic._containerCount = binaryReader.ReadInt(); @dynamic._objectHeaderLoadDatas = Activator.CreateInstance(GetType("Load.ObjectHeaderLoadData[]"), new object[] { (int)DynamicHelper.Unwrap(@dynamic._objectCount) }); @dynamic._containerHeaderLoadDatas = Activator.CreateInstance(GetType("Load.ContainerHeaderLoadData[]"), new object[] { (int)DynamicHelper.Unwrap(@dynamic._containerCount) }); @dynamic._strings = new string[(int)DynamicHelper.Unwrap(@dynamic._stringCount)]; Parallel.For(0, (int)DynamicHelper.Unwrap(@dynamic._objectCount), (int i) => { var objectHeaderLoadData = Activator.CreateInstance(GetType("Load.ObjectHeaderLoadData"), new object[] { __instance, i }).AsDynamic(); var childFolder = headerRootFolder.GetChildFolder(Activator.CreateInstance(GetType("FolderId"), new object[] { i, Enum.ToObject(GetType("SaveFolderExtension"), 0x1) })); objectHeaderLoadData.InitialieReaders(DynamicHelper.Unwrap(childFolder)); ((IList)DynamicHelper.Unwrap(@dynamic._objectHeaderLoadDatas))[i] = DynamicHelper.Unwrap(objectHeaderLoadData); }); Parallel.For(0, (int)DynamicHelper.Unwrap(@dynamic._containerCount), (int i) => { var containerHeaderLoadData = Activator.CreateInstance(GetType("Load.ContainerHeaderLoadData"), new object[] { __instance, i }).AsDynamic(); var childFolder = headerRootFolder.GetChildFolder(Activator.CreateInstance(GetType("FolderId"), new object[] { i, Enum.ToObject(GetType("SaveFolderExtension"), 0x3) })); containerHeaderLoadData.InitialieReaders(DynamicHelper.Unwrap(childFolder)); ((IList)DynamicHelper.Unwrap(@dynamic._containerHeaderLoadDatas))[i] = DynamicHelper.Unwrap(containerHeaderLoadData); }); } using (new PerformanceTestBlock("LoadContext::Create Objects")) { #if REMOVE_INVALID // PATCH var set1 = new HashSet <object>(); var set2 = new HashSet <object>(); // PATCH #endif foreach (object objectHeaderLoadData in @dynamic._objectHeaderLoadDatas) { var objectHeaderLoadDataDynamic = objectHeaderLoadData.AsDynamic(); objectHeaderLoadDataDynamic.CreateObject(); if (objectHeaderLoadDataDynamic.Id == 0) { @dynamic.RootObject = DynamicHelper.Unwrap(objectHeaderLoadDataDynamic.Target); } #if REMOVE_INVALID // PATCH if (objectHeaderLoadDataDynamic.TypeDefinition == null) { set1.Add(objectHeaderLoadData); } // PATCH #endif } foreach (object containerHeaderLoadData in @dynamic._containerHeaderLoadDatas) { var containerHeaderLoadDataDynamic = containerHeaderLoadData.AsDynamic(); if (containerHeaderLoadDataDynamic.GetObjectTypeDefinition()) { containerHeaderLoadDataDynamic.CreateObject(); } #if REMOVE_INVALID // PATCH if (containerHeaderLoadDataDynamic.TypeDefinition == null) { set2.Add(containerHeaderLoadData); } // PATCH #endif } #if REMOVE_INVALID // PATCH foreach (var item in set1) { ((IList)DynamicHelper.Unwrap(@dynamic._objectHeaderLoadDatas)).Remove(item); } @dynamic._objectCount -= set1.Count; foreach (var item in set2) { ((IList)DynamicHelper.Unwrap(@dynamic._containerHeaderLoadDatas)).Remove(item); } @dynamic._containerCount -= set2.Count; // PATCH #endif } } GC.Collect(); GC.WaitForPendingFinalizers(); using (new PerformanceTestBlock("LoadContext::Load Strings")) { var archiveDeserializer2 = Activator.CreateInstance(GetType("ArchiveDeserializer")).AsDynamic(); archiveDeserializer2.LoadFrom(loadData.GameData.Strings); for (var j = 0; j < (int)@dynamic._stringCount; j++) { var method = GetType("Load.LoadContext").GetMethod("LoadString", BindingFlags.NonPublic | BindingFlags.Static); ((IList)DynamicHelper.Unwrap(@dynamic._strings))[j] = (string)method.Invoke(null, new object[] { DynamicHelper.Unwrap(archiveDeserializer2), j }); } } GC.Collect(); GC.WaitForPendingFinalizers(); using (new PerformanceTestBlock("LoadContext::Load Object Datas")) { Parallel.For(0, (int)DynamicHelper.Unwrap(@dynamic._objectCount), (int i) => { var archiveDeserializer2 = Activator.CreateInstance(GetType("ArchiveDeserializer")).AsDynamic(); archiveDeserializer2.LoadFrom(loadData.GameData.ObjectData[i]); var rootFolder = archiveDeserializer2.RootFolder; var objectLoadData = Activator.CreateInstance(GetType("Load.ObjectLoadData"), new object[] { ((IList)DynamicHelper.Unwrap(@dynamic._objectHeaderLoadDatas))[i] }).AsDynamic(); var childFolder = rootFolder.GetChildFolder(Activator.CreateInstance(GetType("FolderId"), new object[] { i, Enum.ToObject(GetType("SaveFolderExtension"), 0x1) })); #if SKIP_INVALID // PATCH if (objectLoadData.TypeDefinition == null) { objectLoadData.Id = -1; return; } // PATCH #endif try { objectLoadData.InitializeReaders(DynamicHelper.Unwrap(childFolder)); // bmountney: Added "z" to correct method name } catch (System.MissingMethodException) // bmountney: If method with new name doesn't exist, try the old name for e1.1.2 { objectLoadData.InitialieReaders(DynamicHelper.Unwrap(childFolder)); } objectLoadData.FillCreatedObject(); objectLoadData.Read(); objectLoadData.FillObject(); }); } using (new PerformanceTestBlock("LoadContext::Load Container Datas")) { Parallel.For(0, (int)DynamicHelper.Unwrap(@dynamic._containerCount), (int i) => { var binaryArchive = loadData.GameData.ContainerData[i]; var archiveDeserializer3 = Activator.CreateInstance(GetType("ArchiveDeserializer")).AsDynamic(); archiveDeserializer3.LoadFrom(binaryArchive); var rootFolder = archiveDeserializer3.RootFolder; var containerLoadData = Activator.CreateInstance(GetType("Load.ContainerLoadData"), new object[] { ((IList)@dynamic._containerHeaderLoadDatas.RealObject)[i] }).AsDynamic(); var childFolder = rootFolder.GetChildFolder(Activator.CreateInstance(GetType("FolderId"), new object[] { i, Enum.ToObject(GetType("SaveFolderExtension"), 0x3) })); #if SKIP_INVALID // PATCH if (containerLoadData.TypeDefinition == null) { containerLoadData.Id = -1; return; } // PATCH #endif try { containerLoadData.InitializeReaders(DynamicHelper.Unwrap(childFolder)); // bmountney: Added "z" to correct method name } catch (System.MissingMethodException) // bmountney: If method with new name doesn't exist, try the old name for e1.1.2 { containerLoadData.InitialieReaders(DynamicHelper.Unwrap(childFolder)); } containerLoadData.FillCreatedObject(); containerLoadData.Read(); ContainerLoadDataPatch1.Prefix(DynamicHelper.Unwrap(containerLoadData)); }); } using (new PerformanceTestBlock("LoadContext::Callbacks")) { try // bmountney: Added to deal with System.Reflection.TargetInvocationException in beta e1.3.0 of the game after removing some mods { foreach (object objectHeaderLoadData2 in @dynamic._objectHeaderLoadDatas) { var objectHeaderLoadData2Dynamic = objectHeaderLoadData2.AsDynamic(); // PATCH if (objectHeaderLoadData2Dynamic.TypeDefinition == null) { continue; } // PATCH foreach (MethodInfo methodInfo in objectHeaderLoadData2Dynamic.TypeDefinition.InitializationCallbacks) { // bmountney: In e1.3.0 this method was throwing a System.Reflection.TargetInvocationExecption at some point // during the loop, and once it started happening it seemed to repeat indefinitely, so attempting to catch // it inside the either the inner or outer loop seemed to result in an infinite loop, or at least it was // taking longer than I was willing to wait. Jumping out of the loops on the first instance of the exception // seemed to cause no issues in my tests after removing the "Tournaments XPanded-for-BL1.3.0" mod. methodInfo.Invoke(DynamicHelper.Unwrap(objectHeaderLoadData2Dynamic.Target), new object[] { loadData.MetaData }); } } } catch (System.Reflection.TargetInvocationException) { } } GC.Collect(); GC.WaitForPendingFinalizers(); __result = true; PostfixUsed = true; } catch { __result = false; PostfixUsed = false; } }