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
5 years ago
|
//========= 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;
|
||
|
}
|