コード例 #1
0
        protected void HookApiVirtualAlterations <T>(CecilContext cecilContext)
        {
            try
            {
                var types = FarmhandAssemblies.SelectMany(a => a.GetTypesWithCustomAttribute(typeof(T).FullName)).ToArray();

                foreach (var asmType in types)
                {
                    try
                    {
                        if (asmType.BaseType != null)
                        {
                            CecilHelper.SetVirtualOnBaseMethods(cecilContext, asmType.BaseType.FullName ?? asmType.BaseType.Namespace + "." + asmType.BaseType.Name);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Error setting protections for {asmType.FullName}: \n\t{ex.Message}");
                    }
                }
            }
            catch (System.Reflection.ReflectionTypeLoadException ex)
            {
                Console.WriteLine($"Error setting method/field protections: \n\t{ex.Message}\n\t\t{ex.LoaderExceptions[0].Message}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error setting method/field protections: \n\t{ex.Message}");
            }
        }
コード例 #2
0
        public override void PatchStardew(string path = null)
        {
            InjectFarmhandCoreClasses(PatcherConstants.PassTwoPackageResult, PatcherConstants.PassOneFarmhandExe, PatcherConstants.FarmhandUiDll, PatcherConstants.FarmhandGameDll, PatcherConstants.FarmhandCharacterDll);
            var cecilContext = new CecilContext(PatcherConstants.PassTwoPackageResult, true);

            FarmhandAssemblies.Add(Assembly.LoadFrom(PatcherConstants.FarmhandUiDll));
            FarmhandAssemblies.Add(Assembly.LoadFrom(PatcherConstants.FarmhandGameDll));
            FarmhandAssemblies.Add(Assembly.LoadFrom(PatcherConstants.FarmhandCharacterDll));

            HookApiEvents(cecilContext);
            HookOutputableApiEvents(cecilContext);
            HookApiFieldProtectionAlterations <HookAlterBaseFieldProtectionAttribute>(cecilContext);
            HookApiTypeProtectionAlterations <HookAlterProtectionAttribute>(cecilContext);
            HookApiVirtualAlterations <HookForceVirtualBaseAttribute>(cecilContext);
            HookMakeBaseVirtualCallAlterations <HookMakeBaseVirtualCallAttribute>(cecilContext);
            HookConstructionRedirectors <HookRedirectConstructorFromBaseAttribute>(cecilContext);
            HookConstructionToMethodRedirectors(cecilContext);

            HookGlobalRouting(cecilContext);

            Console.WriteLine("Second Pass Installation Completed");

            path = path ?? PatcherConstants.FarmhandExe;
            cecilContext.WriteAssembly(path, true);
        }
コード例 #3
0
        protected void HookMakeBaseVirtualCallAlterations <T>(CecilContext cecilContext)
        {
            try
            {
                var methods = FarmhandAssemblies.SelectMany(a => a.GetMethodsWithCustomAttribute(typeof(T).FullName)).ToArray();

                foreach (var asmMethod in methods)
                {
                    try
                    {
                        SetVirtualCallOnMethod(cecilContext, asmMethod);
                    }
                    catch (Exception ex)
                    {
                        if (asmMethod.DeclaringType != null)
                        {
                            Console.WriteLine($"Error setting protections for {asmMethod.DeclaringType.FullName}.{asmMethod.Name}: \n\t{ex.Message}");
                        }
                    }
                }
            }
            catch (System.Reflection.ReflectionTypeLoadException ex)
            {
                Console.WriteLine($"Error setting method/field protections: \n\t{ex.Message}\n\t\t{ex.LoaderExceptions[0].Message}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error setting method/field protections: \n\t{ex.Message}");
            }
        }
コード例 #4
0
        protected void HookConstructionRedirectors <T>(CecilContext cecilContext)
        {
            try
            {
                var test  = FarmhandAssemblies.SelectMany(a => a.GetTypes());
                var types = FarmhandAssemblies.SelectMany(a => a.GetTypesWithCustomAttribute(typeof(T).FullName)).ToArray();

                foreach (var asmType in types)
                {
                    try
                    {
                        RedirectConstructorInMethod(cecilContext, asmType);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Error setting protections for {asmType.FullName}: \n\t{ex.Message}");
                    }
                }
            }
            catch (System.Reflection.ReflectionTypeLoadException ex)
            {
                Console.WriteLine($"Error setting method/field protections: \n\t{ex.Message}\n\t\t{ex.LoaderExceptions[0].Message}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error setting method/field protections: \n\t{ex.Message}");
            }
        }
コード例 #5
0
 protected void HookApiTypeProtectionAlterations <T>(CecilContext cecilContext)
 {
     try
     {
         var types = FarmhandAssemblies.SelectMany(a => a.GetTypesWithCustomAttribute(typeof(T).FullName)).ToArray();
         foreach (var asmType in types)
         {
             try
             {
                 AlterTypeProtections(cecilContext, asmType);
             }
             catch (Exception ex)
             {
                 Console.WriteLine($"Error setting protections for {asmType.FullName}: \n\t{ex.Message}");
             }
         }
     }
     catch (System.Reflection.ReflectionTypeLoadException ex)
     {
         Console.WriteLine($"Error setting type protections: \n\t{ex.Message}\n\t\t{ex.LoaderExceptions[0].Message}");
     }
     catch (Exception ex)
     {
         Console.WriteLine($"Error setting type protections: \n\t{ex.Message}");
     }
 }
コード例 #6
0
        protected override void HookConstructionToMethodRedirectors(CecilContext cecilContext)
        {
            var methods = FarmhandAssemblies.SelectMany(a => a.GetTypes())
                          .SelectMany(t => t.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static))
                          .Where(m => m.GetCustomAttributes(typeof(HookRedirectConstructorToMethodAttribute), false).Any())
                          .ToArray();

            foreach (var method in methods)
            {
                // Check if this method has any properties that would immediately disqualify it from using this hook
                if (method.ReturnType == typeof(void))
                {
                    Logging.Log.Warning($"{method.Name} in {method.DeclaringType.FullName} cannot be used in a hook because it does not return a value!");
                    continue;
                }
                if (!method.IsStatic)
                {
                    Logging.Log.Warning($"{method.Name} in {method.DeclaringType.FullName} cannot be used in a hook because it is not static!");
                    continue;
                }

                // Get the type that the method returns
                var typeName = method.ReturnType.FullName;
                // Get the name of the method
                var methodName = method.Name;
                // Get the type name of the method
                var methodDeclaringType = method.DeclaringType.FullName;
                // Get an array of parameters that the method returns
                var    methodParameterInfo = method.GetParameters();
                Type[] methodParamters     = new Type[methodParameterInfo.Length];
                for (int i = 0; i < methodParamters.Length; i++)
                {
                    methodParamters[i] = methodParameterInfo[i].ParameterType;
                }

                // Get all the hooks for this method
                var hookAttributes = method.GetCustomAttributes(typeof(HookRedirectConstructorToMethodAttribute), false).Cast <HookRedirectConstructorToMethodAttribute>();

                foreach (var hook in hookAttributes)
                {
                    // Get the type name that contains the method we're hooking in
                    var hookTypeName = hook.Type;
                    // Get the name of the method we're hooking in
                    var hookMethodName = hook.Method;
                    try
                    {
                        CecilHelper.RedirectConstructorToMethod(cecilContext, method.ReturnType, hookTypeName, hookMethodName, methodDeclaringType, methodName, methodParamters);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Failed to Inject {typeName}.{methodName} into {hookTypeName}.{hookMethodName}\n\t{ex.Message}");
                        throw ex;
                    }
                }
            }
        }
