mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
287 lines
9.3 KiB
C
287 lines
9.3 KiB
C
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#include "sakeRequest.h"
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
const char * GSI_SAKE_SERVICE_NAMESPACES[GSI_SAKE_SERVICE_NAMESPACE_COUNT] =
|
|
{
|
|
"ns1=\"http://gamespy.net/sake\""
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#define SAKEI_SOAP_URL_FORMAT "http://%s.sake." GSI_DOMAIN_NAME "/SakeStorageServer/StorageServer.asmx"
|
|
char sakeiSoapUrl[SAKE_MAX_URL_LENGTH] = "";
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
SAKERequest SAKE_CALL sakeiInitRequest(SAKE sake, SAKEIRequestType type, void *input, SAKERequestCallback callback, void *userData)
|
|
{
|
|
SAKERequest request;
|
|
|
|
GS_ASSERT(sake);
|
|
|
|
// init the request init result to success
|
|
sake->mStartRequestResult = SAKEStartRequestResult_SUCCESS;
|
|
|
|
// check for input
|
|
if(!input)
|
|
{
|
|
sake->mStartRequestResult = SAKEStartRequestResult_BAD_INPUT;
|
|
return NULL;
|
|
}
|
|
|
|
// check for authentication
|
|
if(gsi_is_false(sake->mIsGameAuthenticated) || gsi_is_false(sake->mIsProfileAuthenticated))
|
|
{
|
|
sake->mStartRequestResult = SAKEStartRequestResult_NOT_AUTHENTICATED;
|
|
return NULL;
|
|
}
|
|
|
|
// allocate memory for the request object
|
|
request = (SAKERequest)gsimalloc(sizeof(SAKERequestInternal));
|
|
if(!request)
|
|
{
|
|
sake->mStartRequestResult = SAKEStartRequestResult_OUT_OF_MEMORY;
|
|
return NULL;
|
|
}
|
|
|
|
// init the request object
|
|
memset(request, 0, sizeof(SAKERequestInternal));
|
|
request->mSake = sake;
|
|
request->mType = type;
|
|
request->mInput = input;
|
|
request->mCallback = callback;
|
|
request->mUserData = userData;
|
|
|
|
return request;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void SAKE_CALL sakeiFreeRequest(SAKERequest request)
|
|
{
|
|
GS_ASSERT(request);
|
|
|
|
// this should already be freed by the time we get here
|
|
GS_ASSERT(request->mOutput == NULL);
|
|
|
|
// free the request
|
|
gsifree(request);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
static SAKERequestResult SAKE_CALL sakeiCheckHttpResult(GHTTPResult httpResult)
|
|
{
|
|
switch(httpResult)
|
|
{
|
|
case GHTTPSuccess:
|
|
return SAKERequestResult_SUCCESS;
|
|
case GHTTPOutOfMemory:
|
|
return SAKERequestResult_OUT_OF_MEMORY;
|
|
default:
|
|
return SAKERequestResult_CONNECTION_ERROR;
|
|
}
|
|
}
|
|
|
|
static SAKERequestResult SAKE_CALL sakeiCheckSakeResult(const char * sakeResult)
|
|
{
|
|
if(strcmp(sakeResult, "Success") == 0)
|
|
return SAKERequestResult_SUCCESS;
|
|
else if(strcmp(sakeResult, "SecretKeyInvalid") == 0)
|
|
return SAKERequestResult_SECRET_KEY_INVALID;
|
|
else if(strcmp(sakeResult, "ServiceDisabled") == 0)
|
|
return SAKERequestResult_SERVICE_DISABLED;
|
|
else if(strcmp(sakeResult, "DatabaseUnavailable") == 0)
|
|
return SAKERequestResult_DATABASE_UNAVAILABLE;
|
|
else if(strcmp(sakeResult, "LoginTicketInvalid") == 0)
|
|
return SAKERequestResult_LOGIN_TICKET_INVALID;
|
|
else if(strcmp(sakeResult, "LoginTicketExpired") == 0)
|
|
return SAKERequestResult_LOGIN_TICKET_EXPIRED;
|
|
else if(strcmp(sakeResult, "TableNotFound") == 0)
|
|
return SAKERequestResult_TABLE_NOT_FOUND;
|
|
else if(strcmp(sakeResult, "RecordNotFound") == 0)
|
|
return SAKERequestResult_RECORD_NOT_FOUND;
|
|
else if(strcmp(sakeResult, "FieldNotFound") == 0)
|
|
return SAKERequestResult_FIELD_NOT_FOUND;
|
|
else if(strcmp(sakeResult, "FieldTypeInvalid") == 0)
|
|
return SAKERequestResult_FIELD_TYPE_INVALID;
|
|
else if(strcmp(sakeResult, "NoPermission") == 0)
|
|
return SAKERequestResult_NO_PERMISSION;
|
|
else if(strcmp(sakeResult, "RecordLimitReached") == 0)
|
|
return SAKERequestResult_RECORD_LIMIT_REACHED;
|
|
else if(strcmp(sakeResult, "AlreadyRated") == 0)
|
|
return SAKERequestResult_ALREADY_RATED;
|
|
else if(strcmp(sakeResult, "NotRateable") == 0)
|
|
return SAKERequestResult_NOT_RATEABLE;
|
|
else if(strcmp(sakeResult, "NotOwned") == 0)
|
|
return SAKERequestResult_NOT_OWNED;
|
|
else if(strcmp(sakeResult, "FilterInvalid") == 0)
|
|
return SAKERequestResult_FILTER_INVALID;
|
|
else if(strcmp(sakeResult, "SortInvalid") == 0)
|
|
return SAKERequestResult_SORT_INVALID;
|
|
else if(strcmp(sakeResult, "TargetFilterInvalid") == 0)
|
|
return SAKERequestResult_TARGET_FILTER_INVALID;
|
|
else
|
|
return SAKERequestResult_UNKNOWN_ERROR;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
static void SAKE_CALL sakeiSoapCallback(GHTTPResult httpResult, GSXmlStreamWriter requestData, GSXmlStreamReader responseData, void *userData)
|
|
{
|
|
SAKERequest request = (SAKERequest)userData;
|
|
void *output = NULL;
|
|
SAKERequestResult result;
|
|
char resultString[32];
|
|
|
|
// sanity check
|
|
GS_ASSERT(request);
|
|
GS_ASSERT(request->mSake);
|
|
GS_ASSERT(request->mInfo);
|
|
if(!request || !request->mSake || !request->mInfo)
|
|
return;
|
|
|
|
result = sakeiCheckHttpResult(httpResult);
|
|
if(result == SAKERequestResult_SUCCESS)
|
|
{
|
|
if(gsi_is_false(gsXmlMoveToStart(responseData)) ||
|
|
gsi_is_false(gsXmlMoveToNext(responseData, request->mInfo->mResponseTag)) ||
|
|
gsi_is_false(gsXmlReadChildAsStringNT(responseData, request->mInfo->mResultTag, resultString, sizeof(resultString))))
|
|
{
|
|
result = SAKERequestResult_MALFORMED_RESPONSE;
|
|
}
|
|
else
|
|
{
|
|
result = sakeiCheckSakeResult(resultString);
|
|
|
|
// fill in the output
|
|
if(result == SAKERequestResult_SUCCESS)
|
|
{
|
|
if(request->mInfo->mSakeOutputSize != 0)
|
|
{
|
|
request->mOutput = gsimalloc(request->mInfo->mSakeOutputSize);
|
|
if(request->mOutput)
|
|
{
|
|
request->mSoapResponse = responseData;
|
|
result = request->mInfo->mProcessSoapResponseFunc(request);
|
|
if(result == SAKERequestResult_SUCCESS)
|
|
output = request->mOutput;
|
|
}
|
|
else
|
|
{
|
|
result = SAKERequestResult_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// call the callback
|
|
if(request->mCallback)
|
|
request->mCallback(request->mSake, request, result, request->mInput, output, request->mUserData);
|
|
|
|
// free data
|
|
if(request->mInfo->mFreeDataFunc)
|
|
request->mInfo->mFreeDataFunc(request);
|
|
|
|
// free the output data
|
|
gsifree(request->mOutput);
|
|
request->mOutput = NULL;
|
|
|
|
// free the sake request
|
|
sakeiFreeRequest(request);
|
|
|
|
GSI_UNUSED(requestData);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
static SAKEStartRequestResult SAKE_CALL sakeiSetupRequest(SAKERequest request)
|
|
{
|
|
SAKEStartRequestResult result;
|
|
SAKEIRequestInfo * info;
|
|
|
|
GS_ASSERT(request);
|
|
GS_ASSERT(request->mSake);
|
|
GS_ASSERT(request->mInfo);
|
|
|
|
// store a utility pointer to the info
|
|
info = request->mInfo;
|
|
|
|
// check the input
|
|
result = info->mValidateInputFunc(request);
|
|
if(result != SAKEStartRequestResult_SUCCESS)
|
|
return result;
|
|
|
|
// create the xml request stream
|
|
request->mSoapRequest = gsXmlCreateStreamWriter(GSI_SAKE_SERVICE_NAMESPACES, GSI_SAKE_SERVICE_NAMESPACE_COUNT);
|
|
if(request->mSoapRequest == NULL)
|
|
return SAKEStartRequestResult_OUT_OF_MEMORY;
|
|
|
|
// open the stream
|
|
gsXmlWriteOpenTag(request->mSoapRequest, GSI_SAKE_SERVICE_NAMESPACE, request->mInfo->mFuncName);
|
|
|
|
// this info is included with every request
|
|
gsXmlWriteIntElement(request->mSoapRequest, GSI_SAKE_SERVICE_NAMESPACE, "gameid", (gsi_u32)request->mSake->mGameId);
|
|
gsXmlWriteStringElement(request->mSoapRequest, GSI_SAKE_SERVICE_NAMESPACE, "secretKey", request->mSake->mSecretKey);
|
|
gsXmlWriteStringElement(request->mSoapRequest, GSI_SAKE_SERVICE_NAMESPACE, "loginTicket", request->mSake->mLoginTicket);
|
|
|
|
// fill in the request data
|
|
result = info->mFillSoapRequestFunc(request);
|
|
if(result != SAKEStartRequestResult_SUCCESS)
|
|
{
|
|
gsXmlFreeWriter(request->mSoapRequest);
|
|
request->mSoapRequest = NULL;
|
|
if(info->mFreeDataFunc)
|
|
info->mFreeDataFunc(request);
|
|
return result;
|
|
}
|
|
|
|
// close the stream and writer
|
|
gsXmlWriteCloseTag(request->mSoapRequest, GSI_SAKE_SERVICE_NAMESPACE, request->mInfo->mFuncName);
|
|
gsXmlCloseWriter(request->mSoapRequest);
|
|
|
|
return SAKEStartRequestResult_SUCCESS;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
static void SAKE_CALL sakeiExecuteRequest(SAKERequest request)
|
|
{
|
|
if(sakeiSoapUrl[0] == '\0')
|
|
{
|
|
int rcode;
|
|
rcode = snprintf(sakeiSoapUrl, SAKE_MAX_URL_LENGTH, SAKEI_SOAP_URL_FORMAT, request->mSake->mGameName);
|
|
GS_ASSERT(rcode >= 0);
|
|
GSI_UNUSED(rcode);
|
|
}
|
|
gsiExecuteSoap(sakeiSoapUrl, request->mInfo->mSoapAction, request->mSoapRequest, sakeiSoapCallback, request);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
SAKEStartRequestResult SAKE_CALL sakeiStartRequest(SAKERequest request, SAKEIRequestInfo * info)
|
|
{
|
|
SAKEStartRequestResult result;
|
|
|
|
request->mInfo = info;
|
|
|
|
result = sakeiSetupRequest(request);
|
|
if(result != SAKEStartRequestResult_SUCCESS)
|
|
return result;
|
|
|
|
sakeiExecuteRequest(request);
|
|
|
|
return SAKEStartRequestResult_SUCCESS;
|
|
}
|