public static void OnXXXLoad()
        {
            var harmony    = HarmonyInstance.Create("test");
            var transpiler = new HarmonyMethod(typeof(Time_test).GetMethod(nameof(Transpiler)));

            var originals = AccessTools.GetDeclaredMethods(typeof(GameClock));

            originals.AddRange(AccessTools.GetDeclaredMethods(typeof(TimerSideScreen)));
            originals.AddRange(AccessTools.GetDeclaredMethods(typeof(ReportManager)));
            //originals.AddRange(AccessTools.GetDeclaredMethods(typeof(EconomyDetails)));
            originals.AddRange(AccessTools.GetDeclaredMethods(typeof(TimeRangeSideScreen)));

            originals.Add(AccessTools.Method(typeof(GameUtil), nameof(GameUtil.ApplyTimeSlice)));
            originals.Add(AccessTools.Method("ColonyDiagnosticScreen.DiagnosticRow:DiagnosticRow"));

            foreach (var original in originals)
            {
                if (original == null)
                {
                    Debug.Log("wups it's a null");
                    continue;
                }

                try
                {
                    Debug.Log("[CustomGameClock] Patching " + original.Name);
                    harmony.Patch(original, transpiler: transpiler);
                }
                catch (Exception)
                {
                }
            }

            Debug.Log("[CustomGameClock] DONE");
        }
        public static void InventoryIngredients(CharacterInventory __instance, Tag _craftingStationTag, ref DictionaryExt <int, CompatibleIngredient> _sortedIngredient)
        {
            try
            {
                if (InnRentStash.CurrentStash == null || !InnRentStash.CurrentStash.IsInteractable || !InnRentStash.Instance.ConfigStashSharing.Value)
                {
                    return;
                }
                //InnRentStash.MyLogger.LogDebug($"InventoryIngredients for {_craftingStationTag}");

                /*foreach (var m in AccessTools.GetDeclaredMethods(typeof(CharacterInventory)))
                 * {
                 *  InnRentStash.MyLogger.LogDebug($"{m.Name}");
                 *  if (m.Name == "InventoryIngredients")
                 *  {
                 *      foreach (var p in m.GetParameters())
                 *      {
                 *          InnRentStash.MyLogger.LogDebug($"  |- {p.Name} {p.IsOut} {p}");
                 *      }
                 *  }
                 * }*/
                MethodInfo mi = AccessTools.GetDeclaredMethods(typeof(CharacterInventory)).FirstOrDefault(m => m.Name == "InventoryIngredients" &&
                                                                                                          m.GetParameters().Any(p => p.Name == "_items"));
                //InnRentStash.MyLogger.LogDebug($"{mi}");
                //InnRentStash.MyLogger.LogDebug($"Before={_sortedIngredient.Count}");
                mi.Invoke(__instance, new object[] {
                    _craftingStationTag, _sortedIngredient, InnRentStash.CurrentStash.GetContainedItems()
                });
                //InnRentStash.MyLogger.LogDebug($"After={_sortedIngredient.Count}");
            }
            catch (Exception ex)
            {
                InnRentStash.MyLogger.LogError("InventoryIngredients: " + ex.Message);
            }
        }
 public static void UnPatchTypePatches(Type type)
 {
     foreach (MethodInfo method in AccessTools.GetDeclaredMethods(type))
     {
         UnpatchMethodsOnMethod(method);
     }
 }
예제 #4
0
 public static IEnumerable <MethodBase> TargetMethods()
 {
     return(AccessTools.GetDeclaredMethods(typeof(Widgets))
            .Where(m => m.GetParameters().Any(p => p.ParameterType == typeof(Rect)))
            .SelectMany(m =>
     {
         if (m.IsGenericMethod == false)
         {
             return new List <MethodInfo> {
                 m
             }
         }
         ;
         if (m.Name == "Dropdown")
         {
             return new List <MethodInfo>()
             {
                 m.MakeGenericMethod(typeof(Bill_Production), typeof(Zone_Stockpile)),
                 m.MakeGenericMethod(typeof(Pawn), typeof(DrugPolicy)),
                 m.MakeGenericMethod(typeof(Pawn), typeof(HostilityResponseMode)),
                 m.MakeGenericMethod(typeof(Pawn), typeof(MedicalCareCategory)),
                 m.MakeGenericMethod(typeof(Pawn), typeof(FoodRestriction)),
                 m.MakeGenericMethod(typeof(Pawn), typeof(Outfit)),
                 m.MakeGenericMethod(typeof(Pawn), typeof(Pawn))
             }
         }
         ;
         return new List <MethodInfo>()
         {
             m.MakeGenericMethod(typeof(int)),
             m.MakeGenericMethod(typeof(float))
         };
     }));
 }