コード例 #7
0
        private void HookOutputableApiEvents(CecilContext cecilContext)
        {
            try
            {
                var methods = FarmhandAssemblies.SelectMany(a => a.GetTypes())
                              .SelectMany(t => t.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static))
                              .Where(m => m.GetCustomAttributes(typeof(HookReturnableAttribute), false).Any())
                              .ToArray();

                foreach (var method in methods)
                {
                    if (method.DeclaringType == null)
                    {
                        continue;
                    }

                    var typeName       = method.DeclaringType.FullName;
                    var methodName     = method.Name;
                    var hookAttributes = method.GetCustomAttributes(typeof(HookReturnableAttribute), false).Cast <HookReturnableAttribute>();

                    foreach (var hook in hookAttributes)
                    {
                        var hookTypeName   = hook.Type;
                        var hookMethodName = hook.Method;
                        try
                        {
                            switch (hook.HookType)
                            {
                            case HookType.Entry:
                                CecilHelper.InjectReturnableEntryMethod <ParameterBindAttribute, ThisBindAttribute, InputBindAttribute, LocalBindAttribute,
                                                                         UseOutputBindAttribute, MethodOutputBindAttribute>
                                    (cecilContext, hookTypeName, hookMethodName, typeName, methodName); break;

                            case HookType.Exit:
                                CecilHelper.InjectReturnableExitMethod <ParameterBindAttribute, ThisBindAttribute, InputBindAttribute, LocalBindAttribute,
                                                                        UseOutputBindAttribute, MethodOutputBindAttribute>
                                    (cecilContext, hookTypeName, hookMethodName, typeName, methodName); break;

                            default:
                                throw new Exception("Unknown HookType");
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"Failed to Inject {typeName}.{methodName} into {hookTypeName}.{hookMethodName}\n\t{ex.Message}");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
コード例 #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="path">Stardew EXE Path</param>
        public override void PatchStardew(string path = null)
        {
            path = path ?? PatcherConstants.StardewExe;
            InjectFarmhandCoreClasses(PatcherConstants.PassOnePackageResult, path, PatcherConstants.FarmhandDll, PatcherConstants.JsonLibrary);
            var cecilContext = new CecilContext(PatcherConstants.PassOnePackageResult, true);

            FarmhandAssemblies.Add(Assembly.LoadFrom(PatcherConstants.FarmhandDll));

            HookApiEvents(cecilContext);
            HookOutputableApiEvents(cecilContext);
            HookApiFieldProtectionAlterations <HookAlterBaseFieldProtectionAttribute>(cecilContext);
            HookApiTypeProtectionAlterations <HookAlterProtectionAttribute>(cecilContext);
            HookApiVirtualAlterations <HookForceVirtualBaseAttribute>(cecilContext);
            HookMakeBaseVirtualCallAlterations <HookMakeBaseVirtualCallAttribute>(cecilContext);
            HookConstructionRedirectors <HookRedirectConstructorFromBaseAttribute>(cecilContext);
            HookConstructionToMethodRedirectors(cecilContext);

            Console.WriteLine("First Pass Installation Completed");

            cecilContext.WriteAssembly(PatcherConstants.PassOneFarmhandExe, true);
        }