summaryrefslogtreecommitdiff
path: root/tracker/AdminServer/playerlist.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /tracker/AdminServer/playerlist.cpp
downloadarchived-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.cpp227
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