/// <summary> /// Callback from the Server object when a heartbeat is received /// </summary> /// <param name="heartbeatType">Type of heartbeat which was received</param> /// <param name="code">Heartbeat code, we shouldn't need to check this since the /// ServerList shouldn't call the function if the code doesn't match</param> /// <param name="port">Port from which the heartbeat was received</param> public virtual void HandleHeartBeat(HeartbeatType heartbeatType, int code, int port) { ConnectionLog("HEARTBEAT TYPE={0} CODE={1} PORT={2} WAITING={3}", heartbeatType, code, port, waitingHearbeats.Count); if (State == ConnectionState.WaitingHeartbeat) { waitingHearbeats.Remove(heartbeatType); if (ping == 0) { ping = (DateTime.Now - waitingHeartbeatTime).TotalMilliseconds; } if (waitingHearbeats.Count == 0) { // To start with I thought the first number in the heartbeat reply was the ping to the // master server, but it seems to always be 120 so I'm not really sure what it actually // means. Different values don't seem to make any difference. SendHeartbeatAcknowledgment(Protocol.HEARTBEAT_COMPLETE_UNKNOWN); //SendHeartbeatAcknowledgment((int)ping); State = ConnectionState.Established; // Begin the server query process server.HeartbeatResponseComplete(); // Assign the match ID SendMatchID(); } } }
/// <summary> /// Called when the heartbeat listener receives a heartbeat packet from this server /// </summary> /// <remarks> /// Code is matched against this server before this function will be called so there is no /// requirement to check the code matches the server's heartbeat code, although it may be /// a good idea to do so in case a bad code gets passed for some reason. /// </remarks> /// <param name="heartbeatType">Type of heartbeat packet which was received</param> /// <param name="code">Code which was received</param> /// <param name="port">Outgoing port from which the heartbeat packet was received</param> public void HandleReceivedHeartBeat(HeartbeatType heartbeatType, int code, int port) { switch (heartbeatType) { case HeartbeatType.QueryInterface: if (!ServerBehindNAT) { queryPort = (ushort)port; } break; case HeartbeatType.GamePort: Port = port; break; case HeartbeatType.GamespyQueryPort: GamespyQueryPort = port; break; } if (Connection != null) { Connection.HandleHeartBeat(heartbeatType, code, port); } }
public Heartbeat GetHeartbeat(HeartbeatType type) { return(new Heartbeat() { Descriptor = GetDescriptor(), Type = type }); }
/// <summary> /// Raise the heartbeat received event /// </summary> /// <param name="heartbeatType">Type of heartbeat that was received</param> /// <param name="heartbeatCode">Heartbeat code</param> /// <param name="port">Remote port the heartbeat was received from</param> private void OnReceivedHeartbeat(HeartbeatType heartbeatType, int heartbeatCode, int port) { ReceivedHeartbeatHandler receivedHeartbeat = this.ReceivedHeartbeat; if (receivedHeartbeat != null) { receivedHeartbeat(heartbeatType, heartbeatCode, port); } }
/// <summary> /// Called when the heartbeat listener receives a valid heartbeat packet. Attempts to match the /// heartbeat's code to a server in the list and notifies the server object if a match is found. /// </summary> /// <param name="heartbeatType">Type of heartbeat packet which was received</param> /// <param name="heartbeatCode">Code embedded in the heartbeat packet</param> /// <param name="port">UDP port from which the heartbeat packet was received</param> public void ReceivedHeartbeat(HeartbeatType heartbeatType, int heartbeatCode, int port) { lock (serverListLock) { // Look for a matching server and send the heartbeat if we find one foreach (Server server in servers) { if (server.HeartbeatCode == heartbeatCode) { server.HandleReceivedHeartBeat(heartbeatType, heartbeatCode, port); return; } } } }
/// <summary> /// Master server requests heartbeat blah with code blah /// </summary> /// <param name="type">Type of heartbeat to request</param> /// <param name="code">Heartbeat code to request</param> protected virtual void SendHeartbeatRequest(HeartbeatType type, int code) { if (State == ConnectionState.WaitingHello) { OutboundPacket HeartbeatPacket = new OutboundPacket(); HeartbeatPacket.Append(Protocol.HEARTBEAT_CMD); HeartbeatPacket.Append((byte)type); HeartbeatPacket.Append(code); waitingHearbeats.Add(type); Send(HeartbeatPacket); } }
/// <summary> /// Thread function for listening for inbound heartbeats /// </summary> private void ListenThreadProc() { while (!aborted) { try { UDPPacket packet = Receive(udpClient); if (packet.Valid) { if (packet.Version == Protocol.UDP_PROTOCOL_VERSION) { HeartbeatType heartbeatType = (HeartbeatType)packet.PopByte(); int heartbeatCode = packet.PopInt(); // Raise the heartbeat received event OnReceivedHeartbeat(heartbeatType, heartbeatCode, packet.RemoteEndpoint.Port); } else { // MasterServer.Log("[NET] Packet with bad version on heartbeat port: Version={0}", packet.Version); System.Diagnostics.Debug.WriteLine(String.Format("[NET] Packet with bad version on heartbeat port: Version={0}", packet.Version)); } } else { System.Diagnostics.Debug.WriteLine("[NET] Unknown UDP data on heartbeat port"); } } catch (ThreadAbortException) { aborted = true; } catch (Exception) { //MasterServer.Log("Heartbeat listener caught exception: {0}", ex.Message); } } }