private void HandleSplitMessage(PlayerNetworkSession playerSession, ConnectedPackage package, SplitPartPackage splitMessage, Player player) { int spId = package._splitPacketId; int spIdx = package._splitPacketIndex; int spCount = package._splitPacketCount; if (!playerSession.Splits.ContainsKey(spId)) { playerSession.Splits.TryAdd(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); SplitPartPackage[] waste; playerSession.Splits.TryRemove(spId, out waste); MemoryStream stream = new MemoryStream(); for (int i = 0; i < spPackets.Length; i++) { SplitPartPackage splitPartPackage = spPackets[i]; byte[] buf = splitPartPackage.Message; if (buf == null) { Log.Error("Expected bytes in splitpart, but got none"); continue; } stream.Write(buf, 0, buf.Length); splitPartPackage.PutPool(); } byte[] buffer = stream.ToArray(); try { Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer); fullMessage.DatagramSequenceNumber = package._datagramSequenceNumber; fullMessage.ReliableMessageNumber = package._reliableMessageNumber; fullMessage.OrderingChannel = package._orderingChannel; fullMessage.OrderingIndex = package._orderingIndex; HandlePackage(fullMessage, playerSession); fullMessage.PutPool(); } catch (Exception e) { player.Disconnect("Bad package received from client."); } } }
private void HandleSplitMessage(PlayerNetworkSession playerSession, ConnectedPackage package, SplitPartPackage splitMessage) { int spId = package._splitPacketId; int spIdx = package._splitPacketIndex; int spCount = package._splitPacketCount; if (!playerSession.Splits.ContainsKey(spId)) { playerSession.Splits.TryAdd(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); SplitPartPackage[] waste; playerSession.Splits.TryRemove(spId, out waste); MemoryStream stream = new MemoryStream(); for (int i = 0; i < spPackets.Length; i++) { SplitPartPackage splitPartPackage = spPackets[i]; byte[] buf = splitPartPackage.Message; stream.Write(buf, 0, buf.Length); splitPartPackage.PutPool(); } byte[] buffer = stream.ToArray(); byte id = buffer[0]; if (id == 0x8e) { id = buffer[1]; } Package fullMessage = PackageFactory.CreatePackage(id, buffer) ?? new UnknownPackage(id, buffer); fullMessage.DatagramSequenceNumber = package._datagramSequenceNumber; fullMessage.OrderingChannel = package._orderingChannel; fullMessage.OrderingIndex = package._orderingIndex; if (!(fullMessage is McpeBatch)) { Log.Debug($"Split: {fullMessage.GetType().Name} 0x{fullMessage.Id:x2} \n{Package.HexDump(buffer)}"); } HandlePackage(fullMessage); fullMessage.PutPool(); } }
private void HandleSplitMessage(PlayerNetworkSession playerSession, ConnectedPackage package, SplitPartPackage splitMessage) { 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++) { SplitPartPackage splitPartPackage = spPackets[i]; byte[] buf = splitPartPackage.Message; stream.Write(buf, 0, buf.Length); splitPartPackage.PutPool(); } playerSession.Splits.Remove(spId); byte[] buffer = stream.ToArray(); Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer); fullMessage.DatagramSequenceNumber = package._datagramSequenceNumber; fullMessage.OrderingChannel = package._orderingChannel; fullMessage.OrderingIndex = package._orderingIndex; HandlePackage(fullMessage); fullMessage.PutPool(); } }
private void HandleSplitMessage(PlayerNetworkSession playerSession, SplitPartPackage splitMessage) { int spId = splitMessage.SplitId; int spIdx = splitMessage.SplitIdx; int spCount = splitMessage.SplitCount; Int24 sequenceNumber = splitMessage.DatagramSequenceNumber; Reliability reliability = splitMessage.Reliability; Int24 reliableMessageNumber = splitMessage.ReliableMessageNumber; Int24 orderingIndex = splitMessage.OrderingIndex; byte orderingChannel = splitMessage.OrderingChannel; SplitPartPackage[] spPackets; bool haveEmpty = false; // Need sync for this part since they come very fast, and very close in time. // If no synk, will often detect complete message two times (or more). lock (playerSession.Splits) { if (!playerSession.Splits.ContainsKey(spId)) { playerSession.Splits.TryAdd(spId, new SplitPartPackage[spCount]); } spPackets = playerSession.Splits[spId]; if (spPackets[spIdx] != null) { Log.Debug("Already had splitpart (resent). Ignore this part."); return; } spPackets[spIdx] = splitMessage; 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); SplitPartPackage[] waste; playerSession.Splits.TryRemove(spId, out waste); using (MemoryStream stream = MemoryStreamManager.GetStream()) { for (int i = 0; i < spPackets.Length; i++) { SplitPartPackage splitPartPackage = spPackets[i]; byte[] buf = splitPartPackage.Message; if (buf == null) { Log.Error("Expected bytes in splitpart, but got none"); continue; } stream.Write(buf, 0, buf.Length); splitPartPackage.PutPool(); } byte[] buffer = stream.ToArray(); try { ConnectedPackage newPackage = ConnectedPackage.CreateObject(); newPackage._datagramSequenceNumber = sequenceNumber; newPackage._reliability = reliability; newPackage._reliableMessageNumber = reliableMessageNumber; newPackage._orderingIndex = orderingIndex; newPackage._orderingChannel = (byte)orderingChannel; newPackage._hasSplit = false; Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer, "raknet") ?? new UnknownPackage(buffer[0], buffer); fullMessage.DatagramSequenceNumber = sequenceNumber; fullMessage.Reliability = reliability; fullMessage.ReliableMessageNumber = reliableMessageNumber; fullMessage.OrderingIndex = orderingIndex; fullMessage.OrderingChannel = orderingChannel; newPackage.Messages = new List <Package>(); newPackage.Messages.Add(fullMessage); Log.Debug( $"Assembled split package {newPackage._reliability} message #{newPackage._reliableMessageNumber}, Chan: #{newPackage._orderingChannel}, OrdIdx: #{newPackage._orderingIndex}"); HandleConnectedPackage(playerSession, newPackage); newPackage.PutPool(); } catch (Exception e) { Log.Error("Error during split message parsing", e); if (Log.IsDebugEnabled) { Log.Debug($"0x{buffer[0]:x2}\n{Package.HexDump(buffer)}"); } playerSession.Disconnect("Bad package received from client.", false); } } } }
private void HandleSplitMessage(PlayerNetworkSession playerSession, ConnectedPackage package, SplitPartPackage splitMessage, Player player) { int spId = package._splitPacketId; int spIdx = package._splitPacketIndex; int spCount = package._splitPacketCount; if (!playerSession.Splits.ContainsKey(spId)) { playerSession.Splits.TryAdd(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); SplitPartPackage[] waste; playerSession.Splits.TryRemove(spId, out waste); MemoryStream stream = new MemoryStream(); for (int i = 0; i < spPackets.Length; i++) { SplitPartPackage splitPartPackage = spPackets[i]; byte[] buf = splitPartPackage.Message; if (buf == null) { Log.Error("Expected bytes in splitpart, but got none"); continue; } stream.Write(buf, 0, buf.Length); splitPartPackage.PutPool(); } byte[] buffer = stream.ToArray(); try { Package fullMessage = PackageFactory.CreatePackage(buffer[1], buffer) ?? new UnknownPackage(buffer[1], buffer); Log.Debug($"0x{fullMessage.Id:x2}\n{Package.HexDump(buffer)}"); fullMessage.DatagramSequenceNumber = package._datagramSequenceNumber; fullMessage.ReliableMessageNumber = package._reliableMessageNumber; fullMessage.OrderingChannel = package._orderingChannel; fullMessage.OrderingIndex = package._orderingIndex; HandlePackage(fullMessage, playerSession); fullMessage.PutPool(); } catch (Exception e) { player.Disconnect("Bad package received from client."); } } }
/// <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 !!!!!"); } } }
private void HandleSplitMessage(PlayerNetworkSession playerSession, ConnectedPackage package, SplitPartPackage splitMessage) { int spId = package._splitPacketId; int spIdx = package._splitPacketIndex; int spCount = package._splitPacketCount; if (!playerSession.Splits.ContainsKey(spId)) { playerSession.Splits.TryAdd(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); SplitPartPackage[] waste; playerSession.Splits.TryRemove(spId, out waste); MemoryStream stream = new MemoryStream(); for (int i = 0; i < spPackets.Length; i++) { SplitPartPackage splitPartPackage = spPackets[i]; byte[] buf = splitPartPackage.Message; stream.Write(buf, 0, buf.Length); splitPartPackage.PutPool(); } byte[] buffer = stream.ToArray(); Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer); fullMessage.DatagramSequenceNumber = package._datagramSequenceNumber; fullMessage.OrderingChannel = package._orderingChannel; fullMessage.OrderingIndex = package._orderingIndex; HandlePackage(fullMessage); fullMessage.PutPool(); } }
/// <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) { //_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 DelayedProcessing(PlayerNetworkSession playerSession, ConnectedPackage package) { Player player = playerSession.Player; if (ForwardAllPlayers) { player.SendPackage(new McpeTransfer { endpoint = ForwardTarget }, true); return; } List <Package> messages = package.Messages; foreach (var message in messages) { message.DatagramSequenceNumber = package._datagramSequenceNumber; message.OrderingChannel = package._orderingChannel; message.OrderingIndex = package._orderingIndex; if (message is SplitPartPackage) { message.Source = "Receive 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++) { SplitPartPackage splitPartPackage = spPackets[i]; byte[] buf = splitPartPackage.Message; stream.Write(buf, 0, buf.Length); splitPartPackage.PutPool(); } playerSession.Splits.Remove(spId); byte[] buffer = stream.ToArray(); try { Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer); fullMessage.DatagramSequenceNumber = package._datagramSequenceNumber; fullMessage.OrderingChannel = package._orderingChannel; fullMessage.OrderingIndex = package._orderingIndex; HandlePackage(fullMessage, playerSession); fullMessage.PutPool(); } catch (Exception e) { player.Disconnect("Bad package received from client."); } } continue; } message.Timer.Restart(); HandlePackage(message, playerSession); message.PutPool(); // Handled in HandlePacket now() } }
private void HandleSplitMessage(PlayerNetworkSession playerSession, ConnectedPackage package, SplitPartPackage splitMessage, Player player) { int spId = package._splitPacketId; int spIdx = package._splitPacketIndex; int spCount = package._splitPacketCount; if (!playerSession.Splits.ContainsKey(spId)) { playerSession.Splits.TryAdd(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); SplitPartPackage[] waste; playerSession.Splits.TryRemove(spId, out waste); MemoryStream stream = MemoryStreamManager.GetStream(); for (int i = 0; i < spPackets.Length; i++) { SplitPartPackage splitPartPackage = spPackets[i]; byte[] buf = splitPartPackage.Message; if (buf == null) { Log.Error("Expected bytes in splitpart, but got none"); continue; } stream.Write(buf, 0, buf.Length); splitPartPackage.PutPool(); } byte[] buffer = stream.ToArray(); try { ConnectedPackage newPackage = ConnectedPackage.CreateObject(); newPackage._datagramSequenceNumber = package._datagramSequenceNumber; newPackage._reliability = package._reliability; newPackage._reliableMessageNumber = package._reliableMessageNumber; newPackage._sequencingIndex = package._sequencingIndex; newPackage._orderingIndex = package._orderingIndex; newPackage._orderingChannel = package._orderingChannel; newPackage._hasSplit = false; Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer, "raknet") ?? new UnknownPackage(buffer[0], buffer); fullMessage.DatagramSequenceNumber = package._datagramSequenceNumber; fullMessage.Reliability = package._reliability; fullMessage.ReliableMessageNumber = package._reliableMessageNumber; fullMessage.OrderingIndex = package._orderingIndex; fullMessage.OrderingChannel = package._orderingChannel; newPackage.Messages = new List <Package>(); newPackage.Messages.Add(fullMessage); Log.Debug($"Assembled split package {newPackage._reliability} message #{newPackage._reliableMessageNumber}, Chan: #{newPackage._orderingChannel}, OrdIdx: #{newPackage._orderingIndex}"); HandleConnectedPackage(playerSession, newPackage); newPackage.PutPool(); } catch (Exception e) { Log.Error("Error during split message parsing", e); if (Log.IsDebugEnabled) { Log.Debug($"0x{buffer[0]:x2}\n{Package.HexDump(buffer)}"); } player.Disconnect("Bad package received from client."); } } }