C
C#2y ago
Icetrack

❔ IL weaving with Mono.Cecil in Unity isn't affecting Unity's assembly.

Hello, I wrote a simple program that finds methods decorated with an [Rpc] attributes, which works at finding them. Issue is when I try to weave Debug.Log("Hi"); into the method in which I'm not presented with any error but it fails. Code is below, any idea why this happens?
partial class Weaver
{
private static void RpcWeave(this MethodDefinition method)
{
Debug.Log($"RpcWeave called for method {method.Name}");
if (method.Body == null)
{
Debug.Log("Method body is null");
return;
}

if (method.Module == null)
{
Debug.Log("Method module is null");
return;
}

// Get the reference to the UnityEngine.Debug class
var debugType = method.Module.ImportReference(typeof(UnityEngine.Debug));
if (debugType == null)
{
Debug.Log("Debug class not found");
return;
}

// Get the reference to the Log method with a single string parameter
var logMethod = method.Module.ImportReference(debugType.Resolve().Methods.FirstOrDefault(m =>
m.Name == "Log" && m.Parameters.Count == 1 &&
m.Parameters[0].ParameterType.FullName == typeof(object).FullName));

// Check if the Log method was found
if (logMethod == null)
{
Debug.Log("Log method not found");
return;
}

ILProcessor weaver = method.Body.GetILProcessor();
if (weaver == null)
{
Debug.Log("ILProcessor is null");
return;
}

weaver.Emit(OpCodes.Ldstr, "Hi");
weaver.Emit(OpCodes.Call, logMethod);
weaver.Emit(OpCodes.Ret);
}

}
partial class Weaver
{
private static void RpcWeave(this MethodDefinition method)
{
Debug.Log($"RpcWeave called for method {method.Name}");
if (method.Body == null)
{
Debug.Log("Method body is null");
return;
}

if (method.Module == null)
{
Debug.Log("Method module is null");
return;
}

// Get the reference to the UnityEngine.Debug class
var debugType = method.Module.ImportReference(typeof(UnityEngine.Debug));
if (debugType == null)
{
Debug.Log("Debug class not found");
return;
}

// Get the reference to the Log method with a single string parameter
var logMethod = method.Module.ImportReference(debugType.Resolve().Methods.FirstOrDefault(m =>
m.Name == "Log" && m.Parameters.Count == 1 &&
m.Parameters[0].ParameterType.FullName == typeof(object).FullName));

// Check if the Log method was found
if (logMethod == null)
{
Debug.Log("Log method not found");
return;
}

ILProcessor weaver = method.Body.GetILProcessor();
if (weaver == null)
{
Debug.Log("ILProcessor is null");
return;
}

weaver.Emit(OpCodes.Ldstr, "Hi");
weaver.Emit(OpCodes.Call, logMethod);
weaver.Emit(OpCodes.Ret);
}

}
2 Replies
Icetrack
IcetrackOP2y ago
This is how I'm testing it
public class NetworkBehaviourTest : NetworkBehaviour
{
private void Start()
{
TestGenerate();
}

[Rpc]
private void TestGenerate()
{
Debug.Log("Method is called");
}
}
public class NetworkBehaviourTest : NetworkBehaviour
{
private void Start()
{
TestGenerate();
}

[Rpc]
private void TestGenerate()
{
Debug.Log("Method is called");
}
}
"Hi" isn't printed so thats how I know weaving didn't work
Accord
Accord2y ago
Looks like nothing has happened here. I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server