/// <summary> /// Handle the network's packets. /// </summary> /// <param name="packet">The packet to handle.</param> private void HandleDefaultPackets(Packet packet) { if (packet.GetType().Equals(typeof(PingRequest))) { Send(new PingResponse()); return; } else if (packet.GetType().Equals(typeof(PingResponse))) { long elapsedTime = currentPingStopWatch.ElapsedMilliseconds; currentPingStopWatch.Reset(); nextPingStopWatch.Restart(); Ping = elapsedTime / 2; RTT = elapsedTime; return; } else if (packet.GetType().Equals(typeof(CloseRequest))) { CloseRequest closeRequest = (CloseRequest)packet; readStreamThread.Abort(); writeStreamThread.Abort(); connectionClosed?.Invoke(closeRequest.CloseReason, this); invokePacketThread.Abort(); CloseSocket(); return; } else if (packet.GetType().Equals(typeof(EstablishUdpRequest))) { EstablishUdpRequest establishUdpRequest = (EstablishUdpRequest)packet; IPEndPoint udpEndPoint = new IPEndPoint(IPAddress.Any, GetFreePort()); Send(new EstablishUdpResponse(udpEndPoint.Port)); UdpConnection udpConnection = new UdpConnection(new UdpClient(udpEndPoint), new IPEndPoint(IPRemoteEndPoint.Address, establishUdpRequest.UdpPort), true); pendingUDPConnections.Enqueue(udpConnection); connectionEstablished?.Invoke((TcpConnection)this, udpConnection); return; } else if (packet.GetType().Equals(typeof(EstablishUdpResponseACK))) { UdpConnection udpConnection = null; while (!pendingUDPConnections.TryDequeue(out udpConnection)) { Thread.Sleep(CPU_SAVE); } udpConnection.WriteLock = false; return; } if (!packetHandler.ContainsKey(packet.GetType())) { CloseHandler(CloseReason.UnknownPacket); return; } packetHandler[packet.GetType()].Invoke(packet, this); }
/// <summary> Handles all default <see cref="Packet"/> s that are in the library. </summary> /// <param name="packet"> The <see cref="Packet"/> to be handled. </param> private void HandleDefaultPackets(Packet packet) { if (packet.GetType().Equals(typeof(PingRequest))) { Send(new PingResponse()); return; } else if (packet.GetType().Equals(typeof(PingResponse))) { long elapsedTime = currentPingStopWatch.ElapsedMilliseconds; currentPingStopWatch.Reset(); nextPingStopWatch.Restart(); Ping = elapsedTime / 2; RTT = elapsedTime; return; } else if (packet.GetType().Equals(typeof(CloseRequest))) { CloseRequest closeRequest = (CloseRequest)packet; ExternalClose(closeRequest.CloseReason); return; } else if (packet.GetType().Equals(typeof(EstablishUdpRequest))) { EstablishUdpRequest establishUdpRequest = (EstablishUdpRequest)packet; IPEndPoint udpEndPoint = new IPEndPoint(IPLocalEndPoint.Address, GetFreePort()); Send(new EstablishUdpResponse(udpEndPoint.Port, establishUdpRequest)); UdpConnection udpConnection = CreateUdpConnection(udpEndPoint, new IPEndPoint(IPRemoteEndPoint.Address, establishUdpRequest.UdpPort), true); pendingUDPConnections.Enqueue(udpConnection); connectionEstablished?.Invoke((TcpConnection)this, udpConnection); return; } else if (packet.GetType().Equals(typeof(EstablishUdpResponseACK))) { UdpConnection udpConnection = null; while (!pendingUDPConnections.TryDequeue(out udpConnection)) { Thread.Sleep(IntPerformance); } udpConnection.AcknowledgePending = false; return; } else if (packet.GetType().Equals(typeof(AddPacketTypeRequest))) { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().Where(a => a.FullName == ((AddPacketTypeRequest)packet).AssemblyName).SingleOrDefault(); if (assembly == null) { CloseHandler(CloseReason.AssemblyDoesNotExist); } else { AddExternalPackets(assembly); } Send(new AddPacketTypeResponse(typeByte.Values.ToList(), (AddPacketTypeRequest)packet)); return; } else if (packet.GetType().Equals(typeof(AddPacketTypeResponse))) { List <Tuple <Packet, object> > internalSendQueue = new List <Tuple <Packet, object> >(); AddPacketTypeResponse addPacketTypeResponse = (AddPacketTypeResponse)packet; //Remove all packets of this type and send them :) while (true) { Tuple <Packet, object> toSend = null; while (!pendingUnknownPackets.TryPeek(out toSend) && pendingUnknownPackets.Count > 0) { Thread.Sleep(IntPerformance); //Wait till we got a result. } //If the other connection contains that packet, send it. if (toSend != null && addPacketTypeResponse.LocalDict.Contains(typeByte[toSend.Item1.GetType()])) { while (!pendingUnknownPackets.TryDequeue(out toSend)) { Thread.Sleep(IntPerformance); //Wait till we got a result. } internalSendQueue.Add(new Tuple <Packet, object>(toSend.Item1, toSend.Item2)); continue; } //Now the pendingUnknownPackets queue doesn't contain those elements any more. internalSendQueue.ForEach(i => Send(i.Item1, i.Item2)); return; } } //Receiving raw data from the connection. else if (packet.GetType().Equals(typeof(RawData))) { RawData rawData = (RawData)packet; if (packetHandlerMap[rawData.Key] == null) { Logger.Log($"RawData packet has no listener. Key: {rawData.Key}", LogLevel.Warning); } else { packetHandlerMap[rawData.Key].DynamicInvoke(new object[] { packet, this }); } return; } try { if (packet.GetType().IsSubclassOf(typeof(ResponsePacket)) && packetHandlerMap[packet.ID] != null) { packetHandlerMap[packet.ID].DynamicInvoke(new object[] { packet, this }); } else if (packetHandlerMap[packet.GetType()] != null) { packetHandlerMap[packet.GetType()].DynamicInvoke(new object[] { packet, this }); } else { PacketWithoutHandlerReceived(packet); } } catch (Exception exception) { Logger.Log("Provided delegate contains a bug. Packet invocation thread crashed.", exception, LogLevel.Exception); } }