openmohaa/code/gamespy/GP/gpiUnique.c
2023-02-04 21:00:01 +01:00

234 lines
6.6 KiB
C

/*
gpiUnique.c
GameSpy Presence SDK
Dan "Mr. Pants" Schoenblum
Copyright 1999-2007 GameSpy Industries, Inc
devsupport@gamespy.com
***********************************************************************
Please see the GameSpy Presence SDK documentation for more information
**********************************************************************/
//INCLUDES
//////////
#include "gpi.h"
//FUNCTIONS
///////////
static GPResult
gpiSendRegisterUniqueNick(
GPConnection * connection,
const char uniquenick[GP_UNIQUENICK_LEN],
const char cdkey[GP_CDKEY_LEN],
int operationid
)
{
GPIConnection * iconnection = (GPIConnection*)*connection;
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\registernick\\\\sesskey\\");
gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->sessKey);
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\uniquenick\\");
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, uniquenick);
if(cdkey)
{
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\cdkey\\");
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, cdkey);
}
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\partnerid\\");
gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->partnerID);
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\id\\");
gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, operationid);
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\final\\");
return GP_NO_ERROR;
}
GPResult gpiRegisterUniqueNick(
GPConnection * connection,
const char uniquenick[GP_UNIQUENICK_LEN],
const char cdkey[GP_CDKEY_LEN],
GPEnum blocking,
GPCallback callback,
void * param
)
{
GPIOperation * operation = NULL;
GPResult result;
// Add the operation.
/////////////////////
CHECK_RESULT(gpiAddOperation(connection, GPI_REGISTER_UNIQUENICK, NULL, &operation, blocking, callback, param));
// Send a request for info.
///////////////////////////
result = gpiSendRegisterUniqueNick(connection, uniquenick, cdkey, operation->id);
CHECK_RESULT(result);
// Process it if blocking.
//////////////////////////
if(blocking)
{
result = gpiProcess(connection, operation->id);
CHECK_RESULT(result);
}
return GP_NO_ERROR;
}
GPResult gpiProcessRegisterUniqueNick(
GPConnection * connection,
GPIOperation * operation,
const char * input
)
{
GPICallback callback;
// Check for an error.
//////////////////////
if(gpiCheckForError(connection, input, GPITrue))
return GP_SERVER_ERROR;
// This should be \rn\.
///////////////////////
if(strncmp(input, "\\rn\\", 4) != 0)
CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
// Call the callback.
/////////////////////
callback = operation->callback;
if(callback.callback != NULL)
{
GPRegisterUniqueNickResponseArg * arg;
arg = (GPRegisterUniqueNickResponseArg *)gsimalloc(sizeof(GPRegisterUniqueNickResponseArg));
if(arg == NULL)
Error(connection, GP_MEMORY_ERROR, "Out of memory.");
arg->result = GP_NO_ERROR;
CHECK_RESULT(gpiAddCallback(connection, callback, arg, operation, 0));
}
// This operation is complete.
//////////////////////////////
gpiRemoveOperation(connection, operation);
return GP_NO_ERROR;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Registration of cdKey now offered separately from uniquenick
static GPResult
gpiSendRegisterCdKey(
GPConnection * connection,
const char cdkey[GP_CDKEY_LEN],
int operationid
)
{
GPIConnection * iconnection = (GPIConnection*)*connection;
// Encrypt the cdkey (xor with random values)
const int useAlternateEncoding = 1;
char cdkeyxor[GP_CDKEY_LEN];
char cdkeyenc[GP_CDKEYENC_LEN];
int cdkeylen = (int)strlen(cdkey);
int i=0;
Util_RandSeed((unsigned long)GP_XOR_SEED);
for (i=0; i < cdkeylen; i++)
{
// XOR each character with the next rand
char aRand = (char)Util_RandInt(0, 0xFF);
cdkeyxor[i] = (char)(cdkey[i] ^ aRand);
}
cdkeyxor[i] = '\0';
// Base 64 it (printable chars only)
B64Encode(cdkeyxor, cdkeyenc, (int)cdkeylen, useAlternateEncoding);
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\registercdkey\\\\sesskey\\");
gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->sessKey);
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\cdkeyenc\\");
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, cdkeyenc);
// gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\partnerid\\");
// gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->partnerID);
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\id\\");
gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, operationid);
gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\final\\");
return GP_NO_ERROR;
}
GPResult gpiRegisterCdKey(
GPConnection * connection,
const char cdkey[GP_CDKEY_LEN],
GPEnum blocking,
GPCallback callback,
void * param
)
{
GPIOperation * operation = NULL;
GPResult result;
// Add the operation.
/////////////////////
CHECK_RESULT(gpiAddOperation(connection, GPI_REGISTER_CDKEY, NULL, &operation, blocking, callback, param));
// Send a request for info.
///////////////////////////
result = gpiSendRegisterCdKey(connection, cdkey, operation->id);
CHECK_RESULT(result);
// Process it if blocking.
//////////////////////////
if(blocking)
{
result = gpiProcess(connection, operation->id);
CHECK_RESULT(result);
}
return GP_NO_ERROR;
}
GPResult gpiProcessRegisterCdKey(
GPConnection * connection,
GPIOperation * operation,
const char * input
)
{
GPICallback callback;
// Check for an error.
//////////////////////
if(gpiCheckForError(connection, input, GPITrue))
return GP_SERVER_ERROR;
// This should be \rc\.
///////////////////////
if(strncmp(input, "\\rc\\", 4) != 0)
CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server.");
// Call the callback.
/////////////////////
callback = operation->callback;
if(callback.callback != NULL)
{
GPRegisterCdKeyResponseArg * arg;
arg = (GPRegisterCdKeyResponseArg *)gsimalloc(sizeof(GPRegisterCdKeyResponseArg));
if(arg == NULL)
Error(connection, GP_MEMORY_ERROR, "Out of memory.");
arg->result = GP_NO_ERROR;
CHECK_RESULT(gpiAddCallback(connection, callback, arg, operation, 0));
}
// This operation is complete.
//////////////////////////////
gpiRemoveOperation(connection, operation);
return GP_NO_ERROR;
}