Fish-Net: Networking Evolved
  • Overview
    • What is FishNet?
      • Features
        • Unity Compatibility
        • Performance
          • Benchmark Setup
          • Fish-Networking Vs Mirror
      • Pro, Projects, and Support
      • Business Support
      • Development
        • Changelog
        • Roadmap
      • Branding
      • Legal Restrictions
    • Showcase
      • Upcoming Releases
    • Asset Integrations
      • Fish-Network-Discovery
    • Community Resources
  • Guides
    • Getting Started
      • Installing Fish-Networking
      • Getting Connected
      • Preparing Your Player
      • Moving Your Player Around
      • Spawning and Despawning Items
      • Using SyncVars to Sync Colors
      • Connecting to Remote Devices
      • Beyond the Basics
    • High-Level Overview
      • Fundamentals
      • Networking Models
      • Terminology
        • Server, Client, Host
        • Communicating
        • Miscellaneous
      • Transports
    • Features
      • Server and Client Identification
        • Executing on Server or Client
        • NetworkConnections
      • Networked GameObjects and Scripts
        • NetworkObjects
        • NetworkBehaviour
        • Spawning and Despawning
          • Predicted Spawning
          • Nested NetworkObjects
          • Object Pooling
      • Network State Events
      • Network Communication
        • Remote Procedure Calls
        • SyncTypes
          • Customizing Behavior
          • SyncVar
          • SyncList
          • SyncHashSet
          • SyncDictionary
          • SyncTimer
          • SyncStopwatch
          • Custom SyncType
        • Broadcasts
      • Data Serialization
        • Custom Serializers
          • Interface Serializers
          • Inheritance Serializers
      • Ownership
        • Using Ownership To Read Values
      • Area of Interest (Observer System)
        • Modifying Conditions
        • Custom Conditions
      • Scene Management
        • Scene Events
        • Scene Data
          • SceneLookupData
          • SceneLoadData
          • SceneUnloadData
        • Loading Scenes
          • Automatic Online and Offline Scenes
        • Unloading Scenes
        • Scene Stacking
        • Scene Caching
        • Scene Visibility
        • Persisting NetworkObjects
        • Custom Scene Processors
          • Addressables
      • InstanceFinder
      • Addressables
      • Transports
        • Multipass
      • Prediction
        • What Is Client-Side Prediction
        • Configuring PredictionManager
        • Configuring TimeManager
        • Configuring NetworkObject
        • Offline Rigidbodies
        • Interpolations
        • Creating Code
          • Controlling An Object
          • Non-Controlled Object
          • Understanding ReplicateState
            • Using States In Code
            • Predicting States In Code
          • Advanced Controls
        • Custom Comparers
        • PredictionRigidbody
        • Using NetworkColliders
      • Lag Compensation
        • States
        • Raycast
        • Projectiles
    • Upgrading API
    • Server Hosting
      • Edgegap - Official Partner
        • Getting Started with Edgegap
      • Hathora
        • Getting Started with Hathora
      • Amazon Web Services (AWS)
        • Getting Started with AWS
    • Upgrading To Fish-Networking
    • Troubleshooting
      • Technical Limitations
      • Creating Bug Reports
        • Report Example
      • FAQ
  • FishNet Building Blocks
    • Components
      • Managers
        • NetworkManager
        • TimeManager
        • PredictionManager
        • ServerManager
        • ClientManager
        • SceneManager
        • TransportManager
          • IntermediateLayer
        • StatisticsManager
        • ObserverManager
          • HashGrid
        • RollbackManager (Pro Feature)
      • Prediction
        • Network Collider
          • NetworkCollision
          • NetworkCollision2D
          • NetworkTrigger
          • NetworkTrigger2D
        • OfflineRigidbody
        • PredictedOwner
        • PredictedSpawn
      • Utilities
        • PingDisplay
        • BandwidthDisplay
        • Tick Smoothers
          • NetworkTickSmoother
          • OfflineTickSmoother
          • MonoTickSmoother [Obsolete]
          • DetachableNetworkTickSmoother [Obsolete]
      • PlayerSpawner
      • DefaultScene
      • ServerSpawner
      • Authenticator
      • ColliderRollback
      • NetworkAnimator
      • NetworkBehaviour
      • NetworkTransform
      • NetworkObject
      • NetworkObserver
    • Prefabs
      • NetworkManager
      • NetworkHudCanvas
    • ScriptableObjects
      • ObserverConditions
        • DistanceCondition
        • GridCondition
        • HostOnlyCondition
        • MatchCondition
        • OwnerOnlyCondition
        • SceneCondition
      • SpawnablePrefabs
        • DefaultPrefabObjects
        • SinglePrefabObjects
        • DualPrefabObjects
      • LevelLoggingConfiguration
    • Transports
      • Tugboat
      • Multipass
      • Yak (Pro Feature)
      • Bayou
      • FishyWebRTC
      • FishyUnityTransport
      • FishySteamworks (Steam)
      • FishyEOS (Epic Online Services)
      • FishyFacepunch (Steam)
      • FishyRealtime (Photon)
  • API Documentation
    • API Reference
