예제 #1
0
        private void OnReceiveDataFromServer(int channelId, byte[] bytesReceived, int numBytesReceived)
        {
            Profiler.BeginSample("OnReceiveDataFromServer");
            using (var memoryStream = new MemoryStream(bytesReceived, 0, numBytesReceived))
            {
                using (var reader = new BinaryReader(memoryStream))
                {
                    var     messageTypeAsByte = reader.ReadByte();
                    RpcInfo rpcInfo;

                    if (messageTypeAsByte == NetLib.StateSynchronizationMessageId)
                    {
                        OnReceiveDeltaGameStateFromServer(reader, bytesReceived, numBytesReceived);
                    }
                    else if (NetLib.rpcInfoById.TryGetValue(messageTypeAsByte, out rpcInfo))
                    {
                        Profiler.BeginSample("Deserialize & Execute RPC");
                        var rpcArguments = NetworkSerializationUtils.DeserializeRpcCallArguments(rpcInfo, reader);
                        NetLib.ExecuteRpc(rpcInfo.Id, null, ObjectContainingRpcs, rpcArguments);
                        Profiler.EndSample();
                    }
                    else
                    {
                        throw new NotImplementedException("Unknown message type: " + messageTypeAsByte);
                    }
                }
            }
            Profiler.EndSample();
        }
예제 #2
0
        public void CallRpcOnServer(string name, int channelId, object argumentsObj)
        {
            var rpcId   = NetLib.rpcIdByName[name];
            var rpcInfo = NetLib.rpcInfoById[rpcId];

            Assert.IsTrue(rpcInfo.ExecuteOn == NetworkPeerType.Server);

            var messageBytes = NetworkSerializationUtils.SerializeRpcCall(rpcInfo, argumentsObj);

            SendMessageToServer(channelId, messageBytes);
        }
예제 #3
0
        public void CallRpcOnAllClientsExcept(string name, int exceptClientConnectionId, int channelId, object argumentsObj)
        {
            var rpcId   = NetLib.rpcIdByName[name];
            var rpcInfo = NetLib.rpcInfoById[rpcId];

            Assert.IsTrue(rpcInfo.ExecuteOn == NetworkPeerType.Client);

            var messageBytes = NetworkSerializationUtils.SerializeRpcCall(rpcInfo, argumentsObj);

            SendMessageToAllClientsExcept(exceptClientConnectionId, channelId, messageBytes);
        }
예제 #4
0
        private void SendGameStateDiff(int connectionId, NetworkedGameState gameState, NetworkedGameState oldGameState)
        {
            byte[] messageBytes;

            using (var memoryStream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(memoryStream))
                {
                    writer.Write(NetLib.StateSynchronizationMessageId);
                    writer.Write(gameState.SequenceNumber);
                    writer.Write(oldGameState.SequenceNumber);
                    NetworkSerializationUtils.SerializeNetworkedGameState(writer, gameState, oldGameState);
                }

                messageBytes = memoryStream.ToArray();
            }

            SendMessageToClient(connectionId, unreliableFragmentedChannelId, messageBytes);
        }
