@@ -1314,8 +1314,6 @@ private void ProcessNetworkBehaviour(TypeDefinition typeDefinition, string[] ass
13141314 }
13151315 var rpcHandlers = new List < ( uint RpcMethodId , MethodDefinition RpcHandler , string RpcMethodName , CustomAttribute rpcAttribute ) > ( ) ;
13161316
1317- bool isEditorOrDevelopment = assemblyDefines . Contains ( "UNITY_EDITOR" ) || assemblyDefines . Contains ( "DEVELOPMENT_BUILD" ) ;
1318-
13191317 foreach ( var methodDefinition in typeDefinition . Methods )
13201318 {
13211319 var rpcAttribute = CheckAndGetRpcAttribute ( methodDefinition ) ;
@@ -1436,16 +1434,18 @@ private void ProcessNetworkBehaviour(TypeDefinition typeDefinition, string[] ass
14361434 callMethod = callMethod . MakeGeneric ( genericTypes . ToArray ( ) ) ;
14371435 }
14381436
1437+ var isServerRpc = rpcAttribute . AttributeType . FullName == CodeGenHelpers . ServerRpcAttribute_FullName ;
14391438 var isClientRpc = rpcAttribute . AttributeType . FullName == CodeGenHelpers . ClientRpcAttribute_FullName ;
14401439
1441- var invokePermission = RpcInvokePermission . Anyone ;
1440+ var invokePermission = isServerRpc ? RpcInvokePermission . Owner : RpcInvokePermission . Everyone ;
14421441
14431442 foreach ( var attrField in rpcAttribute . Fields )
14441443 {
14451444 switch ( attrField . Name )
14461445 {
14471446 case k_ServerRpcAttribute_RequireOwnership :
1448- invokePermission = ( attrField . Argument . Type == rpcHandler . Module . TypeSystem . Boolean && ( bool ) attrField . Argument . Value ) ? RpcInvokePermission . Owner : RpcInvokePermission . Anyone ;
1447+ var requireOwnership = attrField . Argument . Type == rpcHandler . Module . TypeSystem . Boolean && ( bool ) attrField . Argument . Value ;
1448+ invokePermission = requireOwnership ? RpcInvokePermission . Owner : RpcInvokePermission . Everyone ;
14491449 break ;
14501450 case k_RpcAttribute_InvokePermission :
14511451 invokePermission = ( RpcInvokePermission ) attrField . Argument . Value ;
@@ -1583,17 +1583,24 @@ private CustomAttribute CheckAndGetRpcAttribute(MethodDefinition methodDefinitio
15831583 isValid = false ;
15841584 }
15851585
1586- if ( customAttributeType_FullName == CodeGenHelpers . RpcAttribute_FullName &&
1587- ! methodDefinition . Name . EndsWith ( "Rpc " , StringComparison . OrdinalIgnoreCase ) )
1586+ if ( customAttributeType_FullName == CodeGenHelpers . ClientRpcAttribute_FullName &&
1587+ ! methodDefinition . Name . EndsWith ( "ClientRpc " , StringComparison . OrdinalIgnoreCase ) )
15881588 {
1589- m_Diagnostics . AddError ( methodDefinition , "Rpc method must end with 'Rpc ' suffix!" ) ;
1589+ m_Diagnostics . AddError ( methodDefinition , "ClientRpc method must end with 'ClientRpc ' suffix!" ) ;
15901590 isValid = false ;
15911591 }
15921592
1593- if ( customAttributeType_FullName == CodeGenHelpers . ClientRpcAttribute_FullName &&
1594- ! methodDefinition . Name . EndsWith ( "ClientRpc " , StringComparison . OrdinalIgnoreCase ) )
1593+ if ( customAttributeType_FullName == CodeGenHelpers . RpcAttribute_FullName &&
1594+ ! methodDefinition . Name . EndsWith ( "Rpc " , StringComparison . OrdinalIgnoreCase ) )
15951595 {
1596- m_Diagnostics . AddError ( methodDefinition , "ClientRpc method must end with 'ClientRpc' suffix!" ) ;
1596+ m_Diagnostics . AddError ( methodDefinition , "Rpc method must end with 'Rpc' suffix!" ) ;
1597+
1598+ // Extra compiler information if a method was defined as a local function
1599+ if ( methodDefinition . Name . Contains ( "Rpc|" , StringComparison . OrdinalIgnoreCase ) && methodDefinition . Name . StartsWith ( "g__" , StringComparison . OrdinalIgnoreCase ) )
1600+ {
1601+ m_Diagnostics . AddError ( methodDefinition , $ "{ methodDefinition . Name } appears to be a local function. Local functions cannot be RPCs.") ;
1602+ }
1603+
15971604 isValid = false ;
15981605 }
15991606
@@ -1638,8 +1645,6 @@ private CustomAttribute CheckAndGetRpcAttribute(MethodDefinition methodDefinitio
16381645 case k_RpcAttribute_InvokePermission :
16391646 hasInvokePermission = true ;
16401647 break ;
1641- default :
1642- break ;
16431648 }
16441649 }
16451650
@@ -2206,13 +2211,30 @@ private void InjectWriteAndCallBlocks(MethodDefinition methodDefinition, CustomA
22062211 instructions. Add ( processor . Create ( OpCodes . Call , m_NetworkBehaviour_getNetworkManager_MethodRef ) ) ;
22072212 instructions. Add ( processor . Create ( OpCodes . Stloc , netManLocIdx ) ) ;
22082213
2209- // if (networkManager == null || !networkManager.IsListening) return;
2214+ // if (networkManager == null || !networkManager.IsListening) { ... return } ;
22102215 instructions. Add ( processor . Create ( OpCodes . Ldloc , netManLocIdx ) ) ;
22112216 instructions. Add ( processor . Create ( OpCodes . Brfalse , returnInstr ) ) ;
22122217 instructions. Add ( processor . Create ( OpCodes . Ldloc , netManLocIdx ) ) ;
22132218 instructions. Add ( processor . Create ( OpCodes . Callvirt , m_NetworkManager_getIsListening_MethodRef ) ) ;
22142219 instructions. Add ( processor . Create ( OpCodes . Brtrue , lastInstr ) ) ;
22152220
2221+ var logNextInstr = processor. Create ( OpCodes . Nop ) ;
2222+
2223+ // if (LogLevel.Normal > networkManager.LogLevel)
2224+ instructions. Add ( processor . Create ( OpCodes . Ldloc , netManLocIdx ) ) ;
2225+ instructions. Add ( processor . Create ( OpCodes . Ldfld , m_NetworkManager_LogLevel_FieldRef ) ) ;
2226+ instructions. Add ( processor . Create ( OpCodes . Ldc_I4 , ( int ) LogLevel . Normal ) ) ;
2227+ instructions. Add ( processor . Create ( OpCodes . Cgt ) ) ;
2228+ instructions. Add ( processor . Create ( OpCodes . Ldc_I4 , 0 ) ) ;
2229+ instructions. Add ( processor . Create ( OpCodes . Ceq ) ) ;
2230+ instructions. Add ( processor . Create ( OpCodes . Brfalse , logNextInstr ) ) ;
2231+
2232+ // Debug.LogError(...);
2233+ instructions. Add ( processor . Create ( OpCodes . Ldstr , "Rpc methods can only be invoked after starting the NetworkManager!" ) ) ;
2234+ instructions. Add ( processor . Create ( OpCodes . Call , m_Debug_LogError_MethodRef ) ) ;
2235+
2236+ instructions. Add ( logNextInstr ) ;
2237+
22162238 instructions. Add ( returnInstr ) ;
22172239 instructions. Add ( lastInstr ) ;
22182240 }
@@ -2341,7 +2363,7 @@ private void InjectWriteAndCallBlocks(MethodDefinition methodDefinition, CustomA
23412363 instructions. Add ( processor . Create ( OpCodes . Ldloca , rpcAttributeParamsIdx ) ) ;
23422364 instructions. Add ( processor . Create ( OpCodes . Initobj , m_AttributeParamsType_TypeRef ) ) ;
23432365
2344- RpcAttribute. RpcAttributeParams dflt = default ;
2366+ RpcAttribute. RpcAttributeParams defaultParameters = default ;
23452367 foreach ( var field in rpcAttribute . Fields )
23462368 {
23472369 var found = false ;
@@ -2351,8 +2373,8 @@ private void InjectWriteAndCallBlocks(MethodDefinition methodDefinition, CustomA
23512373 {
23522374 found = true ;
23532375 var value = field . Argument . Value ;
2354- var paramField = dflt . GetType ( ) . GetField ( attrField . Name ) ;
2355- if ( value != paramField . GetValue ( dflt ) )
2376+ var paramField = defaultParameters . GetType ( ) . GetField ( attrField . Name ) ;
2377+ if ( value != paramField . GetValue ( defaultParameters ) )
23562378 {
23572379 instructions. Add ( processor . Create ( OpCodes . Ldloca , rpcAttributeParamsIdx ) ) ;
23582380 var type = value . GetType ( ) ;
@@ -2458,11 +2480,11 @@ private void InjectWriteAndCallBlocks(MethodDefinition methodDefinition, CustomA
24582480 {
24592481 if ( paramIndex != paramCount - 1 )
24602482 {
2461- m_Diagnostics. AddError( methodDefinition, $"{ nameof( RpcParams) } must be the last parameter in a ClientRpc. ") ;
2483+ m_Diagnostics. AddError( methodDefinition, $"{ methodDefinition . Name } is invalid . { nameof( RpcParams) } must be the last parameter in a ClientRpc. ") ;
24622484 }
24632485 if ( ! isGenericRpc)
24642486 {
2465- m_Diagnostics. AddError( $"Only Rpcs may accept { nameof( RpcParams) } as a parameter. ") ;
2487+ m_Diagnostics. AddError( $"{ methodDefinition . Name } is invalid . Only Rpcs may accept { nameof( RpcParams) } as a parameter. ") ;
24662488 }
24672489 continue ;
24682490 }
@@ -2897,26 +2919,17 @@ private MethodDefinition GenerateStaticHandler(MethodDefinition methodDefinition
28972919 var isServerRpc = rpcAttribute. AttributeType. FullName == CodeGenHelpers. ServerRpcAttribute_FullName;
28982920 var isClientRpc = rpcAttribute. AttributeType. FullName == CodeGenHelpers. ClientRpcAttribute_FullName;
28992921 var isGenericRpc = rpcAttribute. AttributeType. FullName == CodeGenHelpers. RpcAttribute_FullName;
2900- var invokePermission = RpcInvokePermission . Anyone ;
2922+ var requireOwnership = true ; // default value MUST be == `ServerRpcAttribute.RequireOwnership`
29012923 foreach ( var attrField in rpcAttribute. Fields)
29022924 {
29032925 switch ( attrField. Name)
29042926 {
29052927 case k_ServerRpcAttribute_RequireOwnership:
2906- invokePermission = ( attrField. Argument. Type == typeSystem. Boolean && ( bool ) attrField. Argument. Value) ? RpcInvokePermission. Owner : RpcInvokePermission. Anyone;
2907- break ;
2908- case k_RpcAttribute_InvokePermission:
2909- invokePermission = ( RpcInvokePermission) attrField. Argument. Value;
2928+ requireOwnership = attrField. Argument. Type == typeSystem. Boolean && ( bool ) attrField. Argument. Value;
29102929 break ;
29112930 }
29122931 }
29132932
2914- // legacy ClientRpc should always be RpcInvokePermission.Server
2915- if ( isClientRpc)
2916- {
2917- invokePermission = RpcInvokePermission. Server;
2918- }
2919-
29202933 rpcHandler. Body. InitLocals = true;
29212934 // NetworkManager networkManager;
29222935 rpcHandler. Body. Variables. Add( new VariableDefinition( m_NetworkManager_TypeRef) ) ;
@@ -2942,7 +2955,7 @@ private MethodDefinition GenerateStaticHandler(MethodDefinition methodDefinition
29422955 processor. Append( lastInstr) ;
29432956 }
29442957
2945- if ( isServerRpc && invokePermission == RpcInvokePermission . Owner )
2958+ if ( isServerRpc && requireOwnership )
29462959 {
29472960 var roReturnInstr = processor. Create( OpCodes. Ret) ;
29482961 var roLastInstr = processor. Create( OpCodes. Nop) ;
@@ -2976,42 +2989,6 @@ private MethodDefinition GenerateStaticHandler(MethodDefinition methodDefinition
29762989
29772990 processor. Append( logNextInstr) ;
29782991
2979- processor. Append( roReturnInstr) ;
2980- processor. Append( roLastInstr) ;
2981- } else if ( invokePermission == RpcInvokePermission. Server)
2982- {
2983- var roReturnInstr = processor. Create( OpCodes. Ret) ;
2984- var roLastInstr = processor. Create( OpCodes. Nop) ;
2985-
2986- // if (rpcParams.Server.Receive.SenderClientId != NetworkManager.IsServer) { ... } return;
2987- processor. Emit( OpCodes. Ldarg_2) ;
2988- processor. Emit( OpCodes. Ldfld, m_RpcParams_Server_FieldRef) ;
2989- processor. Emit( OpCodes. Ldfld, m_ServerRpcParams_Receive_FieldRef) ;
2990- processor. Emit( OpCodes. Ldfld, m_ServerRpcParams_Receive_SenderClientId_FieldRef) ;
2991- processor. Emit( OpCodes. Ldarg_0) ;
2992- processor. Emit( OpCodes. Call, m_NetworkManager_getIsServer_MethodRef) ;
2993- processor. Emit( OpCodes. Ceq) ;
2994- processor. Emit( OpCodes. Ldc_I4, 0 ) ;
2995- processor. Emit( OpCodes. Ceq) ;
2996- processor. Emit( OpCodes. Brfalse, roLastInstr) ;
2997-
2998- var logNextInstr = processor. Create( OpCodes. Nop) ;
2999-
3000- // if (LogLevel.Normal > networkManager.LogLevel)
3001- processor. Emit( OpCodes. Ldloc, netManLocIdx) ;
3002- processor. Emit( OpCodes. Ldfld, m_NetworkManager_LogLevel_FieldRef) ;
3003- processor. Emit( OpCodes. Ldc_I4, ( int ) LogLevel. Normal) ;
3004- processor. Emit( OpCodes. Cgt) ;
3005- processor. Emit( OpCodes. Ldc_I4, 0 ) ;
3006- processor. Emit( OpCodes. Ceq) ;
3007- processor. Emit( OpCodes. Brfalse, logNextInstr) ;
3008-
3009- // Debug.LogError(...);
3010- processor. Emit( OpCodes. Ldstr, "Only the server can invoke an Rpc with RpcInvokePermission. Server! ") ;
3011- processor. Emit( OpCodes. Call, m_Debug_LogError_MethodRef) ;
3012-
3013- processor. Append( logNextInstr) ;
3014-
30152992 processor. Append( roReturnInstr) ;
30162993 processor. Append( roLastInstr) ;
30172994 }
0 commit comments