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.
As expected, it didn't worked. The console was flooded with thisCode: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); }
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![]()
Fixed Invalid IL error when hooking method
Discussion in 'Rust Discussion' started by VVoid, Mar 5, 2015.