1. Some history:
    I decided to hook method TOD_Time.FixedUpdate and pass the local variable (l1) to hooks.
    I took a look at the IL and found suitable injection index (5), after i applied the settings i have looked at result code.
    The code were.. gibberish? But i decided to start server.
    Code:
    protected void FixedUpdate()
    {
        float num = 1440f / this.DayLengthInMinutes;
        string arg_27_0 = "OnTimeFixedUpdate";
        object[] args = new object[2];
        args[0] = this;
        args[(float)1] = num;
        object returnvar = Interface.CallHook(arg_27_0, args);
        if (returnvar is float)
        {
            num = (float)returnvar;
        }
        this.AddSeconds(Time.deltaTime * num, true);
    }
    
    As expected, it didn't worked. The console was flooded with this
    I began to study the produced code and i, probably found the problem:
    In my opinion, Box'ing occurs too early. The value of a local variable is being placed in the stack after box'ing. That seems to be definitely wrong.

    I've tried to fix this by simply moving Ldloc backward, and seems that worked well:
    Code:
                        else if (arg[0] == 'l' || arg[0] == 'v')
                        {
                            int index;
                            if (int.TryParse(arg.Substring(1), out index))
                            {
                                VariableDefinition vdef = weaver.Variables[index];
                                weaver.Ldloc(vdef); // <= Here                            if (vdef.VariableType.IsByReference)
                                {
                                    weaver.Add(Instruction.Create(OpCodes.Ldobj, vdef.VariableType));
                                    weaver.Add(Instruction.Create(OpCodes.Box, vdef.VariableType));
                                }
                                else if (vdef.VariableType.IsValueType)
                                    weaver.Add(Instruction.Create(OpCodes.Box, vdef.VariableType));                            //weaver.Ldloc(vdef);
                            }
                            else
                                weaver.Add(Instruction.Create(OpCodes.Ldnull));
                        }

    After that the code became valid, and my hook now working flawlessly.
    Code:
    protected void FixedUpdate()
    {
        float num = 1440f / this.DayLengthInMinutes;
        object returnvar = Interface.CallHook("OnTimeFixedUpdate", new object[]
        {
            this,
            num
        });
        if (returnvar is float)
        {
            num = (float)returnvar;
        }
        this.AddSeconds(Time.deltaTime * num, true);
    }
    

    Correct me if i am did something wrong :)
     
  2. Wulf

    Wulf Community Admin

    Good catch! This should be fixed in the latest Oxide Patcher snapshot.