private void InjectOnionDoWorldGen() { try { var doWorldGenInitialiseBody = CecilHelper.GetMethodDefinition(_csharpModule, "OfflineWorldGen", "DoWordGenInitialise").Body; var callResetInstruction = doWorldGenInitialiseBody .Instructions .Where(instruction => instruction.OpCode == OpCodes.Call) .Reverse() .Skip(3) .First(); var instructionInserter = new InstructionInserter(doWorldGenInitialiseBody); instructionInserter.InsertBefore(callResetInstruction, Instruction.Create(OpCodes.Pop)); instructionInserter.InsertBefore(callResetInstruction, Instruction.Create(OpCodes.Pop)); _onionToCSharpInjector.InjectBefore( "Hooks", "OnDoOfflineWorldGen", doWorldGenInitialiseBody, callResetInstruction); _csharpInstructionRemover.ReplaceByNop(doWorldGenInitialiseBody, callResetInstruction); } catch (Exception e) { Logger.Log("World generation injection failed"); Logger.Log(e); Failed = true; } }
private void InjectOnionDebugHandler() { var debugHandler = _csharpModule .Types .FirstOrDefault(type => type.Name == "DebugHandler"); if (debugHandler != null) { var debugHandlerEnabledProperty = debugHandler .Properties .FirstOrDefault(property => property.Name == "enabled"); if (debugHandlerEnabledProperty != null) { debugHandlerEnabledProperty .SetMethod .IsPublic = true; } } else { Logger.Log("Can't find type DebugHandler"); Failed = true; } var debugHandlerConstructorBody = CecilHelper.GetMethodDefinition(_csharpModule, debugHandler, ".ctor").Body; var lastInstruction = debugHandlerConstructorBody.Instructions.Last(); _onionToCSharpInjector.InjectBefore("Hooks", "OnDebugHandlerCtor", debugHandlerConstructorBody, lastInstruction); }
public void ClearAllButLast(string typeName, string methodName) { var method = CecilHelper.GetMethodDefinition(_targetModule, typeName, methodName); var methodBody = method.Body; ClearAllButLast(methodBody); }
public void ReplaceByNopAt(string typeName, string methodName, int instructionIndex) { var method = CecilHelper.GetMethodDefinition(_targetModule, typeName, methodName); var methodBody = method.Body; ReplaceByNop(methodBody, methodBody.Instructions[instructionIndex]); }
public void InjectBefore( string sourceTypeName, string sourceMethodName, string targetTypeName, string targetMethodName, int instructionIndex, bool includeCallingObject = false, int includeArgumentCount = 0, bool passArgumentsByRef = false, bool useFullName = false) { MethodBody targetMethodBody = CecilHelper .GetMethodDefinition( this._targetModule, targetTypeName, targetMethodName, useFullName).Body; Instruction instruction = targetMethodBody.Instructions[instructionIndex]; this.InjectBefore( sourceTypeName, sourceMethodName, targetMethodBody, instruction, includeCallingObject, includeArgumentCount, passArgumentsByRef, useFullName); }
public void ClearAllButLast(string typeName, string methodName) { MethodDefinition method = CecilHelper.GetMethodDefinition(this._targetModule, typeName, methodName); MethodBody methodBody = method.Body; this.ClearAllButLast(methodBody); }
public void InjectBefore(string sourceTypeName, string sourceMethodName, MethodBody targetMethodBody, Instruction targetInstruction, bool includeCallingObject = false, int includeArgumentCount = 0, bool passArgumentsByRef = false, bool useFullName = false) { var sourceMethod = CecilHelper.GetMethodDefinition(_sourceModule, sourceTypeName, sourceMethodName, useFullName: useFullName); var sourceMethodReference = CecilHelper.GetMethodReference(_targetModule, sourceMethod); InjectBefore(sourceMethodReference, targetMethodBody, targetInstruction, includeCallingObject, includeArgumentCount, passArgumentsByRef); }
// TODO: use other sprite, refactor private void AddOverlayButton() { _csharpPublisher.MakeFieldPublic("OverlayMenu", "overlay_toggle_infos"); var overlayMenu = _csharpModule.Types.First(type => type.Name == "OverlayMenu"); overlayMenu.NestedTypes.First(nestedType => nestedType.Name == "OverlayToggleInfo").IsPublic = true; var onPrefabInitBody = CecilHelper.GetMethodDefinition(_csharpModule, overlayMenu, "OnPrefabInit").Body; var loadOverlayToggleInfosInstuction = onPrefabInitBody.Instructions.First(instruction => instruction.OpCode == OpCodes.Ldfld); _coreToCSharpInjector.InjectBefore( "OverlayMenuManager", "OnOverlayMenuPrefabInit", onPrefabInitBody, loadOverlayToggleInfosInstuction.Next, true); }
private void InjectOnionCameraController() { const string TypeName = "CameraController"; _csharpPublisher.MakeFieldPublic(TypeName, "maxOrthographicSize"); _csharpPublisher.MakeFieldPublic(TypeName, "maxOrthographicSizeDebug"); var cameraControllerOnSpawnBody = CecilHelper.GetMethodDefinition(_csharpModule, TypeName, "OnSpawn").Body; var restoreCall = cameraControllerOnSpawnBody.Instructions.Last(instruction => instruction.OpCode == OpCodes.Call); _onionToCSharpInjector.InjectBefore( "Hooks", "OnCameraControllerCtor", cameraControllerOnSpawnBody, restoreCall, true); }
private void AddDefaultKeybinding(ModuleDefinition CSharpModule, ModuleDefinition firstPassModule, KKeyCode keyCode, Modifier keyModifier, Action action, string screen = "Root") { var beforeFieldInit = CecilHelper.GetMethodDefinition(firstPassModule, CecilHelper.GetTypeDefinition(firstPassModule, "GameInputMapping"), ".cctor"); var lastKeybindingDeclarationEnd = beforeFieldInit.Body.Instructions.Last(instruction => instruction.OpCode == OpCodes.Stobj); var stoBindingEntryInstruction = beforeFieldInit.Body.Instructions.First(instruction => instruction.OpCode == OpCodes.Stobj); var newBindingEntryInstruction = beforeFieldInit.Body.Instructions.First(instruction => instruction.OpCode == OpCodes.Newobj); var lastDupInstruction = beforeFieldInit.Body.Instructions.LastOrDefault(instr => instr.OpCode == OpCodes.Dup); if (lastDupInstruction != null) { var lastEntryIndex = Convert.ToInt32(lastDupInstruction.Next.Operand); var instructionsToAdd = new List <Instruction> { Instruction.Create(OpCodes.Dup), Instruction.Create(OpCodes.Ldc_I4, lastEntryIndex + 1), // index Instruction.Create(OpCodes.Ldelema, (TypeReference)stoBindingEntryInstruction.Operand), Instruction.Create(OpCodes.Ldstr, screen), Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)16), // gamepad button Instruction.Create(OpCodes.Ldc_I4, (int)keyCode), Instruction.Create(OpCodes.Ldc_I4, (int)keyModifier), Instruction.Create(OpCodes.Ldc_I4, (int)action), Instruction.Create(OpCodes.Ldc_I4_1), // rebindable = true Instruction.Create(OpCodes.Ldc_I4_1), // ignore root conflicts = true newBindingEntryInstruction, // create new object stoBindingEntryInstruction // store in array }; var ILProcessor = beforeFieldInit.Body.GetILProcessor(); // increase array size by one var arraySizeSetInstruction = beforeFieldInit.Body.Instructions.First(); ILProcessor.Replace(arraySizeSetInstruction, Instruction.Create(OpCodes.Ldc_I4, (int)arraySizeSetInstruction.Operand + 1)); // new InstructionInserter(ILProcessor).InsertAfter(lastKeybindingDeclarationEnd, instructionsToAdd); } else { Logger.Log("Can't find last duplication instruction at GameInputMapping.cctor"); Failed = true; } }
private void FixGameUpdateExceptionHandling() { var handler = new ExceptionHandler(ExceptionHandlerType.Finally); var methodBody = CecilHelper.GetMethodDefinition(_csharpModule, "Game", "Update").Body; var methodInstructions = methodBody.Instructions; handler.TryStart = methodInstructions.First(instruction => instruction.OpCode == OpCodes.Ldsfld); var tryEndInstruction = methodInstructions.Last(instruction => instruction.OpCode == OpCodes.Ldloca_S); handler.TryEnd = tryEndInstruction; handler.HandlerStart = tryEndInstruction; handler.HandlerEnd = methodInstructions.Last(); handler.CatchType = _csharpModule.Import(typeof(Exception)); methodBody.ExceptionHandlers.Clear(); methodBody.ExceptionHandlers.Add(handler); }
// TODO: notify user when injection fails private void ExtendMaxActionCount() { const int MaxActionCount = 1000; TypeDefinition kInputController = this._firstPassModule.Types.FirstOrDefault(type => type.Name == "KInputController"); if (kInputController != null) { TypeDefinition keyDef = kInputController.NestedTypes.FirstOrDefault(nestedType => nestedType.Name == "KeyDef"); if (keyDef != null) { MethodBody keyDefConstructorBody = keyDef.Methods.First(method => method.Name == ".ctor").Body; keyDefConstructorBody.Instructions.Last(instruction => instruction.OpCode == OpCodes.Ldc_I4) .Operand = MaxActionCount; MethodBody kInputControllerConstructorBody = CecilHelper .GetMethodDefinition( this._firstPassModule, kInputController, ".ctor").Body; kInputControllerConstructorBody .Instructions.First(instruction => instruction.OpCode == OpCodes.Ldc_I4).Operand = MaxActionCount; } else { Console.WriteLine("Can't find type KInputController.KeyDef"); this.Failed = true; } } else { Console.WriteLine("Can't find type KInputController"); this.Failed = true; } }
private void AttachCustomActionToToggle() { var onToggleSelectMethod = CecilHelper.GetMethodDefinition(_csharpModule, "OverlayMenu", "OnToggleSelect"); var onToggleSelectMethodBody = onToggleSelectMethod.Body; var firstInstruction = onToggleSelectMethodBody.Instructions.First(); var instructionsToAdd = new List <Instruction> { Instruction.Create(OpCodes.Brfalse, firstInstruction), Instruction.Create(OpCodes.Ret) }; new InstructionInserter(onToggleSelectMethod).InsertBefore(firstInstruction, instructionsToAdd); _materialToCSharpInjector.InjectAsFirst( "InjectionEntry", "EnterToggle", onToggleSelectMethodBody, true, 1); }
public void MakeMethodPublic(string typeName, string methodName) { MethodDefinition method = CecilHelper.GetMethodDefinition(this._targetModule, typeName, methodName); method.IsPublic = true; }
private MethodBody GetMethodBody(string typeName, string methodName) => CecilHelper.GetMethodDefinition(_targetModule, typeName, methodName).Body;