private void HandleNak(PlayerNetworkSession session, byte[] receiveBytes) { if (session == null) { return; } Player player = session.Player; if (player == null) { return; } Nak nak = Nak.CreateObject(); nak.Decode(receiveBytes); int ackSeqNo = nak.sequenceNumber.IntValue(); int toAckSeqNo = nak.toSequenceNumber.IntValue(); if (nak.onlyOneSequence == 1) { toAckSeqNo = ackSeqNo; } nak.PutPool(); var queue = session.WaitingForAcksQueue; Log.DebugFormat("NAK from Player {0} ({5}) #{1}-{2} IsOnlyOne {3} Count={4}", player.Username, ackSeqNo, toAckSeqNo, nak.onlyOneSequence, nak.count, player.Rtt); for (int i = ackSeqNo; i <= toAckSeqNo; i++) { session.ErrorCount++; Datagram datagram; if (queue.TryRemove(i, out datagram)) { // RTT = RTT * 0.875 + rtt * 0.125 // RTTVar = RTTVar * 0.875 + abs(RTT - rtt)) * 0.125 // RTO = RTT + 4 * RTTVar long rtt = datagram.Timer.ElapsedMilliseconds; long RTT = player.Rtt; long RTTVar = player.RttVar; player.Rtt = (long)(RTT * 0.875 + rtt * 0.125); player.RttVar = (long)(RTTVar * 0.875 + Math.Abs(RTT - rtt) * 0.125); player.Rto = player.Rtt + 4 * player.RttVar + 10; // SYNC time in the end SendDatagram(session, datagram); } else { Log.DebugFormat("NAK, no datagram #{0} to resend for {1}", i, player.Username); } } }
private void HandleNak(byte[] receiveBytes, IPEndPoint senderEndpoint) { PlayerNetworkSession session; if (!_playerSessions.TryGetValue(senderEndpoint, out session)) { return; } Nak nak = Nak.CreateObject(); nak.Decode(receiveBytes); int ackSeqNo = nak.sequenceNumber.IntValue(); int toAckSeqNo = nak.toSequenceNumber.IntValue(); if (nak.onlyOneSequence == 1) { toAckSeqNo = ackSeqNo; } nak.PutPool(); var queue = session.WaitingForAcksQueue; Log.WarnFormat("NAK from Player {0} ({5}) #{1}-{2} IsOnlyOne {3} Count={4}", session.Player.Username, ackSeqNo, toAckSeqNo, nak.onlyOneSequence, nak.count, session.Player.Rtt); for (int i = ackSeqNo; i <= toAckSeqNo; i++) { session.ErrorCount++; Datagram datagram; if (queue.TryRemove(i, out datagram)) { // RTT = RTT * 0.875 + rtt * 0.125 // RTTVar = RTTVar * 0.875 + abs(RTT - rtt)) * 0.125 // RTO = RTT + 4 * RTTVar long rtt = datagram.Timer.ElapsedMilliseconds; if (rtt > session.Player.Rto) { Log.WarnFormat("RTT bigger !!!!!!"); } long RTT = session.Player.Rtt; long RTTVar = session.Player.RttVar; session.Player.Rtt = (long)(RTT * 0.875 + rtt * 0.125); session.Player.RttVar = (long)(RTTVar * 0.875 + Math.Abs(RTT - rtt) * 0.125); session.Player.Rto = session.Player.Rtt + 4 * session.Player.RttVar + 10; // SYNC time in the end ThreadPool.QueueUserWorkItem(delegate(object data) { SendDatagram(senderEndpoint, (Datagram)data); }, datagram); } else { Log.WarnFormat("No datagram #{0} to resend for {1}", i, session.Player.Username); } } }
private void HandleNak(PlayerNetworkSession session, byte[] receiveBytes) { if (session == null) return; Player player = session.Player; if (player == null) return; Nak nak = Nak.CreateObject(); nak.Reset(); nak.Decode(receiveBytes); var queue = session.WaitingForAcksQueue; foreach (Tuple<int, int> range in nak.ranges) { ServerInfo.NumberOfNakReceive++; int start = range.Item1; int end = range.Item2; for (int i = start; i <= end; i++) { session.ErrorCount++; // HACK: Just to make sure we aren't getting unessecary load on the queue during heavy buffering. if (ServerInfo.AvailableBytes > 1000) continue; Datagram datagram; if (queue.TryGetValue(i, out datagram)) { // RTT = RTT * 0.875 + rtt * 0.125 // RTTVar = RTTVar * 0.875 + abs(RTT - rtt)) * 0.125 // RTO = RTT + 4 * RTTVar long rtt = datagram.Timer.ElapsedMilliseconds; long RTT = player.Rtt; long RTTVar = player.RttVar; player.Rtt = (long) (RTT*0.875 + rtt*0.125); player.RttVar = (long) (RTTVar*0.875 + Math.Abs(RTT - rtt)*0.125); player.Rto = player.Rtt + 4*player.RttVar + 100; // SYNC time in the end //if (Log.IsDebugEnabled) // Log.ErrorFormat("NAK, resending datagram #{0} for {1}, MTU: {2}", i, player.Username, session.Mtuize); //SendDatagram(session, datagram, false); } else { if (Log.IsDebugEnabled) //Log.WarnFormat("NAK, no datagram #{0} to resend for {1}", i, player.Username); } } } nak.PutPool(); }
private void HandleNak(PlayerNetworkSession session, byte[] receiveBytes) { if (session == null) { return; } Nak nak = Nak.CreateObject(); nak.Reset(); nak.Decode(receiveBytes); var queue = session.WaitingForAcksQueue; foreach (Tuple <int, int> range in nak.ranges) { Interlocked.Increment(ref ServerInfo.NumberOfNakReceive); int start = range.Item1; int end = range.Item2; for (int i = start; i <= end; i++) { if (queue.TryGetValue(i, out var datagram)) { CalculateRto(session, datagram); datagram.RetransmitImmediate = true; } else { if (Log.IsDebugEnabled) { Log.WarnFormat("NAK, no datagram #{0} for {1}", i, session.Username); } } } } nak.PutPool(); }
private void HandleNak(PlayerNetworkSession session, byte[] receiveBytes) { if (session == null) { return; } Nak nak = Nak.CreateObject(); nak.Reset(); nak.Decode(receiveBytes); var queue = session.WaitingForAcksQueue; foreach (Tuple <int, int> range in nak.ranges) { Interlocked.Increment(ref ServerInfo.NumberOfNakReceive); int start = range.Item1; int end = range.Item2; for (int i = start; i <= end; i++) { session.ErrorCount++; // HACK: Just to make sure we aren't getting unessecary load on the queue during heavy buffering. //if (ServerInfo.AvailableBytes > 1000) continue; Datagram datagram; //if (queue.TryRemove(i, out datagram)) if (!session.Evicted && queue.TryRemove(i, out datagram)) { // RTT = RTT * 0.875 + rtt * 0.125 // RTTVar = RTTVar * 0.875 + abs(RTT - rtt)) * 0.125 // RTO = RTT + 4 * RTTVar long rtt = datagram.Timer.ElapsedMilliseconds; long RTT = session.Rtt; long RTTVar = session.RttVar; session.Rtt = (long)(RTT * 0.875 + rtt * 0.125); session.RttVar = (long)(RTTVar * 0.875 + Math.Abs(RTT - rtt) * 0.125); session.Rto = session.Rtt + 4 * session.RttVar + 100; // SYNC time in the end FastThreadPool.QueueUserWorkItem(delegate { var dgram = (Datagram)datagram; if (Log.IsDebugEnabled) { Log.WarnFormat("NAK, resent datagram #{0} for {1}", dgram.Header.datagramSequenceNumber, session.Username); } SendDatagram(session, dgram); Interlocked.Increment(ref ServerInfo.NumberOfResends); }); } else { if (Log.IsDebugEnabled) { Log.WarnFormat("NAK, no datagram #{0} for {1}", i, session.Username); } } } } nak.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) { 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 <= (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) { //_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"); } } }
/// <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"); } } }