private void ProcessMessage(byte[] receiveBytes, IPEndPoint senderEndpoint) { byte msgId = receiveBytes[0]; if (msgId == 0xFE) { Log.InfoFormat("A query detected from: {0}", senderEndpoint.Address); HandleQuery(receiveBytes, senderEndpoint); } else if (msgId <= (byte)DefaultMessageIdTypes.ID_USER_PACKET_ENUM) { HandleRakNetMessage(receiveBytes, senderEndpoint, msgId); } else { PlayerNetworkSession playerSession; if (!_playerSessions.TryGetValue(senderEndpoint, out playerSession)) { //Log.DebugFormat("Receive MCPE message 0x{1:x2} without session {0}", senderEndpoint.Address, msgId); //if (!_badPacketBans.ContainsKey(senderEndpoint.Address)) //{ // _badPacketBans.Add(senderEndpoint.Address, true); //} return; } if (playerSession.MessageHandler == null) { Log.ErrorFormat("Receive MCPE message 0x{1:x2} without message handler {0}. Session removed.", senderEndpoint.Address, msgId); _playerSessions.TryRemove(senderEndpoint, out playerSession); //if (!_badPacketBans.ContainsKey(senderEndpoint.Address)) //{ // _badPacketBans.Add(senderEndpoint.Address, true); //} return; } if (playerSession.Evicted) { return; } playerSession.LastUpdatedTime = DateTime.UtcNow; DatagramHeader header = new DatagramHeader(receiveBytes[0]); if (!header.isACK && !header.isNAK && header.isValid) { if (receiveBytes[0] == 0xa0) { throw new Exception("Receive ERROR, NAK in wrong place"); } ConnectedPackage package = ConnectedPackage.CreateObject(); try { package.Decode(receiveBytes); } catch (Exception e) { playerSession.Disconnect("Bad package received from client."); Log.Warn($"Bad packet {receiveBytes[0]}\n{Package.HexDump(receiveBytes)}", e); GreylistManager.Blacklist(senderEndpoint.Address); return; } // IF reliable code below is enabled, useItem start sending doubles // for some unknown reason. //Reliability reliability = package._reliability; //if (reliability == Reliability.Reliable // || reliability == Reliability.ReliableSequenced // || reliability == Reliability.ReliableOrdered // ) { EnqueueAck(playerSession, package._datagramSequenceNumber); //if (Log.IsDebugEnabled) Log.Debug("ACK on #" + package._datagramSequenceNumber.IntValue()); } HandleConnectedPackage(playerSession, package); package.PutPool(); } else if (header.isACK && header.isValid) { HandleAck(playerSession, receiveBytes); } else if (header.isNAK && header.isValid) { HandleNak(playerSession, receiveBytes); } else if (!header.isValid) { Log.Warn("!!!! ERROR, Invalid header !!!!!"); } } }
private void HandleRakNetMessage(byte[] receiveBytes, IPEndPoint senderEndpoint, byte msgId) { DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes)msgId; // Increase fast, decrease slow on 1s ticks. if (ServerInfo.NumberOfPlayers < ServerInfo.PlayerSessions.Count) { ServerInfo.NumberOfPlayers = ServerInfo.PlayerSessions.Count; } // Shortcut to reply fast, and no parsing if (msgIdType == DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_1) { if (!GreylistManager.AcceptConnection(senderEndpoint.Address)) { var noFree = NoFreeIncomingConnections.CreateObject(); var bytes = noFree.Encode(); noFree.PutPool(); TraceSend(noFree); SendData(bytes, senderEndpoint); Interlocked.Increment(ref ServerInfo.NumberOfDeniedConnectionRequestsPerSecond); return; } } Package message = null; try { try { message = PackageFactory.CreatePackage(msgId, receiveBytes, "raknet"); } catch (Exception) { message = null; } if (message == null) { GreylistManager.Blacklist(senderEndpoint.Address); Log.ErrorFormat("Receive bad packet with ID: {0} (0x{0:x2}) {2} from {1}", msgId, senderEndpoint.Address, (DefaultMessageIdTypes)msgId); return; } TraceReceive(message); switch (msgIdType) { case DefaultMessageIdTypes.ID_UNCONNECTED_PING: case DefaultMessageIdTypes.ID_UNCONNECTED_PING_OPEN_CONNECTIONS: { HandleRakNetMessage(senderEndpoint, (UnconnectedPing)message); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_1: { HandleRakNetMessage(senderEndpoint, (OpenConnectionRequest1)message); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_2: { HandleRakNetMessage(senderEndpoint, (OpenConnectionRequest2)message); break; } default: GreylistManager.Blacklist(senderEndpoint.Address); Log.ErrorFormat("Receive unexpected packet with ID: {0} (0x{0:x2}) {2} from {1}", msgId, senderEndpoint.Address, (DefaultMessageIdTypes)msgId); break; } } finally { if (message != null) { message.PutPool(); } } }
private void HandleRakNetMessage(byte[] receiveBytes, IPEndPoint senderEndpoint, byte msgId) { DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes)msgId; Package message = null; try { try { message = PackageFactory.CreatePackage(msgId, receiveBytes); } catch (Exception) { message = null; } if (message == null) { GreylistManager.Blacklist(senderEndpoint.Address); Log.ErrorFormat("Receive bad packet with ID: {0} (0x{0:x2}) {2} from {1}", msgId, senderEndpoint.Address, (DefaultMessageIdTypes)msgId); return; } TraceReceive(message); switch (msgIdType) { case DefaultMessageIdTypes.ID_UNCONNECTED_PING: case DefaultMessageIdTypes.ID_UNCONNECTED_PING_OPEN_CONNECTIONS: { HandleRakNetMessage(senderEndpoint, (UnconnectedPing)message); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_1: { HandleRakNetMessage(senderEndpoint, (OpenConnectionRequest1)message); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_2: { HandleRakNetMessage(senderEndpoint, (OpenConnectionRequest2)message); break; } default: GreylistManager.Blacklist(senderEndpoint.Address); Log.ErrorFormat("Receive unexpected packet with ID: {0} (0x{0:x2}) {2} from {1}", msgId, senderEndpoint.Address, (DefaultMessageIdTypes)msgId); break; } } finally { if (message != null) { message.PutPool(); } } }