public static IEnumerable <CodeInstruction> Add(IEnumerable <CodeInstruction> instructions, ILGenerator iLGenerator) { List <CodeInstruction> instructionsList = instructions.ToList(); int i = 0; Type lockObjectType = typeof(object); List <CodeInstruction> loadLockObjectInstructions = new List <CodeInstruction> { new CodeInstruction(OpCodes.Ldsfld, Field(typeof(BattleLog_Transpile), "addLogEntryLock")), }; LocalBuilder lockObject = iLGenerator.DeclareLocal(lockObjectType); LocalBuilder lockTaken = iLGenerator.DeclareLocal(typeof(bool)); foreach (CodeInstruction ci in RimThreadedHarmony.EnterLock( lockObject, lockTaken, loadLockObjectInstructions, instructionsList[i])) { yield return(ci); } while (i < instructionsList.Count - 1) { yield return(instructionsList[i++]); } foreach (CodeInstruction ci in RimThreadedHarmony.ExitLock( iLGenerator, lockObject, lockTaken, instructionsList[i])) { yield return(ci); } while (i < instructionsList.Count) { yield return(instructionsList[i++]); } }
public static IEnumerable <CodeInstruction> Notify_CapacityLevelsDirty(IEnumerable <CodeInstruction> instructions, ILGenerator iLGenerator) { List <CodeInstruction> instructionsList = instructions.ToList(); int i = 0; List <CodeInstruction> loadLockObjectInstructions = new List <CodeInstruction> { new CodeInstruction(OpCodes.Ldarg_0) }; LocalBuilder lockObject = iLGenerator.DeclareLocal(typeof(PawnCapacitiesHandler)); LocalBuilder lockTaken = iLGenerator.DeclareLocal(typeof(bool)); foreach (CodeInstruction ci in RimThreadedHarmony.EnterLock(lockObject, lockTaken, loadLockObjectInstructions, instructionsList[i])) { yield return(ci); } while (i < instructionsList.Count - 1) { yield return(instructionsList[i++]); } foreach (CodeInstruction ci in RimThreadedHarmony.ExitLock(iLGenerator, lockObject, lockTaken, instructionsList[i])) { yield return(ci); } yield return(instructionsList[i]); }
public static IEnumerable <CodeInstruction> Remove(IEnumerable <CodeInstruction> instructions, ILGenerator iLGenerator) { List <CodeInstruction> instructionsList = instructions.ToList(); int i = 0; while (i < instructionsList.Count) { if (i + 9 < instructionsList.Count && instructionsList[i + 9].opcode == OpCodes.Callvirt) { if (instructionsList[i + 9].operand is MethodInfo methodInfo) { if (methodInfo.Name.Contains("RemoveAt") && methodInfo.DeclaringType.FullName.Contains("System.Collections")) { LocalBuilder lockObject = iLGenerator.DeclareLocal(typeof(object)); LocalBuilder lockTaken = iLGenerator.DeclareLocal(typeof(bool)); List <CodeInstruction> loadLockObjectInstructions = new List <CodeInstruction>() { new CodeInstruction(OpCodes.Ldarg_0) }; foreach (CodeInstruction lockInstruction in RimThreadedHarmony.EnterLock(lockObject, lockTaken, loadLockObjectInstructions, instructionsList[i])) { yield return(lockInstruction); } Type collectionType = methodInfo.DeclaringType; LocalBuilder collectionCopy = iLGenerator.DeclareLocal(collectionType); ConstructorInfo constructorInfo = collectionType.GetConstructor(new Type[] { collectionType }); List <CodeInstruction> storeReplay = new List <CodeInstruction>(); storeReplay.Add(instructionsList[i]); yield return(instructionsList[i++]); //this storeReplay.Add(instructionsList[i]); yield return(instructionsList[i++]); //load field yield return(new CodeInstruction(OpCodes.Newobj, constructorInfo)); yield return(new CodeInstruction(OpCodes.Stloc, collectionCopy.LocalIndex)); yield return(new CodeInstruction(OpCodes.Ldloc, collectionCopy.LocalIndex)); yield return(instructionsList[i++]); //load item yield return(instructionsList[i++]); //unbox yield return(instructionsList[i++]); //last index of yield return(instructionsList[i++]); //store to loc 0 i++; //yield return instructionsList[i++]; //this i++; //yield return instructionsList[i++]; //load field yield return(new CodeInstruction(OpCodes.Ldloc, collectionCopy.LocalIndex)); yield return(instructionsList[i++]); //load loc 0 yield return(instructionsList[i++]); //removeAt (void) int j = 0; while (j < storeReplay.Count - 1) { yield return(storeReplay[j++]); } yield return(new CodeInstruction(OpCodes.Ldloc, collectionCopy.LocalIndex)); yield return(new CodeInstruction(OpCodes.Stfld, storeReplay[j].operand)); foreach (CodeInstruction lockInstruction in RimThreadedHarmony.ExitLock(iLGenerator, lockObject, lockTaken, instructionsList[i])) { yield return(lockInstruction); } continue; } } } yield return(instructionsList[i++]); } }