Example #1
0
 public void ExecuteRpc(int type, DataStreamReader reader, ref DataStreamReader.Context ctx, Entity connection, EntityCommandBuffer commandBuffer)
 {
     switch (type)
     {
     case 0:
     {
         var tmp = new RpcLoadLevel();
         tmp.Deserialize(reader, ref ctx);
         tmp.Execute(connection, commandBuffer);
         break;
     }
     }
 }
 public void ExecuteRpc(int type, DataStreamReader reader, ref DataStreamReader.Context ctx, Entity connection, EntityCommandBuffer.Concurrent commandBuffer, int jobIndex)
 {
     switch (type)
     {
     case 0:
     {
         var tmp = new RpcSetNetworkId();
         tmp.Deserialize(reader, ref ctx);
         tmp.Execute(connection, commandBuffer, jobIndex);
         break;
     }
     }
 }
Example #3
0
    public static void ReadPacket(DataStreamReader stream, ref DataStreamReader.Context context, ReadCallback callback = null)
    {
        GameEvent evt = (GameEvent)stream.ReadUInt(ref context);

        List <object> data = new List <object>();

        readFunctions[evt](stream, ref context, ref data);

        if (callback != null)
        {
            callback(data.ToArray());
        }
    }
        public override void Read(DataStreamReader reader, ref DataStreamReader.Context context)
        {
            byte[]  buff     = reader.ReadBytesAsArray(ref context, sizeof(float) * 7);
            Vector3 position = Vector3.zero;

            position.x = BitConverter.ToSingle(buff, 0 * sizeof(float));
            position.y = BitConverter.ToSingle(buff, 1 * sizeof(float));
            position.z = BitConverter.ToSingle(buff, 2 * sizeof(float));

            var rotation = Quaternion.identity;

            rotation.x = BitConverter.ToSingle(buff, 3 * sizeof(float));
            rotation.y = BitConverter.ToSingle(buff, 4 * sizeof(float));
            rotation.z = BitConverter.ToSingle(buff, 5 * sizeof(float));
            rotation.w = BitConverter.ToSingle(buff, 6 * sizeof(float));

            var distance = Vector3.Distance(Data.Target.position, position);

            // the further you are, the slower?

            Data.Target.rotation = rotation;

            if (_currentPosition == null)
            {
                _currentPosition = position;
            }
            else
            {
                var dist = Vector3.Distance(_currentPosition.Value, position);

                if (dist > 0.01f)
                {
                    var newPosition  = position;
                    var lastPosition = _currentPosition;
                    var dir          = newPosition - lastPosition;

                    _currentPosition = position;

                    var predictedPosition = newPosition + dir * 1.1F;
                    position = predictedPosition.Value;
                }
                else
                {
                    position = _currentPosition.Value;
                }
            }

            _targetPosition = position;

            //Debug.Log($"Read: {Data}");
        }
Example #5
0
    public void Deserialize(DataStreamReader reader, ref DataStreamReader.Context ctx)
    {
        var nameLength = reader.ReadUShort(ref ctx);

        GameDebug.Assert(nameLength <= NativeString64.MaxLength);
        MapName.LengthInBytes = nameLength;
        unsafe
        {
            fixed(byte *b = &MapName.buffer.byte0000)
            {
                reader.ReadBytes(ref ctx, b, MapName.LengthInBytes);
            }
        }
    }
Example #6
0
 protected bool ReadQosHeader(DataStreamReader stream, ref DataStreamReader.Context ctx, out QosType qosType, out ushort seqNum, out ushort ackNum)
 {
     if (!stream.IsCreated)
     {
         qosType = QosType.Empty;
         seqNum  = 0;
         ackNum  = 0;
         return(false);
     }
     qosType = (QosType)stream.ReadByte(ref ctx);
     seqNum  = stream.ReadUShort(ref ctx);
     ackNum  = stream.ReadUShort(ref ctx);
     return(true);
 }
Example #7
0
        public void SQP_SerializeChallangeRequest_NoError()
        {
            var snd = new ChallangeRequest();

            snd.ToStream(ref writer);

            reader  = new DataStreamReader(writer, 0, writer.Length);
            context = default(DataStreamReader.Context);
            var rcv = new ChallangeRequest();

            rcv.FromStream(reader, ref context);

            Assert.AreEqual((byte)SQPMessageType.ChallangeRequest, rcv.Header.Type);
        }
