mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 21:57:57 +03:00
601 lines
21 KiB
C
601 lines
21 KiB
C
![]() |
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
#include "../common/gsCore.h"
|
||
|
|
||
|
#include "sci.h"
|
||
|
#include "sciInterface.h"
|
||
|
#include "sciWebServices.h"
|
||
|
#include "sciReport.h"
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
#define SC_CREATEMATCHLESSSESSION_SOAPACTION "SOAPAction: \"http://gamespy.net/competition/CreateMatchlessSession\""
|
||
|
#define SC_CREATESESSION_SOAPACTION "SOAPAction: \"http://gamespy.net/competition/CreateSession\""
|
||
|
#define SC_SUBMITREPORT_SOAPACTION "SOAPAction: \"http://gamespy.net/competition/SubmitReport\""
|
||
|
#define SC_SETINTENTION_SOAPACTION "SOAPAction: \"http://gamespy.net/competition/SetReportIntention\""
|
||
|
|
||
|
#define SC_SERVICE_NAMESPACE_COUNT 1
|
||
|
const char * SC_SERVICE_NAMESPACES[SC_SERVICE_NAMESPACE_COUNT] =
|
||
|
{
|
||
|
"gsc=\"http://gamespy.net/competition/\""
|
||
|
};
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
SCResult sciWsInit(SCWebServices* theWebServices,
|
||
|
SCInterfacePtr theInterface)
|
||
|
{
|
||
|
|
||
|
|
||
|
GS_ASSERT(theWebServices != NULL);
|
||
|
GS_ASSERT(theInterface != NULL);
|
||
|
GS_ASSERT(!theWebServices->mInit);
|
||
|
|
||
|
// Check gsCore
|
||
|
if (gsCoreIsShutdown())
|
||
|
{
|
||
|
return SCResult_CORE_NOT_INITIALIZED;
|
||
|
}
|
||
|
|
||
|
// Initialize SCWebServices struct
|
||
|
theWebServices->mInterface = theInterface;
|
||
|
theWebServices->mCreateSessionCallback = NULL;
|
||
|
theWebServices->mSetReportIntentionCallback = NULL;
|
||
|
theWebServices->mSubmitReportDataCallback = NULL;
|
||
|
theWebServices->mCreateSessionUserData = NULL;
|
||
|
theWebServices->mSetReportIntentionUserData = NULL;
|
||
|
theWebServices->mSubmitReportUserData = NULL;
|
||
|
theWebServices->mCreateSessionPending = gsi_false;
|
||
|
theWebServices->mSetReportIntentionPending = gsi_false;
|
||
|
theWebServices->mSubmitReportPending = gsi_false;
|
||
|
|
||
|
// Now initialized
|
||
|
theWebServices->mInit = gsi_true;
|
||
|
|
||
|
return SCResult_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
void sciWsDestroy(SCWebServices* theWebServices)
|
||
|
{
|
||
|
GS_ASSERT(theWebServices != NULL);
|
||
|
GS_ASSERT(theWebServices->mInit);
|
||
|
|
||
|
// No longer initialized
|
||
|
theWebServices->mInit = gsi_false;
|
||
|
|
||
|
// Destroy SCWebServices struct
|
||
|
theWebServices->mCreateSessionCallback = NULL;
|
||
|
theWebServices->mSetReportIntentionCallback = NULL;
|
||
|
theWebServices->mSubmitReportDataCallback = NULL;
|
||
|
theWebServices->mCreateSessionUserData = NULL;
|
||
|
theWebServices->mSetReportIntentionUserData = NULL;
|
||
|
theWebServices->mSubmitReportUserData = NULL;
|
||
|
theWebServices->mCreateSessionPending = gsi_false;
|
||
|
theWebServices->mSetReportIntentionPending = gsi_false;
|
||
|
theWebServices->mSubmitReportPending = gsi_false;
|
||
|
theWebServices->mInterface = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
void sciWsThink(SCWebServices* theWebServices)
|
||
|
{
|
||
|
GS_ASSERT(theWebServices != NULL);
|
||
|
GS_ASSERT(theWebServices->mInit);
|
||
|
|
||
|
gsCoreThink(0);
|
||
|
|
||
|
GSI_UNUSED(theWebServices);
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
SCResult sciWsCreateSession (SCWebServices * theWebServices,
|
||
|
gsi_u32 theGameId,
|
||
|
const GSLoginCertificate * theCertificate,
|
||
|
const GSLoginPrivateData * thePrivateData,
|
||
|
SCCreateSessionCallback theCallback,
|
||
|
gsi_time theTimeoutMs,
|
||
|
void * theUserData)
|
||
|
{
|
||
|
GSXmlStreamWriter aRequest = NULL;
|
||
|
|
||
|
// Check parameters
|
||
|
GS_ASSERT(theWebServices != NULL);
|
||
|
GS_ASSERT(theWebServices->mInit);
|
||
|
|
||
|
// Check for pending request
|
||
|
if (theWebServices->mCreateSessionPending)
|
||
|
return SCResult_CALLBACK_PENDING;
|
||
|
|
||
|
// Create the XML message writer
|
||
|
aRequest = gsXmlCreateStreamWriter(SC_SERVICE_NAMESPACES, SC_SERVICE_NAMESPACE_COUNT);
|
||
|
if (aRequest == NULL)
|
||
|
return SCResult_OUT_OF_MEMORY;
|
||
|
|
||
|
// Fill in the request data
|
||
|
if (gsi_is_false(gsXmlWriteOpenTag(aRequest, "gsc", "CreateSession")) ||
|
||
|
gsi_is_false(gsXmlWriteOpenTag(aRequest, "gsc", "certificate")) ||
|
||
|
gsi_is_false(wsLoginCertWriteXML(theCertificate, "gsc", aRequest)) ||
|
||
|
gsi_is_false(gsXmlWriteCloseTag(aRequest, "gsc", "certificate")) ||
|
||
|
gsi_is_false(gsXmlWriteHexBinaryElement(aRequest, "gsc", "proof", (const gsi_u8*)thePrivateData->mKeyHash, GS_CRYPT_MD5_HASHSIZE)) ||
|
||
|
gsi_is_false(gsXmlWriteIntElement(aRequest, "gsc", "gameid", (gsi_u32)theGameId)) ||
|
||
|
gsi_is_false(gsXmlWriteCloseTag(aRequest, "gsc", "CreateSession")) ||
|
||
|
gsi_is_false(gsXmlCloseWriter(aRequest))
|
||
|
)
|
||
|
{
|
||
|
gsXmlFreeWriter(aRequest);
|
||
|
return SCResult_HTTP_ERROR;
|
||
|
}
|
||
|
|
||
|
// Set callback
|
||
|
theWebServices->mCreateSessionCallback = theCallback;
|
||
|
theWebServices->mCreateSessionUserData = theUserData;
|
||
|
theWebServices->mCreateSessionPending = gsi_true;
|
||
|
|
||
|
// Execute soap call
|
||
|
gsiExecuteSoap(scServiceURL, SC_CREATESESSION_SOAPACTION,
|
||
|
aRequest, sciWsCreateSessionCallback, theWebServices);
|
||
|
GSI_UNUSED(theTimeoutMs);
|
||
|
return SCResult_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
SCResult sciWsCreateMatchlessSession (SCWebServices * theWebServices,
|
||
|
gsi_u32 theGameId,
|
||
|
const GSLoginCertificate * theCertificate,
|
||
|
const GSLoginPrivateData * thePrivateData,
|
||
|
SCCreateSessionCallback theCallback,
|
||
|
gsi_time theTimeoutMs,
|
||
|
void * theUserData)
|
||
|
{
|
||
|
GSXmlStreamWriter aRequest = NULL;
|
||
|
|
||
|
// Check parameters
|
||
|
GS_ASSERT(theWebServices != NULL);
|
||
|
GS_ASSERT(theWebServices->mInit);
|
||
|
|
||
|
// Check for pending request
|
||
|
if (theWebServices->mCreateSessionPending)
|
||
|
return SCResult_CALLBACK_PENDING;
|
||
|
|
||
|
// Create the XML message writer
|
||
|
aRequest = gsXmlCreateStreamWriter(SC_SERVICE_NAMESPACES, SC_SERVICE_NAMESPACE_COUNT);
|
||
|
if (aRequest == NULL)
|
||
|
return SCResult_OUT_OF_MEMORY;
|
||
|
|
||
|
// Fill in the request data
|
||
|
if (gsi_is_false(gsXmlWriteOpenTag(aRequest, "gsc", "CreateMatchlessSession")) ||
|
||
|
gsi_is_false(gsXmlWriteOpenTag(aRequest, "gsc", "certificate")) ||
|
||
|
gsi_is_false(wsLoginCertWriteXML(theCertificate, "gsc", aRequest)) ||
|
||
|
gsi_is_false(gsXmlWriteCloseTag(aRequest, "gsc", "certificate")) ||
|
||
|
gsi_is_false(gsXmlWriteHexBinaryElement(aRequest, "gsc", "proof", (const gsi_u8*)thePrivateData->mKeyHash, GS_CRYPT_MD5_HASHSIZE)) ||
|
||
|
gsi_is_false(gsXmlWriteIntElement(aRequest, "gsc", "gameid", (gsi_u32)theGameId)) ||
|
||
|
gsi_is_false(gsXmlWriteCloseTag(aRequest, "gsc", "CreateMatchlessSession")) ||
|
||
|
gsi_is_false(gsXmlCloseWriter(aRequest))
|
||
|
)
|
||
|
{
|
||
|
gsXmlFreeWriter(aRequest);
|
||
|
return SCResult_HTTP_ERROR;
|
||
|
}
|
||
|
|
||
|
// Set callback
|
||
|
theWebServices->mCreateSessionCallback = theCallback;
|
||
|
theWebServices->mCreateSessionUserData = theUserData;
|
||
|
theWebServices->mCreateSessionPending = gsi_true;
|
||
|
|
||
|
// Execute soap call
|
||
|
gsiExecuteSoap(scServiceURL, SC_CREATEMATCHLESSSESSION_SOAPACTION,
|
||
|
aRequest, sciWsCreateSessionCallback, theWebServices);
|
||
|
GSI_UNUSED(theTimeoutMs);
|
||
|
return SCResult_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
void sciWsCreateSessionCallback(GHTTPResult theHttpResult,
|
||
|
GSXmlStreamWriter theRequestData,
|
||
|
GSXmlStreamReader theResponseData,
|
||
|
void* theUserData)
|
||
|
{
|
||
|
SCResult aTranslatedResult = SCResult_HTTP_ERROR;
|
||
|
SCWebServices* aWebServices = (SCWebServices*)theUserData;
|
||
|
|
||
|
char csid[255];
|
||
|
char ccid[255];
|
||
|
int csidLen = 255;
|
||
|
int ccidLen = 255;
|
||
|
|
||
|
GS_ASSERT(aWebServices != NULL);
|
||
|
GS_ASSERT(aWebServices->mCreateSessionPending);
|
||
|
|
||
|
// Check for shutdown
|
||
|
if (!aWebServices->mInit)
|
||
|
return;
|
||
|
|
||
|
if (theHttpResult == GHTTPSuccess)
|
||
|
{
|
||
|
int createResult = 0;
|
||
|
|
||
|
// Parse through in a way that will work for either type of CreateSession response.
|
||
|
if (gsi_is_false(gsXmlMoveToStart(theResponseData)))
|
||
|
{
|
||
|
aTranslatedResult = SCResult_RESPONSE_INVALID;
|
||
|
}
|
||
|
else if(gsi_is_false(gsXmlMoveToNext(theResponseData, "CreateSessionResponse")))
|
||
|
{
|
||
|
if(gsi_is_false(gsXmlMoveToNext(theResponseData, "CreateMatchlessSessionResponse")))
|
||
|
{
|
||
|
aTranslatedResult = SCResult_RESPONSE_INVALID;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(gsi_is_false(gsXmlMoveToNext(theResponseData, "CreateSessionResult")))
|
||
|
{
|
||
|
if(gsi_is_false(gsXmlMoveToNext(theResponseData, "CreateMatchlessSessionResult")))
|
||
|
{
|
||
|
aTranslatedResult = SCResult_RESPONSE_INVALID;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(gsi_is_false(gsXmlReadChildAsInt(theResponseData, "result", &createResult)))
|
||
|
{
|
||
|
aTranslatedResult = SCResult_RESPONSE_INVALID;
|
||
|
}
|
||
|
else if(aTranslatedResult != SCResult_RESPONSE_INVALID)
|
||
|
{
|
||
|
// Parse server reported result
|
||
|
if (createResult == SCWsResult_NO_ERROR)
|
||
|
{
|
||
|
// Read session and connection ID
|
||
|
if(gsi_is_false(gsXmlReadChildAsStringNT(theResponseData, "csid", csid, csidLen)) ||
|
||
|
gsi_is_false(gsXmlReadChildAsStringNT(theResponseData, "ccid", ccid, ccidLen))
|
||
|
)
|
||
|
{
|
||
|
aTranslatedResult = SCResult_RESPONSE_INVALID;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sciInterfaceSetSessionId((SCInterface*)aWebServices->mInterface, csid);
|
||
|
sciInterfaceSetConnectionId((SCInterface*)aWebServices->mInterface, ccid);
|
||
|
aTranslatedResult = SCResult_NO_ERROR;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Server reported an error, handle it?
|
||
|
|
||
|
// TODO:
|
||
|
// translate result into developer useable form
|
||
|
// report result string as gsDebugFormat message for easier debugging
|
||
|
aTranslatedResult = SCResult_RESPONSE_INVALID;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
aTranslatedResult = SCResult_HTTP_ERROR;
|
||
|
}
|
||
|
|
||
|
// Client callback
|
||
|
aWebServices->mCreateSessionPending = gsi_false;
|
||
|
if (aWebServices->mCreateSessionCallback != NULL)
|
||
|
{
|
||
|
aWebServices->mCreateSessionCallback(aWebServices->mInterface, theHttpResult, aTranslatedResult, aWebServices->mCreateSessionUserData);
|
||
|
aWebServices->mCreateSessionUserData = NULL;
|
||
|
aWebServices->mCreateSessionCallback = NULL;
|
||
|
}
|
||
|
GSI_UNUSED(theRequestData);
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
SCResult sciWsSetReportIntention(SCWebServices* theWebServices,
|
||
|
gsi_u32 theGameId,
|
||
|
const char * theSessionId,
|
||
|
const char * theConnectionId,
|
||
|
gsi_bool isAuthoritative,
|
||
|
const GSLoginCertificate * theCertificate,
|
||
|
const GSLoginPrivateData * thePrivateData,
|
||
|
SCSetReportIntentionCallback theCallback,
|
||
|
gsi_time theTimeoutMs,
|
||
|
void * theUserData)
|
||
|
{
|
||
|
GSXmlStreamWriter aRequest = NULL;
|
||
|
|
||
|
// Check parameters
|
||
|
GS_ASSERT(theWebServices != NULL);
|
||
|
GS_ASSERT(theWebServices->mInit);
|
||
|
|
||
|
// Check for pending request
|
||
|
if (theWebServices->mSetReportIntentionPending)
|
||
|
return SCResult_CALLBACK_PENDING;
|
||
|
|
||
|
// Create the XML message writer
|
||
|
aRequest = gsXmlCreateStreamWriter(SC_SERVICE_NAMESPACES, SC_SERVICE_NAMESPACE_COUNT);
|
||
|
if (aRequest == NULL)
|
||
|
return SCResult_OUT_OF_MEMORY;
|
||
|
|
||
|
// Fill in the request data
|
||
|
if (gsi_is_false(gsXmlWriteOpenTag(aRequest, "gsc", "SetReportIntention")) ||
|
||
|
gsi_is_false(gsXmlWriteOpenTag(aRequest, "gsc", "certificate")) ||
|
||
|
gsi_is_false(wsLoginCertWriteXML(theCertificate, "gsc", aRequest)) ||
|
||
|
gsi_is_false(gsXmlWriteCloseTag(aRequest, "gsc", "certificate")) ||
|
||
|
gsi_is_false(gsXmlWriteHexBinaryElement(aRequest, "gsc", "proof", (const gsi_u8*)thePrivateData->mKeyHash, GS_CRYPT_MD5_HASHSIZE)) ||
|
||
|
gsi_is_false(gsXmlWriteStringElement(aRequest, "gsc", "csid", theSessionId)) ||
|
||
|
gsi_is_false(gsXmlWriteStringElement(aRequest, "gsc", "ccid", theConnectionId)) ||
|
||
|
gsi_is_false(gsXmlWriteIntElement(aRequest, "gsc", "gameid", (gsi_u32)theGameId)) ||
|
||
|
gsi_is_false(gsXmlWriteIntElement(aRequest, "gsc", "authoritative", (gsi_u32)(gsi_is_true(isAuthoritative) ? 1:0))) ||
|
||
|
gsi_is_false(gsXmlWriteCloseTag(aRequest, "gsc", "SetReportIntention")) ||
|
||
|
gsi_is_false(gsXmlCloseWriter(aRequest))
|
||
|
)
|
||
|
{
|
||
|
gsXmlFreeWriter(aRequest);
|
||
|
return SCResult_HTTP_ERROR;
|
||
|
}
|
||
|
|
||
|
// Set callback
|
||
|
theWebServices->mSetReportIntentionCallback = theCallback;
|
||
|
theWebServices->mSetReportIntentionUserData = theUserData;
|
||
|
theWebServices->mSetReportIntentionPending = gsi_true;
|
||
|
|
||
|
// Execute soap call
|
||
|
gsiExecuteSoap(scServiceURL, SC_SETINTENTION_SOAPACTION,
|
||
|
aRequest, sciWsSetReportIntentionCallback, theWebServices);
|
||
|
|
||
|
GSI_UNUSED(theTimeoutMs);
|
||
|
return SCResult_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
void sciWsSetReportIntentionCallback(GHTTPResult theHttpResult,
|
||
|
GSXmlStreamWriter theRequestData,
|
||
|
GSXmlStreamReader theResponseData,
|
||
|
void* theUserData)
|
||
|
{
|
||
|
SCResult aTranslatedResult = SCResult_HTTP_ERROR;
|
||
|
SCWebServices* aWebServices = (SCWebServices*)theUserData;
|
||
|
|
||
|
char ccid[255];
|
||
|
int ccidLen = 255;
|
||
|
|
||
|
|
||
|
GS_ASSERT(aWebServices != NULL);
|
||
|
GS_ASSERT(aWebServices->mSetReportIntentionPending);
|
||
|
|
||
|
// Check for shutdown
|
||
|
if (!aWebServices->mInit)
|
||
|
return;
|
||
|
|
||
|
if (theHttpResult == GHTTPSuccess)
|
||
|
{
|
||
|
int intentionResult = 0;
|
||
|
|
||
|
if (gsi_is_false(gsXmlMoveToStart(theResponseData)) ||
|
||
|
gsi_is_false(gsXmlMoveToNext(theResponseData, "SetReportIntentionResponse")) ||
|
||
|
gsi_is_false(gsXmlMoveToNext(theResponseData, "SetReportIntentionResult")) ||
|
||
|
gsi_is_false(gsXmlReadChildAsInt(theResponseData, "result", &intentionResult)) ||
|
||
|
gsi_is_false(gsXmlReadChildAsStringNT(theResponseData, "ccid", ccid, ccidLen))
|
||
|
)
|
||
|
{
|
||
|
aTranslatedResult = SCResult_RESPONSE_INVALID;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (intentionResult == SCWsResult_NO_ERROR)
|
||
|
{
|
||
|
aTranslatedResult = SCResult_NO_ERROR;
|
||
|
sciInterfaceSetConnectionId((SCInterface*)aWebServices->mInterface, ccid);
|
||
|
}
|
||
|
else
|
||
|
aTranslatedResult = SCResult_UNKNOWN_RESPONSE;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
aTranslatedResult = SCResult_HTTP_ERROR;
|
||
|
}
|
||
|
|
||
|
// Client callback
|
||
|
aWebServices->mSetReportIntentionPending = gsi_false;
|
||
|
if (aWebServices->mSetReportIntentionCallback != NULL)
|
||
|
{
|
||
|
aWebServices->mSetReportIntentionCallback(aWebServices->mInterface,
|
||
|
theHttpResult,
|
||
|
aTranslatedResult,
|
||
|
aWebServices->mSetReportIntentionUserData);
|
||
|
aWebServices->mSetReportIntentionUserData = NULL;
|
||
|
aWebServices->mSetReportIntentionCallback = NULL;
|
||
|
}
|
||
|
GSI_UNUSED(theRequestData);
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// declared here to allow function to get around Unicode calls
|
||
|
extern GHTTPBool ghiPostAddFileFromMemory(GHTTPPost post,const char * name,const char * buffer,
|
||
|
int bufferLen,const char * reportFilename,const char * contentType);
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// Private GSSoapCustomFunc used by sciWsSubmitReport
|
||
|
static void sciWsSubmitReportCustom(GHTTPPost thePost, void* theUserData)
|
||
|
{
|
||
|
SCWebServices* aWebServices = (SCWebServices*)theUserData;
|
||
|
|
||
|
//Use internal method to get around unicode calls
|
||
|
ghiPostAddFileFromMemory(thePost, "report", (char *)aWebServices->mSubmitReportData,
|
||
|
(gsi_i32)aWebServices->mSubmitReportLength, "report", "application/bin");
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
SCResult sciWsSubmitReport(SCWebServices* theWebServices,
|
||
|
gsi_u32 theGameId,
|
||
|
const char * theSessionId,
|
||
|
const char * theConnectionId,
|
||
|
const SCIReport * theReport,
|
||
|
gsi_bool isAuthoritative,
|
||
|
const GSLoginCertificate * theCertificate,
|
||
|
const GSLoginPrivateData * thePrivateData,
|
||
|
SCSubmitReportCallback theCallback,
|
||
|
gsi_time theTimeoutMs,
|
||
|
void * theUserData)
|
||
|
{
|
||
|
GSXmlStreamWriter aRequest = NULL;
|
||
|
//SCIReportHeader * aReportHeader = NULL;
|
||
|
//gsi_u32 aTotalSize = 0;
|
||
|
|
||
|
//SCReportStatus* aStatus = NULL;
|
||
|
|
||
|
// Check parameters
|
||
|
GS_ASSERT(theWebServices != NULL);
|
||
|
//GS_ASSERT(theReportData != NULL);
|
||
|
|
||
|
// Check for pending request
|
||
|
if (theWebServices->mSubmitReportPending)
|
||
|
{
|
||
|
return SCResult_CALLBACK_PENDING;
|
||
|
}
|
||
|
|
||
|
// Get a pointer to the header
|
||
|
//aReportHeader = (SCIReportHeader*)theReport->mBuffer.mData;
|
||
|
|
||
|
// Check for complete report
|
||
|
if (theReport->mBuffer.mPos < sizeof(SCIReportHeader))
|
||
|
return SCResult_REPORT_INVALID;
|
||
|
|
||
|
// Check size (early check for easier debugging)
|
||
|
//aTotalSize = sizeof(SCIReportHeader);
|
||
|
//aTotalSize += htonl(aReportHeader->mPlayerDataLength);
|
||
|
//aTotalSize += htonl(aReportHeader->mTeamDataLength);
|
||
|
//aTotalSize += htonl(aReportHeader->mSessionDataLength);
|
||
|
// aTotalSize += auth info...
|
||
|
//if (theReport->mBuffer.mPos != aTotalSize)
|
||
|
// return SCResult_REPORT_INVALID;
|
||
|
|
||
|
// Create the XML message writer
|
||
|
aRequest = gsXmlCreateStreamWriter(SC_SERVICE_NAMESPACES, SC_SERVICE_NAMESPACE_COUNT);
|
||
|
if (aRequest == NULL)
|
||
|
return SCResult_OUT_OF_MEMORY;
|
||
|
|
||
|
// Fill in the request data
|
||
|
if (gsi_is_false(gsXmlWriteOpenTag(aRequest, "gsc", "SubmitReport")) ||
|
||
|
gsi_is_false(gsXmlWriteOpenTag(aRequest, "gsc", "certificate")) ||
|
||
|
gsi_is_false(wsLoginCertWriteXML(theCertificate, "gsc", aRequest)) ||
|
||
|
gsi_is_false(gsXmlWriteCloseTag(aRequest, "gsc", "certificate")) ||
|
||
|
gsi_is_false(gsXmlWriteHexBinaryElement(aRequest, "gsc", "proof", (const gsi_u8*)thePrivateData->mKeyHash, GS_CRYPT_MD5_HASHSIZE)) ||
|
||
|
gsi_is_false(gsXmlWriteStringElement(aRequest, "gsc", "csid", theSessionId)) ||
|
||
|
gsi_is_false(gsXmlWriteStringElement(aRequest, "gsc", "ccid", theConnectionId)) ||
|
||
|
gsi_is_false(gsXmlWriteIntElement(aRequest, "gsc", "gameid", (gsi_u32)theGameId)) ||
|
||
|
gsi_is_false(gsXmlWriteIntElement(aRequest, "gsc", "authoritative", (gsi_u32)(gsi_is_true(isAuthoritative) ? 1:0))) ||
|
||
|
gsi_is_false(gsXmlWriteCloseTag(aRequest, "gsc", "SubmitReport")) ||
|
||
|
gsi_is_false(gsXmlCloseWriter(aRequest))
|
||
|
)
|
||
|
{
|
||
|
gsXmlFreeWriter(aRequest);
|
||
|
return SCResult_OUT_OF_MEMORY;
|
||
|
}
|
||
|
|
||
|
// Get submission size
|
||
|
theWebServices->mSubmitReportData = (gsi_u8*)theReport->mBuffer.mData;
|
||
|
theWebServices->mSubmitReportLength = theReport->mBuffer.mPos;
|
||
|
|
||
|
// Set callback
|
||
|
theWebServices->mSubmitReportDataCallback = theCallback;
|
||
|
theWebServices->mSubmitReportUserData = theUserData;
|
||
|
theWebServices->mSubmitReportPending = gsi_true;
|
||
|
|
||
|
// Execute soap call
|
||
|
gsiExecuteSoapCustom(scServiceURL, SC_SUBMITREPORT_SOAPACTION,
|
||
|
aRequest, sciWsSubmitReportCallback,sciWsSubmitReportCustom, theWebServices);
|
||
|
|
||
|
GSI_UNUSED(theTimeoutMs);
|
||
|
return SCResult_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
void sciWsSubmitReportCallback(GHTTPResult theHttpResult,
|
||
|
GSXmlStreamWriter theRequestData,
|
||
|
GSXmlStreamReader theResponseData,
|
||
|
void* theUserData)
|
||
|
{
|
||
|
SCResult aTranslatedResult = SCResult_HTTP_ERROR;
|
||
|
SCWebServices* aWebServices = (SCWebServices*)theUserData;
|
||
|
|
||
|
GS_ASSERT(aWebServices != NULL);
|
||
|
|
||
|
// Check for shutdown
|
||
|
if (!aWebServices->mInit)
|
||
|
return;
|
||
|
|
||
|
GS_ASSERT(aWebServices->mSubmitReportPending);
|
||
|
|
||
|
if (theHttpResult == GHTTPSuccess)
|
||
|
{
|
||
|
int submitResult = 0;
|
||
|
|
||
|
if (gsi_is_false(gsXmlMoveToStart(theResponseData)) ||
|
||
|
gsi_is_false(gsXmlMoveToNext(theResponseData, "SubmitReportResponse")) ||
|
||
|
gsi_is_false(gsXmlMoveToNext(theResponseData, "SubmitReportResult")) ||
|
||
|
gsi_is_false(gsXmlReadChildAsInt(theResponseData, "result", &submitResult))
|
||
|
)
|
||
|
{
|
||
|
aTranslatedResult = SCResult_RESPONSE_INVALID;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
switch (submitResult)
|
||
|
{
|
||
|
case SCWsResult_NO_ERROR:
|
||
|
aTranslatedResult = SCResult_NO_ERROR;
|
||
|
break;
|
||
|
case SCWsResult_REPORT_INVALID:
|
||
|
aTranslatedResult = SCResult_REPORT_INVALID;
|
||
|
break;
|
||
|
case SCWsResult_SINGLE_ATTACHMENT_EXPECTED:
|
||
|
aTranslatedResult = SCResult_SUBMISSION_FAILED;
|
||
|
break;
|
||
|
default:
|
||
|
aTranslatedResult = SCResult_UNKNOWN_RESPONSE;
|
||
|
break;
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
aTranslatedResult = SCResult_HTTP_ERROR;
|
||
|
}
|
||
|
|
||
|
// Client callback
|
||
|
aWebServices->mSubmitReportPending = gsi_false;
|
||
|
if (aWebServices->mSubmitReportDataCallback != NULL)
|
||
|
{
|
||
|
aWebServices->mSubmitReportDataCallback(aWebServices->mInterface,
|
||
|
theHttpResult,
|
||
|
aTranslatedResult,
|
||
|
aWebServices->mSubmitReportUserData);
|
||
|
aWebServices->mSubmitReportUserData = NULL;
|
||
|
aWebServices->mSubmitReportDataCallback = NULL;
|
||
|
}
|
||
|
GSI_UNUSED(theRequestData);
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////
|