1
This commit is contained in:
256
tracker/AdminServer/RemoteServer.cpp
Normal file
256
tracker/AdminServer/RemoteServer.cpp
Normal file
@ -0,0 +1,256 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "RemoteServer.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "IGameServerData.h"
|
||||
extern IGameServerData *g_pGameServerData;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: singleton accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
CRemoteServer &RemoteServer()
|
||||
{
|
||||
static CRemoteServer s_RemoteServer;
|
||||
return s_RemoteServer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CRemoteServer::CRemoteServer()
|
||||
{
|
||||
m_iCurrentRequestID = 0;
|
||||
m_ListenerID = INVALID_LISTENER_ID;
|
||||
m_bInitialized = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CRemoteServer::~CRemoteServer()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRemoteServer::Initialize()
|
||||
{
|
||||
m_bInitialized = true;
|
||||
Assert( g_pGameServerData );
|
||||
m_ListenerID = g_pGameServerData->GetNextListenerID( false ); // don't require auth on this connection
|
||||
g_pGameServerData->RegisterAdminUIID( m_ListenerID );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: connects to a remote game server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRemoteServer::ConnectRemoteGameServer(unsigned int ip, unsigned short port, const char *password)
|
||||
{
|
||||
assert(!("CRemoteServer::ConnectRemoteGameServer() not yet implemented"));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: request a cvar/data from the server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRemoteServer::RequestValue(IServerDataResponse *requester, const char *variable)
|
||||
{
|
||||
Assert( m_bInitialized );
|
||||
// add to the response handling table
|
||||
int i = m_ResponseHandlers.AddToTail();
|
||||
m_ResponseHandlers[i].requestID = m_iCurrentRequestID;
|
||||
m_ResponseHandlers[i].handler = requester;
|
||||
|
||||
// build the command
|
||||
char buf[512];
|
||||
CUtlBuffer cmd(buf, sizeof(buf));
|
||||
|
||||
cmd.PutInt(m_iCurrentRequestID++);
|
||||
cmd.PutInt(SERVERDATA_REQUESTVALUE);
|
||||
cmd.PutString(variable);
|
||||
cmd.PutString("");
|
||||
|
||||
// send to server
|
||||
g_pGameServerData->WriteDataRequest(m_ListenerID, cmd.Base(), cmd.TellPut());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets a value
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRemoteServer::SetValue(const char *variable, const char *value)
|
||||
{
|
||||
Assert( m_bInitialized );
|
||||
// build the command
|
||||
char buf[512];
|
||||
CUtlBuffer cmd(buf, sizeof(buf));
|
||||
|
||||
cmd.PutInt(m_iCurrentRequestID++);
|
||||
cmd.PutInt(SERVERDATA_SETVALUE);
|
||||
cmd.PutString(variable);
|
||||
cmd.PutString(value);
|
||||
|
||||
// send to server
|
||||
g_pGameServerData->WriteDataRequest(m_ListenerID, cmd.Base(), cmd.TellPut());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sends a custom command
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRemoteServer::SendCommand(const char *commandString)
|
||||
{
|
||||
Assert( m_bInitialized );
|
||||
// build the command
|
||||
char buf[512];
|
||||
CUtlBuffer cmd(buf, sizeof(buf));
|
||||
|
||||
cmd.PutInt(m_iCurrentRequestID++);
|
||||
cmd.PutInt(SERVERDATA_EXECCOMMAND);
|
||||
cmd.PutString(commandString);
|
||||
cmd.PutString("");
|
||||
|
||||
g_pGameServerData->WriteDataRequest(m_ListenerID, cmd.Base(), cmd.TellPut());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: changes the current password on the server
|
||||
// responds with "PasswordChange" "true" or "PasswordChange" "false"
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRemoteServer::ChangeAccessPassword(IServerDataResponse *requester, const char *newPassword)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: process any return values, firing any IServerDataResponse items
|
||||
// Output : returns true if any items were fired
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRemoteServer::ProcessServerResponse()
|
||||
{
|
||||
Assert(g_pGameServerData != NULL);
|
||||
Assert( m_bInitialized );
|
||||
|
||||
char charbuf[4096];
|
||||
bool bProcessedAnyPackets = false;
|
||||
while (1)
|
||||
{
|
||||
// get packet from networking
|
||||
int bytesRead = g_pGameServerData->ReadDataResponse(m_ListenerID, charbuf, sizeof(charbuf));
|
||||
if (bytesRead < 1)
|
||||
break;
|
||||
bProcessedAnyPackets = true;
|
||||
|
||||
// parse response
|
||||
CUtlBuffer buf(charbuf, bytesRead, CUtlBuffer::READ_ONLY);
|
||||
int requestID = buf.GetInt();
|
||||
int responseType = buf.GetInt();
|
||||
char variable[64];
|
||||
buf.GetString(variable);
|
||||
|
||||
switch (responseType)
|
||||
{
|
||||
case SERVERDATA_RESPONSE_VALUE:
|
||||
{
|
||||
int valueSize = buf.GetInt();
|
||||
Assert(valueSize > 0);
|
||||
CUtlBuffer value(0, valueSize);
|
||||
if (valueSize > 0)
|
||||
{
|
||||
value.Put(buf.PeekGet(), valueSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
// null terminate
|
||||
value.PutChar(0);
|
||||
}
|
||||
|
||||
// find callback (usually will be the first one in the list)
|
||||
for (int i = m_ResponseHandlers.Head(); m_ResponseHandlers.IsValidIndex(i); i = m_ResponseHandlers.Next(i))
|
||||
{
|
||||
if (m_ResponseHandlers[i].requestID == requestID)
|
||||
{
|
||||
// found, call
|
||||
m_ResponseHandlers[i].handler->OnServerDataResponse(variable, (const char *)value.Base());
|
||||
|
||||
// remove from list
|
||||
m_ResponseHandlers.Remove(i);
|
||||
|
||||
// there is only ever one handler for a message
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SERVERDATA_UPDATE:
|
||||
{
|
||||
// find all the people watching for this message
|
||||
for (int i = m_MessageHandlers.Head(); m_MessageHandlers.IsValidIndex(i); i = m_MessageHandlers.Next(i))
|
||||
{
|
||||
if (!stricmp(m_MessageHandlers[i].messageName, variable))
|
||||
{
|
||||
// found, call
|
||||
m_MessageHandlers[i].handler->OnServerDataResponse(variable, "");
|
||||
|
||||
// keep looking, there can be more than one handler for a message
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Assert(responseType == SERVERDATA_RESPONSE_VALUE || responseType == SERVERDATA_UPDATE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return bProcessedAnyPackets;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: adds a constant watches for a particular message
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRemoteServer::AddServerMessageHandler(IServerDataResponse *handler, const char *watch)
|
||||
{
|
||||
// add to the server message handling table
|
||||
int i = m_MessageHandlers.AddToTail();
|
||||
strncpy(m_MessageHandlers[i].messageName, watch, sizeof(m_MessageHandlers[i].messageName) - 1);
|
||||
m_MessageHandlers[i].messageName[sizeof(m_MessageHandlers[i].messageName) - 1] = 0;
|
||||
m_MessageHandlers[i].handler = handler;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: removes a requester from the list to guarantee the pointer won't be used
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRemoteServer::RemoveServerDataResponseTarget(IServerDataResponse *invalidRequester)
|
||||
{
|
||||
// iterate the responses
|
||||
for (int i = 0; i < m_ResponseHandlers.MaxElementIndex(); i++)
|
||||
{
|
||||
if (m_ResponseHandlers.IsValidIndex(i))
|
||||
{
|
||||
if (m_ResponseHandlers[i].handler == invalidRequester)
|
||||
{
|
||||
// found invalid handler, remove from list
|
||||
m_ResponseHandlers.Remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
// iterate the message handlers
|
||||
for (int i = 0; i < m_MessageHandlers.MaxElementIndex(); i++)
|
||||
{
|
||||
if (m_MessageHandlers.IsValidIndex(i))
|
||||
{
|
||||
if (m_MessageHandlers[i].handler == invalidRequester)
|
||||
{
|
||||
// found invalid handler, remove from list
|
||||
m_MessageHandlers.Remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user