@@ -366,7 +366,7 @@ public virtual void OnNetworkObjectParentChanged(NetworkObject parentNetworkObje
366366
367367 private readonly List < HashSet < int > > m_ChannelMappedNetworkVariableIndexes = new List < HashSet < int > > ( ) ;
368368 private readonly List < NetworkChannel > m_ChannelsForNetworkVariableGroups = new List < NetworkChannel > ( ) ;
369- internal readonly List < INetworkVariable > NetworkVariableFields = new List < INetworkVariable > ( ) ;
369+ internal readonly List < NetworkVariableBase > NetworkVariableFields = new List < NetworkVariableBase > ( ) ;
370370
371371 private static Dictionary < Type , FieldInfo [ ] > s_FieldTypes = new Dictionary < Type , FieldInfo [ ] > ( ) ;
372372
@@ -415,19 +415,19 @@ internal void InitializeVariables()
415415 {
416416 Type fieldType = sortedFields [ i ] . FieldType ;
417417
418- if ( fieldType . HasInterface ( typeof ( INetworkVariable ) ) )
418+ if ( fieldType . IsSubclassOf ( typeof ( NetworkVariableBase ) ) )
419419 {
420- var instance = ( INetworkVariable ) sortedFields [ i ] . GetValue ( this ) ;
420+ var instance = ( NetworkVariableBase ) sortedFields [ i ] . GetValue ( this ) ;
421421
422422 if ( instance == null )
423423 {
424- instance = ( INetworkVariable ) Activator . CreateInstance ( fieldType , true ) ;
424+ instance = ( NetworkVariableBase ) Activator . CreateInstance ( fieldType , true ) ;
425425 sortedFields [ i ] . SetValue ( this , instance ) ;
426426 }
427427
428- instance . SetNetworkBehaviour ( this ) ;
428+ instance . NetworkBehaviour = this ;
429429
430- var instanceNameProperty = fieldType . GetProperty ( nameof ( INetworkVariable . Name ) ) ;
430+ var instanceNameProperty = fieldType . GetProperty ( nameof ( NetworkVariableBase . Name ) ) ;
431431 var sanitizedVariableName = sortedFields [ i ] . Name . Replace ( "<" , string . Empty ) . Replace ( ">k__BackingField" , string . Empty ) ;
432432 instanceNameProperty ? . SetValue ( instance , sanitizedVariableName ) ;
433433
@@ -442,7 +442,7 @@ internal void InitializeVariables()
442442
443443 for ( int i = 0 ; i < NetworkVariableFields . Count ; i ++ )
444444 {
445- NetworkChannel networkChannel = NetworkVariableFields [ i ] . GetChannel ( ) ;
445+ var networkChannel = NetworkVariableBase . NetworkVariableChannel ;
446446
447447 if ( ! firstLevelIndex . ContainsKey ( networkChannel ) )
448448 {
@@ -514,6 +514,7 @@ private void NetworkVariableUpdate(ulong clientId, int behaviourIndex)
514514 {
515515 using ( var writer = PooledNetworkWriter . Get ( buffer ) )
516516 {
517+ // TODO: could skip this if no variables dirty, though obsolete w/ Snapshot
517518 writer . WriteUInt64Packed ( NetworkObjectId ) ;
518519 writer . WriteUInt16Packed ( NetworkObject . GetNetworkBehaviourOrderIndex ( this ) ) ;
519520
@@ -537,14 +538,9 @@ private void NetworkVariableUpdate(ulong clientId, int behaviourIndex)
537538 continue ;
538539 }
539540
540- bool isDirty =
541- NetworkVariableFields [ k ]
542- . IsDirty ( ) ; // cache this here. You never know what operations users will do in the dirty methods
543-
544541 // if I'm dirty AND a client, write (server always has all permissions)
545542 // if I'm dirty AND the server AND the client can read me, send.
546- bool shouldWrite = isDirty &&
547- ( ! IsServer || NetworkVariableFields [ k ] . CanClientRead ( clientId ) ) ;
543+ bool shouldWrite = NetworkVariableFields [ k ] . ShouldWrite ( clientId , IsServer ) ;
548544
549545 if ( NetworkManager . NetworkConfig . EnsureNetworkVariableLengthSafety )
550546 {
@@ -628,7 +624,7 @@ private bool CouldHaveDirtyNetworkVariables()
628624 return false ;
629625 }
630626
631- internal static void HandleNetworkVariableDeltas ( List < INetworkVariable > networkVariableList , Stream stream , ulong clientId , NetworkBehaviour logInstance , NetworkManager networkManager )
627+ internal static void HandleNetworkVariableDeltas ( List < NetworkVariableBase > networkVariableList , Stream stream , ulong clientId , NetworkBehaviour logInstance , NetworkManager networkManager )
632628 {
633629 using ( var reader = PooledNetworkReader . Get ( stream ) )
634630 {
@@ -655,6 +651,7 @@ internal static void HandleNetworkVariableDeltas(List<INetworkVariable> networkV
655651
656652 if ( networkManager . IsServer && ! networkVariableList [ i ] . CanClientWrite ( clientId ) )
657653 {
654+ // we are choosing not to fire an exception here, because otherwise a malicious client could use this to crash the server
658655 if ( networkManager . NetworkConfig . EnsureNetworkVariableLengthSafety )
659656 {
660657 if ( NetworkLog . CurrentLogLevel <= LogLevel . Normal )
@@ -674,7 +671,6 @@ internal static void HandleNetworkVariableDeltas(List<INetworkVariable> networkV
674671 //A dummy read COULD be added to the interface for this situation, but it's just being too nice.
675672 //This is after all a developer fault. A critical error should be fine.
676673 // - TwoTen
677-
678674 if ( NetworkLog . CurrentLogLevel <= LogLevel . Error )
679675 {
680676 NetworkLog . LogError ( $ "Client wrote to { typeof ( NetworkVariable < > ) . Name } without permission. No more variables can be read. This is critical. => { ( logInstance != null ? ( $ "{ nameof ( NetworkObjectId ) } : { logInstance . NetworkObjectId } - { nameof ( NetworkObject . GetNetworkBehaviourOrderIndex ) } (): { logInstance . NetworkObject . GetNetworkBehaviourOrderIndex ( logInstance ) } - VariableIndex: { i } ") : string . Empty ) } ") ;
@@ -683,7 +679,6 @@ internal static void HandleNetworkVariableDeltas(List<INetworkVariable> networkV
683679
684680 return ;
685681 }
686-
687682 long readStartPos = stream . Position ;
688683
689684 networkVariableList [ i ] . ReadDelta ( stream , networkManager . IsServer ) ;
@@ -722,95 +717,7 @@ internal static void HandleNetworkVariableDeltas(List<INetworkVariable> networkV
722717 }
723718 }
724719
725- internal static void HandleNetworkVariableUpdate ( List < INetworkVariable > networkVariableList , Stream stream , ulong clientId , NetworkBehaviour logInstance , NetworkManager networkManager )
726- {
727- using ( var reader = PooledNetworkReader . Get ( stream ) )
728- {
729- for ( int i = 0 ; i < networkVariableList . Count ; i ++ )
730- {
731- ushort varSize = 0 ;
732-
733- if ( networkManager . NetworkConfig . EnsureNetworkVariableLengthSafety )
734- {
735- varSize = reader . ReadUInt16Packed ( ) ;
736-
737- if ( varSize == 0 )
738- {
739- continue ;
740- }
741- }
742- else
743- {
744- if ( ! reader . ReadBool ( ) )
745- {
746- continue ;
747- }
748- }
749-
750- if ( networkManager . IsServer && ! networkVariableList [ i ] . CanClientWrite ( clientId ) )
751- {
752- if ( networkManager . NetworkConfig . EnsureNetworkVariableLengthSafety )
753- {
754- if ( NetworkLog . CurrentLogLevel <= LogLevel . Normal )
755- {
756- NetworkLog . LogWarning ( $ "Client wrote to { typeof ( NetworkVariable < > ) . Name } without permission. => { ( logInstance != null ? ( $ "{ nameof ( NetworkObjectId ) } : { logInstance . NetworkObjectId } - { nameof ( NetworkObject . GetNetworkBehaviourOrderIndex ) } (): { logInstance . NetworkObject . GetNetworkBehaviourOrderIndex ( logInstance ) } - VariableIndex: { i } ") : string . Empty ) } ") ;
757- }
758-
759- stream . Position += varSize ;
760- continue ;
761- }
762-
763- //This client wrote somewhere they are not allowed. This is critical
764- //We can't just skip this field. Because we don't actually know how to dummy read
765- //That is, we don't know how many bytes to skip. Because the interface doesn't have a
766- //Read that gives us the value. Only a Read that applies the value straight away
767- //A dummy read COULD be added to the interface for this situation, but it's just being too nice.
768- //This is after all a developer fault. A critical error should be fine.
769- // - TwoTen
770- if ( NetworkLog . CurrentLogLevel <= LogLevel . Error )
771- {
772- NetworkLog . LogError ( $ "Client wrote to { typeof ( NetworkVariable < > ) . Name } without permission. No more variables can be read. This is critical. => { ( logInstance != null ? ( $ "{ nameof ( NetworkObjectId ) } : { logInstance . NetworkObjectId } - { nameof ( NetworkObject . GetNetworkBehaviourOrderIndex ) } (): { logInstance . NetworkObject . GetNetworkBehaviourOrderIndex ( logInstance ) } - VariableIndex: { i } ") : string . Empty ) } ") ;
773- }
774-
775- return ;
776- }
777-
778- long readStartPos = stream . Position ;
779-
780- networkVariableList [ i ] . ReadField ( stream ) ;
781-
782- if ( networkManager . NetworkConfig . EnsureNetworkVariableLengthSafety )
783- {
784- if ( stream is NetworkBuffer networkBuffer )
785- {
786- networkBuffer . SkipPadBits ( ) ;
787- }
788-
789- if ( stream . Position > ( readStartPos + varSize ) )
790- {
791- if ( NetworkLog . CurrentLogLevel <= LogLevel . Normal )
792- {
793- NetworkLog . LogWarning ( $ "Var update read too far. { stream . Position - ( readStartPos + varSize ) } bytes. => { ( logInstance != null ? ( $ "{ nameof ( NetworkObjectId ) } : { logInstance . NetworkObjectId } - { nameof ( NetworkObject . GetNetworkBehaviourOrderIndex ) } (): { logInstance . NetworkObject . GetNetworkBehaviourOrderIndex ( logInstance ) } - VariableIndex: { i } ") : string . Empty ) } ") ;
794- }
795-
796- stream . Position = readStartPos + varSize ;
797- }
798- else if ( stream . Position < ( readStartPos + varSize ) )
799- {
800- if ( NetworkLog . CurrentLogLevel <= LogLevel . Normal )
801- {
802- NetworkLog . LogWarning ( $ "Var update read too little. { ( readStartPos + varSize ) - stream . Position } bytes. => { ( logInstance != null ? ( $ "{ nameof ( NetworkObjectId ) } : { logInstance . NetworkObjectId } - { nameof ( NetworkObject . GetNetworkBehaviourOrderIndex ) } (): { logInstance . NetworkObject . GetNetworkBehaviourOrderIndex ( logInstance ) } - VariableIndex: { i } ") : string . Empty ) } ") ;
803- }
804-
805- stream . Position = readStartPos + varSize ;
806- }
807- }
808- }
809- }
810- }
811-
812-
813- internal static void WriteNetworkVariableData ( List < INetworkVariable > networkVariableList , Stream stream , ulong clientId , NetworkManager networkManager )
720+ internal static void WriteNetworkVariableData ( List < NetworkVariableBase > networkVariableList , Stream stream , ulong clientId , NetworkManager networkManager )
814721 {
815722 if ( networkVariableList . Count == 0 )
816723 {
@@ -858,7 +765,7 @@ internal static void WriteNetworkVariableData(List<INetworkVariable> networkVari
858765 }
859766 }
860767
861- internal static void SetNetworkVariableData ( List < INetworkVariable > networkVariableList , Stream stream , NetworkManager networkManager )
768+ internal static void SetNetworkVariableData ( List < NetworkVariableBase > networkVariableList , Stream stream , NetworkManager networkManager )
862769 {
863770 if ( networkVariableList . Count == 0 )
864771 {
0 commit comments