示例#1
0
        public void Inject(Dictionary <string, TypeDefinition> typeTable, ModuleDefinition module)
        {
            if (!Mod.Settings.Patch.Vanilla)
            {
                return;
            }

            if (typeTable.TryGetValue(_targetType, out TypeDefinition type))
            {
                _getInstanceID = Instruction.Create(
                    OpCodes.Callvirt
                    , type.Module.ImportReference(typeof(UnityEngine.Object).GetMethod(nameof(UnityEngine.Object.GetInstanceID))));

                InjectField(type, module);
                InjectIL(type);
                //if (InitField(type))
                //{
                //    InjectIL(type);
                //}
            }
            else
            {
                CecilManager.WriteError($"Can't find target type: {_targetType}\n");
            }
        }
示例#2
0
        public void Inject(Dictionary <string, TypeDefinition> typeTable, ModuleDefinition module)
        {
            if (!Mod.Settings.Patch.Vanilla)
            {
                return;
            }

            if (typeTable.TryGetValue(_targetType, out TypeDefinition type))
            {
                InjectField(type, module);
                return;
            }

            CecilManager.WriteError($"Can't find target type: {_targetType}");
        }
        private static void InitField(TypeDefinition type, ModuleDefinition module)
        {
            List <MethodDefinition> consturctors = type.GetConstructors().ToList();

            if (consturctors.Count == 0)
            {
                CecilManager.WriteLog($"Can't find constructor for {nameof(_targetType)}\n");
                return;
            }

            foreach (MethodDefinition constructor in consturctors)
            {
                if (constructor.IsStatic)
                {
                    continue;
                }

                ILProcessor ilProcessor = constructor.Body.GetILProcessor();
                Instruction ctorEnd     = constructor.Body.Instructions.Last();

                // this.InstanceId = this.GetInstanceID();
                ilProcessor.InsertBefore(
                    ctorEnd
                    , Instruction.Create(OpCodes.Ldarg_0));

                ilProcessor.InsertBefore(
                    ctorEnd
                    , Instruction.Create(OpCodes.Ldarg_0));

                ilProcessor.InsertBefore(ctorEnd, _getInstanceId);

                ilProcessor.InsertBefore(
                    ctorEnd
                    , Instruction.Create(OpCodes.Stfld, TargetId));
            }
        }
        private static void InjectIL(TypeDefinition type, ModuleDefinition module)
        {
            MethodDefinition createTween = type.GetMethods().FirstOrDefault(m => m.Name == "CreateTween");

            if (createTween == null)
            {
                CecilManager.WriteError($"Can't find target method: CreateTween\n");
                return;
            }

            module.ImportReference(typeof(Tween));
            module.ImportReference(typeof(ABSAnimationComponent));
            module.ImportReference(typeof(Component));

            FieldReference tween   = module.ImportReference(typeof(ABSAnimationComponent).GetField(nameof(ABSAnimationComponent.tween)));
            FieldReference target  = module.ImportReference(typeof(DOTweenAnimation).GetField(nameof(DOTweenAnimation.target)));
            FieldReference tweenId = module.ImportReference(typeof(Tween).GetField(nameof(Tween.id)));

            MethodReference notEqualTo = module.ImportReference(
                typeof(UnityEngine.Object).GetMethod("op_Inequality", BindingFlags.Public | BindingFlags.Static));

            Instruction loadTargetId              = Instruction.Create(OpCodes.Ldfld, TargetId);
            Instruction loadHasTargetId           = Instruction.Create(OpCodes.Ldfld, HasTargetId);
            Instruction loadTarget                = Instruction.Create(OpCodes.Ldfld, target);
            Instruction loadTween                 = Instruction.Create(OpCodes.Ldfld, tween);
            Instruction setId                     = Instruction.Create(OpCodes.Stfld, tweenId);
            Instruction branchLoad                = Instruction.Create(OpCodes.Ldarg_0);
            Instruction branchReturn              = Instruction.Create(OpCodes.Ret);
            Collection <Instruction> instructions = createTween.Body.Instructions;

            // if (this.HasTargetId) return;
            instructions[instructions.Count - 1].OpCode = OpCodes.Ldarg_0;
            instructions.Add(loadHasTargetId);
            instructions.Add(Instruction.Create(OpCodes.Brtrue, branchReturn));

            // if (this.target == null) return;
            instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
            instructions.Add(loadTarget);
            instructions.Add(Instruction.Create(OpCodes.Ldnull));
            instructions.Add(Instruction.Create(OpCodes.Call, notEqualTo));
            instructions.Add(Instruction.Create(OpCodes.Brfalse, branchReturn));

            // this.TargetId = this.target.GetInstanceID();
            instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
            instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
            instructions.Add(loadTarget);
            instructions.Add(_getInstanceId);
            instructions.Add(Instruction.Create(OpCodes.Stfld, TargetId));

            // this.HasTargetId = true;
            instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
            instructions.Add(Instruction.Create(OpCodes.Ldc_I4_1));
            instructions.Add(Instruction.Create(OpCodes.Stfld, HasTargetId));

            // this.tween.id = this.InstanceId;
            //instructions.Add(branchLoad);
            //instructions.Add(loadTween);
            //instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
            //instructions.Add(loadTargetId);
            //instructions.Add(Instruction.Create(OpCodes.Box, module.ImportReference(typeof(int))));
            //instructions.Add(setId);

            // return;
            instructions.Add(branchReturn);

            createTween.Body.OptimizeMacros();
        }