Beispiel #1
0
        public override void Entry(IModHelper helper)
        {
            ModConfig = helper.ReadConfig <ModConfig>();
            helper.WriteConfig(ModConfig);
            HarmonyInstance harmony = HarmonyInstance.Create("zaneyork.CustomToolEffect");

            harmony.Patch(
                original: AccessTools.DeclaredMethod(typeof(Tree), "performToolAction"),
                prefix: new HarmonyMethod(typeof(TreeRewrites.PerformToolActionRewrite), nameof(TreeRewrites.PerformToolActionRewrite.Prefix))
                );
            harmony.Patch(
                original: AccessTools.DeclaredMethod(typeof(FruitTree), "performToolAction"),
                prefix: new HarmonyMethod(typeof(FruitTreeRewrites.PerformToolActionRewrite), nameof(FruitTreeRewrites.PerformToolActionRewrite.Prefix))
                );
            harmony.Patch(
                original: AccessTools.DeclaredMethod(typeof(ResourceClump), "performToolAction"),
                prefix: new HarmonyMethod(typeof(ResourceClumpRewrites.PerformToolActionRewrite), nameof(ResourceClumpRewrites.PerformToolActionRewrite.Prefix))
                );
            harmony.Patch(
                original: AccessTools.DeclaredMethod(typeof(Pickaxe), "DoFunction"),
                prefix: new HarmonyMethod(typeof(PickaxeRewrites.DoFunctionRewrite), nameof(PickaxeRewrites.DoFunctionRewrite.Prefix))
                );
            harmony.Patch(
                original: AccessTools.DeclaredMethod(typeof(Tool), "tilesAffected"),
                prefix: new HarmonyMethod(typeof(ToolRewrites.TilesAffectedRewrite), nameof(ToolRewrites.TilesAffectedRewrite.Prefix))
                );
            AccessTools.GetDeclaredConstructors(typeof(TemporaryAnimatedSprite)).ForEach(ctor =>
            {
                harmony.Patch(
                    original: ctor,
                    postfix: new HarmonyMethod(typeof(ToolRewrites.TilesAffectedRewrite), nameof(TemporaryAnimatedSpriteRewrites.ConstructorRewrite.Postfix))
                    );
            });
        }
Beispiel #2
0
        public CashRegister(ModContentPack mod)
        {
            var type = AccessTools.TypeByName("CashRegister.Shifts.ITab_Register_Shifts");

            MpCompat.RegisterLambdaMethod(type, "GetGizmos", 1).SetContext(SyncContext.MapSelected);
            MP.RegisterSyncWorker <object>(NoSync, type, shouldConstruct: true);
            MP.RegisterSyncMethod(typeof(CashRegister), nameof(SyncedSetShifts)).ExposeParameter(1).ExposeParameter(2).ExposeParameter(3).ExposeParameter(4).ExposeParameter(5).MinTime(100);
            MpCompat.harmony.Patch(AccessTools.Method(type, "FillTab"),
                                   prefix: new HarmonyMethod(typeof(CashRegister), nameof(PreFillTab)),
                                   postfix: new HarmonyMethod(typeof(CashRegister), nameof(PostFillTab)));

            type = AccessTools.TypeByName("CashRegister.Gizmo_Radius");
            gizmoRadiusConstructor = AccessTools.GetDeclaredConstructors(type).First(x => x.GetParameters().Length == 1);
            gizmoSelectionField    = AccessTools.FieldRefAccess <Building[]>(type, "selection");
            MP.RegisterSyncMethod(AccessTools.DeclaredMethod(type, "ButtonDown"));
            MP.RegisterSyncMethod(AccessTools.DeclaredMethod(type, "ButtonUp"));
            MP.RegisterSyncMethod(AccessTools.DeclaredMethod(type, "ButtonCenter"));
            MP.RegisterSyncWorker <Gizmo>(SyncGizmoRadius, type);

            type             = AccessTools.TypeByName("CashRegister.Building_CashRegister");
            cashRegisterType = type.MakeArrayType();
            shiftsListField  = AccessTools.FieldRefAccess <IList>(type, "shifts");

            type             = AccessTools.TypeByName("CashRegister.Shifts.Shift");
            shiftConstructor = AccessTools.Constructor(type);
            timetableField   = AccessTools.FieldRefAccess <object>(type, "timetable");
            assignedField    = AccessTools.FieldRefAccess <List <Pawn> >(type, "assigned");

            type       = AccessTools.TypeByName("CashRegister.Timetable.TimetableBool");
            timesField = AccessTools.FieldRefAccess <List <bool> >(type, "times");
        }
