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.
230 lines
4.5 KiB
230 lines
4.5 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: defines a RCon class used to send rcon commands to remote servers |
|
// |
|
// $NoKeywords: $ |
|
//============================================================================= |
|
|
|
#include "mapslist.h" |
|
#include "Iresponse.h" |
|
|
|
#include "Socket.h" |
|
#include "proto_oob.h" |
|
#include "DialogGameInfo.h" |
|
#include "inetapi.h" |
|
#include "TokenLine.h" |
|
#include "dialogkickplayer.h" |
|
#include <string.h> |
|
|
|
extern void v_strncpy(char *dest, const char *src, int bufsize); |
|
|
|
typedef enum |
|
{ |
|
NONE = 0, |
|
INFO_REQUESTED, |
|
INFO_RECEIVED |
|
} RCONSTATUS; |
|
|
|
|
|
typedef enum |
|
{ |
|
FS, |
|
PAK |
|
} MAP_TYPES; |
|
|
|
CMapsList::CMapsList(IResponse *target,serveritem_t &server, const char *rconPassword,const char *mod) { |
|
|
|
memcpy(&m_Server, &server,sizeof(serveritem_t)); |
|
m_pResponseTarget=target; |
|
|
|
if(strcmp(mod,"valve") ) |
|
{ |
|
v_strncpy(m_sMod,mod,64); |
|
} |
|
else |
|
{ |
|
m_sMod[0]=0; // its the "valve" default mod, list all maps |
|
} |
|
|
|
m_bIsRefreshing=false; |
|
m_bNewMapsList=false; |
|
m_bRconFailed=false; |
|
|
|
v_strncpy(m_szRconPassword,rconPassword,100); |
|
|
|
m_pRcon = new CRcon(this , server,rconPassword); |
|
} |
|
|
|
CMapsList::~CMapsList() { |
|
delete m_pRcon; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: sends a status query packet to a single server |
|
//----------------------------------------------------------------------------- |
|
void CMapsList::SendQuery() |
|
{ |
|
m_bIsRefreshing=true; |
|
m_pRcon->SendRcon("maps *"); |
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CMapsList::RunFrame() |
|
{ |
|
if(m_pRcon) |
|
{ |
|
m_pRcon->RunFrame(); |
|
} |
|
} |
|
|
|
|
|
void CMapsList::ServerResponded() |
|
{ |
|
char store[2048]; |
|
strcpy(store, m_pRcon->RconResponse()); |
|
char *cur=store; |
|
char *next=NULL; |
|
int i=0,k=0; |
|
bool checkDir=false; |
|
|
|
// maps format: |
|
// Dir: valve |
|
//------------- |
|
//(fs) rapidcore.bsp |
|
//(fs) frenzy.bsp |
|
//(fs) crossfire.bsp |
|
// |
|
//Dir: valve |
|
//------------- |
|
//(pak) boot_camp.bsp |
|
//(pak) bounce.bsp |
|
|
|
m_MapsList.RemoveAll(); |
|
|
|
char check[21]; |
|
_snprintf(check,21,"%s/",m_sMod); |
|
if(strstr(store,check)) |
|
{ // if the name of the mod dir is in the return list its old style format |
|
checkDir=true; |
|
} |
|
|
|
|
|
while(cur!=NULL) |
|
{ |
|
cur++; |
|
next=strchr(cur,'\n'); |
|
if(next!=NULL) |
|
{ |
|
*next='\0'; |
|
} |
|
|
|
if( strncmp(cur,"Dir:",4) && strncmp(cur,"-------------",13) ) |
|
{ |
|
TokenLine mapsLine; |
|
mapsLine.SetLine(cur); |
|
|
|
if(mapsLine.CountToken() >= 2 ) |
|
{ |
|
char tmpMap[100]; |
|
v_strncpy(tmpMap,mapsLine.GetToken(1),100); // type |
|
char *end = strstr(tmpMap,".bsp"); // cull the .bsp |
|
if(end != NULL) |
|
{ |
|
*end='\0'; |
|
} |
|
if(checkDir==true && strstr(tmpMap,m_sMod)==NULL ) |
|
// if the map name doesn't have the mod dir in it |
|
// and its not running the "valve" mod continue |
|
{ |
|
cur=next; |
|
continue; |
|
} |
|
|
|
if ( strchr(tmpMap,'/') ) // remove the directory part of the map name |
|
{ |
|
strcpy(tmpMap,strrchr(tmpMap,'/')+1); |
|
} |
|
|
|
for(k=0;k<m_MapsList.Count();k++) // now check it doesn't already exist inside the map list... |
|
{ |
|
if(!strncmp(tmpMap,m_MapsList[k].name,strlen(tmpMap)) ) |
|
{ |
|
break; |
|
} |
|
} |
|
if(k==m_MapsList.Count() // the map wasn't found |
|
&& !(tmpMap[0]=='c' && (tmpMap[1]>='1' && tmpMap[1]<='5')) // a heuristic to remove single player maps |
|
&& !(tmpMap[0]=='t' && tmpMap[1]=='0') ) // from the list |
|
{ |
|
Maps_t map; |
|
// this map wasn't found already |
|
v_strncpy(map.name,tmpMap,strlen(tmpMap)+1); |
|
if( !strcmp("(fs)",mapsLine.GetToken(0)) ) |
|
{ // name |
|
map.type=FS; |
|
} |
|
else |
|
{ |
|
map.type=PAK; |
|
} |
|
m_MapsList.AddToTail(map); |
|
i++; |
|
} // if k == Count |
|
|
|
} // CountToken |
|
} // if not a Dir: or "----------" |
|
cur=next; |
|
} |
|
|
|
m_bNewMapsList=true; |
|
m_bIsRefreshing=false; |
|
|
|
// notify the UI of the new server info |
|
m_pResponseTarget->ServerResponded(); |
|
|
|
} |
|
|
|
void CMapsList::ServerFailedToRespond() |
|
{ |
|
// rcon failed |
|
//m_pResponseTarget->ServerFailedToRespond(); |
|
} |
|
|
|
void CMapsList::Refresh() |
|
{ |
|
SendQuery(); |
|
} |
|
|
|
bool CMapsList::IsRefreshing() |
|
{ |
|
|
|
return m_bIsRefreshing; |
|
} |
|
|
|
serveritem_t &CMapsList::GetServer() |
|
{ |
|
return m_Server; |
|
} |
|
|
|
|
|
bool CMapsList::NewMapsList() |
|
{ |
|
return m_bNewMapsList; |
|
} |
|
|
|
CUtlVector<Maps_t> *CMapsList::GetMapsList() |
|
{ |
|
m_bNewMapsList=false; |
|
return &m_MapsList; |
|
} |
|
|
|
void CMapsList::SetPassword(const char *newPass) |
|
{ |
|
m_pRcon->SetPassword(newPass); |
|
m_bRconFailed=false; |
|
} |