예제 #5
0
        /*********
        ** Private methods
        *********/
        /// <summary>Raised after the game is launched, right before the first update tick. This happens once per game session (unrelated to loading saves). All mods are loaded and initialized at this point, so this is a good time to set up mod integrations.</summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event data.</param>
        private void OnGameLaunched(object sender, GameLaunchedEventArgs e)
        {
            IAutomateAPI automate = Helper.ModRegistry.GetApi <IAutomateAPI>("Pathoschild.Automate");

            automate.AddFactory(new ProducerFrameworkAutomationFactory());

            var harmony = HarmonyInstance.Create("Digus.PFMAutomate");

            Assembly   automateAssembly   = AppDomain.CurrentDomain.GetAssemblies().First(a => a.FullName.StartsWith("Automate,"));
            MethodInfo automateMethodInfo = AccessTools.GetDeclaredMethods(automateAssembly.GetType("Pathoschild.Stardew.Automate.Framework.AutomationFactory")).Find(m => m.GetParameters().Any(p => p.ParameterType == typeof(SObject)));

            harmony.Patch(
                original: automateMethodInfo,
                postfix: new HarmonyMethod(typeof(AutomateOverrides), nameof(AutomateOverrides.GetFor))
                );

            Assembly ccrmAutomateAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName.StartsWith("CCRMAutomate,"));

            if (ccrmAutomateAssembly != null)
            {
                MethodInfo ccrmAutomateMethodInfo = AccessTools.GetDeclaredMethods(ccrmAutomateAssembly.GetType("CCRMAutomate.Automate.CustomCrystalariumAutomationFactory")).Find(m => m.GetParameters().Any(p => p.ParameterType == typeof(SObject)));
                harmony.Patch(
                    original: ccrmAutomateMethodInfo,
                    postfix: new HarmonyMethod(typeof(CCRMAutomateOverrides), nameof(CCRMAutomateOverrides.GetFor))
                    );
            }
        }
예제 #6
0
 protected override void Apply(Harmony harmony)
 {
     harmony.Patch(
         original: AccessTools.GetDeclaredMethods(typeof(Game1)).Find(MatchGetCharacterFromNameMethod),
         postfix: new HarmonyMethod(typeof(GetCharacterPatch), nameof(GetCharacterPatch.After_getCharacterFromName))
         );
 }
예제 #7
0
        /// <summary>
        /// Applies harmony patches on startup.
        /// </summary>
        /// <param name="harmony">Our instance of harmony to patch with.</param>
        public Cutebold_Patch_Stats(Harmony harmony)
        {
            var settings = Cutebold_Assemblies.CuteboldSettings;

            if (settings.extraYield && ModLister.GetActiveModWithIdentifier("syrchalis.harvestyieldpatch") == null)
            {
                if (settings.eyeAdaptation)
                {
                    adaptation = true;

                    // Insert Dark Adaptation bonus yield explination
                    harmony.Patch(AccessTools.Method(typeof(StatWorker), "GetExplanationUnfinalized"), postfix: new HarmonyMethod(typeof(Cutebold_Patch_Stats), "CuteboldGetExplanationUnfinalizedPostfix"));
                }

                if (settings.altYield) // Use Postfixes
                {
                    // Tweaks Mining Yield for Cutebolds
                    harmony.Patch(AccessTools.Method(typeof(Mineable), "TrySpawnYield"), postfix: new HarmonyMethod(typeof(Cutebold_Patch_Stats), "CuteboldTrySpawnYieldMiningPostfix"));
                    // Tweaks Harvist Yield for Cutebolds
                    harmony.Patch(AccessTools.Method(typeof(JobDriver_PlantWork), "MakeNewToils"), postfix: new HarmonyMethod(typeof(Cutebold_Patch_Stats), "CuteboldMakeNewToilsPlantWorkPostfix"));
                }
                else // Use Transpilers
                {
                    // Tweaks Mining Yield for Cutebolds
                    harmony.Patch(AccessTools.Method(typeof(Mineable), "TrySpawnYield"), transpiler: new HarmonyMethod(typeof(Cutebold_Patch_Stats), "CuteboldTrySpawnYieldMiningTranspiler"));
                    // Tweaks Harvist Yield for Cutebolds
                    var plantWorkToilMethod = AccessTools.GetDeclaredMethods(typeof(JobDriver_PlantWork).GetNestedTypes(AccessTools.all).First()).ElementAt(1);
                    harmony.Patch(plantWorkToilMethod, transpiler: new HarmonyMethod(typeof(Cutebold_Patch_Stats), "CuteboldMakeNewToilsPlantWorkTranspiler"));
                }

                // Edits the stats in the stat bio window to be the correct value.
                harmony.Patch(AccessTools.Method(typeof(StatsReportUtility), "StatsToDraw", new[] { typeof(Thing) }), postfix: new HarmonyMethod(typeof(Cutebold_Patch_Stats), "CuteboldStatsToDrawPostfix"));
            }
        }
