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.

229 lines
4.5 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 "mapslist.h"
  8. #include "Iresponse.h"
  9. #include "Socket.h"
  10. #include "proto_oob.h"
  11. #include "DialogGameInfo.h"
  12. #include "inetapi.h"
  13. #include "TokenLine.h"
  14. #include "dialogkickplayer.h"
  15. #include <string.h>
  16. extern void v_strncpy(char *dest, const char *src, int bufsize);
  17. typedef enum
  18. {
  19. NONE = 0,
  20. INFO_REQUESTED,
  21. INFO_RECEIVED
  22. } RCONSTATUS;
  23. typedef enum
  24. {
  25. FS,
  26. PAK
  27. } MAP_TYPES;
  28. CMapsList::CMapsList(IResponse *target,serveritem_t &server, const char *rconPassword,const char *mod) {
  29. memcpy(&m_Server, &server,sizeof(serveritem_t));
  30. m_pResponseTarget=target;
  31. if(strcmp(mod,"valve") )
  32. {
  33. v_strncpy(m_sMod,mod,64);
  34. }
  35. else
  36. {
  37. m_sMod[0]=0; // its the "valve" default mod, list all maps
  38. }
  39. m_bIsRefreshing=false;
  40. m_bNewMapsList=false;
  41. m_bRconFailed=false;
  42. v_strncpy(m_szRconPassword,rconPassword,100);
  43. m_pRcon = new CRcon(this , server,rconPassword);
  44. }
  45. CMapsList::~CMapsList() {
  46. delete m_pRcon;
  47. }
  48. //-----------------------------------------------------------------------------
  49. // Purpose: sends a status query packet to a single server
  50. //-----------------------------------------------------------------------------
  51. void CMapsList::SendQuery()
  52. {
  53. m_bIsRefreshing=true;
  54. m_pRcon->SendRcon("maps *");
  55. }
  56. //-----------------------------------------------------------------------------
  57. // Purpose:
  58. //-----------------------------------------------------------------------------
  59. void CMapsList::RunFrame()
  60. {
  61. if(m_pRcon)
  62. {
  63. m_pRcon->RunFrame();
  64. }
  65. }
  66. void CMapsList::ServerResponded()
  67. {
  68. char store[2048];
  69. strcpy(store, m_pRcon->RconResponse());
  70. char *cur=store;
  71. char *next=NULL;
  72. int i=0,k=0;
  73. bool checkDir=false;
  74. // maps format:
  75. // Dir: valve
  76. //-------------
  77. //(fs) rapidcore.bsp
  78. //(fs) frenzy.bsp
  79. //(fs) crossfire.bsp
  80. //
  81. //Dir: valve
  82. //-------------
  83. //(pak) boot_camp.bsp
  84. //(pak) bounce.bsp
  85. m_MapsList.RemoveAll();
  86. char check[21];
  87. _snprintf(check,21,"%s/",m_sMod);
  88. if(strstr(store,check))
  89. { // if the name of the mod dir is in the return list its old style format
  90. checkDir=true;
  91. }
  92. while(cur!=NULL)
  93. {
  94. cur++;
  95. next=strchr(cur,'\n');
  96. if(next!=NULL)
  97. {
  98. *next='\0';
  99. }
  100. if( strncmp(cur,"Dir:",4) && strncmp(cur,"-------------",13) )
  101. {
  102. TokenLine mapsLine;
  103. mapsLine.SetLine(cur);
  104. if(mapsLine.CountToken() >= 2 )
  105. {
  106. char tmpMap[100];
  107. v_strncpy(tmpMap,mapsLine.GetToken(1),100); // type
  108. char *end = strstr(tmpMap,".bsp"); // cull the .bsp
  109. if(end != NULL)
  110. {
  111. *end='\0';
  112. }
  113. if(checkDir==true && strstr(tmpMap,m_sMod)==NULL )
  114. // if the map name doesn't have the mod dir in it
  115. // and its not running the "valve" mod continue
  116. {
  117. cur=next;
  118. continue;
  119. }
  120. if ( strchr(tmpMap,'/') ) // remove the directory part of the map name
  121. {
  122. strcpy(tmpMap,strrchr(tmpMap,'/')+1);
  123. }
  124. for(k=0;k<m_MapsList.Count();k++) // now check it doesn't already exist inside the map list...
  125. {
  126. if(!strncmp(tmpMap,m_MapsList[k].name,strlen(tmpMap)) )
  127. {
  128. break;
  129. }
  130. }
  131. if(k==m_MapsList.Count() // the map wasn't found
  132. && !(tmpMap[0]=='c' && (tmpMap[1]>='1' && tmpMap[1]<='5')) // a heuristic to remove single player maps
  133. && !(tmpMap[0]=='t' && tmpMap[1]=='0') ) // from the list
  134. {
  135. Maps_t map;
  136. // this map wasn't found already
  137. v_strncpy(map.name,tmpMap,strlen(tmpMap)+1);
  138. if( !strcmp("(fs)",mapsLine.GetToken(0)) )
  139. { // name
  140. map.type=FS;
  141. }
  142. else
  143. {
  144. map.type=PAK;
  145. }
  146. m_MapsList.AddToTail(map);
  147. i++;
  148. } // if k == Count
  149. } // CountToken
  150. } // if not a Dir: or "----------"
  151. cur=next;
  152. }
  153. m_bNewMapsList=true;
  154. m_bIsRefreshing=false;
  155. // notify the UI of the new server info
  156. m_pResponseTarget->ServerResponded();
  157. }
  158. void CMapsList::ServerFailedToRespond()
  159. {
  160. // rcon failed
  161. //m_pResponseTarget->ServerFailedToRespond();
  162. }
  163. void CMapsList::Refresh()
  164. {
  165. SendQuery();
  166. }
  167. bool CMapsList::IsRefreshing()
  168. {
  169. return m_bIsRefreshing;
  170. }
  171. serveritem_t &CMapsList::GetServer()
  172. {
  173. return m_Server;
  174. }
  175. bool CMapsList::NewMapsList()
  176. {
  177. return m_bNewMapsList;
  178. }
  179. CUtlVector<Maps_t> *CMapsList::GetMapsList()
  180. {
  181. m_bNewMapsList=false;
  182. return &m_MapsList;
  183. }
  184. void CMapsList::SetPassword(const char *newPass)
  185. {
  186. m_pRcon->SetPassword(newPass);
  187. m_bRconFailed=false;
  188. }