Example #8
0
    public static void ClientInputChanged(object caller, DataStreamReader stream, ref DataStreamReader.Context context, NetworkConnection source)
    {
        MyServerBehaviour server = caller as MyServerBehaviour;
        uint  playerIndex        = stream.ReadUInt(ref context);
        uint  dirtFlags          = stream.ReadUInt(ref context);
        uint  buttonState        = stream.ReadUInt(ref context);
        float mouseX             = stream.ReadFloat(ref context);
        float mouseY             = stream.ReadFloat(ref context);
        float mouseZ             = stream.ReadFloat(ref context);

        server.UpdateClientInput(playerIndex, buttonState, mouseX, mouseY, mouseZ);

        Debug.Log("Got Client Input for " + playerIndex);
    }
Example #9
0
    public bool Deserialize(int serializer, Entity entity, uint snapshot, uint baseline, uint baseline2, uint baseline3,
                            DataStreamReader reader,
                            ref DataStreamReader.Context ctx, NetworkCompressionModel compressionModel)
    {
        switch (serializer)
        {
        case 0:
            return(GhostReceiveSystem <CubeGhostDeserializerCollection> .InvokeDeserialize(m_CubeSnapshotDataFromEntity, entity, snapshot, baseline, baseline2,
                                                                                           baseline3, reader, ref ctx, compressionModel));

        default:
            throw new ArgumentException("Invalid serializer type");
        }
    }
Example #10
0
    public void Spawn(int serializer, int ghostId, uint snapshot, DataStreamReader reader,
                      ref DataStreamReader.Context ctx, NetworkCompressionModel compressionModel)
    {
        switch (serializer)
        {
        case 0:
            m_CubeSnapshotDataNewGhostIds.Add(ghostId);
            m_CubeSnapshotDataNewGhosts.Add(GhostReceiveSystem <CubeGhostDeserializerCollection> .InvokeSpawn <CubeSnapshotData>(snapshot, reader, ref ctx, compressionModel));
            break;

        default:
            throw new ArgumentException("Invalid serializer type");
        }
    }
Example #11
0
    public void Deserialize(DataStreamReader reader, ref DataStreamReader.Context ctx)
    {
        var msgLength = reader.ReadUShort(ref ctx);

        GameDebug.Assert(msgLength <= NativeString64.MaxLength);
        Command.LengthInBytes = msgLength;
        unsafe
        {
            fixed(byte *b = &Command.buffer.byte0000)
            {
                reader.ReadBytes(ref ctx, b, Command.LengthInBytes);
            }
        }
    }
Example #12
0
    /// <summary>
    /// This constructor is for UNWRAPPING the data to read a request
    /// </summary> 
    public GetResultsResponseData(DataStreamReader reader){
        DataStreamReader.Context readerCtx = default(DataStreamReader.Context);

        int commandCheck = reader.ReadInt(ref readerCtx);

        if (commandCheck == commandCode){
            this.playerId = reader.ReadInt(ref readerCtx);
            this.playerColor = reader.ReadInt(ref readerCtx);
            this.playerState = reader.ReadInt(ref readerCtx);
            playerPosition = new Vector2Int(reader.ReadInt(ref readerCtx), reader.ReadInt(ref readerCtx));
        }else{
            readerCtx = default(DataStreamReader.Context);
            throw new System.Exception(string.Format("Command {0} received is not compatible with this class command {1}", commandCheck, commandCode));
        }
    }
Example #13
0
    /// <summary>
    /// This constructor is for UNWRAPPING the data to read a request
    /// </summary>
    public GetStateRequestData(DataStreamReader reader)
    {
        DataStreamReader.Context readerCtx = default(DataStreamReader.Context);

        int commandCheck = reader.ReadInt(ref readerCtx);

        if (commandCheck == commandCode)
        {
            this.playerId = reader.ReadInt(ref readerCtx);
        }
        else
        {
            readerCtx = default(DataStreamReader.Context);
            throw new System.Exception(string.Format("Command {0} received is not compatible with this class command {1}", commandCheck, commandCode));
        }
    }