예제 #8
0
 public static IEnumerable <MethodInfo> GetTypeMethods(Type type)
 {
     foreach (var method in AccessTools.GetDeclaredMethods(type).Where(ValidMethod))
     {
         yield return(method);
     }
 }
        public static void FindUnpatchedInType(Type type, string[] unsupportedTypes, List <string> systemRngLog, List <string> unityRngLog, List <string> logAllClasses = null)
        {            // Don't mind all the try/catch blocks, I went for maximum safety
            try
            {
                if (unsupportedTypes.Any(t => type.Namespace != null && (type.Namespace == t || type.Namespace.StartsWith($"{t}."))))
                {
                    return;
                }
            }
            catch (Exception)
            {
                // ignored
            }

            if (logAllClasses != null)
            {
                lock (logAllClasses)
                    logAllClasses.Add(type.FullName);
            }

            try
            {
                // Get all methods, constructors, getters, and setters (everything that should have IL instructions)
                var methods = AccessTools.GetDeclaredMethods(type).Cast <MethodBase>()
                              .Concat(AccessTools.GetDeclaredConstructors(type))
                              .Concat(AccessTools.GetDeclaredProperties(type).SelectMany(p => new[] { p.GetGetMethod(true), p.GetSetMethod(true) }).Where(p => p != null));

                foreach (var method in methods)
                {
                    try
                    {
                        MpCompat.harmony.Patch(method,
                                               transpiler: new HarmonyMethod(typeof(DebugActions), nameof(FindRng)));
                    }
                    catch (Exception e) when((e?.InnerException ?? e) is PatchingCancelledException cancelled)
                    {
                        if (cancelled.foundSystemRng)
                        {
                            lock (systemRngLog)
                                systemRngLog.Add($"{type.FullName}:{method.Name}");
                        }

                        if (cancelled.foundUnityRng)
                        {
                            lock (unityRngLog)
                                unityRngLog.Add($"{type.FullName}:{method.Name}");
                        }
                    }
                    catch (Exception)
                    {
                        // ignored
                    }
                }
            }
            catch (Exception)
            {
                // ignored
            }
        }
예제 #10
0
            public static void Init()
            {
                var i = HarmonyWrapper.PatchAll(typeof(Hooks));

                foreach (var target in AccessTools.GetDeclaredMethods(typeof(ShapeInfoBase)).Where(x => x.Name == nameof(ShapeInfoBase.ChangeValue)))
                {
                    i.Patch(target, null, new HarmonyMethod(typeof(Hooks), nameof(ChangeValuePost)));
                }
            }
예제 #11
0
            public static void InitHooks()
            {
                MethodInfo TryMethod(Type type, string name, Type[] parameters = null, Type[] generics = null)
                {
                    return(type == null ? null : AccessTools.Method(type, name, parameters, generics));
                }

                var hi = Harmony.CreateAndPatchAll(typeof(Hooks), GamepadSupportPlugin.Guid + ".CanvasCharmer");

                // Fix keyboard navigation not working in chara/map lists
                var handlerPost = AccessTools.Method(typeof(Hooks), nameof(SetToggleHandlerPost));

                foreach (var methodInfo in new[]
                {
                    // Some are KK or KKP specific, hence why not using typeof
                    TryMethod(Type.GetType("ActionGame.ClassRoomFileListCtrl, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", false), "SetToggleHandler", new[] { typeof(GameObject) }),
                    TryMethod(Type.GetType("StaffRoom.StaffRoomCharaListCtrl, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", false), "SetToggleHandler", new[] { typeof(GameObject) }),
                    TryMethod(Type.GetType("StaffRoom.StaffRoomMapListCtrl, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", false), "SetToggleHandler", new[] { typeof(GameObject) }),

                    TryMethod(Type.GetType("ChaCustom.CustomSelectListCtrl, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", false), "SetToggleHandler", new[] { typeof(GameObject) }),
                    TryMethod(Type.GetType("ExternalFile.ExternalFileListCtrl, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", false), "SetToggleHandler", new[] { typeof(GameObject) }),
                    TryMethod(Type.GetType("EmblemSelectListCtrl, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", false), "SetToggleHandler", new[] { typeof(GameObject) }),

                    TryMethod(Type.GetType("UGUI_AssistLibrary.UIAL_ListCtrl, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", false), "SetToggleHandler", new[] { typeof(GameObject) }),
                })
                {
                    if (methodInfo != null)
                    {
                        hi.Patch(methodInfo, null, new HarmonyMethod(handlerPost));
                    }
                }

                // KKP specific, has a MonoB argument instead of GameObj like others
                var listType = Type.GetType("FileListUI.ThreadFileListCtrl`2[[ChaCustom.CustomFileInfo, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],[ChaCustom.CustomFileInfoComponent, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", false);

                if (listType != null)
                {
                    var kkpList = AccessTools.Method(listType, "SetToggleHandler");
                    if (kkpList != null)
                    {
                        hi.Patch(kkpList, null, new HarmonyMethod(AccessTools.Method(typeof(Hooks), nameof(SetToggleHandlerPostForParty))));
                    }
                }

                // Fix keyboard navigation not working in HSprite / h scene
                var hspriteTargets = AccessTools.GetDeclaredMethods(typeof(HSprite));
                var mouseKillerTpl = AccessTools.Method(typeof(Hooks), nameof(MouseCheckKillerTpl));

                foreach (var mName in _hSpriteKillList)
                {
                    foreach (var m in hspriteTargets.Where(x => x.Name == mName))
                    {
                        hi.Patch(m, null, null, new HarmonyMethod(mouseKillerTpl));
                    }
                }
            }