Beispiel #3
0
 public static List <ConstructorInfo> GetDeclaredConstructors(Type type)
 {
     // Harmony 1.x matched both static and instance constructors
     return
         (AccessTools.GetDeclaredConstructors(type, searchForStatic: false)
          ?? AccessTools.GetDeclaredConstructors(type, searchForStatic: true));
 }
 public static IEnumerable <MethodBase> TargetMethods()
 {
     foreach (var ctor in AccessTools.GetDeclaredConstructors(typeof(DialogueBox)))
     {
         yield return(ctor);
     }
 }
        private void Start()
        {
            _logger = Logger;

            // UserData is universal across games. Run in Start to let the game create the dir. Don't use UserData.Path since it's broken in EC
            _fullUserDataPath = Path.GetFullPath(Path.Combine(Paths.GameRootPath, "UserData"));

            var h = HarmonyWrapper.PatchAll(typeof(RemoveToRecycleBin));

            // Patch all FileStream to account for differences in internals of different framework versions
            var hook = new HarmonyMethod(typeof(RemoveToRecycleBin), nameof(FileStreamHook));

            if (hook == null)
            {
                throw new ArgumentNullException(nameof(hook));
            }
            foreach (var m in AccessTools.GetDeclaredConstructors(typeof(FileStream)))
            {
                var args = m.GetParameters();
                if (args.Any(x => x.ParameterType == typeof(FileMode)) && args.Any(x => x.ParameterType == typeof(FileAccess)))
                {
                    h.Patch(m, hook);
                    //_logger.LogDebug("Patching " + m);
                }
            }
        }
        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
            }
        }
        private static MethodBase GetOriginalMethod(HarmonyMethod attribute)
        {
            if (attribute.declaringType == null)
            {
                return(null);
            }

            switch (attribute.methodType)
            {
            case MethodType.Normal:
                if (attribute.methodName == null)
                {
                    return(null);
                }
                return(AccessTools.DeclaredMethod(attribute.declaringType, attribute.methodName, attribute.argumentTypes));

            case MethodType.Getter:
                if (attribute.methodName == null)
                {
                    return(null);
                }
                return(AccessTools.DeclaredProperty(attribute.declaringType, attribute.methodName)
                       .GetGetMethod(true));

            case MethodType.Setter:
                if (attribute.methodName == null)
                {
                    return(null);
                }
                return(AccessTools.DeclaredProperty(attribute.declaringType, attribute.methodName)
                       .GetSetMethod(true));

            case MethodType.Constructor:
                return(AccessTools.GetDeclaredConstructors(attribute.declaringType)
                       .FirstOrDefault((ConstructorInfo c) =>
                {
                    if (c.IsStatic)
                    {
                        return false;
                    }
                    ParameterInfo[] parameters = c.GetParameters();
                    if (attribute.argumentTypes == null && parameters.Length == 0)
                    {
                        return true;
                    }
                    return parameters
                    .Select((p) => p.ParameterType)
                    .SequenceEqual(attribute.argumentTypes);
                }));

            case MethodType.StaticConstructor:
                return(AccessTools.GetDeclaredConstructors(attribute.declaringType)
                       .FirstOrDefault(c => c.IsStatic));
            }

            return(null);
        }
