Something went wrong. Try again.
the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
Something went wrong. Try again.
19 kB · 690 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691//// Class to handle and manage integration with social networks.// 4J Studios Ltd, 2011.// Andy West//
#include "stdafx.h"#include "SocialManager.h"#include <assert.h>#include <xgraphics.h>#include "..\Sentient\SentientManager.h"
///////////////////////////////////////////////////////////////////////////// Constants.///////////////////////////////////////////////////////////////////////////
// Table of SDK IDs for the social networks.static const DWORD kaSocialNetworkIDS[ eNumSocialNetworks ] ={ 2, // eFacebook};
// WESTY : Not sure if we even need to get social access key!/*// Table of social network permissions that we will required to post.static const LPCWSTR kaSocialNetworkRequiredPermissions[ eNumSocialNetworks ] = { L"publish_stream", // eFacebook};
// Default size to use for social network access key text.static const DWORD kDefaultAccessKeyTextSize = 64;*/
///////////////////////////////////////////////////////////////////////////// Static members intialisation.///////////////////////////////////////////////////////////////////////////
// Initialise static instance pointer.CSocialManager* CSocialManager::m_pInstance = 0;
///////////////////////////////////////////////////////////////////////////// Class functions.///////////////////////////////////////////////////////////////////////////
// Get singleton instance.CSocialManager* CSocialManager::Instance(){ if ( m_pInstance == 0 ) // Is this the first time? { m_pInstance = new CSocialManager; // Create the singleton instance. } return m_pInstance;}
// Default constructor.CSocialManager::CSocialManager(){ m_eCurrState = eStateUnitialised; m_dwSocialPostingCapability = 0;
// WESTY : Not sure if we even need to get social access key!/* m_pAccessKeyText = NULL; m_dwAccessKeyTextSize = 0;*/
m_pMainImageBuffer = NULL; m_dwMainImageBufferSize = 0;
m_PostPreviewImage.pBytes = NULL; m_dwCurrRequestUser = -1;
ZeroMemory(m_wchTitleA,sizeof(WCHAR)*MAX_SOCIALPOST_CAPTION); ZeroMemory(m_wchCaptionA,sizeof(WCHAR)*MAX_SOCIALPOST_CAPTION); ZeroMemory(m_wchDescA,sizeof(WCHAR)*MAX_SOCIALPOST_DESC);
}
// To be called once during game init.void CSocialManager::Initialise(){ assert( m_eCurrState == eStateUnitialised ); m_eCurrState = eStateReady;
}
void CSocialManager::Tick(){ switch( m_eCurrState ) { case eStateUnitialised: // Nothing to do. break;
case eStateReady: // Nothing to do. break;
case eStateGetPostingCapability: { // Poll for result. DWORD dwResult = XGetOverlappedResult( &( m_Overlapped ), &( m_dwOverlappedResultCode ), false );
switch( dwResult ) { case ERROR_SUCCESS: app.DebugPrintf( "XSocialGetCapabilities - SUCCESS - FLAGS = %d\n", m_dwSocialPostingCapability ); m_eCurrState = eStateReady; break;
case ERROR_IO_INCOMPLETE: // Still on going. break;
default: // Some kind of error occured. app.DebugPrintf( "XSocialGetCapabilities - FAILED\n", m_dwSocialPostingCapability ); // WESTY: TO DO: Get error code, and possibly extened error code to figure out what went wrong. //assert( false ); m_eCurrState = eStateReady; break; } } break;
case eStatePostingImage: { // Poll for result. DWORD dwResult = XGetOverlappedResult( &( m_Overlapped ), &( m_dwOverlappedResultCode ), false );
switch( dwResult ) { case ERROR_SUCCESS: TelemetryManager->RecordMediaShareUpload(m_dwCurrRequestUser, ESen_MediaDestination_Facebook, eSen_MediaType_Picture);
app.DebugPrintf( "Facebook image post success!!!\n" ); DestroyMainPostImage(); DestroyPreviewPostImage();
// Award for successful post. ProfileManager.Award( m_dwCurrRequestUser, eAward_socialPost ); m_eCurrState = eStateReady; break;
case ERROR_IO_INCOMPLETE: // Still on going. break;
default: // For some reason, the operation did not complete. // SDK docs give no indication why this may be, but could be user cancelled the operation. app.DebugPrintf( "Facebook image post failure!!!\n" ); DestroyMainPostImage(); DestroyPreviewPostImage(); m_eCurrState = eStateReady; break; } } break;
case eStatePostingLink: { // Poll for result. DWORD dwResult = XGetOverlappedResult( &( m_Overlapped ), &( m_dwOverlappedResultCode ), false );
switch( dwResult ) { case ERROR_SUCCESS: app.DebugPrintf( "Facebook link post success!!!\n" );
// Award for successful post. ProfileManager.Award( m_dwCurrRequestUser, eAward_socialPost );
m_eCurrState = eStateReady; break;
case ERROR_IO_INCOMPLETE: // Still on going. break;
default: // For some reason, the operation did not complete. // SDK docs give no indication why this may be, but could be user cancelled the operation. app.DebugPrintf( "Facebook link post failure!!!\n" ); m_eCurrState = eStateReady; break; } } break;
default: // Unhandled state! assert( false ); break; }}
// Find out if we are allowed to post to social networks.bool CSocialManager::RefreshPostingCapability(){ bool bResult = false;
if ( m_eCurrState != eStateReady ) { return bResult; }
// Test for titles ability to post to social networks.
// Test for titles ability to post to social networks.
XMemSet( &m_Overlapped, 0, sizeof(XOVERLAPPED) );
DWORD dwResult = XSocialGetCapabilities( &( m_dwSocialPostingCapability ), &( m_Overlapped ) ); switch( dwResult ) { case ERROR_IO_PENDING: bResult = true; m_eCurrState = eStateGetPostingCapability; break;
case ERROR_FUNCTION_FAILED: { // Hmm ... why would it fail, and what are we meant to do about it? DWORD dwExtendedError = XGetOverlappedExtendedError( &( m_Overlapped ) ); app.DebugPrintf( "XSocialGetCapabilities ASYNC : FAILED : Extended Error %d\n", dwExtendedError ); //assert( false ); } break;
default: { // Should never get in here. DWORD dwExtendedError = XGetOverlappedExtendedError( &( m_Overlapped ) ); app.DebugPrintf( "XSocialGetCapabilities ASYNC : FAILED : Extended Error %d\n", dwExtendedError ); //assert( false ); } break; }
return bResult;}
bool CSocialManager::IsTitleAllowedToPostAnything(){ assert( m_eCurrState != eStateUnitialised );
return( m_dwSocialPostingCapability != 0 );}
bool CSocialManager::IsTitleAllowedToPostImages(){ assert( m_eCurrState != eStateUnitialised );
return( ( m_dwSocialPostingCapability & XSOCIAL_CAPABILITY_POSTIMAGE ) != 0 );}
bool CSocialManager::IsTitleAllowedToPostLinks(){ assert( m_eCurrState != eStateUnitialised );
return( ( m_dwSocialPostingCapability & XSOCIAL_CAPABILITY_POSTLINK ) != 0 );}
bool CSocialManager::AreAllUsersAllowedToPostImages(){ // catch no user being signed in to LIVE here too (or a local disconnect) BOOL bUserAllowedToPost=FALSE;
for(int i=0;i<XUSER_MAX_COUNT;i++) { if(ProfileManager.IsSignedInLive(i)) { XUserCheckPrivilege(i,XPRIVILEGE_SOCIAL_NETWORK_SHARING ,&bUserAllowedToPost); if(bUserAllowedToPost==FALSE) { return false; } } } return bUserAllowedToPost?true:false;}
// Ensure this is only done after posting is complete.void CSocialManager::DestroyMainPostImage(){ delete [] m_PostImageParams.pFullImage; m_PostImageParams.pFullImage=NULL; m_dwMainImageBufferSize=0; }
void CSocialManager::DestroyPreviewPostImage(){ XPhysicalFree( (void *)m_PostPreviewImage.pBytes ); m_PostPreviewImage.pBytes = NULL;}
void CSocialManager::SetSocialPostText(LPCWSTR pwchTitle, LPCWSTR pwchCaption, LPCWSTR pwchDesc){ wstring wTemp;
ZeroMemory(m_wchTitleA,sizeof(WCHAR)*(MAX_SOCIALPOST_CAPTION+1)); ZeroMemory(m_wchCaptionA,sizeof(WCHAR)*(MAX_SOCIALPOST_CAPTION+1)); ZeroMemory(m_wchDescA,sizeof(WCHAR)*(MAX_SOCIALPOST_DESC+1)); wTemp = pwchTitle; memcpy(m_wchTitleA,wTemp.c_str(),wTemp.length()*sizeof(WCHAR)); wTemp = pwchCaption; memcpy(m_wchCaptionA,wTemp.c_str(),wTemp.length()*sizeof(WCHAR)); wTemp = pwchDesc; memcpy(m_wchDescA,wTemp.c_str(),wTemp.length()*sizeof(WCHAR));}
bool CSocialManager::PostLinkToSocialNetwork( ESocialNetwork eSocialNetwork, DWORD dwUserIndex, bool bUsingKinect ){ if ( m_eCurrState != eStateReady ) { return false; }
// Ensure title is actually allowed to post links ... should always be the case, but we have to check for TCR. if ( IsTitleAllowedToPostLinks() == false ) { //assert( false ); return false; } // Ensure dwUserIndex is sensible. if ( dwUserIndex > 3 ) { //assert( false ); return false; }
// Store user index for award on successful post. m_dwCurrRequestUser = dwUserIndex;
// Required for kinect only. DWORD dwUserTrackingIndex = 0; if ( bUsingKinect ) { // WESTY - Will need a method to get this. dwUserTrackingIndex = 0; }
bool bResult = false;
// CreatePreviewImage();
// SDK social post flags.... // XSOCIAL_POST_USERGENERATEDCONTENT // XSOCIAL_POST_KINECTCONTENT // XSOCIAL_POST_GAMECONTENT // XSOCIAL_POST_ACHIEVEMENTCONTENT // XSOCIAL_POST_MEDIACONTENT
// 4J Stu - MessageText is not a member of the struct in the header of the latest XDK 20871.6 // The documentation hasn't changed though... //m_PostLinkParams.MessageText = L"This is a test link post."; m_PostLinkParams.TitleText = L"Test Title"; m_PostLinkParams.TitleURL = L"http:\\www.4jstudios.com"; m_PostLinkParams.PictureCaption = L"Test Picture Caption"; m_PostLinkParams.PictureDescription = L"Test Picture Description"; m_PostLinkParams.PictureURL = L"http:\\www.4jstudios.com"; m_PostLinkParams.PreviewImage = m_PostPreviewImage; m_PostLinkParams.Flags = ( XSOCIAL_POST_GAMECONTENT | XSOCIAL_POST_USERGENERATEDCONTENT ); // WESTY: Need to set correct flags for content type. m_PostLinkParams.Size = sizeof( m_PostLinkParams );
// BEGIN: Asyncronous function call version DWORD dwResult;
XMemSet( &m_Overlapped, 0, sizeof(XOVERLAPPED) );
if ( bUsingKinect ) { dwResult = XShowNuiSocialNetworkLinkPostUI( dwUserTrackingIndex, dwUserIndex, &( m_PostLinkParams ), &( m_Overlapped ) ); } else // using normal controller UI { dwResult = XShowSocialNetworkLinkPostUI( dwUserIndex, &( m_PostLinkParams ), &( m_Overlapped ) ); } switch( dwResult ) { case ERROR_IO_PENDING: bResult = true; m_eCurrState = eStatePostingLink; break;
case ERROR_FUNCTION_FAILED: // Hmm ... why would it fail, and what are we meant to do about it? Get extended error code!? DestroyMainPostImage(); DestroyPreviewPostImage(); //assert( false ); break;
default: // Should never get in here. DestroyMainPostImage(); DestroyPreviewPostImage(); assert( false ); break; } // END: Asyncronous function call version return bResult;}
bool CSocialManager::PostImageToSocialNetwork( ESocialNetwork eSocialNetwork, DWORD dwUserIndex, bool bUsingKinect ){ if ( m_eCurrState != eStateReady ) { return false; }
// Ensure title is actually allowed to post images ... should always be the case, but we have to check for TCR. if ( IsTitleAllowedToPostImages() == false ) { //assert( false ); return false; } // Ensure dwUserIndex is sensible. if ( dwUserIndex > 3 ) { //assert( false ); return false; }
// Store user index for award on successful post. m_dwCurrRequestUser = dwUserIndex;
// Required for kinect only. DWORD dwUserTrackingIndex = 0; if ( bUsingKinect ) { // WESTY - Will need a method to get this. dwUserTrackingIndex = 0; }
bool bResult = false;
PBYTE pbData=NULL; DWORD dwDataSize;
app.GetScreenshot(dwUserIndex,&pbData,&dwDataSize); app.GetPreviewImage(dwUserIndex,&m_PostPreviewImage);
// SDK social post flags.... // XSOCIAL_POST_USERGENERATEDCONTENT // XSOCIAL_POST_KINECTCONTENT // XSOCIAL_POST_GAMECONTENT // XSOCIAL_POST_ACHIEVEMENTCONTENT // XSOCIAL_POST_MEDIACONTENT
// 4J Stu - MessageText is not a member of the struct in the header of the latest XDK 20871.6 // The documentation hasn't changed though... //m_PostImageParams.MessageText = L"This is a test image post."; m_PostImageParams.TitleText = m_wchTitleA; m_PostImageParams.PictureCaption = m_wchCaptionA; m_PostImageParams.PictureDescription = m_wchDescA; m_PostImageParams.PreviewImage = m_PostPreviewImage; m_PostImageParams.Flags = ( XSOCIAL_POST_GAMECONTENT | XSOCIAL_POST_USERGENERATEDCONTENT ); // WESTY: Need to set correct flags for content type. m_PostImageParams.pFullImage = pbData;//m_pMainImageBuffer; m_PostImageParams.FullImageByteCount = dwDataSize;//m_dwMainImageBufferSize; m_PostImageParams.Size = sizeof( m_PostImageParams );
// BEGIN: Asyncronous function call version DWORD dwResult;
XMemSet( &m_Overlapped, 0, sizeof(XOVERLAPPED) );
if ( bUsingKinect ) { dwResult = XShowNuiSocialNetworkImagePostUI( dwUserTrackingIndex, dwUserIndex, &( m_PostImageParams ), &( m_Overlapped ) ); } else // using normal controller UI { dwResult = XShowSocialNetworkImagePostUI( dwUserIndex, &( m_PostImageParams ), &( m_Overlapped ) ); } switch( dwResult ) { case ERROR_IO_PENDING: bResult = true; m_eCurrState = eStatePostingImage; break;
case ERROR_FUNCTION_FAILED: // Hmm ... why would it fail, and what are we meant to do about it? Get extended error code!? DestroyMainPostImage(); DestroyPreviewPostImage(); //assert( false ); break;
default: // Should never get in here. DestroyMainPostImage(); DestroyPreviewPostImage(); assert( false ); break; } // END: Asyncronous function call version
return bResult;}
// WESTY : Not sure if we even need to get social access key!/*// It is unclear from the sdk docs what this is actually used for.// So far we have only created a syncronous version of this function, and the xbox functionality does not seem to work yet!bool CSocialManager::GetSocialNetworkAccessKey( ESocialNetwork eSocialNetwork, DWORD dwUserIndex, bool bUsingKinect, DWORD dwUserTrackingIndex, bool bShowNetworkSignin ){ bool bReturn = false;
DWORD dwResult;
// Ensure that we free any previously used access key buffer. if ( m_pAccessKeyText != NULL ) { delete [] m_pAccessKeyText; m_pAccessKeyText = NULL; }
// Get social network ID and permissions. DWORD dwSocialNetworkID = kaSocialNetworkIDS[ eSocialNetwork ]; LPCWSTR pRequiredPermissions = kaSocialNetworkRequiredPermissions[ eSocialNetwork ];
// Allocate buffer for social network access key text. m_dwAccessKeyTextSize = kDefaultAccessKeyTextSize; m_pAccessKeyText = new wchar_t [ m_dwAccessKeyTextSize ];
if ( bShowNetworkSignin ) { if ( bUsingKinect ) { dwResult = XShowNuiSocialGetUserToken( dwUserTrackingIndex, dwUserIndex, dwSocialNetworkID, pRequiredPermissions, m_pAccessKeyText, &( m_dwAccessKeyTextSize ), NULL );
// If buffer for key text was not large enough, reallocate buffer that is large enough and try again. if ( dwResult == ERROR_INSUFFICIENT_BUFFER ) { delete [] m_pAccessKeyText; m_pAccessKeyText = new wchar_t[ m_dwAccessKeyTextSize ]; dwResult = XShowNuiSocialGetUserToken( dwUserTrackingIndex, dwUserIndex, dwSocialNetworkID, pRequiredPermissions, m_pAccessKeyText, &( m_dwAccessKeyTextSize ), NULL ); } } else // using standard controller interface. { dwResult = XShowSocialGetUserToken( dwUserIndex, dwSocialNetworkID, pRequiredPermissions, m_pAccessKeyText, &( m_dwAccessKeyTextSize ), NULL );
// If buffer for key text was not large enough, reallocate buffer that is large enough and try again. if ( dwResult == ERROR_INSUFFICIENT_BUFFER ) { delete [] m_pAccessKeyText; m_pAccessKeyText = new wchar_t[ m_dwAccessKeyTextSize ]; dwResult = XShowSocialGetUserToken( dwUserIndex, dwSocialNetworkID, pRequiredPermissions, m_pAccessKeyText, &( m_dwAccessKeyTextSize ), NULL ); } } } else // we are trying to obtain cached user access key. { dwResult = XSocialGetUserToken( dwUserIndex, dwSocialNetworkID, pRequiredPermissions, m_pAccessKeyText, &( m_dwAccessKeyTextSize ), NULL );
// If buffer for key text was not large enough, reallocate buffer that is large enough and try again. if ( dwResult == ERROR_INSUFFICIENT_BUFFER ) { delete [] m_pAccessKeyText; m_pAccessKeyText = new wchar_t[ m_dwAccessKeyTextSize ]; dwResult = XSocialGetUserToken( dwUserIndex, dwSocialNetworkID, pRequiredPermissions, m_pAccessKeyText, &( m_dwAccessKeyTextSize ), NULL ); } }
// Check result. if ( dwResult != ERROR_SUCCESS ) { switch( dwResult ) { // ERROR_OUT_MEMORY does not seem to exist, despite being mentioned in the XDK docs. //case ERROR_OUT_MEMORY: // // Not much we can do about this?! // assert( false ); // break;
case ERROR_INVALID_PARAMETER: // dwUserIndex or dwSocialNetworkID are incorrect! assert( false ); break;
case ERROR_ACCESS_DENIED: // Either no user is signed in, or title not allowed to use social posting (the latter should never occur!). break;
case ERROR_FUNCTION_FAILED: // dwTrackingID is not valid. Kinect only. Not sure what we would do about this one? assert( false ); break;
case ERROR_INSUFFICIENT_BUFFER: // This should not be possible, we already resized the buffer and retried if it was too small. assert( false ); break;
case ERROR_GRACEFUL_DISCONNECT: // User disconnected before process was complete. break;
case ERROR_CANCELLED: // User cancelled the request. break;
case ERROR_BAD_NET_RESP: // Error in access, or some kind of network related error. // Need to display warning?? assert( false ); break;
default: // Should never get here. assert( false ); break; } } else // success { bReturn = true; }
return bReturn;}*/
// WESTY : Not sure if we even need to get social access key!/*
// It is unclear from the sdk docs what this is actually used for.// So far we have only created a syncronous version of this function, and the xbox functionality does not seem to work yet!bool CSocialManager::ObtainSocialNetworkAccessKey( ESocialNetwork eSocialNetwork, DWORD dwUserIndex, bool bUsingKinect ){ if ( m_eCurrState != eStateReady ) { return false; } // Ensure dwUserIndex is sensible. if ( dwUserIndex > 3 ) { assert( false ); return false; }
// Kinect user tracking index. DWORD dwUserTrackingIndex = 0; if ( bUsingKinect ) { // WESTY - Will need a method to get this. dwUserTrackingIndex = 0; } // Try first of all to obtain cached user key. bool bSocialNetworkAccessKeyAvailable = GetSocialNetworkAccessKey( eSocialNetwork, dwUserIndex, bUsingKinect, dwUserTrackingIndex, false );
if ( bSocialNetworkAccessKeyAvailable == false ) { // No chached user key, so we will try the UI version to signin to social network? bSocialNetworkAccessKeyAvailable = GetSocialNetworkAccessKey( eSocialNetwork, dwUserIndex, bUsingKinect, dwUserTrackingIndex, true ); }
return bSocialNetworkAccessKeyAvailable;}*/