예제 #12
0
        public void LinkTypes(Type originalType, Type targetType, object targetForAllInstances = null)
        {
            if (TracedTypes.Any(tt => tt.FromType == originalType && tt.ToType == targetType))
            {
                return;
            }

            TracedTypes.Add(new TypeForwarding(originalType, targetType, Plato, targetForAllInstances));

            foreach (MethodInfo tmethod in AccessTools.GetDeclaredMethods(targetType))
            {
                if (AccessTools.Method(originalType, tmethod.Name, tmethod.GetParameters().Select(p => p.ParameterType).ToArray(), null) is MethodInfo method && method.GetParameters() is ParameterInfo[] parameters)
                {
                    if (TracedMethods.Contains(method))
                    {
                        continue;
                    }
                    else
                    {
                        TracedMethods.Add(method);
                    }

                    if (!method.IsDeclaredMember())
                    {
                        method = method.DeclaringType.GetMethod(method.Name, method.GetParameters().Select(p => p.ParameterType).ToArray());
                    }

                    bool        hasReturnType     = method.ReturnType != Type.GetType("System.Void");
                    List <Type> patchParameters   = new List <Type>();
                    List <Type> genericParameters = new List <Type>();

                    if (hasReturnType)
                    {
                        genericParameters.Add(method.ReturnType);
                        patchParameters.Add(typeof(object).MakeByRefType());
                    }

                    genericParameters.Add(originalType);

                    string patchName = hasReturnType ? nameof(MethodPatches.ForwardMethodPatch) : nameof(MethodPatches.ForwardMethodPatchVoid);

                    patchParameters.Add(typeof(object));
                    patchParameters.Add(typeof(MethodInfo));
                    patchParameters.AddRange(method.GetParameters().Select(p => typeof(object)));
                    genericParameters.AddRange(method.GetParameters().Select(p => p.ParameterType));

                    if (AccessTools.GetDeclaredMethods(typeof(MethodPatches)).FirstOrDefault(m => m.Name == patchName && m.IsGenericMethod && m.GetParameters().Length == patchParameters.Count) is MethodInfo sMethod)
                    {
                        HarmonyInstance.Patch(
                            original: method,
                            prefix: new HarmonyMethod(sMethod.MakeGenericMethod(genericParameters.ToArray()))
                            );
                    }
                }
            }
        }
예제 #13
0
        public static void ResolveSyncListFields()
        {
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (var type in assembly.GetTypes())
                {
                    if (!typeof(NetworkBehaviour).IsAssignableFrom(type))
                    {
                        continue;
                    }

                    // execute the static constructor instead of parsing its instructions
                    System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);

                    foreach (var method in AccessTools.GetDeclaredMethods(type))
                    {
                        if (!method.Name.StartsWith("InvokeSyncList"))
                        {
                            continue;
                        }

                        var methodParams = method.GetParameters();
                        if (methodParams.Length != 2 ||
                            methodParams[0].ParameterType.FullName != "EvoS.Framework.Network.Unity.NetworkBehaviour" ||
                            methodParams[1].ParameterType.FullName != "EvoS.Framework.Network.Unity.NetworkReader")
                        {
                            continue;
                        }

                        var methodDelegate = (NetworkBehaviour.CmdDelegate)Delegate.CreateDelegate(
                            typeof(NetworkBehaviour.CmdDelegate), method);

                        var instructions = AnalysisUtils.GetMethodInstructions(method);
                        var hash         = 0;
                        foreach (var instruction in instructions)
                        {
                            if (instruction.opcode != OpCodes.Ldfld)
                            {
                                continue;
                            }

                            hash = NetworkBehaviour.GetHashByDelegate(methodDelegate);
                            SyncListLookup.Add(hash, (FieldInfo)instruction.operand);
                            break;
                        }

                        if (hash != 0)
                        {
                            continue;
                        }

                        Log.Print(LogType.Warning, $"No SyncList found in {method.FullDescription()}");
                    }
                }
            }
        }
예제 #14
0
 static IEnumerable <MethodBase> TargetMethods()
 {
     foreach (var m in AccessTools.GetDeclaredMethods(typeof(OverlayDrawer)))
     {
         if (m.GetParameters().Length > 0 && m.GetParameters()[0].ParameterType == typeof(Thing))
         {
             yield return(m);
         }
     }
 }
 public static IEnumerable <MethodInfo> GetTypeMethods(Type type)
 {
     foreach (var method in AccessTools.GetDeclaredMethods(type))
     {
         if (method.DeclaringType == type && !method.IsSpecialName && !method.IsAssembly && method.HasMethodBody())
         {
             yield return(method);
         }
     }
 }
예제 #16
0
        static MethodBase TargetMethod()
        {
            MethodInfo methodReloadContent = AccessTools.DeclaredMethod(typeof(ModContentPack), "ReloadContentInt");

            if (methodReloadContent != null)
            {
                return(methodReloadContent);
            }
            return(AccessTools.GetDeclaredMethods(typeof(ModContentPack)).Where(x => x.Name.StartsWith("<ReloadContent>")).FirstOrDefault());
        }
 static IEnumerable <MethodBase> TargetMethods()
 {
     foreach (var m in AccessTools.GetDeclaredMethods(typeof(MirroredBeatmapObjectManager)))
     {
         if (m.Name.EndsWith("WasSpawned") || m.Name.EndsWith("WasDespawned"))
         {
             yield return(m);
         }
     }
 }
