#include "pureclient.h"
SimpleQueue<EVENT_STRUCT> PureClient::_eventQueue[127];
unsigned int PureClient::_arg[8] = {0x00};
PureClient::~PureClient()
{
// destroy hooks
for(int i = 0; i < eEND; i++)
delete _HookTable[i];
}
void PureClient::Init(void)
{
// hooks
_HookTable[ePLAYERPSCWRITEPACKET] =
new x86Hook(&PlayerPSCWritePacket, 0x482E37, 1);
_HookTable[ePLAYERPSCREADPACKET] =
new x86Hook(&PlayerPSCReadPacket, 0x4854CB, 1);
// register net events
NetEventFactory::template registerEvent<SetHashEvent>(EVENT_SETHASH);
NetEventFactory::template registerEvent<ByteEvent>(EVENT_GETBYTE);
NetEventFactory::template registerEvent<WordEvent>(EVENT_GETWORD);
NetEventFactory::template registerEvent<DWordEvent>(EVENT_GETDWORD);
NetEventFactory::template registerEvent<EvalEvent>(EVENT_EVAL);
// Set Version
Tribes::SetVersion(PURECLIENT_VERSION);
Console::AddPluginCommand(this, 0, "t");
}
// t(2049, 2, 0x12345, 0x401000);
const char *PureClient::consoleCallback(void*,int id,int argc,const char *argv[])
{
if(argc < 2)
return TRIBES_FALSE;
switch(id)
{
case 0:
NetEvent *evt;
EVENT_STRUCT netEvent;
unsigned int clientIndex,
eventId = 0;
// client index
clientIndex = getClientIndex(atoi(argv[1]));
if(clientIndex > 127 || clientIndex < 1)
{
Log("PCError - Bad Client Index ( %d )", clientIndex);
return TRIBES_FALSE;
}
// delated process?
netEvent.arg = NULL;
eventId = atoi(argv[2]);
switch(eventId)
{
// GETBYTE & SETHASH
// ----------------------------------------------------------------------
case EVENT_SETHASH:
case EVENT_GETBYTE:
case EVENT_GETWORD:
case EVENT_GETDWORD:
if(argc < 5)
return TRIBES_FALSE;
evt = NetEventFactory::getEventById(eventId);
if(evt)
netEvent.arg = (void*)atoi(argv[4]);
break;
// EVAL
// ----------------------------------------------------------------------
case EVENT_EVAL:
if(argc < 5)
return TRIBES_FALSE;
evt = NetEventFactory::getEventById(EVENT_EVAL);
if(evt)
{
netEvent.arg = new char[255];
char *pRequest = (char*)netEvent.arg;
strncpy(pRequest, argv[4], 255);
pRequest[255] = 0x00;
}
break;
// GUID
// ----------------------------------------------------------------------
case EVENT_GUID:
if(argc < 3)
return TRIBES_FALSE;
evt = NetEventFactory::getEventById(EVENT_GUID);
break;
default:
return TRIBES_FALSE;
}
if(!evt)
return TRIBES_FALSE;
netEvent.eventId = eventId;
netEvent.key = atoi(argv[3]);
_eventQueue[clientIndex].push(netEvent);
break;
}
return TRIBES_TRUE;
}
// PlayerPSCWritePacket - writes request/response to packetstream
// ----------------------------------------------------------------------------
__x86Hook PureClient::PlayerPSCWritePacket(CpuState &cs)
{
Bitstream *pStream = (Bitstream*)(cs.reg.esp+0x8C);
bool isServer = !(bool)cs.eflag.zf;
EVENT_STRUCT cEvt = {0x00};
int eventId = 0;
if(isServer)
{
int clientIndex, clientId;
// client
clientId = *(int*)(cs.reg.ebp+0x54);
clientId = *(int*)(clientId + 0x44);
clientIndex = getClientIndex(clientId);
if(clientIndex > 127 || clientIndex < 1)
return;
if(!_eventQueue[clientIndex].isEmpty())
{
cEvt = _eventQueue[clientIndex].front();
_eventQueue[clientIndex].pop();
}
BitStream::WriteInt(pStream, cEvt.eventId, 5);
if(cEvt.eventId)
{
BitStream::WriteInt(pStream, cEvt.key, 32);
NetEvent *evt = NetEventFactory::getEventById(cEvt.eventId);
if(evt)
{
// delayed processes
//if(cEvt.OLDarg[0] != NULL)
// evt->process((void*)cEvt.arg, (void*)0xFF);
if(cEvt.arg)
evt->process(cEvt.arg, (void*)0xFF);
evt->pack(&cEvt, pStream, isServer);
}
}
}
else
{
// eventqueue 0 for client
if(!_eventQueue[0].isEmpty())
{
cEvt = _eventQueue[0].front();
_eventQueue[0].pop();
}
BitStream::WriteInt(pStream, cEvt.eventId, 5);
if(cEvt.eventId)
{
BitStream::WriteInt(pStream, cEvt.key, 32);
NetEvent *evt = NetEventFactory::getEventById(cEvt.eventId);
if(evt)
evt->pack(&cEvt, pStream, isServer);
}
}
}
// PlayerPSCReadPacket - reads request/response to packetstream
// ----------------------------------------------------------------------------
__x86Hook PureClient::PlayerPSCReadPacket(CpuState &cs)
{
bool isServer;
int clientId;
EVENT_STRUCT cEvt;
Bitstream *pStream;
clientId = *(int*)(cs.reg.edi + 0x44);
pStream = (Bitstream*)(cs.reg.ebp);
isServer = !(bool)cs.eflag.zf;
cEvt.eventId = BitStream::ReadInt(pStream, 5);
if(!cEvt.eventId)
return;
cEvt.key = BitStream::ReadInt(pStream, 32);
NetEvent *evt = NetEventFactory::getEventById(cEvt.eventId);
if(evt)
{
evt->unpack(clientId, &cEvt, pStream, isServer);
if(!isServer)
_eventQueue[0].push(cEvt);
}
}
void PureClient::Log(const char *pFmt, ...)
{
#ifdef PURECLIENT_LOG
char buf[1024];
va_list arglist;
va_start(arglist, pFmt);
_vsnprintf(buf, 1023, pFmt, arglist);
va_end(arglist);
Console::Echo(1, "%s", buf);
#endif
}