first commit
This commit is contained in:
690
Minecraft.Client/Xbox/Social/SocialManager.cpp
Normal file
690
Minecraft.Client/Xbox/Social/SocialManager.cpp
Normal file
@@ -0,0 +1,690 @@
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
*/
|
||||
135
Minecraft.Client/Xbox/Social/SocialManager.h
Normal file
135
Minecraft.Client/Xbox/Social/SocialManager.h
Normal file
@@ -0,0 +1,135 @@
|
||||
//
|
||||
// Class to handle and manage integration with social networks.
|
||||
// 4J Studios Ltd, 2011.
|
||||
// Andy West
|
||||
//
|
||||
|
||||
#ifndef _SOCIAL_MANAGER_H
|
||||
#define _SOCIAL_MANAGER_H
|
||||
|
||||
#include <xsocialpost.h>
|
||||
|
||||
#define MAX_SOCIALPOST_CAPTION 60
|
||||
#define MAX_SOCIALPOST_DESC 100
|
||||
|
||||
// XDK only provides for facebook so far. Others may follow!?
|
||||
enum ESocialNetwork
|
||||
{
|
||||
eFacebook = 0,
|
||||
eNumSocialNetworks
|
||||
};
|
||||
|
||||
|
||||
// Class follows singleton design pattern.
|
||||
class CSocialManager
|
||||
{
|
||||
private:
|
||||
// Default constructor, copy constructor and assignment operator are all private.
|
||||
CSocialManager();
|
||||
CSocialManager( const CSocialManager& );
|
||||
CSocialManager& operator= ( const CSocialManager& );
|
||||
|
||||
// Static private instance.
|
||||
static CSocialManager* m_pInstance;
|
||||
|
||||
// Bitset of title posting capability flags ( XSOCIAL_CAPABILITY_POSTIMAGE, XSOCIAL_CAPABILITY_POSTLINK ).
|
||||
DWORD m_dwSocialPostingCapability;
|
||||
|
||||
// Index of user who made current active request.
|
||||
DWORD m_dwCurrRequestUser;
|
||||
|
||||
// WESTY : Not sure if we even need to get social access key!
|
||||
/*
|
||||
// Size of the social network access key text buffer.
|
||||
DWORD m_dwAccessKeyTextSize;
|
||||
|
||||
// Pointer to the social network access key text buffer.
|
||||
LPWSTR m_pAccessKeyText;
|
||||
*/
|
||||
|
||||
// The various states of the manager.
|
||||
enum EState
|
||||
{
|
||||
eStateUnitialised = 0,
|
||||
eStateReady,
|
||||
eStateGetPostingCapability,
|
||||
eStatePostingImage,
|
||||
eStatePostingLink,
|
||||
};
|
||||
|
||||
|
||||
// Current state that manager is in.
|
||||
EState m_eCurrState;
|
||||
|
||||
// For xsocial asyncronous operations.
|
||||
XOVERLAPPED m_Overlapped;
|
||||
DWORD m_dwOverlappedResultCode;
|
||||
|
||||
// Social post preview image struct.
|
||||
XSOCIAL_PREVIEWIMAGE m_PostPreviewImage;
|
||||
|
||||
// Social post image params.
|
||||
XSOCIAL_IMAGEPOSTPARAMS m_PostImageParams;
|
||||
|
||||
// Social post link params.
|
||||
XSOCIAL_LINKPOSTPARAMS m_PostLinkParams;
|
||||
|
||||
// Image details for posting an image to social network.
|
||||
unsigned char* m_pMainImageBuffer;
|
||||
DWORD m_dwMainImageBufferSize;
|
||||
|
||||
void DestroyMainPostImage();
|
||||
void DestroyPreviewPostImage();
|
||||
|
||||
// WESTY : Not sure if we even need to get social access key!
|
||||
/*
|
||||
bool GetSocialNetworkAccessKey( ESocialNetwork eSocialNetwork, DWORD dwUserIndex, bool bUsingKinect, DWORD dwUserTrackingIndex, bool bShowNetworkSignin );
|
||||
*/
|
||||
|
||||
public:
|
||||
// Retrieve singleton instance.
|
||||
static CSocialManager* Instance();
|
||||
|
||||
// To be called once during game init.
|
||||
void Initialise();
|
||||
|
||||
// Tick the social manager. Only does anything in async mode, polls for results of async actions.
|
||||
void Tick();
|
||||
|
||||
// May need to be called if something changes (i.e. player signs in to live ).
|
||||
bool RefreshPostingCapability();
|
||||
|
||||
// Returns true if any social newtork posting is allowed by us, false if not (if false, game must not display any social network UI).
|
||||
bool IsTitleAllowedToPostAnything();
|
||||
|
||||
// Returns true if we are allowed to post images to social networks.
|
||||
bool IsTitleAllowedToPostImages();
|
||||
|
||||
// Returns true if we are allowed to post links to social networks.
|
||||
bool IsTitleAllowedToPostLinks();
|
||||
|
||||
// Returns false if any of the live signed in users have disabled XPRIVILEGE_SOCIAL_NETWORK_SHARING
|
||||
bool AreAllUsersAllowedToPostImages();
|
||||
|
||||
// Post a test link to social network.
|
||||
bool PostLinkToSocialNetwork( ESocialNetwork eSocialNetwork, DWORD dwUserIndex, bool bUsingKinect );
|
||||
|
||||
// Post a test image to social network.
|
||||
bool PostImageToSocialNetwork( ESocialNetwork eSocialNetwork, DWORD dwUserIndex, bool bUsingKinect );
|
||||
|
||||
void SetSocialPostText(LPCWSTR Title, LPCWSTR Caption, LPCWSTR Desc);
|
||||
|
||||
// WESTY : Not sure if we even need to get social access key!
|
||||
/*
|
||||
// We do not currently know what this is used for. We may not even need it?
|
||||
bool ObtainSocialNetworkAccessKey( ESocialNetwork eSocialNetwork, DWORD dwUserIndex, bool bUsingKinect );
|
||||
*/
|
||||
|
||||
private:
|
||||
WCHAR m_wchTitleA[MAX_SOCIALPOST_CAPTION+1];
|
||||
WCHAR m_wchCaptionA[MAX_SOCIALPOST_CAPTION+1];
|
||||
WCHAR m_wchDescA[MAX_SOCIALPOST_DESC+1];
|
||||
|
||||
};
|
||||
|
||||
#endif //_SOCIAL_MANAGER_H
|
||||
Reference in New Issue
Block a user