Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
3.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: defines a RCon class used to send rcon commands to remote servers
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include "serverinfo.h"
  8. #include "Iresponse.h"
  9. #include "ServerInfoMsgHandler.h"
  10. #include "Socket.h"
  11. #include "proto_oob.h"
  12. #include "DialogGameInfo.h"
  13. extern void v_strncpy(char *dest, const char *src, int bufsize);
  14. namespace
  15. {
  16. const float SERVER_TIMEOUT =5.0f; // timeout before failing
  17. }
  18. typedef enum
  19. {
  20. NONE = 0,
  21. INFO_REQUESTED,
  22. INFO_RECEIVED
  23. } RCONSTATUS;
  24. CServerInfo::CServerInfo(IResponse *target,serveritem_t &server) {
  25. memcpy(&m_Server, &server,sizeof(serveritem_t));
  26. m_pResponseTarget=target;
  27. m_bIsRefreshing=false;
  28. int bytecode = S2A_INFO_DETAILED;
  29. m_pQuery = new CSocket("internet server query", -1);
  30. m_pQuery->AddMessageHandler(new CServerInfoMsgHandlerDetails(this, CMsgHandler::MSGHANDLER_ALL, &bytecode));
  31. m_fSendTime= 0;
  32. }
  33. CServerInfo::~CServerInfo() {
  34. delete m_pQuery;
  35. }
  36. //-----------------------------------------------------------------------------
  37. // Purpose: sends a status query packet to a single server
  38. //-----------------------------------------------------------------------------
  39. void CServerInfo::Query()
  40. {
  41. CMsgBuffer *buffer = m_pQuery->GetSendBuffer();
  42. assert( buffer );
  43. if ( !buffer )
  44. {
  45. return;
  46. }
  47. m_bIsRefreshing=true;
  48. m_bRefreshed=false;
  49. netadr_t adr;
  50. adr.ip[0] = m_Server.ip[0];
  51. adr.ip[1] = m_Server.ip[1];
  52. adr.ip[2] = m_Server.ip[2];
  53. adr.ip[3] = m_Server.ip[3];
  54. adr.port = (m_Server.port & 0xff) << 8 | (m_Server.port & 0xff00) >> 8;
  55. adr.type = NA_IP;
  56. // Set state
  57. m_Server.received = (int)INFO_REQUESTED;
  58. // Create query message
  59. buffer->Clear();
  60. // Write control sequence
  61. buffer->WriteLong(0xffffffff);
  62. // Write query string
  63. buffer->WriteString("infostring");
  64. // Sendmessage
  65. m_pQuery->SendMessage( &adr );
  66. m_fSendTime = CSocket::GetClock();
  67. }
  68. //-----------------------------------------------------------------------------
  69. // Purpose:
  70. //-----------------------------------------------------------------------------
  71. void CServerInfo::RunFrame()
  72. {
  73. float curtime = CSocket::GetClock();
  74. if(m_fSendTime!=0 && (curtime-m_fSendTime)> 5.0f) // 10 seconds timeout
  75. {
  76. m_fSendTime = 0;
  77. m_pResponseTarget->ServerFailedToRespond();
  78. }
  79. if (m_pQuery)
  80. {
  81. m_pQuery->Frame();
  82. }
  83. }
  84. void CServerInfo::UpdateServer(netadr_t *adr, bool proxy, const char *serverName, const char *map,
  85. const char *gamedir, const char *gameDescription, int players,
  86. int maxPlayers, float recvTime, bool password)
  87. {
  88. m_Server.received = INFO_RECEIVED;
  89. m_Server.hadSuccessfulResponse = true;
  90. // copy in data necessary for filters
  91. v_strncpy(m_Server.gameDir, gamedir, sizeof(m_Server.gameDir) - 1);
  92. v_strncpy(m_Server.map, map, sizeof(m_Server.map) - 1);
  93. v_strncpy(m_Server.name, serverName, sizeof(m_Server.name) - 1);
  94. v_strncpy(m_Server.gameDescription, gameDescription, sizeof(m_Server.gameDescription) - 1);
  95. m_Server.players = players;
  96. m_Server.maxPlayers = maxPlayers;
  97. m_Server.proxy = proxy;
  98. m_Server.password = password;
  99. int ping = (int)((recvTime - m_fSendTime) * 1000);
  100. if (ping > 3000 || ping < 0)
  101. {
  102. // make sure ping is valid
  103. ping = 1200;
  104. }
  105. // add to ping times list
  106. // server.pings[0] = server.pings[1];
  107. // server.pings[1] = server.pings[2];
  108. // server.pings[2] = ping;
  109. // calculate ping
  110. // ping = CalculateAveragePing(server);
  111. m_Server.ping = ping;
  112. m_bIsRefreshing=false;
  113. m_bRefreshed=true;
  114. m_fSendTime = 0;
  115. // notify the UI of the new server info
  116. m_pResponseTarget->ServerResponded();
  117. }
  118. void CServerInfo::Refresh()
  119. {
  120. Query();
  121. }
  122. bool CServerInfo::IsRefreshing()
  123. {
  124. return m_bIsRefreshing;
  125. }
  126. serveritem_t &CServerInfo::GetServer()
  127. {
  128. return m_Server;
  129. }
  130. bool CServerInfo::Refreshed()
  131. {
  132. bool val = m_bRefreshed;
  133. m_bRefreshed=false;
  134. return val;
  135. }