static StartUp() { var harmony = new Harmony("SRTSExpanded.smashphil.neceros"); harmony.PatchAll(Assembly.GetExecutingAssembly()); //Harmony.DEBUG = true; /* Mechanics and Rendering */ harmony.Patch(original: AccessTools.Method(type: typeof(CompTransporter), name: nameof(CompTransporter.CompGetGizmosExtra)), prefix: null, postfix: new HarmonyMethod(typeof(StartUp), nameof(NoLaunchGroupForSRTS))); harmony.Patch(original: AccessTools.Method(type: typeof(Settlement_TraderTracker), name: nameof(Settlement_TraderTracker.GiveSoldThingToPlayer)), prefix: null, postfix: null, transpiler: new HarmonyMethod(typeof(StartUp), nameof(GiveSoldThingsToSRTSTranspiler))); harmony.Patch(original: AccessTools.Method(type: typeof(WorldDynamicDrawManager), name: nameof(WorldDynamicDrawManager.DrawDynamicWorldObjects)), prefix: null, postfix: null, transpiler: new HarmonyMethod(typeof(StartUp), nameof(DrawDynamicSRTSObjectsTranspiler))); harmony.Patch(original: AccessTools.Method(type: typeof(ExpandableWorldObjectsUtility), name: nameof(ExpandableWorldObjectsUtility.ExpandableWorldObjectsOnGUI)), prefix: null, postfix: null, transpiler: new HarmonyMethod(typeof(StartUp), nameof(ExpandableIconDetourSRTSTranspiler))); harmony.Patch(original: AccessTools.Method(type: typeof(WorldSelector), name: "HandleWorldClicks"), prefix: null, postfix: new HarmonyMethod(typeof(StartUp), nameof(TravelingSRTSChangeDirection))); //Maybe add in the future ...? /*harmony.Patch(original: AccessTools.Method(type: typeof(Dialog_Trade), name: "SetupPlayerCaravanVariables"), prefix: null, postfix: null, transpiler: new HarmonyMethod(type: typeof(StartUp), name: nameof(SRTSAreNotTradeable)));*/ /* Bomb Runs */ harmony.Patch(original: AccessTools.Method(type: typeof(TransportPodsArrivalActionUtility), name: nameof(TransportPodsArrivalActionUtility.DropTravelingTransportPods)), prefix: new HarmonyMethod(typeof(StartUp), nameof(DropSRTSExactSpot))); harmony.Patch(original: AccessTools.Method(type: typeof(Targeter), name: nameof(Targeter.TargeterOnGUI)), prefix: null, postfix: new HarmonyMethod(typeof(StartUp), nameof(DrawBombingTargeter))); harmony.Patch(original: AccessTools.Method(type: typeof(Targeter), name: nameof(Targeter.ProcessInputEvents)), prefix: null, postfix: new HarmonyMethod(typeof(StartUp), nameof(ProcessBombingInputEvents))); harmony.Patch(original: AccessTools.Method(type: typeof(Targeter), name: nameof(Targeter.TargeterUpdate)), prefix: null, postfix: new HarmonyMethod(typeof(StartUp), nameof(BombTargeterUpdate))); /* Custom Settings */ harmony.Patch(original: AccessTools.Property(type: typeof(TravelingTransportPods), name: "TraveledPctStepPerTick").GetGetMethod(nonPublic: true), prefix: new HarmonyMethod(typeof(StartUp), nameof(CustomTravelSpeedSRTS))); harmony.Patch(original: AccessTools.Property(type: typeof(Dialog_LoadTransporters), name: "MassCapacity").GetGetMethod(nonPublic: true), prefix: new HarmonyMethod(typeof(StartUp), nameof(CustomSRTSMassCapacity))); harmony.Patch(original: AccessTools.Property(type: typeof(Dialog_Trade), name: "MassUsage").GetGetMethod(nonPublic: true), prefix: null, postfix: null, transpiler: new HarmonyMethod(typeof(StartUp), nameof(SRTSMassUsageCaravanTranspiler))); harmony.Patch(original: AccessTools.Method(type: typeof(CollectionsMassCalculator), name: nameof(CollectionsMassCalculator.CapacityLeftAfterTradeableTransfer)), prefix: new HarmonyMethod(typeof(StartUp), nameof(SRTSMassCapacityCaravan))); harmony.Patch(original: AccessTools.Method(type: typeof(Dialog_LoadTransporters), name: "AddItemsToTransferables"), prefix: null, postfix: null, transpiler: new HarmonyMethod(typeof(StartUp), nameof(AddItemsEntireMapNonHomeTranspiler))); /*harmony.Patch(original: AccessTools.Method(type: typeof(Dialog_LoadTransporters), name: "CheckForErrors"), prefix: null, postfix: null, transpiler: new HarmonyMethod(type: typeof(StartUp), name: nameof(ErrorOnNoPawnsTranspiler)));*/ harmony.Patch(original: AccessTools.Property(type: typeof(ResearchProjectDef), name: nameof(ResearchProjectDef.CostApparent)).GetGetMethod(), prefix: new HarmonyMethod(typeof(StartUp), nameof(ResearchCostApparent))); harmony.Patch(original: AccessTools.Property(type: typeof(ResearchProjectDef), name: nameof(ResearchProjectDef.IsFinished)).GetGetMethod(), prefix: new HarmonyMethod(typeof(StartUp), nameof(ResearchIsFinished))); harmony.Patch(original: AccessTools.Property(type: typeof(ResearchProjectDef), name: nameof(ResearchProjectDef.ProgressPercent)).GetGetMethod(), prefix: new HarmonyMethod(typeof(StartUp), nameof(ResearchProgressPercent))); harmony.Patch(original: AccessTools.Method(type: typeof(ResearchManager), name: nameof(ResearchManager.FinishProject)), prefix: null, postfix: null, transpiler: new HarmonyMethod(typeof(StartUp), nameof(ResearchFinishProjectTranspiler))); harmony.Patch(original: AccessTools.Method(type: typeof(MainTabWindow_Research), name: "DrawLeftRect"), prefix: null, postfix: null, transpiler: new HarmonyMethod(typeof(StartUp), nameof(ResearchTranslatedCostTranspiler))); harmony.Patch(original: AccessTools.Method(type: typeof(ResearchManager), name: nameof(ResearchManager.DebugSetAllProjectsFinished)), prefix: null, postfix: new HarmonyMethod(typeof(StartUp), nameof(ResearchFinishAllSRTS))); harmony.Patch(original: AccessTools.Property(type: typeof(ResearchProjectDef), name: nameof(ResearchProjectDef.PrerequisitesCompleted)).GetGetMethod(), prefix: null, postfix: new HarmonyMethod(typeof(StartUp), nameof(CustomPrerequisitesCompleted))); //harmony.Patch(original: AccessTools.Method(type: typeof(MainTabWindow_Research), name: "DrawRightRect"), prefix: null, postfix: null, // transpiler: new HarmonyMethod(typeof(StartUp), // nameof(DrawCustomResearchTranspiler))); harmony.Patch(original: AccessTools.Method(type: typeof(MainTabWindow_Research), name: "DrawResearchPrereqs"), prefix: null, postfix: new HarmonyMethod(typeof(StartUp), nameof(DrawCustomResearchPrereqs))); harmony.Patch(original: AccessTools.Method(type: typeof(Caravan), name: nameof(Caravan.GetGizmos)), prefix: null, postfix: new HarmonyMethod(typeof(StartUp), nameof(LaunchAndBombGizmosPassthrough))); // Vehicles update /*harmony.Patch(original: AccessTools.Method(typeof(Targeter), nameof(Targeter.TargeterOnGUI)), prefix: null, postfix: new HarmonyMethod(typeof(ShipHarmony), nameof(DrawCannonTargeter))); harmony.Patch(original: AccessTools.Method(typeof(Targeter), nameof(Targeter.ProcessInputEvents)), prefix: null, postfix: new HarmonyMethod(typeof(ShipHarmony), nameof(ProcessCannonInputEvents))); harmony.Patch(original: AccessTools.Method(typeof(Targeter), nameof(Targeter.TargeterUpdate)), prefix: null, postfix: new HarmonyMethod(typeof(ShipHarmony), nameof(CannonTargeterUpdate)));*/ /* Destructive Patch Fixes */ bool sos2Flag = false; if (ModLister.HasActiveModWithName("Save Our Ship 2")) { sos2Flag = true; Log.Message("[SRTSExpanded] Overriding SOS2 Destructive Patches."); } harmony.Patch(original: AccessTools.Method(type: typeof(Dialog_LoadTransporters), name: "AddPawnsToTransferables"), prefix: sos2Flag ? new HarmonyMethod(typeof(StartUp), nameof(CustomOptionsPawnsToTransportOverride)) : null, postfix: null, transpiler: sos2Flag ? null : new HarmonyMethod(typeof(StartUp), nameof(CustomOptionsPawnsToTransportTranspiler))); /* Unpatch Save our Ship 2 's destructive and incompetent patch on transporter pawns */ //harmony.Unpatch(AccessTools.Method(type: typeof(Dialog_LoadTransporters), name: "AddPawnsToTransferables"), HarmonyPatchType.Prefix, "HugsLib.ShipInteriorMod2"); /*bool flag = harmony.HasAnyPatches("HugsLib.ShipInteriorMod2"); Log.Message("SoS2: " + flag);*/ }
// Doesn't load the type public static bool HasAttr(ICustomAttributeProvider provider, Type attrType) { if (IsDefinedInternal == null) { IsDefinedInternal = (Func <ICustomAttributeProvider, Type, bool>)Delegate.CreateDelegate(typeof(Func <ICustomAttributeProvider, Type, bool>), AccessTools.Method(Type.GetType("System.MonoCustomAttrs"), "IsDefinedInternal")); } return(IsDefinedInternal(provider, attrType)); }
public static bool InitMenuItemScript(SceneEdit.SMenuItem mi, string f_strMenuFileName, bool f_bMan, out string IconTex) { var fetchedField = AccessTools.DeclaredField(typeof(SceneEdit), "m_byItemFileBuffer"); var fetchedVal = fetchedField.GetValue(@this) as byte[]; IconTex = null; if (f_strMenuFileName.IndexOf("mod_") == 0) { string modPathFileName = Menu.GetModPathFileName(f_strMenuFileName); return(!string.IsNullOrEmpty(modPathFileName) && SceneEdit.InitModMenuItemScript(mi, modPathFileName)); } try { using (AFileBase afileBase = GameUty.FileOpen(f_strMenuFileName, null)) { NDebug.Assert(afileBase.IsValid(), "メニューファイルが存在しません。 :" + f_strMenuFileName); if (fetchedVal == null) { fetchedVal = new byte[System.Math.Max(500000, afileBase.GetSize())]; } else if (fetchedVal.Length < afileBase.GetSize()) { fetchedVal = new byte[afileBase.GetSize()]; } afileBase.Read(ref fetchedVal, afileBase.GetSize()); } } catch (Exception ex) { Main.logger.LogError(string.Concat(new string[] { "メニューファイルがが読み込めませんでした。 : ", f_strMenuFileName, " : ", ex.Message, " : StackTrace :\n", ex.StackTrace })); throw ex; } BinaryReader binaryReader = new BinaryReader(new MemoryStream(fetchedVal), Encoding.UTF8); string text = binaryReader.ReadString(); NDebug.Assert(text == "CM3D2_MENU", "ProcScriptBin 例外 : ヘッダーファイルが不正です。" + text); int num = binaryReader.ReadInt32(); string path = binaryReader.ReadString(); string text2 = binaryReader.ReadString(); string text3 = binaryReader.ReadString(); string text4 = binaryReader.ReadString(); long num2 = (long)binaryReader.ReadInt32(); int num3 = 0; string text5 = null; string text6 = string.Empty; string text7 = string.Empty; try { for (; ;) { int num4 = (int)binaryReader.ReadByte(); text7 = text6; text6 = string.Empty; if (num4 == 0) { break; } for (int i = 0; i < num4; i++) { text6 = text6 + "\"" + binaryReader.ReadString() + "\" "; } if (!(text6 == string.Empty)) { string stringCom = UTY.GetStringCom(text6); string[] stringList = UTY.GetStringList(text6); if (stringCom == "name") { string text8 = stringList[1]; string text9 = string.Empty; string arg = string.Empty; int j = 0; while (j < text8.Length && text8[j] != '\u3000' && text8[j] != ' ') { text9 += text8[j]; j++; } while (j < text8.Length) { arg += text8[j]; j++; } mi.m_strMenuName = text9; } else if (stringCom == "setumei") { mi.m_strInfo = stringList[1]; mi.m_strInfo = mi.m_strInfo.Replace("《改行》", "\n"); } else if (stringCom == "category") { string strCateName = stringList[1].ToLower(); mi.m_strCateName = strCateName; try { mi.m_mpn = (MPN)Enum.Parse(typeof(MPN), mi.m_strCateName); } catch { Main.logger.LogWarning("カテゴリがありません。" + mi.m_strCateName); mi.m_mpn = MPN.null_mpn; } } else if (stringCom == "color_set") { try { mi.m_eColorSetMPN = (MPN)Enum.Parse(typeof(MPN), stringList[1].ToLower()); } catch { Main.logger.LogWarning("カテゴリがありません。" + mi.m_strCateName); } if (stringList.Length >= 3) { mi.m_strMenuNameInColorSet = stringList[2].ToLower(); } } else if (stringCom == "tex" || stringCom == "テクスチャ変更") { MaidParts.PARTS_COLOR pcMultiColorID = MaidParts.PARTS_COLOR.NONE; if (stringList.Length == 6) { string text10 = stringList[5]; try { pcMultiColorID = (MaidParts.PARTS_COLOR)Enum.Parse(typeof(MaidParts.PARTS_COLOR), text10.ToUpper()); } catch { NDebug.Assert("無限色IDがありません。" + text10, false); } mi.m_pcMultiColorID = pcMultiColorID; } } else if (stringCom == "icon" || stringCom == "icons") { text5 = stringList[1]; } else if (!(stringCom == "iconl")) { if (!(stringCom == "setstr")) { if (!(stringCom == "アイテムパラメータ")) { if (stringCom == "saveitem") { string text11 = stringList[1]; if (text11 == string.Empty) { Main.logger.LogError("err SaveItem \"" + text11); } if (text11 == null) { Main.logger.LogError("err SaveItem null=\"" + text11); } if (text11 != string.Empty) { } } else if (!(stringCom == "catno")) { if (stringCom == "additem") { num3++; } else if (stringCom == "unsetitem") { mi.m_boDelOnly = true; } else if (stringCom == "priority") { mi.m_fPriority = float.Parse(stringList[1]); } else if (stringCom == "メニューフォルダ" && stringList[1].ToLower() == "man") { mi.m_bMan = true; } } } } } } } } catch (Exception ex2) { Main.logger.LogError(string.Concat(new string[] { "Exception ", Path.GetFileName(path), " 現在処理中だった行 = ", text6, " 以前の行 = ", text7, " ", ex2.Message, "StackTrace:\n", ex2.StackTrace })); throw ex2; } if (text5 != null && text5 != string.Empty) { try { IconTex = text5; //mi.m_texIcon = ImportCM.CreateTexture(text5); } catch (Exception) { Main.logger.LogError("Error:"); } } binaryReader.Close(); return(true); }
static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(FirstPersonFlyingController), "Start"); yield return AccessTools.Method(typeof(FirstPersonFlyingController), "OnEnable"); yield return AccessTools.Method(typeof(FirstPersonFlyingController), "OnDisable"); }
static MethodBase TargetMethod() { var parameters = new Type[] { AccessTools.Inner(typeof(Messages), "LiveMessage"), typeof(MessageSound) }; return(AccessTools.Method(typeof(Messages), "Message", parameters)); }
public static object CreateInstance(this Type type) => AccessTools.CreateInstance(type);
public static MethodInfo GetMethod(this object instance, string method, Type[] parameters = null, Type[] generics = null) => AccessTools.Method(instance.GetType(), method, parameters, generics);
internal static MethodInfo TargetMethod() { return(AccessTools.Method(PyUtils.getTypeSDV("GameLocation"), "isActionableTile")); }
internal static MethodInfo TargetMethod() { return(AccessTools.Method(PyUtils.getTypeSDV("Game1"), "tryToCheckAt")); }
internal static MethodInfo TargetMethod() { return(AccessTools.Method(PyUtils.getTypeSDV("Buildings.Building"), "load")); }
internal static MethodInfo TargetMethod() { return(AccessTools.Method(PyUtils.getTypeSDV("GameLocation"), "performTouchAction")); }
public static bool Prefix(HumanDescriptionDef __instance, ref Text __result) { var instance = __instance; if (instance.Details == null) { __result = new Text(); return(false); } if (instance.GetLocalizedDetails() != null && (bool)AccessTools.Field(typeof(BaseDescriptionDef), "detailsParsed").GetValue(instance)) { __result = instance.GetLocalizedDetails(); return(false); } Text text = new Text(); if (instance.isGenerated) { string[] strArray = instance.Details.Split(new string[4] { Environment.NewLine, "<b>", ":</b>", "\n\n" }, StringSplitOptions.RemoveEmptyEntries); // pad the array length to make it even if (strArray.Length % 2 != 0) { Array.Resize(ref strArray, strArray.Length + 1); } int index = 0; while (index < strArray.Length) { text.Append("<b>{0}:</b> {1}\n\n", (object[])new string[2] { strArray[index], strArray[index + 1] }); index += 2; } } else if (instance.isCommander) { string details = instance.Details; string[] separator = new string[1] { Environment.NewLine }; int num = 1; foreach (object obj in details.Split(separator, (StringSplitOptions)num)) { text.Append("{0} \n\n", obj); } } else { text.Append(instance.Details, new object[0]); } AccessTools.Field(typeof(BaseDescriptionDef), "detailsParsed").SetValue(instance, true); AccessTools.Field(typeof(BaseDescriptionDef), "detailsParsed").SetValue(instance, text); __result = text; return(false); }
public static IEnumerable<CodeInstruction> ResearchTranslatedCostTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator ilg) { List<CodeInstruction> instructionList = instructions.ToList(); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.opcode == OpCodes.Ldflda && (FieldInfo)instruction.operand == AccessTools.Field(type: typeof(ResearchProjectDef), name: "baseCost")) { Label label = ilg.DefineLabel(); Label brlabel = ilg.DefineLabel(); yield return new CodeInstruction(opcode: OpCodes.Ldarg_0); yield return new CodeInstruction(opcode: OpCodes.Ldfld, operand: AccessTools.Field(type: typeof(MainTabWindow_Research), name: "selectedProject")); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(SRTSHelper), name: nameof(SRTSHelper.ContainedInDefProjects))); yield return new CodeInstruction(opcode: OpCodes.Brfalse, label); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(SRTSHelper), name: nameof(SRTSHelper.GetResearchStatString))); yield return new CodeInstruction(opcode: OpCodes.Br, brlabel); instruction.labels.Add(label); instructionList[i + 4].labels.Add(brlabel); } yield return instruction; } }
/*public static IEnumerable<CodeInstruction> ErrorOnNoPawnsTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator ilg) { List<CodeInstruction> instructionsList = instructions.ToList(); for (int i = 0; i < instructionsList.Count; i++) { CodeInstruction instruction = instructionsList[i]; if (instruction.opcode == OpCodes.Ldc_I4_1 && instructionsList[i + 1].opcode == OpCodes.Ret && SRTSMod.mod.settings.passengerLimits) { Label label = ilg.DefineLabel(); Label label2 = ilg.DefineLabel(); Label brlabelMin = ilg.DefineLabel(); Label brlabelMax = ilg.DefineLabel(); yield return new CodeInstruction(opcode: OpCodes.Ldarg_0); yield return new CodeInstruction(opcode: OpCodes.Ldfld, operand: AccessTools.Field(type: typeof(Dialog_LoadTransporters), name: "transporters")); yield return new CodeInstruction(opcode: OpCodes.Ldarg_1); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(StartUp), name: nameof(StartUp.NoPawnInSRTS))); yield return new CodeInstruction(opcode: OpCodes.Brfalse_S, label); yield return new CodeInstruction(opcode: OpCodes.Ldstr, operand: "SRTSNoPilot"); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(Translator), parameters: new Type[] { typeof(string) }, name: nameof(Translator.Translate))); yield return new CodeInstruction(opcode: OpCodes.Ldsfld, operand: AccessTools.Field(type: typeof(MessageTypeDefOf), name: nameof(MessageTypeDefOf.RejectInput))); yield return new CodeInstruction(opcode: OpCodes.Ldc_I4_0); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(Messages), parameters: new Type[] { typeof(string), typeof(MessageTypeDef), typeof(bool) }, name: nameof(Messages.Message))); yield return new CodeInstruction(opcode: OpCodes.Ldc_I4_0); yield return new CodeInstruction(opcode: OpCodes.Ret); yield return new CodeInstruction(opcode: OpCodes.Ldarg_0) { labels = new List<Label> { label } }; yield return new CodeInstruction(opcode: OpCodes.Ldfld, operand: AccessTools.Field(type: typeof(Dialog_LoadTransporters), name: "transporters")); yield return new CodeInstruction(opcode: OpCodes.Ldarg_1); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(StartUp), name: nameof(StartUp.MinPawnRestrictionsSRTS))); yield return new CodeInstruction(opcode: OpCodes.Brtrue, brlabelMin); yield return new CodeInstruction(opcode: OpCodes.Ldarg_0); yield return new CodeInstruction(opcode: OpCodes.Ldfld, operand: AccessTools.Field(type: typeof(Dialog_LoadTransporters), name: "transporters")); yield return new CodeInstruction(opcode: OpCodes.Ldarg_1); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(StartUp), name: nameof(StartUp.MaxPawnRestrictionsSRTS))); yield return new CodeInstruction(opcode: OpCodes.Brtrue, brlabelMax); yield return new CodeInstruction(opcode: OpCodes.Br, label2); yield return new CodeInstruction(opcode: OpCodes.Ldarg_0) { labels = new List<Label> { brlabelMin } }; yield return new CodeInstruction(opcode: OpCodes.Ldfld, operand: AccessTools.Field(type: typeof(Dialog_LoadTransporters), name: "transporters")); yield return new CodeInstruction(opcode: OpCodes.Ldc_I4_1); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(StartUp), name: nameof(StartUp.MinMaxString))); yield return new CodeInstruction(opcode: OpCodes.Ldsfld, operand: AccessTools.Field(type: typeof(MessageTypeDefOf), name: nameof(MessageTypeDefOf.RejectInput))); yield return new CodeInstruction(opcode: OpCodes.Ldc_I4_0); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(Messages), parameters: new Type[] { typeof(string), typeof(MessageTypeDef), typeof(bool) }, name: nameof(Messages.Message))); yield return new CodeInstruction(opcode: OpCodes.Ldc_I4_0); yield return new CodeInstruction(opcode: OpCodes.Ret); yield return new CodeInstruction(opcode: OpCodes.Ldarg_0) { labels = new List<Label> { brlabelMax } }; yield return new CodeInstruction(opcode: OpCodes.Ldfld, operand: AccessTools.Field(type: typeof(Dialog_LoadTransporters), name: "transporters")); yield return new CodeInstruction(opcode: OpCodes.Ldc_I4_0); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(StartUp), name: nameof(StartUp.MinMaxString))); yield return new CodeInstruction(opcode: OpCodes.Ldsfld, operand: AccessTools.Field(type: typeof(MessageTypeDefOf), name: nameof(MessageTypeDefOf.RejectInput))); yield return new CodeInstruction(opcode: OpCodes.Ldc_I4_0); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(Messages), parameters: new Type[] { typeof(string), typeof(MessageTypeDef), typeof(bool) }, name: nameof(Messages.Message))); yield return new CodeInstruction(opcode: OpCodes.Ldc_I4_0); yield return new CodeInstruction(opcode: OpCodes.Ret); instruction.labels.Add(label2); } yield return instruction; } }*/ /*public static void DrawCannonTargeter() { HelperMethods.CannonTargeter.TargeterOnGUI(); } public static void ProcessCannonInputEvents() { HelperMethods.CannonTargeter.ProcessInputEvents(); } public static void CannonTargeterUpdate() { HelperMethods.CannonTargeter.TargeterUpdate(); }*/ /// <summary> /// Insert all items on map (non minifiable) if map is not player home. /// </summary> /// <param name="instructions"></param> /// <param name="ilg"></param> /// <returns></returns> public static IEnumerable<CodeInstruction> AddItemsEntireMapNonHomeTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator ilg) { List<CodeInstruction> instructionList = instructions.ToList(); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (SRTSMod.mod.settings.displayHomeItems && instruction.opcode == OpCodes.Call && (MethodInfo)instruction.operand == AccessTools.Method(type: typeof(CaravanFormingUtility), name: nameof(CaravanFormingUtility.AllReachableColonyItems))) { Label label = ilg.DefineLabel(); ///Check if SRTS is present inside dialog menu transferables yield return new CodeInstruction(opcode: OpCodes.Ldarg_0); yield return new CodeInstruction(opcode: OpCodes.Ldfld, operand: AccessTools.Field(type: typeof(Dialog_LoadTransporters), name: "transporters")); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(SRTSHelper), name: nameof(SRTSHelper.SRTSLauncherSelected))); yield return new CodeInstruction(opcode: OpCodes.Brfalse, label); ///Check if player / SRTS selected is inside non playerhome map yield return new CodeInstruction(opcode: OpCodes.Ldarg_0); yield return new CodeInstruction(opcode: OpCodes.Ldfld, operand: AccessTools.Field(type: typeof(Dialog_LoadTransporters), name: "map")); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(SRTSHelper), name: nameof(SRTSHelper.SRTSNonPlayerHomeMap))); yield return new CodeInstruction(opcode: OpCodes.Brfalse, label); ///Pop top 3 values from stack, which are all false yield return new CodeInstruction(opcode: OpCodes.Pop); yield return new CodeInstruction(opcode: OpCodes.Pop); yield return new CodeInstruction(opcode: OpCodes.Pop); ///Push true, true, false onto stack, to change resulting method call parameters yield return new CodeInstruction(opcode: OpCodes.Ldc_I4_1); yield return new CodeInstruction(opcode: OpCodes.Ldc_I4_1); yield return new CodeInstruction(opcode: OpCodes.Ldc_I4_0); instruction.labels.Add(label); } yield return instruction; } }
public static T GetField <T>(this object instance, string fieldname) => (T)AccessTools.Field(instance.GetType(), fieldname).GetValue(instance);
internal static MethodInfo TargetMethod() { return(AccessTools.Method(PyUtils.getTypeSDV("GameLocation"), "tryToAddCritters")); }
public static T GetProperty <T>(this object instance, string fieldname) => (T)AccessTools.Property(instance.GetType(), fieldname).GetValue(instance);
internal static MethodInfo TargetMethod() { return(AccessTools.Method(PyUtils.getTypeSDV("Game1"), "getLocationRequest")); }
public static void SetField(this object instance, string fieldname, object setVal) => AccessTools.Field(instance.GetType(), fieldname).SetValue(instance, setVal);
internal static MethodInfo TargetMethod() { return(AccessTools.Method(PyUtils.getTypeSDV("GameLocation"), "getSourceRectForObject", new[] { typeof(int) })); }
static IEnumerable <CodeInstruction> Transpiler(MethodBase original, IEnumerable <CodeInstruction> instructions, ILGenerator gen) { int idx; var label = gen.DefineLabel(); var parameter = original.GetParameters(); idx = 0; foreach (var pInfo in parameter) { var argIndex = idx++ + (original.IsStatic ? 0 : 1); var pType = pInfo.ParameterType; if (pInfo.IsOut || pInfo.IsRetval) { yield return(new CodeInstruction(OpCodes.Ldarg, argIndex)); yield return(CreateDefaultCodes(gen, pType).Last()); if (AccessTools.IsClass(pType)) { yield return(new CodeInstruction(OpCodes.Stind_Ref)); } if (AccessTools.IsValue(pType)) { if (pType == typeof(float)) { yield return(new CodeInstruction(OpCodes.Stind_R4, (float)0)); } else if (pType == typeof(double)) { yield return(new CodeInstruction(OpCodes.Stind_R8, (double)0)); } else if (pType == typeof(long)) { yield return(new CodeInstruction(OpCodes.Stind_I8, (long)0)); } else { yield return(new CodeInstruction(OpCodes.Stind_I4, 0)); } } } } yield return(new CodeInstruction(OpCodes.Ldstr, original.DeclaringType.FullName)); yield return(new CodeInstruction(OpCodes.Ldc_I4, original.MetadataToken)); // Note: While some .NET runtimes allow representing 0 (via ldc.i*.0) as null, at least mono doesn't allow that - just use ldnull instead. yield return(new CodeInstruction(original.IsStatic ? OpCodes.Ldnull : OpCodes.Ldarg_0)); yield return(new CodeInstruction(OpCodes.Ldc_I4, parameter.Length)); yield return(new CodeInstruction(OpCodes.Newarr, typeof(object))); idx = 0; var arrayIdx = 0; foreach (var pInfo in parameter) { var argIndex = idx++ + (original.IsStatic ? 0 : 1); var pType = pInfo.ParameterType; yield return(new CodeInstruction(OpCodes.Dup)); yield return(new CodeInstruction(OpCodes.Ldc_I4, arrayIdx++)); yield return(new CodeInstruction(OpCodes.Ldarg, argIndex)); if (pInfo.IsOut || pInfo.IsRetval) { if (pType.IsValueType) { yield return(new CodeInstruction(OpCodes.Ldobj, pType)); } else { yield return(new CodeInstruction(OpCodes.Ldind_Ref)); } } if (pType.IsValueType) { yield return(new CodeInstruction(OpCodes.Box, pType)); } yield return(new CodeInstruction(OpCodes.Stelem_Ref)); } yield return(new CodeInstruction(OpCodes.Call, m_General)); yield return(new CodeInstruction(OpCodes.Brtrue, label)); foreach (var code in CreateDefaultCodes(gen, AccessTools.GetReturnedType(original))) { yield return(code); } yield return(new CodeInstruction(OpCodes.Ret)); var list = instructions.ToList(); list.First().labels.Add(label); foreach (var instruction in list) { yield return(instruction); } }
internal static MethodInfo TargetMethod() { return(AccessTools.Method(PyUtils.getTypeSDV("GameLocation"), "Equals", new[] { PyUtils.getTypeSDV("GameLocation") })); }
public static MethodInfo TargetMethod() { return(AccessTools.Method(typeof(SavedGame), "PushActorData")); }
internal static MethodInfo TargetMethod() { return(AccessTools.Method(PyUtils.getTypeSDV("GameLocation"), "checkEventPrecondition")); }
/// <summary>Try rewriting the direct field reference with reflection access.</summary> /// <param name="cil">The CIL processor.</param> /// <param name="module">The assembly module containing the instruction.</param> /// <param name="instruction">The CIL instruction to rewrite.</param> /// <param name="fieldRef">The field reference.</param> /// <param name="isRead">Whether the field is being read; else it's being written to.</param> /// <param name="isStatic">Whether the field is static field; else it's instance field.</param> /// <param name="declaringType">The type on which the field was defined.</param> private bool TryRewriteWithReflection(ILProcessor cil, ModuleDefinition module, Instruction instruction, FieldReference fieldRef, bool isRead, bool isStatic) { MethodReference getTypeFromHandleRef = module.ImportReference(typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) })); MethodReference getFieldRef = module.ImportReference(typeof(Type).GetMethod("GetField", new Type[] { typeof(string), typeof(BindingFlags) })); VariableDefinition varInstance = null; if (isRead) { if (!isStatic) { varInstance = new VariableDefinition(fieldRef.DeclaringType); cil.Body.Variables.Add(varInstance); } // inverse order insert // load instance (origin logic, if not static) // stloc.s 0 // ldtoken MonoGame.Framework.Patcher.Test // call System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle) // ldstr text // ldc.i4.s 60 // callvirt System.Reflection.FieldInfo System.Type::GetField(System.String,System.Reflection.BindingFlags) // ldloc.0 // callvirt System.Object System.Reflection.FieldInfo::GetValue(System.Object) // castclass System.String if (fieldRef.FieldType.IsValueType) { cil.InsertAfter(instruction, cil.Create(OpCodes.Unbox_Any, fieldRef.FieldType)); } else { cil.InsertAfter(instruction, cil.Create(OpCodes.Castclass, fieldRef.FieldType)); } MethodReference getValueMethodRef = module.ImportReference(AccessTools.Method(typeof(FieldInfo), nameof(FieldInfo.GetValue))); cil.InsertAfter(instruction, cil.Create(OpCodes.Callvirt, getValueMethodRef)); if (!isStatic) { cil.InsertAfter(instruction, cil.Create(OpCodes.Ldloc_S, varInstance)); } else { cil.InsertAfter(instruction, cil.Create(OpCodes.Ldnull)); } cil.InsertAfter(instruction, cil.Create(OpCodes.Callvirt, getFieldRef)); cil.InsertAfter(instruction, cil.Create(OpCodes.Ldc_I4_S, (sbyte)60)); cil.InsertAfter(instruction, cil.Create(OpCodes.Ldstr, fieldRef.Name)); cil.InsertAfter(instruction, cil.Create(OpCodes.Call, getTypeFromHandleRef)); if (!isStatic) { // prohibit replace remove entry point (may cause jump logic broken) cil.InsertAfter(instruction, cil.Create(OpCodes.Nop)); instruction.OpCode = OpCodes.Stloc_S; instruction.Operand = varInstance; instruction = instruction.Next; } } else { VariableDefinition varValue = null; if (!isStatic) { varInstance = new VariableDefinition(fieldRef.DeclaringType); cil.Body.Variables.Add(varInstance); } varValue = new VariableDefinition(fieldRef.FieldType); cil.Body.Variables.Add(varValue); // inverse order insert // load instance (origin logic, if not static) // load value (origin logic) // stloc.s 0 // ldtoken Patcher.TestClass // call System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle) // ldstr text // ldc.i4.s 60 // callvirt System.Reflection.FieldInfo System.Type::GetField(System.String,System.Reflection.BindingFlags) // ldloc.0 // ldloc.1 // callvirt System.Object System.Reflection.FieldInfo::SetValue(System.Object, System.Object) MethodReference setValueMethodRef = module.ImportReference(AccessTools.Method(typeof(FieldInfo), nameof(FieldInfo.SetValue), new Type[] { typeof(object), typeof(object) })); cil.InsertAfter(instruction, cil.Create(OpCodes.Callvirt, setValueMethodRef)); cil.InsertAfter(instruction, cil.Create(OpCodes.Ldloc_S, varValue)); if (isStatic) { cil.InsertAfter(instruction, cil.Create(OpCodes.Ldnull)); } else { cil.InsertAfter(instruction, cil.Create(OpCodes.Ldloc_S, varInstance)); } cil.InsertAfter(instruction, cil.Create(OpCodes.Callvirt, getFieldRef)); cil.InsertAfter(instruction, cil.Create(OpCodes.Ldc_I4_S, (sbyte)60)); cil.InsertAfter(instruction, cil.Create(OpCodes.Ldstr, fieldRef.Name)); cil.InsertAfter(instruction, cil.Create(OpCodes.Call, getTypeFromHandleRef)); // prohibit replace remove entry point (may cause jump logic broken) instruction.OpCode = OpCodes.Stloc_S; instruction.Operand = varValue; cil.InsertAfter(instruction, cil.Create(OpCodes.Nop)); if (!isStatic) { cil.InsertAfter(instruction, cil.Create(OpCodes.Stloc_S, varInstance)); instruction = instruction.Next; } instruction = instruction.Next; } // rewrite field ref to ldtoken instruction.OpCode = OpCodes.Ldtoken; instruction.Operand = fieldRef.DeclaringType; this.Phrases.Add($"{fieldRef.DeclaringType.Name}.{fieldRef.Name} (field ref => reflection ref)"); // #if SMAPI_FOR_MOBILE // this.Phrases.Add($"{cil.Body.Method.FullName} => {cil.Body.Instructions.Select(ins => ins.ToString()).Join(null, ";")}"); // #endif cil.Body.MaxStackSize += 5; return(this.MarkRewritten()); }
internal static MethodInfo TargetMethod() { return(AccessTools.Method(Type.GetType("Pong.ModEntry, Pong"), "OnCursorMoved")); }
public static IEnumerator test2() { Stopwatch test = new Stopwatch(); Main.logger.LogError("Coroutine was successfully engaged!"); while (GameMain.Instance.CharacterMgr.IsBusy()) { yield return(null); } MenuDataBase menuDataBase = GameMain.Instance.MenuDataBase; while (!menuDataBase.JobFinished()) { yield return(null); } test.Start(); Main.logger.LogError("Reaching first access method."); AccessTools.Method(typeof(SceneEdit), "InitCategoryList").Invoke(@this, null); //@this.InitCategoryList(); int fileCount = menuDataBase.GetDataSize(); ConcurrentQueue <SceneEdit.SMenuItem> menuList = new ConcurrentQueue <SceneEdit.SMenuItem>(); @this.m_menuRidDic = new Dictionary <int, SceneEdit.SMenuItem>(fileCount); var menuRidDicThreadSafe = new ConcurrentDictionary <int, SceneEdit.SMenuItem>(@this.m_menuRidDic); ConcurrentDictionary <int, ConcurrentQueue <int> > menuGroupMemberDic = new ConcurrentDictionary <int, ConcurrentQueue <int> >(); float time = Time.realtimeSinceStartup; for (int i = 0; i < fileCount; i++) { menuDataBase.SetIndex(i); string fileName = menuDataBase.GetMenuFileName(); string parent_filename = menuDataBase.GetParentMenuFileName(); if (GameMain.Instance.CharacterMgr.status.IsHavePartsItem(fileName)) { SceneEdit.SMenuItem mi = new SceneEdit.SMenuItem(); mi.m_strMenuFileName = fileName; mi.m_nMenuFileRID = fileName.GetHashCode(); try { SceneEdit.ReadMenuItemDataFromNative(mi, i); } catch (Exception ex) { Main.logger.LogError(string.Concat(new string[] { "ReadMenuItemDataFromNative 例外/", fileName, "/", ex.Message, " StackTrace/", ex.StackTrace })); } if (!mi.m_bMan && @this.editItemTextureCache.IsRegister(mi.m_nMenuFileRID)) { AccessTools.Method(typeof(SceneEdit), "AddMenuItemToList").Invoke(@this, new object[] { mi }); //@this.AddMenuItemToList(mi); menuList.Enqueue(mi); if (!menuRidDicThreadSafe.ContainsKey(mi.m_nMenuFileRID)) { menuRidDicThreadSafe[mi.m_nMenuFileRID] = mi; } string parentMenuName = AccessTools.Method(typeof(SceneEdit), "GetParentMenuFileName").Invoke(@this, new object[] { mi }) as string; //string parentMenuName = SceneEdit.GetParentMenuFileName(mi); if (!string.IsNullOrEmpty(parentMenuName)) { int hashCode = parentMenuName.GetHashCode(); if (!menuGroupMemberDic.ContainsKey(hashCode)) { menuGroupMemberDic[hashCode] = new ConcurrentQueue <int>(); } menuGroupMemberDic[hashCode].Enqueue(mi.m_strMenuFileName.ToLower().GetHashCode()); } else if (mi.m_strCateName.IndexOf("set_") != -1 && mi.m_strMenuFileName.IndexOf("_del") == -1) { mi.m_bGroupLeader = true; mi.m_listMember = new List <SceneEdit.SMenuItem>(); mi.m_listMember.Add(mi); } if (0.5f < Time.realtimeSinceStartup - time) { yield return(null); time = Time.realtimeSinceStartup; } } } } Main.logger.LogError($"Reaching the load ForEach at {test.Elapsed}."); //Parallel.ForEach(GameUty.ModOnlysMenuFiles, (strFileName) => Task.Factory.StartNew(new Action(() => { foreach (string strFileName in GameUty.ModOnlysMenuFiles) { Stopwatch test2 = new Stopwatch(); test2.Start(); //Main.logger.LogError("Invoking GetMenuItemSetUP"); SceneEdit.SMenuItem mi2 = new SceneEdit.SMenuItem(); if (Main.GetMenuItemSetUP(mi2, strFileName, out string IconTex, false)) { //Main.logger.LogError("Managed to setup menu item correctly. Adding to list to continue processing..."); ListOfIconLoads[mi2] = IconTex; } //Thread.Sleep(100); Main.logger.LogError("Finished One GetMenuItemSetUP in " + test2.Elapsed); } } //); )).Wait(); Main.logger.LogError($"We've finished SceneEdit.SMenuItem {test.Elapsed}"); SetupDone = true; while (IconLoadDone != true) { yield return(null); } Main.logger.LogError($"Now we've finished loading icons into each menu at {test.Elapsed}."); //Parallel.ForEach(ListOfContinues, (mi2) => foreach (SceneEdit.SMenuItem mi2 in ListOfContinues) { Stopwatch test2 = new Stopwatch(); if (!mi2.m_bMan && !(mi2.m_texIconRef == null)) { test2.Start(); //Main.logger.LogError("Invoking addmenuitemtolist"); AccessTools.Method(typeof(SceneEdit), "AddMenuItemToList").Invoke(@this, new object[] { mi2 }); //@this.AddMenuItemToList(mi2); //Main.logger.LogError($"Done invoking AddMenuItemToList at: {test2.Elapsed}"); if (!menuRidDicThreadSafe.ContainsKey(mi2.m_nMenuFileRID)) { menuRidDicThreadSafe[mi2.m_nMenuFileRID] = mi2; } //Main.logger.LogError("Invoking GetParentMenuFileName"); string parentMenuName2 = AccessTools.Method(typeof(SceneEdit), "GetParentMenuFileName").Invoke(@this, new object[] { mi2 }) as string; //string parentMenuName2 = SceneEdit.GetParentMenuFileName(mi2); //Main.logger.LogError($"Done Invoking GetParentMenuFileName at: {test2.Elapsed}"); if (!string.IsNullOrEmpty(parentMenuName2)) { int hashCode2 = parentMenuName2.GetHashCode(); if (!menuGroupMemberDic.ContainsKey(hashCode2)) { menuGroupMemberDic[hashCode2] = new ConcurrentQueue <int>(); } menuGroupMemberDic[hashCode2].Enqueue(mi2.m_strMenuFileName.ToLower().GetHashCode()); } else if (mi2.m_strCateName.IndexOf("set_") != -1 && mi2.m_strMenuFileName.IndexOf("_del") == -1) { mi2.m_bGroupLeader = true; mi2.m_listMember = new List <SceneEdit.SMenuItem>(); mi2.m_listMember.Add(mi2); } /* * if (true || 0.5f < Time.realtimeSinceStartup - time) * { * //yield return null; * Main.logger.LogError($"Sleeping thread, 100ms..."); * //Thread.Sleep(20); * time = Time.realtimeSinceStartup; * }*/ Main.logger.LogError($"Finished processing one menu file in {test2.Elapsed}"); } } //); Main.logger.LogError($"Finished previous foreach at {test.Elapsed}\nInvoking coroutines..."); SetupDone = true; //@this.m_menuRidDic = menuRidDicThreadSafe //.ToDictionary(t => t.Key, t => t.Value); Main.logger.LogError($"Converted Dictionary back..."); //yield return @this.StartCoroutine(@this.CoLoadWait()); yield return(@this.StartCoroutine(AccessTools.Method(typeof(SceneEdit), "CoLoadWait").Invoke(@this, null) as IEnumerator)); Main.logger.LogError($"Starting problematic coroutine."); //yield return @this.StartCoroutine(@this.FixedInitMenu(menuList, @this.m_menuRidDic, menuGroupMemberDic)); yield return(@this.StartCoroutine(AccessTools.Method(typeof(SceneEdit), "FixedInitMenu").Invoke(@this, new object[] { menuList, menuRidDicThreadSafe, menuGroupMemberDic }) as IEnumerator)); test.Stop(); Main.logger.LogError($"Done {test.Elapsed}"); yield break; }
internal static MethodInfo TargetMethod() { return(AccessTools.Method(Type.GetType("Pong.ModEntry, Pong"), "SwitchToNewMenu")); }
static IEnumerable <CodeInstruction> Transpiler1(IEnumerable <CodeInstruction> instructions) { var custominstruc = new CodeMatcher(instructions) .MatchForward(false, new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(l => l.opcode == OpCodes.Call && l.Calls(AccessTools.Method(typeof(SceneEdit), "InitMenuNative")))) .SetAndAdvance(OpCodes.Nop, null) .SetAndAdvance(OpCodes.Nop, null) .SetAndAdvance(OpCodes.Nop, null) .SetAndAdvance(OpCodes.Nop, null) .SetAndAdvance(OpCodes.Nop, null) //.SetAndAdvance(OpCodes.Nop, null) .Insert( new CodeInstruction(OpCodes.Ldarg_0), Transpilers.EmitDelegate <Action>(() => { Main.logger.LogInfo("Calling your test coroutine."); //InitMenuNativeRe(); @this2.StartCoroutine(LoadIcons()); @this2.StartCoroutine(test2()); //test2(); }), new CodeInstruction(OpCodes.Pop) ) //.Insert(new CodeInstruction (OpCodes.Call, AccessTools.Method(typeof(Main), "InitMenuNativeRe"))) .InstructionEnumeration(); return(custominstruc); }
static IEnumerable <CodeInstruction> OpportunisticJobs(IEnumerable <CodeInstruction> _codes, ILGenerator generator) { var t = new Transpiler(_codes, MethodBase.GetCurrentMethod()); var listerHaulablesIdx = t.TryFindCodeIndex(code => code.LoadsField(AccessTools.Field(typeof(Map), nameof(Map.listerHaulables)))); var skipMod = generator.DefineLabel(); t.TryInsertCodes( -3, (i, codes) => i == listerHaulablesIdx, (i, codes) => new List <CodeInstruction> { new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Pawn_JobTracker_TryOpportunisticJob_Patch), nameof(IsEnabled))), new CodeInstruction(OpCodes.Brfalse_S, skipMod), new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldarg_1), new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Patch_TryOpportunisticJob), nameof(TryOpportunisticJob))), new CodeInstruction(OpCodes.Ret), }, true); t.codes[t.MatchIdx - 3].labels.Add(skipMod); return(t.GetFinalCodes()); }