diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /tracker/AdminServer/playerlist.cpp | |
| download | archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip | |
Diffstat (limited to 'tracker/AdminServer/playerlist.cpp')
| -rw-r--r-- | tracker/AdminServer/playerlist.cpp | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/tracker/AdminServer/playerlist.cpp b/tracker/AdminServer/playerlist.cpp new file mode 100644 index 0000000..f710c2a --- /dev/null +++ b/tracker/AdminServer/playerlist.cpp @@ -0,0 +1,227 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: defines a RCon class used to send rcon commands to remote servers +// +// $NoKeywords: $ +//============================================================================= + +#include "playerlist.h" +#include "Iresponse.h" + +#include "PlayerMsgHandler.h" +#include "Socket.h" +#include "proto_oob.h" +#include "DialogGameInfo.h" +#include "inetapi.h" +#include "TokenLine.h" +#include "dialogkickplayer.h" + +extern void v_strncpy(char *dest, const char *src, int bufsize); + +typedef enum +{ + NONE = 0, + INFO_REQUESTED, + INFO_RECEIVED +} RCONSTATUS; + +CPlayerList::CPlayerList(IResponse *target,serveritem_t &server, const char *rconPassword) { + + memcpy(&m_Server, &server,sizeof(serveritem_t)); + m_pResponseTarget=target; + + m_bIsRefreshing=false; + m_bNewPlayerList=false; + m_bRconFailed=false; + + v_strncpy(m_szRconPassword,rconPassword,100); + + m_pRcon = new CRcon(this , server,rconPassword); + m_PlayerList=NULL; + m_pPlayerInfoMsg=NULL; + + m_pQuery = new CSocket("internet player query", -1); + +} + +CPlayerList::~CPlayerList() { + delete m_pQuery; + delete m_pRcon; +} + + +//----------------------------------------------------------------------------- +// Purpose: sends a status query packet to a single server +//----------------------------------------------------------------------------- +void CPlayerList::SendQuery() +{ + CMsgBuffer *buffer = m_pQuery->GetSendBuffer(); + assert( buffer ); + + if ( !buffer ) + { + return; + } + + int bytecode = S2A_PLAYER; + if ( m_pPlayerInfoMsg != NULL ) + { + delete m_pPlayerInfoMsg; + } + m_pPlayerInfoMsg=new CPlayerMsgHandlerDetails(this, &m_PlayerList,CMsgHandler::MSGHANDLER_ALL, &bytecode); + m_pQuery->AddMessageHandler(m_pPlayerInfoMsg); + + m_bIsRefreshing=true; + + netadr_t adr; + + adr.ip[0] = m_Server.ip[0]; + adr.ip[1] = m_Server.ip[1]; + adr.ip[2] = m_Server.ip[2]; + adr.ip[3] = m_Server.ip[3]; + adr.port = (m_Server.port & 0xff) << 8 | (m_Server.port & 0xff00) >> 8; + adr.type = NA_IP; + + // Set state + m_Server.received = (int)INFO_REQUESTED; + + // Create query message + buffer->Clear(); + // Write control sequence + buffer->WriteLong(0xffffffff); + + // Write query string + buffer->WriteString("players"); + + // Sendmessage + m_pQuery->SendMessage( &adr ); + +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPlayerList::RunFrame() +{ + if (m_pQuery && m_bIsRefreshing) + { + m_pQuery->Frame(); + } + if(m_pRcon) + { + m_pRcon->RunFrame(); + } + +} + + +void CPlayerList::ServerResponded() +{ + const char *rconResp = m_pRcon->RconResponse(); + const char *cur = strstr(rconResp,"name userid uniqueid frag time ping loss adr\n") + + strlen("name userid uniqueid frag time ping loss adr\n"); + +// status format: +// # name userid uniqueid frag time ping loss adr +// # 1 "Player" 1 4294967295 0 30:56 22 0 192.168.3.64:27005 + + + for(int i=0;i<m_PlayerList.Count();i++) + { + if(cur!=NULL) + { + TokenLine playerLine; + playerLine.SetLine(cur); + + if(playerLine.CountToken() >= 9 ) + { + // playerLine.GetToken(1); // count + // playerLine.GetToken(2); // player name + // char *player= playerLine.GetToken(2); + + m_PlayerList[i].userid=atoi(playerLine.GetToken(3)); // userid + v_strncpy(m_PlayerList[i].authid,playerLine.GetToken(4),20); // authid + //playerLine.GetToken(5); // frag + // playerLine.GetToken(6); // time + m_PlayerList[i].ping=atoi(playerLine.GetToken(7)); //ping + m_PlayerList[i].loss=atoi(playerLine.GetToken(8)); // loss + // playerLine.GetToken(9); // adr + } + cur=strchr(cur,'\n')+1; + + } + } + + m_bNewPlayerList=true; + m_bIsRefreshing=false; + + // notify the UI of the new server info + m_pResponseTarget->ServerResponded(); + +} + +void CPlayerList::ServerFailedToRespond() +{ + m_bNewPlayerList=true; + m_bIsRefreshing=false; + + if(m_bRconFailed==false) + { + m_bRconFailed=true; + // CDialogKickPlayer *box = new CDialogKickPlayer(); + //box->addActionSignalTarget(this); + // box->Activate("","Bad Rcon Password","badrcon"); + } + + // rcon failed BUT we still have some valid data :) + m_pResponseTarget->ServerResponded(); +} + + +void CPlayerList::UpdateServer() +{ + + m_pQuery->RemoveMessageHandler(m_pPlayerInfoMsg); + // you CANNOT delete this handler because we are inside of it at the moment... (yes, this was an ugly bug) + // delete m_pPlayerInfoMsg; + + // now use "rcon status" to pull extra info about the players + m_pRcon->SendRcon("status"); + +} + +void CPlayerList::Refresh() +{ + SendQuery(); +} + +bool CPlayerList::IsRefreshing() +{ + + return m_bIsRefreshing; +} + +serveritem_t &CPlayerList::GetServer() +{ + return m_Server; +} + + +bool CPlayerList::NewPlayerList() +{ + return m_bNewPlayerList; +} + +CUtlVector<Players_t> *CPlayerList::GetPlayerList() +{ + m_bNewPlayerList=false; + return &m_PlayerList; +} + +void CPlayerList::SetPassword(const char *newPass) +{ + m_pRcon->SetPassword(newPass); + m_bRconFailed=false; +}
\ No newline at end of file |