예제 #18
0
        public static IEnumerable <MethodBase> GetTargetMethodsForAssembly(string assemblyName)
        {
            Assembly assembly = GetAssemblyByName(assemblyName);

            if (assembly == null)
            {
                Debug.LogError("Failed to find assembly");
            }

            var assemblyTypes = assembly.GetTypes()
                                .Where(type =>
                                       type.IsClass &&
                                       !type.Attributes.HasFlag(TypeAttributes.HasSecurity) &&
                                       !type.Attributes.HasFlag(TypeAttributes.Import) &&
                                       !type.Attributes.HasFlag(TypeAttributes.Interface) &&
                                       !type.IsImport &&
                                       !type.IsInterface &&
                                       !type.IsSecurityCritical &&
                                       !BANNED_TYPES.Any(type.FullName.StartsWith)
                                       );

            var assemblyMethods = assemblyTypes
                                  .SelectMany(type => AccessTools.GetDeclaredMethods(type))
                                  .Where(method => {
                foreach (object attr in method.GetCustomAttributes(false))
                {
                    if ((attr is DllImportAttribute) ||
                        (attr is MethodImplAttribute) ||
                        (attr is CLSCompliantAttribute) ||
                        (attr is SecurityCriticalAttribute) ||
                        (attr is ObsoleteAttribute)
                        )
                    {
                        return(false);
                    }
                }

                if (method.GetMethodBody() == null || method.Name.Equals("ReadUInt64"))
                {
                    return(false);
                }

                return(!method.ContainsGenericParameters &&
                       !method.IsAbstract &&
                       !method.IsVirtual &&
                       !method.GetMethodImplementationFlags().HasFlag(MethodImplAttributes.Native) &&
                       !method.GetMethodImplementationFlags().HasFlag(MethodImplAttributes.Unmanaged) &&
                       !method.GetMethodImplementationFlags().HasFlag(MethodImplAttributes.InternalCall) &&
                       !method.Attributes.HasFlag(MethodAttributes.PinvokeImpl) &&
                       !method.Attributes.HasFlag(MethodAttributes.Abstract) &&
                       !method.Attributes.HasFlag(MethodAttributes.UnmanagedExport));
            });

            return(assemblyMethods.Cast <MethodBase>());
        }
예제 #19
0
        protected override MethodBase GetTargetMethod()
        {
            // return AccessTools.Method("Diz.Resources.EasyAssets:Init");

            easyBundleType = PatcherConstants.TargetAssembly.GetTypes()
                             .Single(type => type.IsClass && type.GetProperty("SameNameAsset") != null);
            bundlesFieldName = easyBundleType.Name.ToLower() + "_0";

            Type targetType = PatcherConstants.TargetAssembly.GetTypes().Single(IsTargetType);

            return(AccessTools.GetDeclaredMethods(targetType).Single(IsTargetMethod));
        }
예제 #20
0
        static MethodBase TargetMethod()
        {
            index  = DeserializeOrDefault <Dictionary <string, string> >("localeIndex.json");
            locale = DeserializeOrDefault <Dictionary <string, string> >(InjectorService.LocaleFile);

            // Taken from de4dot
            MethodInfo method = null;

            foreach (var type in ReflectionHelper.MainModule.GetTypes())
            {
                var fields  = AccessTools.GetDeclaredFields(type);
                var methods = AccessTools.GetDeclaredMethods(type);
                if (type.IsPublic)
                {
                    continue;
                }
                if (fields.Count != 1)
                {
                    continue;
                }
                if (!fields.Any(field => field.FieldType == typeof(byte[])))
                {
                    continue;
                }
                if (methods.Count != 1 && methods.Count != 2)
                {
                    continue;
                }
                if (type.GetNestedTypes(AccessTools.all).Length > 0)
                {
                    continue;
                }

                foreach (var m in methods)
                {
                    var parameters = m.GetParameters();
                    if (m.ReturnType == typeof(string) && parameters.FirstOrDefault()?.ParameterType == typeof(int))
                    {
                        method = m;
                        continue;
                    }
                    break;
                }

                if (method != null)
                {
                    break;
                }
            }

            return(method);
        }
예제 #21
0
        public static List <MethodInfo> InnerMethodsStartingWith(this Type type, string prefix)
        {
            var method = GetAllInnerTypes(type)
                         .SelectMany(innerType => AccessTools.GetDeclaredMethods(innerType))
                         .Where(m => prefix == "*" || m.Name.StartsWith(prefix))
                         .ToList();

            if (method.Count == 0)
            {
                throw new Exception("Cannot find method starting with '" + prefix + "' in any inner type of " + type.FullName);
            }
            return(method);
        }