Powered by GitBook
On this page
  1. FishNet Building Blocks
  2. Components
  3. Managers
  4. TransportManager

IntermediateLayer

The IntermediateLayer is a pass-through for data in and out. This feature can be used to encrypt data, inject headers, and more.

Using the IntermediateLayer is simple as overriding two methods, one for when data is sent and one for when data is received.

Below is an example included with FishNet which demonstrates using a Caesar cipher to encrypt data.

You can find this example in the Demos folder, file name IntermediateLayerCipher.cs.

using FishNet.Managing.Transporting;
using System;

namespace FishNet.Example.IntermediateLayers
{
    /* Below is an example of creating a basic Caesar Cipher.
     * Bytes are modified by a set value of CIPHER_KEY, and then
     * the original src ArraySegment is returned.
     * 
     * It's very important to only iterate the bytes provided
     * as the segment. For example, if the ArraySegment contains
     * 1000 bytes but the Offset is 3 and Count is 5 then you should
     * only iterate bytes on index 3, 4, 5, 6, 7. The code below
     * shows one way of properly doing so.
     * 
     * If you are to change the byte array reference, size, or segment
     * count be sure to return a new ArraySegment with the new values.
     * For example, if your Offset was 0 and count was 10 but after
     * encrypting data the Offset was still 0 and count 15 you would
     * return new ArraySegment<byte>(theArray, 0, 15); */
    public class IntermediateLayerCipher : IntermediateLayer
    {
        private const byte CIPHER_KEY = 5;
        //Decipher incoming data.
        public override ArraySegment<byte> HandleIncoming(ArraySegment<byte> src, bool fromServer)
        {
            byte[] arr = src.Array;
            int length = src.Count;
            int offset = src.Offset;

            for (int i = src.Offset; i < (offset + length); i++)
            {
                short next = (short)(arr[i] - CIPHER_KEY);
                if (next < 0)
                    next += 256;
                arr[i] = (byte)next;
            }

            return src;
        }
        //Cipher outgoing data.
        public override ArraySegment<byte> HandleOutgoing(ArraySegment<byte> src, bool toServer)
        {
            byte[] arr = src.Array;
            int length = src.Count;
            int offset = src.Offset;

            for (int i = offset; i < (offset + length); i++)
            {
                short next = (short)(arr[i] + CIPHER_KEY);
                if (next > byte.MaxValue)
                    next -= 256;
                arr[i] = (byte)next;
            }

            return src;
        }

    }
}

In some cases you may need to inject headers into data sent, such as if you are validating each packet with an authorization key.

If such is the case it may be wise to reserve a number of bytes needed for your header. You can do this by calling SetMTUReserve() on your TransportManager. Here is an example of doing such.

public class MyIntermediateLayer : IntermediateLayer
{
    public override void InitializeOnce(TransportManager manager)
    {
        base.InitializeOnce(manager);
        const int bytesForMyHeader = 10;
        manager.SetMTUReserve(bytesForMyHeader);
    }
    //...rest omitted
PreviousTransportManagerNextStatisticsManager

Last updated 1 year ago