Example #14
0
    public void Spawn(int serializer, int ghostId, uint snapshot, DataStreamReader reader,
                      ref DataStreamReader.Context ctx, NetworkCompressionModel compressionModel)
    {
        switch (serializer)
        {
            #region __GHOST_INVOKE_SPAWN__
        case __GHOST_SERIALIZER_INDEX__:
            m___GHOST_SNAPSHOT_TYPE__NewGhostIds.Add(ghostId);
            m___GHOST_SNAPSHOT_TYPE__NewGhosts.Add(GhostReceiveSystem <__GHOST_COLLECTION_PREFIX__GhostDeserializerCollection> .InvokeSpawn <__GHOST_SNAPSHOT_TYPE__>(snapshot, reader, ref ctx, compressionModel));
            break;

            #endregion
        default:
            throw new ArgumentException("Invalid serializer type");
        }
    }
Example #15
0
    public void Deserialize(DataStreamReader reader, ref DataStreamReader.Context ctx)
    {
        TeamId        = reader.ReadShort(ref ctx);
        CharacterType = reader.ReadInt(ref ctx);
        var nameLength = reader.ReadUShort(ref ctx);

        GameDebug.Assert(nameLength <= NativeString64.MaxLength);
        PlayerName.LengthInBytes = nameLength;
        unsafe
        {
            fixed(byte *b = &PlayerName.buffer.byte0000)
            {
                reader.ReadBytes(ref ctx, b, PlayerName.LengthInBytes);
            }
        }
    }
Example #16
0
    public bool Deserialize(int serializer, Entity entity, uint snapshot, uint baseline, uint baseline2, uint baseline3,
                            DataStreamReader reader,
                            ref DataStreamReader.Context ctx, NetworkCompressionModel compressionModel)
    {
        switch (serializer)
        {
            #region __GHOST_INVOKE_DESERIALIZE__
        case __GHOST_SERIALIZER_INDEX__:
            return(GhostReceiveSystem <__GHOST_COLLECTION_PREFIX__GhostDeserializerCollection> .InvokeDeserialize(m___GHOST_SNAPSHOT_TYPE__FromEntity, entity, snapshot, baseline, baseline2,
                                                                                                                  baseline3, reader, ref ctx, compressionModel));

            #endregion
        default:
            throw new ArgumentException("Invalid serializer type");
        }
    }
Example #17
0
        public static void InvokeDeserialize <T>(BufferFromEntity <T> snapshotFromEntity,
                                                 Entity entity, uint snapshot, uint baseline, uint baseline2, uint baseline3,
                                                 DataStreamReader reader, ref DataStreamReader.Context ctx, NetworkCompressionModel compressionModel)
            where T : struct, ISnapshotData <T>
        {
            DynamicBuffer <T> snapshotArray = snapshotFromEntity[entity];
            var baselineData = default(T);

            if (baseline != snapshot)
            {
                for (int i = 0; i < snapshotArray.Length; ++i)
                {
                    if (snapshotArray[i].Tick == baseline)
                    {
                        baselineData = snapshotArray[i];
                        break;
                    }
                }
            }
            if (baseline3 != snapshot)
            {
                var baselineData2 = default(T);
                var baselineData3 = default(T);
                for (int i = 0; i < snapshotArray.Length; ++i)
                {
                    if (snapshotArray[i].Tick == baseline2)
                    {
                        baselineData2 = snapshotArray[i];
                    }
                    if (snapshotArray[i].Tick == baseline3)
                    {
                        baselineData3 = snapshotArray[i];
                    }
                }

                baselineData.PredictDelta(snapshot, ref baselineData2, ref baselineData3);
            }
            var data = default(T);

            data.Deserialize(snapshot, ref baselineData, reader, ref ctx, compressionModel);
            // Replace the oldest snapshot and add a new one
            if (snapshotArray.Length == GhostSystemConstants.SnapshotHistorySize)
            {
                snapshotArray.RemoveAt(0);
            }
            snapshotArray.Add(data);
        }
