From 10e118c498da74997ba8971a28f205358632ce3f Mon Sep 17 00:00:00 2001 From: tylerfangfb <70449874+tylerfangfb@users.noreply.github.com> Date: Sat, 29 Aug 2020 17:06:20 -0700 Subject: [PATCH 1/2] Support Facebook Gaming Graph Domain Facebook Gaming Graph Domain (graph.fb.gg) is a new domian dedicated for applications integrated with Facebook Login for Gaming. This change adds support in SDK to distinguish access token for FB or GG domain and make graph API calls accordingly. --- samples/LoginCpp-UWP/LoginCpp/Resources.resw | 2 +- .../winsdkfb.Shared/FacebookAccessTokenData.cpp | 11 +++++++++++ .../winsdkfb.Shared/FacebookAccessTokenData.h | 9 +++++++++ .../winsdkfb/winsdkfb.Shared/FacebookClient.cpp | 15 ++++++++++++++- .../winsdkfb/winsdkfb.Shared/FacebookSession.cpp | 12 ++++++++++-- .../winsdkfb/winsdkfb.Shared/GraphUriBuilder.cpp | 6 +++++- .../winsdkfb/winsdkfb.Shared/GraphUriBuilder.h | 2 +- 7 files changed, 51 insertions(+), 6 deletions(-) diff --git a/samples/LoginCpp-UWP/LoginCpp/Resources.resw b/samples/LoginCpp-UWP/LoginCpp/Resources.resw index 83ee551..67ed136 100644 --- a/samples/LoginCpp-UWP/LoginCpp/Resources.resw +++ b/samples/LoginCpp-UWP/LoginCpp/Resources.resw @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 1606735379540755 + 2607649655979891 Facebook Application ID diff --git a/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookAccessTokenData.cpp b/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookAccessTokenData.cpp index dc2cfef..6d533da 100644 --- a/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookAccessTokenData.cpp +++ b/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookAccessTokenData.cpp @@ -47,6 +47,9 @@ FBAccessTokenData::FBAccessTokenData( #ifdef _DEBUG DebugPrintExpirationTime(); #endif + + std::wstring wsAccessToken(AccessToken->Data()); + _graphDomain = (wsAccessToken.substr(0, 2) == L"GG") ? L"gaming" : L"facebook"; } FBAccessTokenData::FBAccessTokenData( @@ -64,6 +67,9 @@ FBAccessTokenData::FBAccessTokenData( Vector^ v = ref new Vector(0); _grantedPermissions = ref new FBPermissions(v->GetView()); _declinedPermissions = ref new FBPermissions(v->GetView()); + + std::wstring wsAccessToken(AccessToken->Data()); + _graphDomain = (wsAccessToken.substr(0, 2) == L"GG") ? L"gaming" : L"facebook"; } String^ FBAccessTokenData::AccessToken::get() @@ -71,6 +77,11 @@ String^ FBAccessTokenData::AccessToken::get() return _accessToken; } +String^ FBAccessTokenData::GraphDomain::get() +{ + return _graphDomain; +} + DateTime FBAccessTokenData::ExpirationDate::get() { return _expirationDate; diff --git a/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookAccessTokenData.h b/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookAccessTokenData.h index 3df957d..40860a4 100644 --- a/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookAccessTokenData.h +++ b/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookAccessTokenData.h @@ -50,6 +50,14 @@ namespace winsdkfb Platform::String^ get(); } + /** + * Graph domain should be used for current access token. + */ + property Platform::String^ GraphDomain + { + Platform::String^ get(); + } + /** * Expiration date of the access token. */ @@ -119,6 +127,7 @@ namespace winsdkfb #endif Platform::String^ _accessToken; + Platform::String^ _graphDomain; Windows::Foundation::DateTime _expirationDate; FBPermissions^ _grantedPermissions; FBPermissions^ _declinedPermissions; diff --git a/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookClient.cpp b/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookClient.cpp index 8d12db0..557b3cf 100644 --- a/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookClient.cpp +++ b/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookClient.cpp @@ -398,8 +398,8 @@ Uri^ FBClient::PrepareRequestUri( PropertySet^ parameters ) { + String^ graphDomain = L"facebook"; FBSession^ sess = FBSession::ActiveSession; - GraphUriBuilder^ uriBuilder = ref new GraphUriBuilder(path); if (parameters == nullptr) { @@ -427,11 +427,24 @@ Uri^ FBClient::PrepareRequestUri( sess->AccessTokenData->AccessToken); } + // For applications using Facebook Login for Gaming, graph API requests + // should be sent to different graph domain: graph.fb.gg + if (parametersWithoutMediaObjects->HasKey("access_token")) + { + String^ accessToken = safe_cast(parametersWithoutMediaObjects->Lookup("access_token")); + std::wstring wsAccessToken(accessToken->Data()); + if ((wsAccessToken.substr(0, 2) == L"GG")) + { + graphDomain = L"gaming"; + } + } + if (parametersWithoutMediaObjects->HasKey("format")) { parametersWithoutMediaObjects->Insert("format", "json-strings"); } + GraphUriBuilder^ uriBuilder = ref new GraphUriBuilder(path, graphDomain); SerializeParameters(parametersWithoutMediaObjects); // Add remaining parameters to query string. Note that parameters that diff --git a/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookSession.cpp b/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookSession.cpp index fe30e62..4cc7ca7 100644 --- a/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookSession.cpp +++ b/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookSession.cpp @@ -209,8 +209,16 @@ task FBSession::GetUserInfo( ) { PropertySet^ parameters = ref new PropertySet(); - parameters->Insert(L"fields", - L"gender,link,first_name,last_name,locale,timezone,email,updated_time,verified,name,id,picture"); + if (TokenData->GraphDomain == L"gaming") + { + parameters->Insert(L"fields", L"link,email,name,id,picture"); + } + else + { + parameters->Insert(L"fields", + L"gender,link,first_name,last_name,locale,timezone,email,updated_time,verified,name,id,picture"); + } + FBSingleValue^ value = ref new FBSingleValue( "/me", parameters, diff --git a/winsdkfb/winsdkfb/winsdkfb.Shared/GraphUriBuilder.cpp b/winsdkfb/winsdkfb/winsdkfb.Shared/GraphUriBuilder.cpp index 0b17f0b..0daceea 100644 --- a/winsdkfb/winsdkfb/winsdkfb.Shared/GraphUriBuilder.cpp +++ b/winsdkfb/winsdkfb/winsdkfb.Shared/GraphUriBuilder.cpp @@ -27,7 +27,7 @@ using namespace Windows::Foundation::Collections; using namespace winsdkfb; -GraphUriBuilder::GraphUriBuilder(String^ path) +GraphUriBuilder::GraphUriBuilder(String^ path, String^ graphDomain) : _queryParams { ref new PropertySet() } { @@ -45,6 +45,10 @@ GraphUriBuilder::GraphUriBuilder(String^ path) if (buildDomain) { String^ domain = L"https://graph.facebook.com/"; + if (graphDomain == L"gaming") + { + domain = L"https://graph.fb.gg/"; + } testUri = ref new Uri(domain + path); } _host = testUri->Host; diff --git a/winsdkfb/winsdkfb/winsdkfb.Shared/GraphUriBuilder.h b/winsdkfb/winsdkfb/winsdkfb.Shared/GraphUriBuilder.h index 18971c5..eb452ae 100644 --- a/winsdkfb/winsdkfb/winsdkfb.Shared/GraphUriBuilder.h +++ b/winsdkfb/winsdkfb/winsdkfb.Shared/GraphUriBuilder.h @@ -23,7 +23,7 @@ namespace winsdkfb public ref class GraphUriBuilder sealed { public: - GraphUriBuilder(Platform::String^ path); + GraphUriBuilder(Platform::String^ path, Platform::String^ graphDomain); Windows::Foundation::Uri^ MakeUri(); void AddQueryParam(Platform::String^ query, Platform::String^ param); From e2b3e8a3d7af342b1dbf95ee48498b567872a1e4 Mon Sep 17 00:00:00 2001 From: tylerfangfb <70449874+tylerfangfb@users.noreply.github.com> Date: Mon, 25 Jan 2021 00:33:34 -0800 Subject: [PATCH 2/2] Patch a race condition after login completes There seems to be a race condition for certain users that after login completes, the access token data was not written with granted or declined permissions. The root cause is yet to be found, but this fix avoid the SDK from crashing. --- .gitignore | 1 + samples/LoginCpp-UWP/LoginCpp/MainPage.xaml.cpp | 2 +- samples/LoginCpp-UWP/LoginCpp/Resources.resw | 2 +- winsdkfb/winsdkfb/winsdkfb.Shared/FacebookSession.cpp | 4 +++- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 7e68f46..8788d6d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ Packages.dgml Release sdk-build.log project.lock.json +winsdkfb/winsdkfb_uwp/UpgradeLog.htm diff --git a/samples/LoginCpp-UWP/LoginCpp/MainPage.xaml.cpp b/samples/LoginCpp-UWP/LoginCpp/MainPage.xaml.cpp index 239fb1d..6106124 100644 --- a/samples/LoginCpp-UWP/LoginCpp/MainPage.xaml.cpp +++ b/samples/LoginCpp-UWP/LoginCpp/MainPage.xaml.cpp @@ -105,7 +105,7 @@ BOOL MainPage::DidGetAllRequestedPermissions( BOOL success = FALSE; FBAccessTokenData^ data = FBSession::ActiveSession->AccessTokenData; - if (data) + if (data && data->DeclinedPermissions) { success = !data->DeclinedPermissions->Values->Size; } diff --git a/samples/LoginCpp-UWP/LoginCpp/Resources.resw b/samples/LoginCpp-UWP/LoginCpp/Resources.resw index 67ed136..64021f8 100644 --- a/samples/LoginCpp-UWP/LoginCpp/Resources.resw +++ b/samples/LoginCpp-UWP/LoginCpp/Resources.resw @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 2607649655979891 + 519296541448237 Facebook Application ID diff --git a/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookSession.cpp b/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookSession.cpp index 4cc7ca7..4716afa 100644 --- a/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookSession.cpp +++ b/winsdkfb/winsdkfb/winsdkfb.Shared/FacebookSession.cpp @@ -1334,7 +1334,9 @@ int FBSession::APIMinorVersion::get() void FBSession::SaveGrantedPermissions() { auto values =FBSession::DataContainer->Values; - values->Insert(GRANTED_PERMISSIONS_KEY, AccessTokenData->GrantedPermissions->ToString()); + if (AccessTokenData->GrantedPermissions != nullptr) { + values->Insert(GRANTED_PERMISSIONS_KEY, this->_AccessTokenData->GrantedPermissions->ToString()); + } } String^ FBSession::GetGrantedPermissions()