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(); }
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); }
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); }
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); }
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); } }
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(); } } }
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); } } } }