Example #18
0
        public void SQP_SerializeServerInfo_NoError()
        {
            var current = (ushort)34;
            var max     = (ushort)35;
            var port    = (ushort)35001;
            var build   = "2018.3";

            var header = new QueryResponseHeader();

            header.Header.ChallangeId = 1337;
            header.Version            = 12345;
            header.CurrentPacket      = 12;
            header.LastPacket         = 13;

            var snd = new SQP.ServerInfo();

            snd.QueryHeader = header;
            snd.ServerInfoData.CurrentPlayers = current;
            snd.ServerInfoData.MaxPlayers     = max;
            snd.ServerInfoData.ServerName     = "Server";
            snd.ServerInfoData.GameType       = "GameType";
            snd.ServerInfoData.BuildId        = "2018.3";
            snd.ServerInfoData.Map            = "Level0";
            snd.ServerInfoData.Port           = port;

            snd.ToStream(ref writer);

            var rcv = new SQP.ServerInfo();

            reader  = new DataStreamReader(writer, 0, writer.Length);
            context = default(DataStreamReader.Context);
            rcv.FromStream(reader, ref context);

            Assert.AreEqual((byte)SQPMessageType.QueryResponse, rcv.QueryHeader.Header.Type);
            Assert.AreEqual((uint)header.Header.ChallangeId, (uint)rcv.QueryHeader.Header.ChallangeId);
            Assert.AreEqual(header.Version, rcv.QueryHeader.Version);
            Assert.AreEqual(header.CurrentPacket, rcv.QueryHeader.CurrentPacket);
            Assert.AreEqual(header.LastPacket, rcv.QueryHeader.LastPacket);

            Assert.AreEqual(current, (ushort)rcv.ServerInfoData.CurrentPlayers);
            Assert.AreEqual(max, (ushort)rcv.ServerInfoData.MaxPlayers);
            Assert.AreEqual(port, (ushort)rcv.ServerInfoData.Port);

            Assert.AreEqual(build, rcv.ServerInfoData.BuildId);
        }
Example #19
0
        public void SQP_SerializeChallangeResponse_NoError()
        {
            var id  = (uint)1337;
            var snd = new ChallangeResponse();

            snd.Header.ChallangeId = id;

            snd.ToStream(ref writer);

            var rcv = new ChallangeResponse();

            reader  = new DataStreamReader(writer, 0, writer.Length);
            context = default(DataStreamReader.Context);
            rcv.FromStream(reader, ref context);

            Assert.AreEqual((byte)SQPMessageType.ChallangeResponse, rcv.Header.Type);
            Assert.AreEqual(id, (uint)rcv.Header.ChallangeId);
        }
        public void ReadWriteString()
        {
            var dataStream = new DataStreamWriter(300 * 4, Allocator.Temp);

            NativeString64 src = new NativeString64("This is a string");

            dataStream.WriteString(src);

            //Assert.AreEqual(src.LengthInBytes+2, dataStream.Length);

            var reader = new DataStreamReader(dataStream, 0, dataStream.Length);

            DataStreamReader.Context ctx = default;
            var dst = reader.ReadString(ref ctx);

            Assert.AreEqual(src, dst);
            ctx = default;
        }
Example #21
0
    /// <summary>
    /// This constructor is for UNWRAPPING the data to read a request
    /// </summary>
    public PutPlayRequestData(DataStreamReader reader)
    {
        DataStreamReader.Context readerCtx = default(DataStreamReader.Context);

        int commandCheck = reader.ReadInt(ref readerCtx);

        if (commandCheck == commandCode)
        {
            this.playerId        = reader.ReadInt(ref readerCtx);
            this.movementTo      = new Vector2Int(reader.ReadInt(ref readerCtx), reader.ReadInt(ref readerCtx));
            this.sound           = new Vector2Int(reader.ReadInt(ref readerCtx), reader.ReadInt(ref readerCtx));
            this._playerAttacked = reader.ReadInt(ref readerCtx);
        }
        else
        {
            readerCtx = default(DataStreamReader.Context);
            throw new System.Exception(string.Format("Command {0} received is not compatible with this class command {1}", commandCheck, commandCode));
        }
    }
