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 !!!!!"); } } }
/// <summary> /// Processes a message. /// </summary> /// <param name="receiveBytes">The received bytes.</param> /// <param name="senderEndpoint">The sender's endpoint.</param> /// <exception cref="System.Exception">Receive ERROR, NAK in wrong place</exception> private void ProcessMessage(byte[] receiveBytes, IPEndPoint senderEndpoint) { byte msgId = receiveBytes[0]; if (msgId <= (byte) DefaultMessageIdTypes.ID_USER_PACKET_ENUM) { DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes) msgId; Package message = PackageFactory.CreatePackage(msgId, receiveBytes); if (message == null) return; TraceReceive(message); switch (msgIdType) { case DefaultMessageIdTypes.ID_UNCONNECTED_PONG: { UnconnectedPong incoming = (UnconnectedPong) message; HaveServer = true; SendOpenConnectionRequest1(); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_1: { OpenConnectionReply1 incoming = (OpenConnectionReply1) message; _mtuSize = incoming.mtuSize; //if (incoming.mtuSize < _mtuSize) throw new Exception("Error:" + incoming.mtuSize); SendOpenConnectionRequest2(); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_2: { OpenConnectionReply2 incoming = (OpenConnectionReply2) message; //_mtuSize = incoming.mtuSize; SendConnectionRequest(); break; } } } else { 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(); ConnectedPackage package = new ConnectedPackage(); package.Decode(receiveBytes); header = package._datagramHeader; //Log.Debug($"> Datagram #{header.datagramSequenceNumber}, {package._hasSplit}, {package._splitPacketId}, {package._reliability}, {package._reliableMessageNumber}, {package._sequencingIndex}, {package._orderingChannel}, {package._orderingIndex}"); var messages = package.Messages; //Reliability reliability = package._reliability; //if (reliability == Reliability.Reliable // || reliability == Reliability.ReliableSequenced // || reliability == Reliability.ReliableOrdered // ) { if (header.datagramSequenceNumber == 1000) { Log.Error("Datagram 1000 ignored"); } else { // Send ACK Acks ack = new Acks(); ack.acks.Add(package._datagramSequenceNumber.IntValue()); byte[] data = ack.Encode(); //Log.Info("Send ACK #" + package._datagramSequenceNumber.IntValue()); SendData(data, senderEndpoint); } } //if (LoginSent) return; //HACK foreach (var message in messages) { if (message is SplitPartPackage) { lock (Session.SyncRoot) { HandleSplitMessage(Session, package, (SplitPartPackage) message); } continue; } message.Timer.Restart(); HandlePackage(message); message.PutPool(); } //package.PutPool(); } else if (header.isPacketPair) { Log.Warn("header.isPacketPair"); } else if (header.isACK && header.isValid) { HandleAck(receiveBytes, senderEndpoint); } else if (header.isNAK && header.isValid) { Nak nak = new Nak(); nak.Decode(receiveBytes); HandleNak(receiveBytes, senderEndpoint); } else if (!header.isValid) { Log.Warn("!!!! ERROR, Invalid header !!!!!"); } else { Log.Warn("!! WHAT THE F"); } } }
/// <summary> /// Processes a message. /// </summary> /// <param name="receiveBytes">The received bytes.</param> /// <param name="senderEndpoint">The sender's endpoint.</param> /// <exception cref="System.Exception">Receive ERROR, NAK in wrong place</exception> private void ProcessMessage(byte[] receiveBytes, IPEndPoint senderEndpoint) { byte msgId = receiveBytes[0]; if (msgId == 0xFE) { Log.WarnFormat("A query detected from: {0}", senderEndpoint.Address); HandleQuery(receiveBytes, senderEndpoint); } else if (msgId <= (byte)DefaultMessageIdTypes.ID_USER_PACKET_ENUM) { DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes)msgId; Package message = PackageFactory.CreatePackage(msgId, receiveBytes); TraceReceive(message); switch (msgIdType) { case DefaultMessageIdTypes.ID_UNCONNECTED_PING: case DefaultMessageIdTypes.ID_UNCONNECTED_PING_OPEN_CONNECTIONS: { UnconnectedPing incoming = (UnconnectedPing)message; //TODO: This needs to be verified with RakNet first //response.sendpingtime = msg.sendpingtime; //response.sendpongtime = DateTimeOffset.UtcNow.Ticks / TimeSpan.TicksPerMillisecond; var packet = new UnconnectedPong { serverId = 22345, pingId = incoming.pingId /*incoming.pingId*/, serverName = string.Format(@"MCPE;{0};27;0.11.1;{1};{2}", Motd, _playerSessions.Count, 1000) }; var data = packet.Encode(); TraceSend(packet); SendData(data, senderEndpoint, _listener); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_1: { OpenConnectionRequest1 incoming = (OpenConnectionRequest1)message; _isPerformanceTest = _isPerformanceTest || incoming.raknetProtocolVersion == byte.MaxValue; var packet = new OpenConnectionReply1 { serverGuid = 12345, mtuSize = incoming.mtuSize, serverHasSecurity = 0 }; var data = packet.Encode(); TraceSend(packet); SendData(data, senderEndpoint, _listener); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_2: { OpenConnectionRequest2 incoming = (OpenConnectionRequest2)message; Log.WarnFormat("New connection from: {0} {1}", senderEndpoint.Address, incoming.clientUdpPort); var packet = new OpenConnectionReply2 { serverGuid = 12345, mtuSize = incoming.mtuSize, doSecurityAndHandshake = new byte[0] }; PlayerNetworkSession session = null; lock (_playerSessions) { if (_playerSessions.ContainsKey(senderEndpoint)) { PlayerNetworkSession value; _playerSessions.TryRemove(senderEndpoint, out value); value.Player.HandleDisconnectionNotification(); Log.Info("Removed ghost"); } session = new PlayerNetworkSession(new Player(this, senderEndpoint, _levels[_random.Next(0, _levels.Count)], _pluginManager, incoming.mtuSize), senderEndpoint); session.LastUpdatedTime = DateTime.UtcNow; session.Mtuize = incoming.mtuSize; _playerSessions.TryAdd(senderEndpoint, session); } var data = packet.Encode(); TraceSend(packet); SendData(data, senderEndpoint, session.SyncRoot); break; } default: Log.ErrorFormat("Receive unexpected packet with ID: {0} (0x{0:x2}) from {1}", msgId, senderEndpoint.Address); break; } if (message != null) { message.PutPool(); } else { Log.ErrorFormat("Receive unexpected packet with ID: {0} (0x{0:x2}) from {1}", msgId, senderEndpoint.Address); } } else { 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(); package.Decode(receiveBytes); List <Package> messages = package.Messages; if (messages.Count == 1) { McpeBatch batch = messages.First() as McpeBatch; if (batch != null) { messages = new List <Package>(); // Get bytes byte[] payload = batch.payload; // Decompress bytes MemoryStream stream = new MemoryStream(payload); if (stream.ReadByte() != 0x78) { throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C"); } stream.ReadByte(); using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false)) { // Get actual package out of bytes MemoryStream destination = new MemoryStream(); defStream2.CopyTo(destination); byte[] internalBuffer = destination.ToArray(); messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer) ?? new UnknownPackage(internalBuffer[0], internalBuffer)); } } } // 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(senderEndpoint, package._datagramSequenceNumber); } PlayerNetworkSession playerSession; if (_playerSessions.TryGetValue(senderEndpoint, out playerSession)) { foreach (var message in messages) { if (message is SplitPartPackage) { SplitPartPackage splitMessage = message as SplitPartPackage; int spId = package._splitPacketId; int spIdx = package._splitPacketIndex; int spCount = package._splitPacketCount; if (!playerSession.Splits.ContainsKey(spId)) { playerSession.Splits.Add(spId, new SplitPartPackage[spCount]); } SplitPartPackage[] spPackets = playerSession.Splits[spId]; spPackets[spIdx] = splitMessage; bool haveEmpty = false; for (int i = 0; i < spPackets.Length; i++) { haveEmpty = haveEmpty || spPackets[i] == null; } if (!haveEmpty) { Log.DebugFormat("Got all {0} split packages for split ID: {1}", spCount, spId); MemoryStream stream = new MemoryStream(); for (int i = 0; i < spPackets.Length; i++) { byte[] buf = spPackets[i].Message; stream.Write(buf, 0, buf.Length); } byte[] buffer = stream.ToArray(); var fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer); HandlePackage(fullMessage, playerSession); } continue; } message.Timer.Restart(); HandlePackage(message, playerSession); message.PutPool(); } } package.PutPool(); } else if (header.isACK && header.isValid) { HandleAck(receiveBytes, senderEndpoint); } else if (header.isNAK && header.isValid) { HandleNak(receiveBytes, senderEndpoint); } else if (!header.isValid) { Log.Warn("!!!! ERROR, Invalid header !!!!!"); } } }
/// <summary> /// Processes a message. /// </summary> /// <param name="receiveBytes">The received bytes.</param> /// <param name="senderEndpoint">The sender's endpoint.</param> /// <exception cref="System.Exception">Receive ERROR, NAK in wrong place</exception> private void ProcessMessage(byte[] receiveBytes, IPEndPoint senderEndpoint) { byte msgId = receiveBytes[0]; if (msgId <= (byte)DefaultMessageIdTypes.ID_USER_PACKET_ENUM) { DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes)msgId; Package message = PackageFactory.CreatePackage(msgId, receiveBytes); if (message == null) { return; } TraceReceive(message); switch (msgIdType) { case DefaultMessageIdTypes.ID_UNCONNECTED_PONG: { UnconnectedPong incoming = (UnconnectedPong)message; HaveServer = true; SendOpenConnectionRequest1(); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_1: { OpenConnectionReply1 incoming = (OpenConnectionReply1)message; _mtuSize = incoming.mtuSize; //if (incoming.mtuSize < _mtuSize) throw new Exception("Error:" + incoming.mtuSize); SendOpenConnectionRequest2(); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_2: { OpenConnectionReply2 incoming = (OpenConnectionReply2)message; //_mtuSize = incoming.mtuSize; SendConnectionRequest(); break; } } } else { 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(); ConnectedPackage package = new ConnectedPackage(); package.Decode(receiveBytes); header = package._datagramHeader; //Log.Debug(">\tReceive Datagram #" + package._datagramSequenceNumber.IntValue()); Log.Debug($"> Datagram #{header.datagramSequenceNumber}, {package._hasSplit}, {package._splitPacketId}, {package._reliability}, {package._reliableMessageNumber}, {package._sequencingIndex}, {package._orderingChannel}, {package._orderingIndex}"); var messages = package.Messages; //Reliability reliability = package._reliability; //if (reliability == Reliability.Reliable // || reliability == Reliability.ReliableSequenced // || reliability == Reliability.ReliableOrdered // ) { if (header.datagramSequenceNumber == 1000) { Log.Error("Datagram 1000 ignored"); } else { // Send ACK Acks ack = new Acks(); ack.acks.Add(package._datagramSequenceNumber.IntValue()); byte[] data = ack.Encode(); //Log.Info("Send ACK #" + package._datagramSequenceNumber.IntValue()); SendData(data, senderEndpoint); } } //if (LoginSent) return; //HACK foreach (var message in messages) { if (message is SplitPartPackage) { lock (Session.SyncRoot) { HandleSplitMessage(Session, package, (SplitPartPackage)message); } continue; } message.Timer.Restart(); HandlePackage(message); message.PutPool(); } //package.PutPool(); } else if (header.isPacketPair) { Log.Warn("header.isPacketPair"); } else if (header.isACK && header.isValid) { HandleAck(receiveBytes, senderEndpoint); } else if (header.isNAK && header.isValid) { Nak nak = new Nak(); nak.Decode(receiveBytes); HandleNak(receiveBytes, senderEndpoint); } else if (!header.isValid) { Log.Warn("!!!! ERROR, Invalid header !!!!!"); } else { Log.Warn("!! WHAT THE F"); } } }
/// <summary> /// Processes a message. /// </summary> /// <param name="receiveBytes">The received bytes.</param> /// <param name="senderEndpoint">The sender's endpoint.</param> /// <exception cref="System.Exception">Receive ERROR, NAK in wrong place</exception> private void ProcessMessage(byte[] receiveBytes, IPEndPoint senderEndpoint) { //_serverEndpoint = senderEndpoint; byte msgId = receiveBytes[0]; if (msgId <= (byte)DefaultMessageIdTypes.ID_USER_PACKET_ENUM) { DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes)msgId; Package message = PackageFactory.CreatePackage(msgId, receiveBytes); if (message == null) { return; } TraceReceive(message); switch (msgIdType) { case DefaultMessageIdTypes.ID_UNCONNECTED_PONG: { //Thread.Sleep(50); UnconnectedPong incoming = (UnconnectedPong)message; SendOpenConnectionRequest1(); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_1: { //Thread.Sleep(50); OpenConnectionReply1 incoming = (OpenConnectionReply1)message; if (incoming.mtuSize < _mtuSize) { throw new Exception("Error:" + incoming.mtuSize); } SendOpenConnectionRequest2(); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_2: { OpenConnectionReply2 incoming = (OpenConnectionReply2)message; //Thread.Sleep(50); //_mtuSize = incoming.mtuSize; SendConnectionRequest(); break; } case DefaultMessageIdTypes.ID_CONNECTION_REQUEST_ACCEPTED: { //Thread.Sleep(50); SendNewIncomingConnection(); var t1 = new Timer(state => SendConnectedPing(), null, 0, 5000); //Thread.Sleep(50); SendLogin("Client12"); break; } } } else { 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(); package.Decode(receiveBytes); Log.Debug(">\tReceive Datagram #" + package._datagramSequenceNumber.IntValue()); var messages = package.Messages; //Log.Debug("Received package: #" + package._datagramSequenceNumber.IntValue()); Reliability reliability = package._reliability; //Log.InfoFormat("Reliability: {0}", reliability); //if (reliability == Reliability.Reliable // || reliability == Reliability.ReliableSequenced // || reliability == Reliability.ReliableOrdered // ) { // Send ACK Acks ack = new Acks(); ack.acks.Add(package._datagramSequenceNumber.IntValue()); byte[] data = ack.Encode(); //Log.Debug("<\tSend ACK on #" + package._datagramSequenceNumber.IntValue()); SendData(data, senderEndpoint); } foreach (var message in messages) { if (message is SplitPartPackage) { SplitPartPackage splitMessage = message as SplitPartPackage; int spId = package._splitPacketId; int spIdx = package._splitPacketIndex; int spCount = package._splitPacketCount; Log.DebugFormat("Got split package {2} (of {0}) for split ID: {1}", spCount, spId, spIdx); if (!_splits.ContainsKey(spId)) { _splits[spId] = new SplitPartPackage[spCount]; } else { Log.WarnFormat("Resent split package {2} (of {0}) for split ID: {1}", spCount, spId, spIdx); } SplitPartPackage[] spPackets = _splits[spId]; spPackets[spIdx] = splitMessage; bool haveEmpty = false; for (int i = 0; i < spPackets.Length; i++) { haveEmpty = haveEmpty || spPackets[i] == null; } if (!haveEmpty) { Log.WarnFormat("Got all {0} split packages for split ID: {1}", spCount, spId); MemoryStream stream = new MemoryStream(); for (int i = 0; i < spPackets.Length; i++) { byte[] buf = spPackets[i].Message; stream.Write(buf, 0, buf.Length); } try { byte[] buffer = stream.ToArray(); var fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer); Log.Debug("Processing split-message"); HandlePackage(fullMessage, senderEndpoint); fullMessage.PutPool(); } catch (Exception e) { Log.Warn("When processing split-message", e); } } message.PutPool(); return; } { message.Timer.Restart(); HandlePackage(message, senderEndpoint); //message.PutPool(); } } //package.PutPool(); } else if (header.isPacketPair) { Log.Warn("header.isPacketPair"); } else if (header.isACK && header.isValid) { HandleAck(receiveBytes, senderEndpoint); } else if (header.isNAK && header.isValid) { Nak nak = new Nak(); nak.Decode(receiveBytes); Log.Warn("!!!! NAK !!!!!" + nak.sequenceNumber.IntValue()); HandleNak(receiveBytes, senderEndpoint); } else if (!header.isValid) { Log.Warn("!!!! ERROR, Invalid header !!!!!"); } else { Log.Warn("!! WHAT THE F"); } } }
/// <summary> /// Processes a message. /// </summary> /// <param name="receiveBytes">The received bytes.</param> /// <param name="senderEndpoint">The sender's endpoint.</param> /// <exception cref="System.Exception">Receive ERROR, NAK in wrong place</exception> private void ProcessMessage(byte[] receiveBytes, IPEndPoint senderEndpoint) { byte msgId = receiveBytes[0]; //Log.DebugFormat("Recieve {0} 0x{0:x2} len: {1}", msgId, receiveBytes.Length); if (msgId <= (byte)DefaultMessageIdTypes.ID_USER_PACKET_ENUM) { DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes)msgId; Package message = PackageFactory.CreatePackage(msgId, receiveBytes); if (message == null) { return; } TraceReceive(message); switch (msgIdType) { case DefaultMessageIdTypes.ID_UNCONNECTED_PONG: { UnconnectedPong incoming = (UnconnectedPong)message; SendOpenConnectionRequest1(); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_1: { OpenConnectionReply1 incoming = (OpenConnectionReply1)message; _mtuSize = incoming.mtuSize; //if (incoming.mtuSize < _mtuSize) throw new Exception("Error:" + incoming.mtuSize); SendOpenConnectionRequest2(); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_2: { OpenConnectionReply2 incoming = (OpenConnectionReply2)message; //_mtuSize = incoming.mtuSize; SendConnectionRequest(); break; } } } else { 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(); ConnectedPackage package = new ConnectedPackage(); package.Decode(receiveBytes); //Log.Debug(">\tReceive Datagram #" + package._datagramSequenceNumber.IntValue()); var messages = package.Messages; //Reliability reliability = package._reliability; //if (reliability == Reliability.Reliable // || reliability == Reliability.ReliableSequenced // || reliability == Reliability.ReliableOrdered // ) { // Send ACK Acks ack = new Acks(); ack.acks.Add(package._datagramSequenceNumber.IntValue()); byte[] data = ack.Encode(); //Log.Info("Send ACK #" + package._datagramSequenceNumber.IntValue()); SendData(data, senderEndpoint); } //if (LoginSent) return; //HACK foreach (var message in messages) { if (message is SplitPartPackage) { lock (Session.SyncRoot) { var splits = Session.Splits; SplitPartPackage splitMessage = message as SplitPartPackage; int spId = package._splitPacketId; int spIdx = package._splitPacketIndex; int spCount = package._splitPacketCount; Log.DebugFormat("Got split package {2} (of {0}) for split ID: {1}", spCount, spId, spIdx); if (!splits.ContainsKey(spId)) { splits.Add(spId, new SplitPartPackage[spCount]); } SplitPartPackage[] spPackets = splits[spId]; if (spIdx < 0 || spIdx >= spPackets.Length) { Log.DebugFormat("Unexpeted split package {2} (of {0}) for split ID: {1}", spCount, spId, spIdx); continue; } if (splitMessage.Message == null) { Log.DebugFormat("Empty split package"); continue; } spPackets[spIdx] = splitMessage; bool haveEmpty = false; for (int i = 0; i < spPackets.Length; i++) { haveEmpty = haveEmpty || spPackets[i] == null; } if (!haveEmpty) { Log.DebugFormat("Got all {0} split packages for split ID: {1}", spCount, spId); MemoryStream stream = new MemoryStream(); for (int i = 0; i < spPackets.Length; i++) { byte[] buf = spPackets[i].Message; stream.Write(buf, 0, buf.Length); } try { byte[] buffer = stream.ToArray(); Log.DebugFormat("Processing split-message 0x{1:x2}, lenght={0}", buffer.Length, buffer[0]); Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer); HandlePackage(fullMessage, senderEndpoint); fullMessage.PutPool(); continue; } catch (Exception e) { Log.Error("When processing split-message", e); } } message.PutPool(); continue; } } else { message.Timer.Restart(); HandlePackage(message, senderEndpoint); message.PutPool(); } } //package.PutPool(); } else if (header.isPacketPair) { Log.Warn("header.isPacketPair"); } else if (header.isACK && header.isValid) { HandleAck(receiveBytes, senderEndpoint); } else if (header.isNAK && header.isValid) { Nak nak = new Nak(); nak.Decode(receiveBytes); Log.Warn("!!!! NAK !!!!!" + nak.sequenceNumber.IntValue()); HandleNak(receiveBytes, senderEndpoint); } else if (!header.isValid) { Log.Warn("!!!! ERROR, Invalid header !!!!!"); } else { Log.Warn("!! WHAT THE F"); } } }
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); return; } Player player = playerSession.Player; if (player == null) { Log.ErrorFormat("Receive MCPE message 0x{1:x2} without player {0}. Session removed.", senderEndpoint.Address, msgId); _playerSessions.TryRemove(senderEndpoint, out playerSession); 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) { player.Disconnect("Bad package received from client."); 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); } List <Package> messages = package.Messages; if (messages.Count == 1) { McpeBatch batch = messages.First() as McpeBatch; if (batch != null) { batch.Source = "Client"; messages.Clear(); // Get bytes byte[] payload = batch.payload; // Decompress bytes MemoryStream stream = new MemoryStream(payload); if (stream.ReadByte() != 0x78) { throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C"); } stream.ReadByte(); using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false)) { // Get actual package out of bytes MemoryStream destination = new MemoryStream(); defStream2.CopyTo(destination); byte[] internalBuffer = destination.ToArray(); messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer) ?? new UnknownPackage(internalBuffer[0], internalBuffer)); } batch.PutPool(); } } DelayedProcessing(playerSession, package); package.PutPool(); } else if (header.isACK && header.isValid) { ServerInfo.NumberOfAckReceive++; HandleAck(playerSession, receiveBytes); } else if (header.isNAK && header.isValid) { ServerInfo.NumberOfNakReceive++; HandleNak(playerSession, receiveBytes); } else if (!header.isValid) { Log.Warn("!!!! ERROR, Invalid header !!!!!"); } } }
/// <summary> /// Processes a message. /// </summary> /// <param name="receiveBytes">The received bytes.</param> /// <param name="senderEndpoint">The sender's endpoint.</param> /// <exception cref="System.Exception">Receive ERROR, NAK in wrong place</exception> private void ProcessMessage(byte[] receiveBytes, IPEndPoint senderEndpoint) { byte msgId = receiveBytes[0]; //Log.DebugFormat("Recieve {0} 0x{0:x2} len: {1}", msgId, receiveBytes.Length); if (msgId <= (byte) DefaultMessageIdTypes.ID_USER_PACKET_ENUM) { DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes) msgId; Package message = PackageFactory.CreatePackage(msgId, receiveBytes); if (message == null) return; TraceReceive(message); switch (msgIdType) { case DefaultMessageIdTypes.ID_UNCONNECTED_PONG: { UnconnectedPong incoming = (UnconnectedPong) message; SendOpenConnectionRequest1(); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_1: { OpenConnectionReply1 incoming = (OpenConnectionReply1) message; _mtuSize = incoming.mtuSize; //if (incoming.mtuSize < _mtuSize) throw new Exception("Error:" + incoming.mtuSize); SendOpenConnectionRequest2(); break; } case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_2: { OpenConnectionReply2 incoming = (OpenConnectionReply2) message; //_mtuSize = incoming.mtuSize; SendConnectionRequest(); break; } } } else { 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(); ConnectedPackage package = new ConnectedPackage(); package.Decode(receiveBytes); //Log.Debug(">\tReceive Datagram #" + package._datagramSequenceNumber.IntValue()); var messages = package.Messages; //Reliability reliability = package._reliability; //if (reliability == Reliability.Reliable // || reliability == Reliability.ReliableSequenced // || reliability == Reliability.ReliableOrdered // ) { // Send ACK Acks ack = new Acks(); ack.acks.Add(package._datagramSequenceNumber.IntValue()); byte[] data = ack.Encode(); //Log.Info("Send ACK #" + package._datagramSequenceNumber.IntValue()); SendData(data, senderEndpoint); } //if (LoginSent) return; //HACK foreach (var message in messages) { if (message is SplitPartPackage) { lock (Session.SyncRoot) { var splits = Session.Splits; SplitPartPackage splitMessage = message as SplitPartPackage; int spId = package._splitPacketId; int spIdx = package._splitPacketIndex; int spCount = package._splitPacketCount; Log.DebugFormat("Got split package {2} (of {0}) for split ID: {1}", spCount, spId, spIdx); if (!splits.ContainsKey(spId)) { splits.Add(spId, new SplitPartPackage[spCount]); } SplitPartPackage[] spPackets = splits[spId]; if (spIdx < 0 || spIdx >= spPackets.Length) { Log.DebugFormat("Unexpeted split package {2} (of {0}) for split ID: {1}", spCount, spId, spIdx); continue; } if (splitMessage.Message == null) { Log.DebugFormat("Empty split package"); continue; } spPackets[spIdx] = splitMessage; bool haveEmpty = false; for (int i = 0; i < spPackets.Length; i++) { haveEmpty = haveEmpty || spPackets[i] == null; } if (!haveEmpty) { Log.DebugFormat("Got all {0} split packages for split ID: {1}", spCount, spId); MemoryStream stream = new MemoryStream(); for (int i = 0; i < spPackets.Length; i++) { byte[] buf = spPackets[i].Message; stream.Write(buf, 0, buf.Length); } try { byte[] buffer = stream.ToArray(); Log.DebugFormat("Processing split-message 0x{1:x2}, lenght={0}", buffer.Length, buffer[0]); Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer); HandlePackage(fullMessage, senderEndpoint); fullMessage.PutPool(); continue; } catch (Exception e) { Log.Error("When processing split-message", e); } } message.PutPool(); continue; } } else { message.Timer.Restart(); HandlePackage(message, senderEndpoint); message.PutPool(); } } //package.PutPool(); } else if (header.isPacketPair) { Log.Warn("header.isPacketPair"); } else if (header.isACK && header.isValid) { HandleAck(receiveBytes, senderEndpoint); } else if (header.isNAK && header.isValid) { Nak nak = new Nak(); nak.Decode(receiveBytes); HandleNak(receiveBytes, senderEndpoint); } else if (!header.isValid) { Log.Warn("!!!! ERROR, Invalid header !!!!!"); } else { Log.Warn("!! WHAT THE F"); } } }