Beispiel #8
0
        public static MethodBase GetOriginalMethod(HarmonyMethod attr)
        {
            if (attr.declaringType == null)
            {
                return(null);
            }

            if (attr.methodType == null)
            {
                attr.methodType = MethodType.Normal;
            }

            switch (attr.methodType)
            {
            case MethodType.Normal:
                if (attr.methodName == null)
                {
                    return(null);
                }

                return(AccessTools.DeclaredMethod(
                           attr.declaringType,
                           attr.methodName,
                           attr.argumentTypes));

            case MethodType.Getter:
                if (attr.methodName == null)
                {
                    return(null);
                }

                return(AccessTools.DeclaredProperty(attr.declaringType, attr.methodName)
                       .GetGetMethod(true));

            case MethodType.Setter:
                if (attr.methodName == null)
                {
                    return(null);
                }

                return(AccessTools.DeclaredProperty(attr.declaringType, attr.methodName)
                       .GetSetMethod(true));

            case MethodType.Constructor:
                return(AccessTools.DeclaredConstructor(attr.declaringType, attr.argumentTypes));

            case MethodType.StaticConstructor:
                return(AccessTools.GetDeclaredConstructors(attr.declaringType)
                       .FirstOrDefault(c => c.IsStatic));
            }

            return(null);
        }
Beispiel #9
0
        public static ParameterInfo[] GetConstructorExtraParameterInfo(Type type)
        {
            var constructors = AccessTools.GetDeclaredConstructors(type);

            if (constructors == null || constructors.Count == 0)
            {
                return(null);
            }

            // the first 3 parameters are always the same, we only want the extra
            return(constructors[0].GetParameters().Skip(3).ToArray());
        }
Beispiel #10
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator generator)
        {
            // Player RoleType Vector3 float
            List <CodeInstruction> newInstructions = ListPool <CodeInstruction> .Shared.Rent(instructions);

            // Find the index of the ldarg.0 before the only ldfld CharacterClassManager::SpawnProtected
            const int offset = -1;
            int       index  = newInstructions.FindIndex(i => i.opcode == OpCodes.Ldfld && (FieldInfo)i.operand == AccessTools.Field(typeof(CharacterClassManager), nameof(CharacterClassManager.SpawnProtected))) + offset;

            // Remove all existing this._pms.OnPlayerClassChange calls (we will want to call this ourselves after our even fires, to allow their spawn position to change.)
            foreach (CodeInstruction instruction in newInstructions.FindAll(i =>
                                                                            i.opcode == OpCodes.Call && (MethodInfo)i.operand == AccessTools.Method(typeof(PlayerMovementSync), nameof(PlayerMovementSync.OnPlayerClassChange))))
            {
                newInstructions.Remove(instruction);
            }
            LocalBuilder ev = generator.DeclareLocal(typeof(SpawningEventArgs));

            newInstructions.InsertRange(index, new[]
            {
                // Player.Get(this._hub)
                new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]),
                new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(CharacterClassManager), nameof(CharacterClassManager._hub))),
                new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),

                // this.CurClass
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(CharacterClassManager), nameof(CharacterClassManager.CurClass))),

                // var ev = new SpawningEventArg(Player, RoleType)
                // Exiled.Events.Handlers.Player.OnSpawning(ev);
                new CodeInstruction(OpCodes.Newobj, AccessTools.GetDeclaredConstructors(typeof(SpawningEventArgs))[0]),
                new CodeInstruction(OpCodes.Dup),
                new CodeInstruction(OpCodes.Stloc, ev.LocalIndex),
                new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Exiled.Events.Handlers.Player), nameof(Handlers.Player.OnSpawning))),

                // this._pms.OnPlayerClassChange(ev.Position, ev.RotationY)
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(CharacterClassManager), nameof(CharacterClassManager._pms))),
                new CodeInstruction(OpCodes.Ldloc, ev.LocalIndex),
                new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(SpawningEventArgs), nameof(SpawningEventArgs.Position))),
                new CodeInstruction(OpCodes.Ldloc, ev.LocalIndex),
                new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(SpawningEventArgs), nameof(SpawningEventArgs.RotationY))),
                new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PlayerMovementSync), nameof(PlayerMovementSync.OnPlayerClassChange))),
            });

            for (int z = 0; z < newInstructions.Count; z++)
            {
                yield return(newInstructions[z]);
            }

            ListPool <CodeInstruction> .Shared.Return(newInstructions);
        }
 static ResourceDepotUtils()
 {
     foreach (var constructorInfo in AccessTools.GetDeclaredConstructors(typeof(ResourceDepot), false))
     {
         var @params = constructorInfo.GetParameters();
         if (@params.Length == 0)
         {
             V1 = AccessTools2.GetDelegate <V1Delegate>(constructorInfo);
         }
         if (@params.Length == 1 && @params[0].ParameterType == typeof(string))
         {
             V2 = AccessTools2.GetDelegate <V2Delegate>(constructorInfo);
         }
     }
 }
        public static MethodBase GetConstructorMethodBase(Type type, string ctorName)
        {
            List <ConstructorInfo> ctor_Infos = new List <ConstructorInfo>();

            ctor_Infos = AccessTools.GetDeclaredConstructors(type);

            foreach (ConstructorInfo ctor_info in ctor_Infos)
            {
                GetConstructorInfo(ctor_info);

                if (ctor_info.Name == ctorName)
                {
                    return(ctor_info as MethodBase);
                }
            }

            return(null);
        }
