|
|
|
|
@@ -7,7 +7,6 @@ using System.Runtime.CompilerServices;
|
|
|
|
|
using Mono.Cecil;
|
|
|
|
|
using Mono.Cecil.Cil;
|
|
|
|
|
using Mono.Cecil.Rocks;
|
|
|
|
|
using Unity.Collections;
|
|
|
|
|
using Unity.CompilationPipeline.Common.Diagnostics;
|
|
|
|
|
using Unity.CompilationPipeline.Common.ILPostProcessing;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
@@ -17,7 +16,6 @@ using ILPPInterface = Unity.CompilationPipeline.Common.ILPostProcessing.ILPostPr
|
|
|
|
|
|
|
|
|
|
namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
internal sealed class NetworkBehaviourILPP : ILPPInterface
|
|
|
|
|
{
|
|
|
|
|
private const string k_ReadValueMethodName = nameof(FastBufferReader.ReadValueSafe);
|
|
|
|
|
@@ -25,7 +23,8 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
|
|
|
|
|
public override ILPPInterface GetInstance() => this;
|
|
|
|
|
|
|
|
|
|
public override bool WillProcess(ICompiledAssembly compiledAssembly) => compiledAssembly.References.Any(filePath => Path.GetFileNameWithoutExtension(filePath) == CodeGenHelpers.RuntimeAssemblyName);
|
|
|
|
|
public override bool WillProcess(ICompiledAssembly compiledAssembly) =>
|
|
|
|
|
compiledAssembly.References.Any(filePath => Path.GetFileNameWithoutExtension(filePath) == CodeGenHelpers.RuntimeAssemblyName);
|
|
|
|
|
|
|
|
|
|
private readonly List<DiagnosticMessage> m_Diagnostics = new List<DiagnosticMessage>();
|
|
|
|
|
|
|
|
|
|
@@ -109,8 +108,10 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
private FieldReference m_NetworkManager_rpc_name_table_FieldRef;
|
|
|
|
|
private MethodReference m_NetworkManager_rpc_name_table_Add_MethodRef;
|
|
|
|
|
private TypeReference m_NetworkBehaviour_TypeRef;
|
|
|
|
|
private MethodReference m_NetworkBehaviour_SendServerRpc_MethodRef;
|
|
|
|
|
private MethodReference m_NetworkBehaviour_SendClientRpc_MethodRef;
|
|
|
|
|
private MethodReference m_NetworkBehaviour_beginSendServerRpc_MethodRef;
|
|
|
|
|
private MethodReference m_NetworkBehaviour_endSendServerRpc_MethodRef;
|
|
|
|
|
private MethodReference m_NetworkBehaviour_beginSendClientRpc_MethodRef;
|
|
|
|
|
private MethodReference m_NetworkBehaviour_endSendClientRpc_MethodRef;
|
|
|
|
|
private FieldReference m_NetworkBehaviour_rpc_exec_stage_FieldRef;
|
|
|
|
|
private MethodReference m_NetworkBehaviour_getNetworkManager_MethodRef;
|
|
|
|
|
private MethodReference m_NetworkBehaviour_getOwnerClientId_MethodRef;
|
|
|
|
|
@@ -124,8 +125,6 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
private TypeReference m_ClientRpcParams_TypeRef;
|
|
|
|
|
|
|
|
|
|
private TypeReference m_FastBufferWriter_TypeRef;
|
|
|
|
|
private MethodReference m_FastBufferWriter_Constructor;
|
|
|
|
|
private MethodReference m_FastBufferWriter_Dispose;
|
|
|
|
|
private Dictionary<string, MethodReference> m_FastBufferWriter_WriteValue_MethodRefs = new Dictionary<string, MethodReference>();
|
|
|
|
|
private List<MethodReference> m_FastBufferWriter_ExtensionMethodRefs = new List<MethodReference>();
|
|
|
|
|
|
|
|
|
|
@@ -144,8 +143,10 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
private const string k_NetworkManager_rpc_name_table = nameof(NetworkManager.__rpc_name_table);
|
|
|
|
|
|
|
|
|
|
private const string k_NetworkBehaviour_rpc_exec_stage = nameof(NetworkBehaviour.__rpc_exec_stage);
|
|
|
|
|
private const string k_NetworkBehaviour_SendServerRpc = nameof(NetworkBehaviour.__sendServerRpc);
|
|
|
|
|
private const string k_NetworkBehaviour_SendClientRpc = nameof(NetworkBehaviour.__sendClientRpc);
|
|
|
|
|
private const string k_NetworkBehaviour_beginSendServerRpc = nameof(NetworkBehaviour.__beginSendServerRpc);
|
|
|
|
|
private const string k_NetworkBehaviour_endSendServerRpc = nameof(NetworkBehaviour.__endSendServerRpc);
|
|
|
|
|
private const string k_NetworkBehaviour_beginSendClientRpc = nameof(NetworkBehaviour.__beginSendClientRpc);
|
|
|
|
|
private const string k_NetworkBehaviour_endSendClientRpc = nameof(NetworkBehaviour.__endSendClientRpc);
|
|
|
|
|
private const string k_NetworkBehaviour_NetworkManager = nameof(NetworkBehaviour.NetworkManager);
|
|
|
|
|
private const string k_NetworkBehaviour_OwnerClientId = nameof(NetworkBehaviour.OwnerClientId);
|
|
|
|
|
|
|
|
|
|
@@ -234,11 +235,17 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
{
|
|
|
|
|
switch (methodInfo.Name)
|
|
|
|
|
{
|
|
|
|
|
case k_NetworkBehaviour_SendServerRpc:
|
|
|
|
|
m_NetworkBehaviour_SendServerRpc_MethodRef = moduleDefinition.ImportReference(methodInfo);
|
|
|
|
|
case k_NetworkBehaviour_beginSendServerRpc:
|
|
|
|
|
m_NetworkBehaviour_beginSendServerRpc_MethodRef = moduleDefinition.ImportReference(methodInfo);
|
|
|
|
|
break;
|
|
|
|
|
case k_NetworkBehaviour_SendClientRpc:
|
|
|
|
|
m_NetworkBehaviour_SendClientRpc_MethodRef = moduleDefinition.ImportReference(methodInfo);
|
|
|
|
|
case k_NetworkBehaviour_endSendServerRpc:
|
|
|
|
|
m_NetworkBehaviour_endSendServerRpc_MethodRef = moduleDefinition.ImportReference(methodInfo);
|
|
|
|
|
break;
|
|
|
|
|
case k_NetworkBehaviour_beginSendClientRpc:
|
|
|
|
|
m_NetworkBehaviour_beginSendClientRpc_MethodRef = moduleDefinition.ImportReference(methodInfo);
|
|
|
|
|
break;
|
|
|
|
|
case k_NetworkBehaviour_endSendClientRpc:
|
|
|
|
|
m_NetworkBehaviour_endSendClientRpc_MethodRef = moduleDefinition.ImportReference(methodInfo);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -299,17 +306,12 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
var fastBufferWriterType = typeof(FastBufferWriter);
|
|
|
|
|
m_FastBufferWriter_TypeRef = moduleDefinition.ImportReference(fastBufferWriterType);
|
|
|
|
|
|
|
|
|
|
m_FastBufferWriter_Constructor = moduleDefinition.ImportReference(
|
|
|
|
|
fastBufferWriterType.GetConstructor(new[] { typeof(int), typeof(Allocator), typeof(int) }));
|
|
|
|
|
m_FastBufferWriter_Dispose = moduleDefinition.ImportReference(fastBufferWriterType.GetMethod("Dispose"));
|
|
|
|
|
|
|
|
|
|
var fastBufferReaderType = typeof(FastBufferReader);
|
|
|
|
|
m_FastBufferReader_TypeRef = moduleDefinition.ImportReference(fastBufferReaderType);
|
|
|
|
|
|
|
|
|
|
// Find all extension methods for FastBufferReader and FastBufferWriter to enable user-implemented
|
|
|
|
|
// methods to be called.
|
|
|
|
|
var assemblies = new List<AssemblyDefinition>();
|
|
|
|
|
assemblies.Add(m_MainModule.Assembly);
|
|
|
|
|
var assemblies = new List<AssemblyDefinition> { m_MainModule.Assembly };
|
|
|
|
|
foreach (var reference in m_MainModule.AssemblyReferences)
|
|
|
|
|
{
|
|
|
|
|
var assembly = m_AssemblyResolver.Resolve(reference);
|
|
|
|
|
@@ -319,8 +321,7 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var extensionConstructor =
|
|
|
|
|
moduleDefinition.ImportReference(typeof(ExtensionAttribute).GetConstructor(new Type[] { }));
|
|
|
|
|
var extensionConstructor = moduleDefinition.ImportReference(typeof(ExtensionAttribute).GetConstructor(new Type[] { }));
|
|
|
|
|
foreach (var assembly in assemblies)
|
|
|
|
|
{
|
|
|
|
|
foreach (var module in assembly.Modules)
|
|
|
|
|
@@ -332,6 +333,7 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var method in type.Methods)
|
|
|
|
|
{
|
|
|
|
|
if (!method.IsStatic)
|
|
|
|
|
@@ -356,13 +358,11 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
|
|
|
|
|
var parameters = method.Parameters;
|
|
|
|
|
|
|
|
|
|
if (parameters.Count == 2
|
|
|
|
|
&& parameters[0].ParameterType.Resolve() == m_FastBufferWriter_TypeRef.MakeByReferenceType().Resolve())
|
|
|
|
|
if (parameters.Count == 2 && parameters[0].ParameterType.Resolve() == m_FastBufferWriter_TypeRef.MakeByReferenceType().Resolve())
|
|
|
|
|
{
|
|
|
|
|
m_FastBufferWriter_ExtensionMethodRefs.Add(m_MainModule.ImportReference(method));
|
|
|
|
|
}
|
|
|
|
|
else if (parameters.Count == 2
|
|
|
|
|
&& parameters[0].ParameterType.Resolve() == m_FastBufferReader_TypeRef.MakeByReferenceType().Resolve())
|
|
|
|
|
else if (parameters.Count == 2 && parameters[0].ParameterType.Resolve() == m_FastBufferReader_TypeRef.MakeByReferenceType().Resolve())
|
|
|
|
|
{
|
|
|
|
|
m_FastBufferReader_ExtensionMethodRefs.Add(m_MainModule.ImportReference(method));
|
|
|
|
|
}
|
|
|
|
|
@@ -395,9 +395,20 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (methodDefinition.HasCustomAttributes)
|
|
|
|
|
{
|
|
|
|
|
foreach (var attribute in methodDefinition.CustomAttributes)
|
|
|
|
|
{
|
|
|
|
|
if (attribute.AttributeType.Name == nameof(AsyncStateMachineAttribute))
|
|
|
|
|
{
|
|
|
|
|
m_Diagnostics.AddError(methodDefinition, $"{methodDefinition.FullName}: RPCs cannot be 'async'");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InjectWriteAndCallBlocks(methodDefinition, rpcAttribute, rpcMethodId);
|
|
|
|
|
|
|
|
|
|
rpcHandlers.Add((rpcMethodId, GenerateStaticHandler(methodDefinition, rpcAttribute)));
|
|
|
|
|
rpcHandlers.Add((rpcMethodId, GenerateStaticHandler(methodDefinition, rpcAttribute, rpcMethodId)));
|
|
|
|
|
|
|
|
|
|
if (isEditorOrDevelopment)
|
|
|
|
|
{
|
|
|
|
|
@@ -477,7 +488,6 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
private CustomAttribute CheckAndGetRpcAttribute(MethodDefinition methodDefinition)
|
|
|
|
|
{
|
|
|
|
|
CustomAttribute rpcAttribute = null;
|
|
|
|
|
bool isServerRpc = false;
|
|
|
|
|
foreach (var customAttribute in methodDefinition.CustomAttributes)
|
|
|
|
|
{
|
|
|
|
|
var customAttributeType_FullName = customAttribute.AttributeType.FullName;
|
|
|
|
|
@@ -521,7 +531,6 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
|
|
|
|
|
if (isValid)
|
|
|
|
|
{
|
|
|
|
|
isServerRpc = customAttributeType_FullName == CodeGenHelpers.ServerRpcAttribute_FullName;
|
|
|
|
|
rpcAttribute = customAttribute;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -569,12 +578,12 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
checkType = paramType.GetElementType().Resolve();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
(parameters[0].ParameterType.Resolve() == checkType
|
|
|
|
|
|| (parameters[0].ParameterType.Resolve() == checkType.MakeByReferenceType().Resolve() && parameters[0].IsIn)))
|
|
|
|
|
if ((parameters[0].ParameterType.Resolve() == checkType ||
|
|
|
|
|
(parameters[0].ParameterType.Resolve() == checkType.MakeByReferenceType().Resolve() && parameters[0].IsIn)))
|
|
|
|
|
{
|
|
|
|
|
return method;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (method.HasGenericParameters && method.GenericParameters.Count == 1)
|
|
|
|
|
{
|
|
|
|
|
if (method.GenericParameters[0].HasConstraints)
|
|
|
|
|
@@ -584,17 +593,15 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
{
|
|
|
|
|
var resolvedConstraint = constraint.Resolve();
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
(resolvedConstraint.IsInterface &&
|
|
|
|
|
!checkType.HasInterface(resolvedConstraint.FullName))
|
|
|
|
|
|| (resolvedConstraint.IsClass &&
|
|
|
|
|
!checkType.Resolve().IsSubclassOf(resolvedConstraint.FullName))
|
|
|
|
|
|| (resolvedConstraint.Name == "ValueType" && !checkType.IsValueType))
|
|
|
|
|
if ((resolvedConstraint.IsInterface && !checkType.HasInterface(resolvedConstraint.FullName)) ||
|
|
|
|
|
(resolvedConstraint.IsClass && !checkType.Resolve().IsSubclassOf(resolvedConstraint.FullName)) ||
|
|
|
|
|
(resolvedConstraint.Name == "ValueType" && !checkType.IsValueType))
|
|
|
|
|
{
|
|
|
|
|
meetsConstraints = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (meetsConstraints)
|
|
|
|
|
{
|
|
|
|
|
var instanceMethod = new GenericInstanceMethod(method);
|
|
|
|
|
@@ -624,8 +631,8 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
{
|
|
|
|
|
if (parameters[1].IsIn)
|
|
|
|
|
{
|
|
|
|
|
if (parameters[1].ParameterType.Resolve() == paramType.MakeByReferenceType().Resolve()
|
|
|
|
|
&& ((ByReferenceType)parameters[1].ParameterType).ElementType.IsArray == paramType.IsArray)
|
|
|
|
|
if (parameters[1].ParameterType.Resolve() == paramType.MakeByReferenceType().Resolve() &&
|
|
|
|
|
((ByReferenceType)parameters[1].ParameterType).ElementType.IsArray == paramType.IsArray)
|
|
|
|
|
{
|
|
|
|
|
methodRef = method;
|
|
|
|
|
m_FastBufferWriter_WriteValue_MethodRefs[assemblyQualifiedName] = methodRef;
|
|
|
|
|
@@ -635,8 +642,8 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (parameters[1].ParameterType.Resolve() == paramType.Resolve()
|
|
|
|
|
&& parameters[1].ParameterType.IsArray == paramType.IsArray)
|
|
|
|
|
if (parameters[1].ParameterType.Resolve() == paramType.Resolve() &&
|
|
|
|
|
parameters[1].ParameterType.IsArray == paramType.IsArray)
|
|
|
|
|
{
|
|
|
|
|
methodRef = method;
|
|
|
|
|
m_FastBufferWriter_WriteValue_MethodRefs[assemblyQualifiedName] = methodRef;
|
|
|
|
|
@@ -707,11 +714,8 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
{
|
|
|
|
|
var resolvedConstraint = constraint.Resolve();
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
(resolvedConstraint.IsInterface &&
|
|
|
|
|
checkType.HasInterface(resolvedConstraint.FullName))
|
|
|
|
|
|| (resolvedConstraint.IsClass &&
|
|
|
|
|
checkType.Resolve().IsSubclassOf(resolvedConstraint.FullName)))
|
|
|
|
|
if ((resolvedConstraint.IsInterface && checkType.HasInterface(resolvedConstraint.FullName)) ||
|
|
|
|
|
(resolvedConstraint.IsClass && checkType.Resolve().IsSubclassOf(resolvedConstraint.FullName)))
|
|
|
|
|
{
|
|
|
|
|
var instanceMethod = new GenericInstanceMethod(method);
|
|
|
|
|
instanceMethod.GenericArguments.Add(checkType);
|
|
|
|
|
@@ -736,11 +740,10 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
foreach (var method in m_FastBufferReader_ExtensionMethodRefs)
|
|
|
|
|
{
|
|
|
|
|
var parameters = method.Resolve().Parameters;
|
|
|
|
|
if (
|
|
|
|
|
method.Name == k_ReadValueMethodName
|
|
|
|
|
&& parameters[1].IsOut
|
|
|
|
|
&& parameters[1].ParameterType.Resolve() == paramType.MakeByReferenceType().Resolve()
|
|
|
|
|
&& ((ByReferenceType)parameters[1].ParameterType).ElementType.IsArray == paramType.IsArray)
|
|
|
|
|
if (method.Name == k_ReadValueMethodName &&
|
|
|
|
|
parameters[1].IsOut &&
|
|
|
|
|
parameters[1].ParameterType.Resolve() == paramType.MakeByReferenceType().Resolve() &&
|
|
|
|
|
((ByReferenceType)parameters[1].ParameterType).ElementType.IsArray == paramType.IsArray)
|
|
|
|
|
{
|
|
|
|
|
methodRef = method;
|
|
|
|
|
m_FastBufferReader_ReadValue_MethodRefs[assemblyQualifiedName] = methodRef;
|
|
|
|
|
@@ -772,8 +775,8 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
var instructions = new List<Instruction>();
|
|
|
|
|
var processor = methodDefinition.Body.GetILProcessor();
|
|
|
|
|
var isServerRpc = rpcAttribute.AttributeType.FullName == CodeGenHelpers.ServerRpcAttribute_FullName;
|
|
|
|
|
var requireOwnership = true; // default value MUST be = `ServerRpcAttribute.RequireOwnership`
|
|
|
|
|
var rpcDelivery = RpcDelivery.Reliable; // default value MUST be = `RpcAttribute.Delivery`
|
|
|
|
|
var requireOwnership = true; // default value MUST be == `ServerRpcAttribute.RequireOwnership`
|
|
|
|
|
var rpcDelivery = RpcDelivery.Reliable; // default value MUST be == `RpcAttribute.Delivery`
|
|
|
|
|
foreach (var attrField in rpcAttribute.Fields)
|
|
|
|
|
{
|
|
|
|
|
switch (attrField.Name)
|
|
|
|
|
@@ -797,9 +800,9 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
// NetworkManager networkManager;
|
|
|
|
|
methodDefinition.Body.Variables.Add(new VariableDefinition(m_NetworkManager_TypeRef));
|
|
|
|
|
int netManLocIdx = methodDefinition.Body.Variables.Count - 1;
|
|
|
|
|
// NetworkSerializer serializer;
|
|
|
|
|
// FastBufferWriter bufferWriter;
|
|
|
|
|
methodDefinition.Body.Variables.Add(new VariableDefinition(m_FastBufferWriter_TypeRef));
|
|
|
|
|
int serializerLocIdx = methodDefinition.Body.Variables.Count - 1;
|
|
|
|
|
int bufWriterLocIdx = methodDefinition.Body.Variables.Count - 1;
|
|
|
|
|
|
|
|
|
|
// XXXRpcParams
|
|
|
|
|
if (!hasRpcParams)
|
|
|
|
|
@@ -854,6 +857,8 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
|
|
|
|
|
instructions.Add(beginInstr);
|
|
|
|
|
|
|
|
|
|
// var bufferWriter = __beginSendServerRpc(rpcMethodId, serverRpcParams, rpcDelivery) -> ServerRpc
|
|
|
|
|
// var bufferWriter = __beginSendClientRpc(rpcMethodId, clientRpcParams, rpcDelivery) -> ClientRpc
|
|
|
|
|
if (isServerRpc)
|
|
|
|
|
{
|
|
|
|
|
// ServerRpc
|
|
|
|
|
@@ -867,8 +872,7 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldarg_0));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Call, m_NetworkBehaviour_getOwnerClientId_MethodRef));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloc, netManLocIdx));
|
|
|
|
|
instructions.Add(
|
|
|
|
|
processor.Create(OpCodes.Callvirt, m_NetworkManager_getLocalClientId_MethodRef));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Callvirt, m_NetworkManager_getLocalClientId_MethodRef));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ceq));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4, 0));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ceq));
|
|
|
|
|
@@ -886,8 +890,7 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Brfalse, logNextInstr));
|
|
|
|
|
|
|
|
|
|
// Debug.LogError(...);
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldstr,
|
|
|
|
|
"Only the owner can invoke a ServerRpc that requires ownership!"));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldstr, "Only the owner can invoke a ServerRpc that requires ownership!"));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Call, m_Debug_LogError_MethodRef));
|
|
|
|
|
|
|
|
|
|
instructions.Add(logNextInstr);
|
|
|
|
|
@@ -895,31 +898,86 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
instructions.Add(roReturnInstr);
|
|
|
|
|
instructions.Add(roLastInstr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// var bufferWriter = __beginSendServerRpc(rpcMethodId, serverRpcParams, rpcDelivery);
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldarg_0));
|
|
|
|
|
|
|
|
|
|
// rpcMethodId
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)rpcMethodId)));
|
|
|
|
|
|
|
|
|
|
// rpcParams
|
|
|
|
|
instructions.Add(hasRpcParams ? processor.Create(OpCodes.Ldarg, paramCount) : processor.Create(OpCodes.Ldloc, rpcParamsIdx));
|
|
|
|
|
|
|
|
|
|
// rpcDelivery
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4, (int)rpcDelivery));
|
|
|
|
|
|
|
|
|
|
// __beginSendServerRpc
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Call, m_NetworkBehaviour_beginSendServerRpc_MethodRef));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Stloc, bufWriterLocIdx));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// ClientRpc
|
|
|
|
|
|
|
|
|
|
// var writer = new FastBufferWriter(1285, Allocator.Temp, 63985);
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloca, serializerLocIdx));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4, 1300 - sizeof(byte) - sizeof(ulong) - sizeof(uint) - sizeof(ushort)));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4_2));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4, 64000 - sizeof(byte) - sizeof(ulong) - sizeof(uint) - sizeof(ushort)));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Call, m_FastBufferWriter_Constructor));
|
|
|
|
|
// var bufferWriter = __beginSendClientRpc(rpcMethodId, clientRpcParams, rpcDelivery);
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldarg_0));
|
|
|
|
|
|
|
|
|
|
var firstInstruction = processor.Create(OpCodes.Nop);
|
|
|
|
|
instructions.Add(firstInstruction);
|
|
|
|
|
// rpcMethodId
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)rpcMethodId)));
|
|
|
|
|
|
|
|
|
|
// rpcParams
|
|
|
|
|
instructions.Add(hasRpcParams ? processor.Create(OpCodes.Ldarg, paramCount) : processor.Create(OpCodes.Ldloc, rpcParamsIdx));
|
|
|
|
|
|
|
|
|
|
// rpcDelivery
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4, (int)rpcDelivery));
|
|
|
|
|
|
|
|
|
|
// __beginSendClientRpc
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Call, m_NetworkBehaviour_beginSendClientRpc_MethodRef));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Stloc, bufWriterLocIdx));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// write method parameters into stream
|
|
|
|
|
for (int paramIndex = 0; paramIndex < paramCount; ++paramIndex)
|
|
|
|
|
{
|
|
|
|
|
var paramDef = methodDefinition.Parameters[paramIndex];
|
|
|
|
|
var paramType = paramDef.ParameterType;
|
|
|
|
|
// ServerRpcParams
|
|
|
|
|
if (paramType.FullName == CodeGenHelpers.ServerRpcParams_FullName && isServerRpc && paramIndex == paramCount - 1)
|
|
|
|
|
if (paramType.FullName == CodeGenHelpers.ClientRpcSendParams_FullName ||
|
|
|
|
|
paramType.FullName == CodeGenHelpers.ClientRpcReceiveParams_FullName)
|
|
|
|
|
{
|
|
|
|
|
m_Diagnostics.AddError($"Rpcs may not accept {paramType.FullName} as a parameter. Use {nameof(ClientRpcParams)} instead.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (paramType.FullName == CodeGenHelpers.ServerRpcSendParams_FullName ||
|
|
|
|
|
paramType.FullName == CodeGenHelpers.ServerRpcReceiveParams_FullName)
|
|
|
|
|
{
|
|
|
|
|
m_Diagnostics.AddError($"Rpcs may not accept {paramType.FullName} as a parameter. Use {nameof(ServerRpcParams)} instead.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// ServerRpcParams
|
|
|
|
|
if (paramType.FullName == CodeGenHelpers.ServerRpcParams_FullName)
|
|
|
|
|
{
|
|
|
|
|
if (paramIndex != paramCount - 1)
|
|
|
|
|
{
|
|
|
|
|
m_Diagnostics.AddError(methodDefinition, $"{nameof(ServerRpcParams)} must be the last parameter in a ServerRpc.");
|
|
|
|
|
}
|
|
|
|
|
if (!isServerRpc)
|
|
|
|
|
{
|
|
|
|
|
m_Diagnostics.AddError($"ClientRpcs may not accept {nameof(ServerRpcParams)} as a parameter.");
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// ClientRpcParams
|
|
|
|
|
if (paramType.FullName == CodeGenHelpers.ClientRpcParams_FullName && !isServerRpc && paramIndex == paramCount - 1)
|
|
|
|
|
if (paramType.FullName == CodeGenHelpers.ClientRpcParams_FullName)
|
|
|
|
|
{
|
|
|
|
|
if (paramIndex != paramCount - 1)
|
|
|
|
|
{
|
|
|
|
|
m_Diagnostics.AddError(methodDefinition, $"{nameof(ClientRpcParams)} must be the last parameter in a ClientRpc.");
|
|
|
|
|
}
|
|
|
|
|
if (isServerRpc)
|
|
|
|
|
{
|
|
|
|
|
m_Diagnostics.AddError($"ServerRpcs may not accept {nameof(ClientRpcParams)} as a parameter.");
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -942,8 +1000,8 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Cgt_Un));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Stloc, isSetLocalIndex));
|
|
|
|
|
|
|
|
|
|
// writer.WriteValueSafe(isSet);
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloca, serializerLocIdx));
|
|
|
|
|
// bufferWriter.WriteValueSafe(isSet);
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloca, bufWriterLocIdx));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloca, isSetLocalIndex));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Call, boolMethodRef));
|
|
|
|
|
|
|
|
|
|
@@ -956,11 +1014,11 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
var foundMethodRef = GetWriteMethodForParameter(paramType, out var methodRef);
|
|
|
|
|
if (foundMethodRef)
|
|
|
|
|
{
|
|
|
|
|
// writer.WriteNetworkSerializable(param) for INetworkSerializable, OR
|
|
|
|
|
// writer.WriteNetworkSerializable(param, -1, 0) for INetworkSerializable arrays, OR
|
|
|
|
|
// writer.WriteValueSafe(param) for value types, OR
|
|
|
|
|
// writer.WriteValueSafe(param, -1, 0) for arrays of value types, OR
|
|
|
|
|
// writer.WriteValueSafe(param, false) for strings
|
|
|
|
|
// bufferWriter.WriteNetworkSerializable(param) for INetworkSerializable, OR
|
|
|
|
|
// bufferWriter.WriteNetworkSerializable(param, -1, 0) for INetworkSerializable arrays, OR
|
|
|
|
|
// bufferWriter.WriteValueSafe(param) for value types, OR
|
|
|
|
|
// bufferWriter.WriteValueSafe(param, -1, 0) for arrays of value types, OR
|
|
|
|
|
// bufferWriter.WriteValueSafe(param, false) for strings
|
|
|
|
|
var method = methodRef.Resolve();
|
|
|
|
|
var checkParameter = method.Parameters[0];
|
|
|
|
|
var isExtensionMethod = false;
|
|
|
|
|
@@ -971,11 +1029,11 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
}
|
|
|
|
|
if (!isExtensionMethod || method.Parameters[0].ParameterType.IsByReference)
|
|
|
|
|
{
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloca, serializerLocIdx));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloca, bufWriterLocIdx));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloc, serializerLocIdx));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloc, bufWriterLocIdx));
|
|
|
|
|
}
|
|
|
|
|
if (checkParameter.IsIn || checkParameter.IsOut || checkParameter.ParameterType.IsByReference)
|
|
|
|
|
{
|
|
|
|
|
@@ -986,16 +1044,14 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldarg, paramIndex + 1));
|
|
|
|
|
}
|
|
|
|
|
// Special handling for WriteValue() on arrays and strings since they have additional arguments.
|
|
|
|
|
if (paramType.IsArray
|
|
|
|
|
&& ((!isExtensionMethod && methodRef.Parameters.Count == 3)
|
|
|
|
|
|| (isExtensionMethod && methodRef.Parameters.Count == 4)))
|
|
|
|
|
if (paramType.IsArray && ((!isExtensionMethod && methodRef.Parameters.Count == 3) ||
|
|
|
|
|
(isExtensionMethod && methodRef.Parameters.Count == 4)))
|
|
|
|
|
{
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4_M1));
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4_0));
|
|
|
|
|
}
|
|
|
|
|
else if (paramType == typeSystem.String
|
|
|
|
|
&& ((!isExtensionMethod && methodRef.Parameters.Count == 2)
|
|
|
|
|
|| (isExtensionMethod && methodRef.Parameters.Count == 3)))
|
|
|
|
|
else if (paramType == typeSystem.String && ((!isExtensionMethod && methodRef.Parameters.Count == 2) ||
|
|
|
|
|
(isExtensionMethod && methodRef.Parameters.Count == 3)))
|
|
|
|
|
{
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4_0));
|
|
|
|
|
}
|
|
|
|
|
@@ -1015,20 +1071,20 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
|
|
|
|
|
instructions.Add(endInstr);
|
|
|
|
|
|
|
|
|
|
// __sendServerRpc(ref serializer, rpcMethodId, serverRpcParams, rpcDelivery) -> ServerRpc
|
|
|
|
|
// __sendClientRpc(ref serializer, rpcMethodId, clientRpcParams, rpcDelivery) -> ClientRpc
|
|
|
|
|
// __endSendServerRpc(ref bufferWriter, rpcMethodId, serverRpcParams, rpcDelivery) -> ServerRpc
|
|
|
|
|
// __endSendClientRpc(ref bufferWriter, rpcMethodId, clientRpcParams, rpcDelivery) -> ClientRpc
|
|
|
|
|
if (isServerRpc)
|
|
|
|
|
{
|
|
|
|
|
// ServerRpc
|
|
|
|
|
// __sendServerRpc(ref serializer, rpcMethodId, serverRpcParams, rpcDelivery);
|
|
|
|
|
|
|
|
|
|
// __endSendServerRpc(ref bufferWriter, rpcMethodId, serverRpcParams, rpcDelivery);
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldarg_0));
|
|
|
|
|
|
|
|
|
|
// serializer
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloc, serializerLocIdx));
|
|
|
|
|
// bufferWriter
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloca, bufWriterLocIdx));
|
|
|
|
|
|
|
|
|
|
// rpcMethodId
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)rpcMethodId)));
|
|
|
|
|
|
|
|
|
|
if (hasRpcParams)
|
|
|
|
|
{
|
|
|
|
|
// rpcParams
|
|
|
|
|
@@ -1039,25 +1095,24 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
// default
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloc, rpcParamsIdx));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// rpcDelivery
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4, (int)rpcDelivery));
|
|
|
|
|
|
|
|
|
|
// EndSendServerRpc
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Call, m_NetworkBehaviour_SendServerRpc_MethodRef));
|
|
|
|
|
// __endSendServerRpc
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Call, m_NetworkBehaviour_endSendServerRpc_MethodRef));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// ClientRpc
|
|
|
|
|
// __sendClientRpc(ref serializer, rpcMethodId, clientRpcParams, rpcDelivery);
|
|
|
|
|
|
|
|
|
|
// __endSendClientRpc(ref bufferWriter, rpcMethodId, clientRpcParams, rpcDelivery);
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldarg_0));
|
|
|
|
|
|
|
|
|
|
// serializer
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloc, serializerLocIdx));
|
|
|
|
|
// bufferWriter
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloca, bufWriterLocIdx));
|
|
|
|
|
|
|
|
|
|
// rpcMethodId
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)rpcMethodId)));
|
|
|
|
|
|
|
|
|
|
if (hasRpcParams)
|
|
|
|
|
{
|
|
|
|
|
// rpcParams
|
|
|
|
|
@@ -1068,36 +1123,11 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
// default
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldloc, rpcParamsIdx));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// rpcDelivery
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Ldc_I4, (int)rpcDelivery));
|
|
|
|
|
|
|
|
|
|
// EndSendClientRpc
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Call, m_NetworkBehaviour_SendClientRpc_MethodRef));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
// TODO: Figure out why try/catch here cause the try block not to execute at all.
|
|
|
|
|
// End try block
|
|
|
|
|
//instructions.Add(processor.Create(OpCodes.Leave, lastInstr));
|
|
|
|
|
|
|
|
|
|
// writer.Dispose();
|
|
|
|
|
var handlerFirst = processor.Create(OpCodes.Ldloca, serializerLocIdx);
|
|
|
|
|
instructions.Add(handlerFirst);
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Call, m_FastBufferWriter_Dispose));
|
|
|
|
|
|
|
|
|
|
// End finally block
|
|
|
|
|
//instructions.Add(processor.Create(OpCodes.Endfinally));
|
|
|
|
|
|
|
|
|
|
// try { ... serialization code ... } finally { writer.Dispose(); }
|
|
|
|
|
/*var handler = new ExceptionHandler(ExceptionHandlerType.Finally)
|
|
|
|
|
{
|
|
|
|
|
TryStart = firstInstruction,
|
|
|
|
|
TryEnd = handlerFirst,
|
|
|
|
|
HandlerStart = handlerFirst,
|
|
|
|
|
HandlerEnd = lastInstr
|
|
|
|
|
};
|
|
|
|
|
processor.Body.ExceptionHandlers.Add(handler);*/
|
|
|
|
|
// __endSendClientRpc
|
|
|
|
|
instructions.Add(processor.Create(OpCodes.Call, m_NetworkBehaviour_endSendClientRpc_MethodRef));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
instructions.Add(lastInstr);
|
|
|
|
|
@@ -1132,25 +1162,21 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
instructions.ForEach(instruction => processor.Body.Instructions.Insert(0, instruction));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private MethodDefinition GenerateStaticHandler(MethodDefinition methodDefinition, CustomAttribute rpcAttribute)
|
|
|
|
|
private MethodDefinition GenerateStaticHandler(MethodDefinition methodDefinition, CustomAttribute rpcAttribute, uint rpcMethodId)
|
|
|
|
|
{
|
|
|
|
|
var typeSystem = methodDefinition.Module.TypeSystem;
|
|
|
|
|
var nhandler = new MethodDefinition(
|
|
|
|
|
$"{methodDefinition.Name}__nhandler",
|
|
|
|
|
var rpcHandler = new MethodDefinition(
|
|
|
|
|
$"__rpc_handler_{rpcMethodId}",
|
|
|
|
|
MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.HideBySig,
|
|
|
|
|
methodDefinition.Module.TypeSystem.Void);
|
|
|
|
|
nhandler.Parameters.Add(new ParameterDefinition("target", ParameterAttributes.None, m_NetworkBehaviour_TypeRef));
|
|
|
|
|
nhandler.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, m_FastBufferReader_TypeRef));
|
|
|
|
|
nhandler.Parameters.Add(new ParameterDefinition("rpcParams", ParameterAttributes.None, m_RpcParams_TypeRef));
|
|
|
|
|
rpcHandler.Parameters.Add(new ParameterDefinition("target", ParameterAttributes.None, m_NetworkBehaviour_TypeRef));
|
|
|
|
|
rpcHandler.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, m_FastBufferReader_TypeRef));
|
|
|
|
|
rpcHandler.Parameters.Add(new ParameterDefinition("rpcParams", ParameterAttributes.None, m_RpcParams_TypeRef));
|
|
|
|
|
|
|
|
|
|
var processor = nhandler.Body.GetILProcessor();
|
|
|
|
|
|
|
|
|
|
// begin Try/Catch
|
|
|
|
|
var tryStart = processor.Create(OpCodes.Nop);
|
|
|
|
|
processor.Append(tryStart);
|
|
|
|
|
var processor = rpcHandler.Body.GetILProcessor();
|
|
|
|
|
|
|
|
|
|
var isServerRpc = rpcAttribute.AttributeType.FullName == CodeGenHelpers.ServerRpcAttribute_FullName;
|
|
|
|
|
var requireOwnership = true; // default value MUST be = `ServerRpcAttribute.RequireOwnership`
|
|
|
|
|
var requireOwnership = true; // default value MUST be == `ServerRpcAttribute.RequireOwnership`
|
|
|
|
|
foreach (var attrField in rpcAttribute.Fields)
|
|
|
|
|
{
|
|
|
|
|
switch (attrField.Name)
|
|
|
|
|
@@ -1161,10 +1187,10 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nhandler.Body.InitLocals = true;
|
|
|
|
|
rpcHandler.Body.InitLocals = true;
|
|
|
|
|
// NetworkManager networkManager;
|
|
|
|
|
nhandler.Body.Variables.Add(new VariableDefinition(m_NetworkManager_TypeRef));
|
|
|
|
|
int netManLocIdx = nhandler.Body.Variables.Count - 1;
|
|
|
|
|
rpcHandler.Body.Variables.Add(new VariableDefinition(m_NetworkManager_TypeRef));
|
|
|
|
|
int netManLocIdx = rpcHandler.Body.Variables.Count - 1;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
var returnInstr = processor.Create(OpCodes.Ret);
|
|
|
|
|
@@ -1233,8 +1259,8 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
var paramType = paramDef.ParameterType;
|
|
|
|
|
|
|
|
|
|
// local variable
|
|
|
|
|
nhandler.Body.Variables.Add(new VariableDefinition(paramType));
|
|
|
|
|
int localIndex = nhandler.Body.Variables.Count - 1;
|
|
|
|
|
rpcHandler.Body.Variables.Add(new VariableDefinition(paramType));
|
|
|
|
|
int localIndex = rpcHandler.Body.Variables.Count - 1;
|
|
|
|
|
paramLocalMap[paramIndex] = localIndex;
|
|
|
|
|
|
|
|
|
|
// ServerRpcParams, ClientRpcParams
|
|
|
|
|
@@ -1268,8 +1294,8 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// reader.ReadValueSafe(out bool isSet)
|
|
|
|
|
nhandler.Body.Variables.Add(new VariableDefinition(typeSystem.Boolean));
|
|
|
|
|
int isSetLocalIndex = nhandler.Body.Variables.Count - 1;
|
|
|
|
|
rpcHandler.Body.Variables.Add(new VariableDefinition(typeSystem.Boolean));
|
|
|
|
|
int isSetLocalIndex = rpcHandler.Body.Variables.Count - 1;
|
|
|
|
|
processor.Emit(OpCodes.Ldarga, 1);
|
|
|
|
|
processor.Emit(OpCodes.Ldloca, isSetLocalIndex);
|
|
|
|
|
processor.Emit(OpCodes.Call, boolMethodRef);
|
|
|
|
|
@@ -1336,55 +1362,8 @@ namespace Unity.Netcode.Editor.CodeGen
|
|
|
|
|
processor.Emit(OpCodes.Ldc_I4, (int)NetworkBehaviour.__RpcExecStage.None);
|
|
|
|
|
processor.Emit(OpCodes.Stfld, m_NetworkBehaviour_rpc_exec_stage_FieldRef);
|
|
|
|
|
|
|
|
|
|
// pull in the Exception Module
|
|
|
|
|
var exception = m_MainModule.ImportReference(typeof(Exception));
|
|
|
|
|
|
|
|
|
|
// Get Exception.ToString()
|
|
|
|
|
var exp = m_MainModule.ImportReference(typeof(Exception).GetMethod("ToString", new Type[] { }));
|
|
|
|
|
|
|
|
|
|
// Get String.Format (This is equivalent to an interpolated string)
|
|
|
|
|
var stringFormat = m_MainModule.ImportReference(typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(object) }));
|
|
|
|
|
|
|
|
|
|
nhandler.Body.Variables.Add(new VariableDefinition(exception));
|
|
|
|
|
int exceptionVariableIndex = nhandler.Body.Variables.Count - 1;
|
|
|
|
|
|
|
|
|
|
//try ends/catch begins
|
|
|
|
|
var catchEnds = processor.Create(OpCodes.Nop);
|
|
|
|
|
processor.Emit(OpCodes.Leave, catchEnds);
|
|
|
|
|
|
|
|
|
|
// Load the Exception onto the stack
|
|
|
|
|
var catchStarts = processor.Create(OpCodes.Stloc, exceptionVariableIndex);
|
|
|
|
|
processor.Append(catchStarts);
|
|
|
|
|
|
|
|
|
|
// Load string for the error log that will be shown
|
|
|
|
|
processor.Emit(OpCodes.Ldstr, $"Unhandled RPC Exception:\n {{0}}");
|
|
|
|
|
processor.Emit(OpCodes.Ldloc, exceptionVariableIndex);
|
|
|
|
|
processor.Emit(OpCodes.Callvirt, exp);
|
|
|
|
|
processor.Emit(OpCodes.Call, stringFormat);
|
|
|
|
|
|
|
|
|
|
// Call Debug.LogError
|
|
|
|
|
processor.Emit(OpCodes.Call, m_Debug_LogError_MethodRef);
|
|
|
|
|
|
|
|
|
|
// reset NetworkBehaviour.__rpc_exec_stage = __RpcExecStage.None;
|
|
|
|
|
processor.Emit(OpCodes.Ldarg_0);
|
|
|
|
|
processor.Emit(OpCodes.Ldc_I4, (int)NetworkBehaviour.__RpcExecStage.None);
|
|
|
|
|
processor.Emit(OpCodes.Stfld, m_NetworkBehaviour_rpc_exec_stage_FieldRef);
|
|
|
|
|
|
|
|
|
|
// catch ends
|
|
|
|
|
processor.Append(catchEnds);
|
|
|
|
|
|
|
|
|
|
processor.Body.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Catch)
|
|
|
|
|
{
|
|
|
|
|
CatchType = exception,
|
|
|
|
|
TryStart = tryStart,
|
|
|
|
|
TryEnd = catchStarts,
|
|
|
|
|
HandlerStart = catchStarts,
|
|
|
|
|
HandlerEnd = catchEnds
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
processor.Emit(OpCodes.Ret);
|
|
|
|
|
|
|
|
|
|
return nhandler;
|
|
|
|
|
return rpcHandler;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|