예제 #5
0
        private void OnReceiveDeltaGameStateFromServer(BinaryReader reader, byte[] bytesReceived, int numBytesReceived)
        {
            uint latestReceivedGameStateSequenceNumber = (cachedReceivedGameStates.Any())
                ? cachedReceivedGameStates[cachedReceivedGameStates.Count - 1].SequenceNumber
                : 0;

            latestReceivedGameStateSequenceNumber = Math.Max(
                latestReceivedGameStateSequenceNumber,
                latestSequenceNumberDeltaGameStateBytesPair?.Item1 ?? 0
                );

            var sequenceNumber = reader.ReadUInt32();

            if (sequenceNumber > latestReceivedGameStateSequenceNumber)
            {
                var bytesLeft = new byte[numBytesReceived - reader.BaseStream.Position];

                Array.Copy(bytesReceived, reader.BaseStream.Position, bytesLeft, 0, bytesLeft.Length);
                latestSequenceNumberDeltaGameStateBytesPair = new Tuple <uint, byte[]>(
                    sequenceNumber,
                    bytesLeft
                    );
            }

            if (NetLib.EnableStateDeltaLogging)
            {
                var sequenceNumberRelativeTo     = reader.ReadUInt32();
                var networkedGameStateRelativeTo = GetNetworkedGameStateRelativeTo(sequenceNumberRelativeTo);

                Profiler.BeginSample("State Deserialization");
                var receivedGameState = NetworkSerializationUtils.DeserializeNetworkedGameState(
                    reader, sequenceNumber, networkedGameStateRelativeTo
                    );
                Profiler.EndSample();

                LogReceivedStateDelta(receivedGameState);
            }
        }
예제 #6
0
        private void FinishHandlingDeltaGameState(uint sequenceNumber, byte[] deltaBytes)
        {
            using (var memoryStream = new MemoryStream(deltaBytes))
            {
                using (var reader = new BinaryReader(memoryStream))
                {
                    var sequenceNumberRelativeTo     = reader.ReadUInt32();
                    var networkedGameStateRelativeTo = GetNetworkedGameStateRelativeTo(sequenceNumberRelativeTo);

                    Profiler.BeginSample("State Deserialization");
                    var receivedGameState = NetworkSerializationUtils.DeserializeNetworkedGameState(
                        reader, sequenceNumber, networkedGameStateRelativeTo
                        );
                    Profiler.EndSample();

                    CallRpcOnServer("ServerOnReceiveClientGameStateAck", unreliableChannelId, new
                    {
                        gameStateSequenceNumber = receivedGameState.SequenceNumber
                    });

                    cachedReceivedGameStates.Add(receivedGameState);

                    var indexOfLatestGameStateToDiscard = cachedReceivedGameStates
                                                          .FindLastIndex(ngs => ngs.SequenceNumber < sequenceNumberRelativeTo);
                    if (indexOfLatestGameStateToDiscard >= 0)
                    {
                        var numberOfLatestGameStatesToDiscard = indexOfLatestGameStateToDiscard + 1;
                        cachedReceivedGameStates.RemoveRange(0, numberOfLatestGameStatesToDiscard);
                    }

                    Profiler.BeginSample("ClientOnReceiveGameState");
                    OnReceiveGameState(receivedGameState);
                    Profiler.EndSample();
                }
            }
        }
예제 #7
0
        private void OnReceiveDataFromClient(int connectionId, int channelId, byte[] bytesReceived, int numBytesReceived)
        {
            using (var memoryStream = new MemoryStream(bytesReceived, 0, numBytesReceived))
            {
                using (var reader = new BinaryReader(memoryStream))
                {
                    var messageTypeAsByte = reader.ReadByte();

                    RpcInfo rpcInfo;

                    if (messageTypeAsByte == NetLib.StateSynchronizationMessageId)
                    {
                        throw new System.NotImplementedException("Servers don't support receiving state synchronization messages.");
                    }
                    else if (NetLib.rpcInfoById.TryGetValue(messageTypeAsByte, out rpcInfo))
                    {
                        var rpcArguments = NetworkSerializationUtils.DeserializeRpcCallArguments(rpcInfo, reader);

                        CurrentRpcSenderConnectionId = connectionId;

                        if (rpcInfo.Name != "ServerOnReceiveClientGameStateAck")
                        {
                            NetLib.ExecuteRpc(rpcInfo.Id, ObjectContainingRpcs, null, rpcArguments);
                        }
                        else
                        {
                            NetLib.ExecuteRpc(rpcInfo.Id, this, null, rpcArguments);
                        }
                    }
                    else
                    {
                        throw new System.NotImplementedException("Unknown message type: " + messageTypeAsByte);
                    }
                }
            }
        }