Example #22
0
    public static void ReadHelloClientPacket(DataStreamReader stream, ref DataStreamReader.Context context, ref List <object> data)
    {
        uint value = stream.ReadUInt(ref context);

        //Debug.Log("Received Hello Client: "+value);
        data.Add(value);

        string msg    = "";
        uint   strLen = stream.ReadUInt(ref context);
        int    i      = 0;

        while (i < strLen)
        {
            msg += (char)stream.ReadUInt(ref context);
            i++;
        }

        data.Add(msg);
    }
    public override void Read(int connectionId, DataStreamReader stream, ref DataStreamReader.Context context)
    {
        byte[]  buff = stream.ReadBytesAsArray(ref context, sizeof(float) * 7);
        Vector3 vect = Vector3.zero;

        vect.x = BitConverter.ToSingle(buff, 0 * sizeof(float));
        vect.y = BitConverter.ToSingle(buff, 1 * sizeof(float));
        vect.z = BitConverter.ToSingle(buff, 2 * sizeof(float));

        var rotation = Quaternion.identity;

        rotation.x = BitConverter.ToSingle(buff, 3 * sizeof(float));
        rotation.y = BitConverter.ToSingle(buff, 4 * sizeof(float));
        rotation.z = BitConverter.ToSingle(buff, 5 * sizeof(float));
        rotation.w = BitConverter.ToSingle(buff, 6 * sizeof(float));

        Target.rotation = rotation;
        Target.position = vect;
    }
    public override void Read(int connectionId, DataStreamReader stream, ref DataStreamReader.Context context)
    {
        var prefabId = stream.ReadInt(ref context);

        byte[]  buff     = stream.ReadBytesAsArray(ref context, sizeof(float) * 7);
        Vector3 position = Vector3.zero;

        position.x = BitConverter.ToSingle(buff, 0 * sizeof(float));
        position.y = BitConverter.ToSingle(buff, 1 * sizeof(float));
        position.z = BitConverter.ToSingle(buff, 2 * sizeof(float));

        var rotation = Quaternion.identity;

        rotation.x = BitConverter.ToSingle(buff, 3 * sizeof(float));
        rotation.y = BitConverter.ToSingle(buff, 4 * sizeof(float));
        rotation.z = BitConverter.ToSingle(buff, 5 * sizeof(float));
        rotation.w = BitConverter.ToSingle(buff, 6 * sizeof(float));

        Spawner.SpawnInServer(prefabId, position, rotation);
    }
        public void ReadWritePackedStringDelta()
        {
            var dataStream       = new DataStreamWriter(300 * 4, Allocator.Temp);
            var compressionModel = new NetworkCompressionModel(Allocator.Temp);

            NativeString64 src      = new NativeString64("This is a string");
            NativeString64 baseline = new NativeString64("This is another string");

            dataStream.WritePackedStringDelta(src, baseline, compressionModel);
            dataStream.Flush();

            //Assert.LessOrEqual(dataStream.Length, src.LengthInBytes+2);

            var reader = new DataStreamReader(dataStream, 0, dataStream.Length);

            DataStreamReader.Context ctx = default;
            var dst = reader.ReadPackedStringDelta(ref ctx, baseline, compressionModel);

            Assert.AreEqual(src, dst);
            ctx = default;
        }