Beispiel #13
0
        private static MethodBase GetConstructorMethodBase(Type type, string ctorName)
        {
            List <ConstructorInfo> ctor_Infos = new List <ConstructorInfo>();

            ctor_Infos = AccessTools.GetDeclaredConstructors(type);

            foreach (ConstructorInfo ctor_info in ctor_Infos)
            {
                BZLogger.Debug($"found constructor [{ctorName}] in class [{type}]");

                if (ctor_info.Name == ctorName)
                {
                    return(ctor_info as MethodBase);
                }
            }

            BZLogger.Debug($"the required constructor [{ctorName}] in class [{type}] has not found!");

            return(null);
        }
Beispiel #14
0
        // Copied from Harmony.PatchProcessor
        public static MethodBase GetMethod(Type type, string methodName, MethodType methodType, Type[] args)
        {
            if (type == null)
            {
                return(null);
            }

            switch (methodType)
            {
            case MethodType.Normal:
                if (methodName == null)
                {
                    return(null);
                }
                return(AccessTools.DeclaredMethod(type, methodName, args));

            case MethodType.Getter:
                if (methodName == null)
                {
                    return(null);
                }
                return(AccessTools.DeclaredProperty(type, methodName).GetGetMethod(true));

            case MethodType.Setter:
                if (methodName == null)
                {
                    return(null);
                }
                return(AccessTools.DeclaredProperty(type, methodName).GetSetMethod(true));

            case MethodType.Constructor:
                return(AccessTools.DeclaredConstructor(type, args));

            case MethodType.StaticConstructor:
                return(AccessTools.GetDeclaredConstructors(type)
                       .Where(c => c.IsStatic)
                       .FirstOrDefault());
            }

            return(null);
        }
 public static List <ConstructorInfo> GetDeclaredConstructors(Type type)
 {
     return(AccessTools.GetDeclaredConstructors(type, searchForStatic: true));
 }
 /// <summary>Get a constructor and assert that it was found.</summary>
 /// <param name="parameterCount">The the number of parameters in the overload signature.</param>
 /// <returns>The first constructor that matches the specified parameter count.</returns>
 /// <remarks>Useful when there's no compile-time access to one or more parameter types.</remarks>
 public static ConstructorInfo RequireConstructor(this Type type, int parametersCount)
 {
     return(AccessTools.GetDeclaredConstructors(type).First(c => c.GetParameters().Length == parametersCount));
 }
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator generator)
        {
            List <CodeInstruction> newInstructions = ListPool <CodeInstruction> .Shared.Rent(instructions);

            Label continueLabel = generator.DefineLabel();
            Label endLabel      = generator.DefineLabel();
            Label elseLabel     = generator.DefineLabel();

            LocalBuilder player = generator.DeclareLocal(typeof(API.Features.Player));
            LocalBuilder ev     = generator.DeclareLocal(typeof(ChangingSpectatedPlayerEventArgs));

            int index = newInstructions.FindIndex(x => x.opcode == OpCodes.Ret) + 1;

            CodeInstruction firstLabel = new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]);

            newInstructions[index].WithLabels(endLabel);

            newInstructions.InsertRange(
                index,
                new CodeInstruction[]
            {
                /*
                 *  var player = Player.Get(__instance._hub);
                 *  if (player != null)
                 *  {
                 *      var ev = new ChangingSpectatedPlayerEventArgs(player, Player.Get(__instance.CurrentSpectatedPlayer), Player.Get(value));
                 *
                 *      Exiled.Events.Handlers.Player.OnChangingSpectatedPlayer(ev);
                 *
                 *      if(!ev.IsAllowed) return;
                 *
                 *      value = ev.NewTarget?.ReferenceHub ?? ev.Player.ReferenceHub;
                 *  }
                 */

                // var player = Player.Get(__instance._hub);
                firstLabel,
                new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(SpectatorManager), nameof(SpectatorManager._hub))),
                new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new System.Type[] { typeof(ReferenceHub) })),
                new CodeInstruction(OpCodes.Dup),

                // if (player != null)
                new CodeInstruction(OpCodes.Stloc, player),
                new CodeInstruction(OpCodes.Brfalse_S, endLabel),
                new CodeInstruction(OpCodes.Ldloc, player),

                // Player.Get(__instance.CurrentSpectatedPlayer)
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(SpectatorManager), nameof(SpectatorManager._currentSpectatedPlayer))),
                new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new System.Type[] { typeof(ReferenceHub) })),

                // Player.Get(value)
                new CodeInstruction(OpCodes.Ldarg_1),
                new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new System.Type[] { typeof(ReferenceHub) })),

                // var ev = new ChangingSpectatedPlayerEventArgs(player, Player.Get(__instance.CurrentSpectatedPlayer), Player.Get(value))
                new CodeInstruction(OpCodes.Ldc_I4_1),
                new CodeInstruction(OpCodes.Newobj, AccessTools.GetDeclaredConstructors(typeof(ChangingSpectatedPlayerEventArgs))[0]),
                new CodeInstruction(OpCodes.Dup),
                new CodeInstruction(OpCodes.Dup),
                new CodeInstruction(OpCodes.Stloc, ev),

                // Exiled.Events.Handlers.Player.OnChangingSpectatedPlayer(ev);
                new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Player), nameof(Player.OnChangingSpectatedPlayer))),

                // if(!ev.IsAllowed) return;
                new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(ChangingSpectatedPlayerEventArgs), nameof(ChangingSpectatedPlayerEventArgs.IsAllowed))),
                new CodeInstruction(OpCodes.Brtrue_S, continueLabel),
                new CodeInstruction(OpCodes.Ret),

                // ev.NewTarget;
                new CodeInstruction(OpCodes.Ldloc, ev).WithLabels(continueLabel),
                new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(ChangingSpectatedPlayerEventArgs), nameof(ChangingSpectatedPlayerEventArgs.NewTarget))),

                // if(ev.NewTarget == null)
                new CodeInstruction(OpCodes.Dup),
                new CodeInstruction(OpCodes.Brtrue_S, elseLabel),

                // value = ev.Player.ReferenceHub;
                new CodeInstruction(OpCodes.Pop),
                new CodeInstruction(OpCodes.Ldloc, ev),
                new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(ChangingSpectatedPlayerEventArgs), nameof(ChangingSpectatedPlayerEventArgs.Player))),

                // value = ev.NewTarget.ReferenceHub;
                new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(API.Features.Player), nameof(API.Features.Player.ReferenceHub))).WithLabels(elseLabel),
                new CodeInstruction(OpCodes.Starg_S, 1),
            });

            for (int z = 0; z < newInstructions.Count; z++)
            {
                yield return(newInstructions[z]);
            }

            ListPool <CodeInstruction> .Shared.Return(newInstructions);

            yield break;
        }