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 InjectCore() { _coreToCSharpInjector.InjectBefore( "UpdateQueueManager", "OnGameUpdate", "Game", "Update", 5); }
private void InjectMain() { _materialToCSharpInjector.InjectAsFirst( "InjectionEntry", "EnterOnce", "Game", "OnPrefabInit"); _materialToCSharpInjector.InjectBefore( "InjectionEntry", "EnterEveryUpdate", "Game", "Update", 5); }
// TODO: refactor public void Inject(InjectorState injectorState) { InjectCore(); if (injectorState.FixLogicBridges) { MakeLogicBridgesPlaceableOnLogicGates(); } if (injectorState.EnableImprovedOxygenOverlay) { try { _csharpInstructionRemover.ClearAllButLast("SimDebugView", "GetOxygenMapColour"); _materialToCSharpInjector.InjectAsFirst("InjectionEntry", "EnterGasOverlay", "SimDebugView", "GetOxygenMapColour", includeArgumentCount: 1); } catch (Exception e) { Logger.Log("Improved gas overlay injection failed"); Logger.Log(e); Failed = true; } } if (injectorState.EnableDraggableGUI) { try { var coreToFirstpass = new MethodInjector(_coreModule, _firstPassModule); coreToFirstpass.InjectAsFirst("DraggablePanel", "Attach", "KScreen", "OnPrefabInit", includeCallingObject: true); var kScreen = _firstPassModule.Types.First(t => t.Name == "KScreen"); var onSpawnBody = kScreen.Methods.First(m => m.Name == "OnSpawn").Body; var lastInstruction = onSpawnBody.Instructions.Last(); coreToFirstpass.InjectBefore("DraggablePanel", "SetPositionFromFile", onSpawnBody, lastInstruction, includeCallingObject: true); var injectedCallFirstInstruction = onSpawnBody.Instructions.Last(i => i.OpCode == OpCodes.Ldarg_0); foreach (var branch in onSpawnBody.Instructions.Where(i => i.OpCode == OpCodes.Brtrue || i.OpCode == OpCodes.Brfalse)) { branch.Operand = injectedCallFirstInstruction; } } catch (Exception e) { Logger.Log("Draggable GUI injection failed"); Logger.Log(e); Failed = true; } } if (injectorState.InjectMaterialColor) { InjectMain(); InjectCellColorHandling(); InjectBuildingsSpecialCasesHandling(); try { _materialToCSharpInjector.InjectAsFirst("InjectionEntry", "OverlayChangedEntry", "OverlayMenu", "OnOverlayChanged"); } catch (Exception e) { Logger.Log("OverlayChangedEntry injection failed"); Logger.Log(e); Failed = true; } if (injectorState.InjectMaterialColorOverlayButton) { try { InjectToggleButton(); } catch (Exception e) { if (Logger != null) { Logger.Log("Overlay menu button injection failed"); Logger.Log(e); Failed = true; } } } } if (injectorState.InjectOnion) { try { InjectOnionPatcher(); } catch (Exception e) { Logger.Log("OnionPatcher injection failed"); Logger.Log(e); Failed = true; } } if (injectorState.CustomSensorRanges) { ExpandTemperatureSensorRange(injectorState.MaxSensorTemperature); ExpandGasSensorPressureRange(injectorState.MaxGasSensorPressure); ExpandLiquidSensorPressureRange(injectorState.MaxLiquidSensorPressure); } InjectPatchedSign(); FixGameUpdateExceptionHandling(); }