예제 #22
0
            /* todo useful?
             * /// <summary>
             * /// Keep Load button in maker character load list enabled if any of the extra toggles are enabled, but none of the stock ones are.
             * /// </summary>
             * [HarmonyPrefix]
             * [HarmonyPatch(typeof(Selectable), "set_interactable")]
             * public static void LoadButtonOverride(Selectable __instance, ref bool value)
             * {
             *  if (!value)
             *  {
             *      if (ReferenceEquals(__instance, MakerLoadToggle.LoadButton))
             *          value = MakerLoadToggle.AnyEnabled;
             *      else if (ReferenceEquals(__instance, MakerCoordinateLoadToggle.LoadButton))
             *          value = MakerCoordinateLoadToggle.AnyEnabled;
             *  }
             * }*/

            public static void Init()
            {
                var hi = BepInEx.Harmony.HarmonyWrapper.PatchAll(typeof(Hooks));

                // AI LoadFile(BinaryReader br, int lang, bool noLoadPNG = false, bool noLoadStatus = true)
                var target = AccessTools.GetDeclaredMethods(typeof(ChaFile))
                             .Where(x => x.Name == "LoadFile" && x.GetParameters().Any(p => p.ParameterType == typeof(BinaryReader)))
                             .OrderByDescending(x => x.GetParameters().Length)
                             .First();

                KoikatuAPI.Logger.LogDebug("Hooking " + target.FullDescription());
                hi.Patch(target, new HarmonyMethod(typeof(Hooks), nameof(ChaFileLoadFilePreHook)));
            }
예제 #23
0
        /*********
        ** Private methods
        *********/
        /// <summary>Raised after the game is launched, right before the first update tick. This happens once per game session (unrelated to loading saves). All mods are loaded and initialised at this point, so this is a good time to set up mod integrations.</summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event data.</param>
        private void OnGameLaunched(object sender, GameLaunchedEventArgs e)
        {
            var harmony = HarmonyInstance.Create("GZhynko.PufferEggsToMayonnaise.Automate");

            if (Helper.ModRegistry.IsLoaded("Pathoschild.Automate"))
            {
                harmony.Patch((MethodBase)AccessTools.GetDeclaredMethods(((IEnumerable <Assembly>)AppDomain.CurrentDomain.GetAssemblies()).First <Assembly>((Func <Assembly, bool>)(a => a.FullName.StartsWith("Automate,"))).GetType("Pathoschild.Stardew.Automate.Framework.AutomationFactory")).Find((Predicate <MethodInfo>)(m => ((IEnumerable <ParameterInfo>)m.GetParameters()).Any <ParameterInfo>((Func <ParameterInfo, bool>)(p => p.ParameterType == typeof(StardewValley.Object))))), (HarmonyMethod)null, new HarmonyMethod(typeof(AutomatePatchOverrides), "GetFor", (System.Type[])null), (HarmonyMethod)null);

                automate = this.Helper.ModRegistry.GetApi <Pathoschild.Stardew.Automate.IAutomateAPI>("Pathoschild.Automate");
                automate.AddFactory(new MayonnaiseAutomationFactory());

                Monitor.Log("This mod patches Automate. If you encounter any issues using Automate with this mod, try removing it first. If this does help, please report the issue to Pufferfish Chickens mod's page. Thanks!", LogLevel.Debug);
            }
        }
예제 #24
0
 static IEnumerable <MethodBase> TargetMethods()
 {
     /************* speed limit */
     // public bool SetTrafficLight(ushort nodeId, bool flag, ref NetNode node, out ToggleTrafficLightError reason)
     foreach (var m in AccessTools.GetDeclaredMethods(typeof(TrafficLightManager)))
     {
         if (m.Name == nameof(TrafficLightManager.SetTrafficLight) &&
             m.GetParameters().Length == 4
             )
         {
             yield return(m);
         }
     }
 }