Example #26
0
        public void SQP_SerializeQueryRequest_NoError()
        {
            var id    = (uint)1337;
            var chunk = (byte)31;

            var snd = new QueryRequest();

            snd.Header.ChallangeId = id;
            snd.RequestedChunks    = chunk;

            snd.ToStream(ref writer);

            var rcv = new QueryRequest();

            reader  = new DataStreamReader(writer, 0, writer.Length);
            context = default(DataStreamReader.Context);
            rcv.FromStream(reader, ref context);

            Assert.AreEqual((byte)SQPMessageType.QueryRequest, rcv.Header.Type);
            Assert.AreEqual(id, (uint)rcv.Header.ChallangeId);
            Assert.AreEqual(chunk, rcv.RequestedChunks);
        }
        // Wouldn't it be smarter to read the ID, the InstanceID and then find the reader that matches?
        public ReaderHeader Match(DataStreamReader stream, ref DataStreamReader.Context context)
        {
            var readerId = stream.ReadInt(ref context);

            if (Id != readerId)
            {
                return(new ReaderHeader(false));
            }

            var conId      = -1;
            var instanceId = -1;

            if (ConnectionId != null)
            {
                conId = stream.ReadInt(ref context);
            }

            if (InstanceId != null)
            {
                instanceId = stream.ReadInt(ref context);

                if (InstanceId != instanceId)
                {
                    return(new ReaderHeader(false));
                }
            }

            var currentTick = stream.ReadInt(ref context);

            return(new ReaderHeader
            {
                Matched = true,
                InstanceId = instanceId,
                ConnectionId = conId,
            });
        }
    public void Spawn(int serializer, int ghostId, uint snapshot, DataStreamReader reader,
                      ref DataStreamReader.Context ctx, NetworkCompressionModel compressionModel)
    {
        switch ((GhostSerializerCollection.SerializerType)serializer)
        {
        case GhostSerializerCollection.SerializerType.Ship:
            shipNewGhostIds.Add(ghostId);
            shipNewGhosts.Add(GhostReceiveSystem.InvokeSpawn <ShipSnapshotData>(snapshot, reader, ref ctx, compressionModel));
            break;

        case GhostSerializerCollection.SerializerType.Asteroid:
            asteroidNewGhostIds.Add(ghostId);
            asteroidNewGhosts.Add(GhostReceiveSystem.InvokeSpawn <AsteroidSnapshotData>(snapshot, reader, ref ctx, compressionModel));
            break;

        case GhostSerializerCollection.SerializerType.Bullet:
            bulletNewGhostIds.Add(ghostId);
            bulletNewGhosts.Add(GhostReceiveSystem.InvokeSpawn <BulletSnapshotData>(snapshot, reader, ref ctx, compressionModel));
            break;

        default:
            throw new ArgumentException("Invalid serializer type");
        }
    }
 public override void FromStream(DataStreamReader reader, ref DataStreamReader.Context ctx)
 {
     TopPlayerScore    = reader.ReadInt(ref ctx);
     BottomPlayerScore = reader.ReadInt(ref ctx);
 }
    public void Execute(int index)
    {
        //  querying for events that might have happened sincd last event
        DataStreamReader stream;

        if (!connections[index].IsCreated)
        {
            Assert.IsTrue(true);
        }

        //  while there are more events needed to process, we will keep popping
        //  events for connection
        NetworkEvent.Type netEvent;
        while ((netEvent = driver.PopEventForConnection(connections[index], out stream)) != NetworkEvent.Type.Empty)
        {
            //  This is where we will process different types of events

            //  Date Event
            if (netEvent == NetworkEvent.Type.Data)
            {
                DataStreamReader.Context readerContext = default(DataStreamReader.Context);
                int   dataSize        = stream.ReadUShort(ref readerContext) + 1;
                int   dataReadCounter = 0;
                float data;

                while (dataReadCounter < dataSize)
                {
                    data = stream.ReadFloat(ref readerContext);

                    dataReadCounter++;

                    switch ((int)data)
                    {
                    case (int)packetTypes.Player_Moved:
                        Debug.Log("Server got player move");

                        ClientPlayer player = new ClientPlayer(connections[index].InternalId);

                        player.PosX = stream.ReadFloat(ref readerContext);
                        player.PosY = stream.ReadFloat(ref readerContext);
                        player.PosZ = stream.ReadFloat(ref readerContext);
                        player.RotX = stream.ReadFloat(ref readerContext);
                        player.RotY = stream.ReadFloat(ref readerContext);
                        player.RotZ = stream.ReadFloat(ref readerContext);

                        players[findIndexOfPlayerWithId(connections[index].InternalId)] = player;

                        Debug.Log($"Player x: {player.PosX}, Player y: {player.PosY}, Player z: {player.PosZ}");

                        //Debug.Log($"x_pos read: {players[findIndexOfPlayerWithId(connections[index].InternalId)].PosX}, y_pos read: {player.PosY}, y_pos read: {player.PosY}");
                        //Debug.Log($"x_rot read: {player.RotX}, y_rot read: {player.RotY}, y_ros read: {player.RotY}");
                        dataReadCounter += 6;
                        break;

                    case (int)packetTypes.Player_Fire:
                        Debug.Log("Server got player fire");
                        dataReadCounter++;
                        break;
                    }
                }

                Debug.Log("Server end of packet");

                // update player object positions

                /*
                 * uint number = stream.ReadUInt(ref readerContext);
                 *
                 * Debug.Log("Got " + number + " from the Client.");
                 *
                 * using (DataStreamWriter connectionWriter = new DataStreamWriter(4, Allocator.Temp))
                 * {
                 *  connectionWriter.Write(number);
                 *  driver.Send(NetworkPipeline.Null, connections[index], connectionWriter);
                 * }
                 */
            }

            //  Disconnect Event
            else if (netEvent == NetworkEvent.Type.Disconnect)
            {
                Debug.Log("Client disconnected from server");
                connections[index] = default(NetworkConnection);
            }
        }
    }