예제 #25
0
        /// <summary>
        /// Enables patches depending on various options or other mods.
        /// </summary>
        /// <param name="harmony">Our harmony instance.</param>
        public Cutebold_Patch_HediffRelated(Harmony harmony)
        {
            if (Cutebold_Assemblies.CuteboldSettings.eyeAdaptation)
            {
                // Allows for dark adaptation, obviously not cave adaptation since that is a different game with cute kobolds.
                harmony.Patch(AccessTools.Method(typeof(StatPart_Glow), "FactorFromGlow"), postfix: new HarmonyMethod(typeof(Cutebold_Patch_HediffRelated), "CuteboldFactorFromGlowPostfix"));
                if (Cutebold_Assemblies.CuteboldSettings.darknessOptions != Cutebold_DarknessOptions.IdeologyDefault)
                {
                    // Ignores the ignoreIfPrefersDarkness flag.
                    harmony.Patch(AccessTools.Method(typeof(StatPart_Glow), "ActiveFor"), postfix: new HarmonyMethod(typeof(Cutebold_Patch_HediffRelated), "CuteboldGlowActiveForPostfix"));
                }
                // Applies dark adaptation to all cutebolds as they spawn.
                harmony.Patch(AccessTools.Method(typeof(Pawn), "SpawnSetup"), postfix: new HarmonyMethod(typeof(Cutebold_Patch_HediffRelated), "CuteboldAdaptationSpawnSetupPostfix"));
                // Update dark adaptation eye references.
                harmony.Patch(AccessTools.Method(typeof(HediffSet), "DirtyCache"), postfix: new HarmonyMethod(typeof(Cutebold_Patch_HediffRelated), "CuteboldHediffSetDirtyCachePostfix"));
                // Update dark adaptation goggle references.
                harmony.Patch(AccessTools.Method(typeof(Pawn_ApparelTracker), "Notify_ApparelChanged"), postfix: new HarmonyMethod(typeof(Cutebold_Patch_HediffRelated), "CuteboldApparelChangedPostfix"));
// 1.1          harmony.Patch(AccessTools.Method(typeof(Pawn_ApparelTracker), "Notify_ApparelAdded"), postfix: new HarmonyMethod(typeof(Cutebold_Patch_HediffRelated), "CuteboldApparelChangedPostfix"));
// 1.1          harmony.Patch(AccessTools.Method(typeof(Pawn_ApparelTracker), "Notify_ApparelRemoved"), postfix: new HarmonyMethod(typeof(Cutebold_Patch_HediffRelated), "CuteboldApparelChangedPostfix"));
            }
            else
            {
                // Removes dark adaptation to all cutebolds as they spawn in.
                harmony.Patch(AccessTools.Method(typeof(Pawn), "SpawnSetup"), postfix: new HarmonyMethod(typeof(Cutebold_Patch_HediffRelated), "CuteboldNoAdaptationSpawnSetupPostfix"));
            }

            // Don't patch if CE is running, we will use that to put goggles below headgear.
            if (ModLister.GetActiveModWithIdentifier("CETeam.CombatExtended") == null)
            {
                // Adjust layer offset for cutebold goggles.
                //Harmony.DEBUG = true;
                //Hat rendering was moved to a local function to make things even more fun to patch!
                MethodInfo toBePatched = AccessTools.GetDeclaredMethods(typeof(PawnRenderer)).ElementAt(29);
                harmony.Patch(toBePatched, transpiler: new HarmonyMethod(typeof(Cutebold_Patch_HediffRelated), "CuteboldGogglesFixTranspiler"));

/* 1.1          harmony.Patch(AccessTools.Method(typeof(PawnRenderer), "RenderPawnInternal", new[] {
 *                  typeof(Vector3),
 *                  typeof(float),
 *                  typeof(bool),
 *                  typeof(Rot4),
 *                  typeof(Rot4),
 *                  typeof(RotDrawMode),
 *                  typeof(bool),
 *                  typeof(bool),
 *                  typeof(bool)
 *              }), transpiler: new HarmonyMethod(typeof(Cutebold_Patch_HediffRelated), "CuteboldRenderPawnInternalTranspiler"));*/
                //Harmony.DEBUG = false;
            }
        }
        private static void PatchAssemblyFull(string key, List <Assembly> assemblies)
        {
            var meths = new HashSet <MethodInfo>();

            foreach (var asm in assemblies)
            {
                try
                {
                    var asmName = $"{asm.GetName().Name}.dll";
                    if (patchedAssemblies.Contains(asm.FullName))
                    {
                        Warn($"patching {asmName} failed, already patched");
                        continue;
                    }

                    patchedAssemblies.Add(asm.FullName);

                    foreach (var type in AccessTools.GetTypesFromAssembly(asm))
                    {
                        var methods = AccessTools.GetDeclaredMethods(type).ToList();
                        foreach (var m in methods)
                        {
                            try
                            {
                                if (ValidMethod(m) && m.DeclaringType == type)
                                {
                                    meths.TryAdd(m);
                                }
                            }
                            catch (Exception e)
                            {
                                ReportException(e, $"Skipping method {GetSignature(m)}");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    ReportException(e, $"Failed to patch the assembly {asm.FullName}");
                }
            }

            var asms      = assemblies.Select(a => a.GetName().Name + ".dll").Join();
            var asmString = assemblies.Count > 1 ? "assemblies" : "assembly";

            Messages.Message($"Attempting to patch {meths.Count} methods from the {asmString} [{asms}]", MessageTypeDefOf.CautionInput, false);

            MethodTransplanting.UpdateMethods(GUIController.types[key], meths);
        }
예제 #27
0
        public static IEnumerable <MethodBase> TargetMethods()
        {
            Type targetClass = typeof(FoodUtility)
                               .GetNestedTypes(AccessTools.all)
                               .FirstOrDefault(type => type.GetFields(AccessTools.all).Any(field => field.Name == _validatorName));

            if (targetClass == null)
            {
                return(Enumerable.Empty <MethodBase>());
            }

            _eater = targetClass.GetField("eater", AccessTools.all);

            return(AccessTools.GetDeclaredMethods(targetClass).Where(m => m.HasMethodBody()));
        }
        public static void PatchGeneratedMethod(this Harmony harmony, Type masterType, Func <MethodInfo, bool> check,
                                                HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null)
        {
            //Find the compiler-created method nested in masterType that passes the check, Patch it
            List <Type> nestedTypes = new List <Type>(masterType.GetNestedTypes(BindingFlags.NonPublic));

            while (nestedTypes.Any())
            {
                Type type = nestedTypes.Pop();
                nestedTypes.AddRange(type.GetNestedTypes(BindingFlags.NonPublic));

                foreach (MethodInfo method in AccessTools.GetDeclaredMethods(type).Where(check))
                {
                    harmony.Patch(method, prefix, postfix, transpiler);
                }
            }
        }
예제 #29
0
        /// <summary>
        /// Patches game through Harmony and sets up mod integration.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void OnGameLaunched(object sender, GameLaunchedEventArgs args)
        {
            HarmonyInstance harmony = HarmonyInstance.Create("JacquePott.MassProduction");

            harmony.Patch(
                original: AccessTools.Method(typeof(SObject), nameof(SObject.performObjectDropInAction)),
                prefix: new HarmonyMethod(typeof(ObjectOverrides), nameof(ObjectOverrides.PerformObjectDropInAction))
                );
            harmony.Patch(
                original: AccessTools.Method(typeof(SObject), nameof(SObject.draw), new Type[] { typeof(SpriteBatch), typeof(int), typeof(int), typeof(float) }),
                postfix: new HarmonyMethod(typeof(ObjectOverrides), nameof(ObjectOverrides.Draw_Postfix))
                );
            harmony.Patch(
                original: AccessTools.Method(typeof(SObject), nameof(SObject.isPlaceable)),
                postfix: new HarmonyMethod(typeof(ObjectOverrides), nameof(ObjectOverrides.isPlaceable_Postfix))
                );
            harmony.Patch(
                original: AccessTools.Method(typeof(SObject), nameof(SObject.performDropDownAction)),
                prefix: new HarmonyMethod(typeof(ObjectOverrides), nameof(ObjectOverrides.performDropDownAction_Prefix))
                );
            harmony.Patch(
                original: AccessTools.Method(typeof(SObject), nameof(SObject.DayUpdate)),
                prefix: new HarmonyMethod(typeof(ObjectOverrides), nameof(ObjectOverrides.DayUpdate_Prefix))
                );

            //Automate integration
            if (Helper.ModRegistry.IsLoaded("Pathoschild.Automate"))
            {
                IAutomateAPI automate = Helper.ModRegistry.GetApi <IAutomateAPI>("Pathoschild.Automate");
                automate.AddFactory(new MPMAutomationFactory());

                Assembly   automateAssembly      = AppDomain.CurrentDomain.GetAssemblies().First(a => a.FullName.StartsWith("Automate,"));
                Type       automationFactoryType = automateAssembly.GetType("Pathoschild.Stardew.Automate.Framework.AutomationFactory");
                MethodInfo methodInfo            = AccessTools.GetDeclaredMethods(automationFactoryType).Find(m => m.GetParameters().Any(p => p.ParameterType == typeof(SObject)));
                harmony.Patch(
                    original: methodInfo,
                    postfix: new HarmonyMethod(typeof(AutomateOverrides), nameof(AutomateOverrides.GetFor))
                    );

                if (Helper.ModRegistry.IsLoaded("Digus.PFMAutomate"))
                {
                    Monitor.Log("Automate integration for Mass Production clashes with PFMAutomate. Please remove PFMAutomate " +
                                "to have this functionality work correctly.", LogLevel.Warn);
                }
            }
        }
예제 #30
0
        // Adapted from MpUtil.GetLambda
        static IEnumerable <MethodInfo> GetLambda(Type parentType, string parentMethod = null, MethodType parentMethodType = MethodType.Normal, Type[] parentArgs = null, params int[] lambdaOrdinals)
        {
            var parent = GetMethod(parentType, parentMethod, parentMethodType, parentArgs);

            if (parent == null)
            {
                throw new Exception($"Couldn't find parent method ({parentMethodType}) {parentType}::{parentMethod}");
            }

            var parentId = GetMethodDebugId(parent);

            // Example: <>c__DisplayClass10_
            var displayClassPrefix = $"{DisplayClassPrefix}{parentId}_";

            foreach (int lambdaOrdinal in lambdaOrdinals)
            {
                // Example: <FillTab>b__0
                var lambdaNameShort = $"<{parent.Name}>{LambdaMethodInfix}{lambdaOrdinal}";

                // Capturing lambda
                var lambda = parentType.GetNestedTypes(AccessTools.all).
                             Where(t => t.Name.StartsWith(displayClassPrefix)).
                             SelectMany(t => AccessTools.GetDeclaredMethods(t)).
                             FirstOrDefault(m => m.Name == lambdaNameShort);

                // Example: <FillTab>b__10_0
                var lambdaNameFull = $"<{parent.Name}>{LambdaMethodInfix}{parentId}_{lambdaOrdinal}";

                // Non-capturing lambda
                lambda ??= AccessTools.Method(parentType, lambdaNameFull);

                // Non-capturing cached lambda
                if (lambda == null && AccessTools.Inner(parentType, SharedDisplayClass) is Type sharedDisplayClass)
                {
                    lambda = AccessTools.Method(sharedDisplayClass, lambdaNameFull);
                }

                if (lambda == null)
                {
                    throw new Exception($"Couldn't find lambda {lambdaOrdinal} in parent method {parentType}::{parent.Name} (parent method id: {parentId})");
                }

                yield return(lambda);
            }
        }