5
5
#include " pch.h"
6
6
#include " Game.h"
7
7
8
+ #include < ppltasks.h>
9
+
8
10
using namespace DirectX ;
9
11
using namespace Windows ::Xbox::Input;
10
12
using namespace Windows ::Foundation::Collections;
13
+ using namespace concurrency ;
14
+ using namespace Windows ::Xbox::System;
11
15
12
16
using Microsoft::WRL::ComPtr;
13
17
@@ -33,50 +37,80 @@ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
33
37
#define INTERACTIVE_ID " 135704"
34
38
#define SHARE_CODE " xe7dpqd5"
35
39
36
- // Display a short code to the user in order to obtain a reusable token for future connections.
37
- int authorize (std::string& authorization)
40
+ int GetXToken (std::string& token)
38
41
{
39
- int err = 0 ;
40
- char shortCode[7 ];
41
- size_t shortCodeLength = sizeof (shortCode);
42
- char shortCodeHandle[1024 ];
43
- size_t shortCodeHandleLength = sizeof (shortCodeHandle);
44
- err = interactive_auth_get_short_code (CLIENT_ID, nullptr , shortCode, &shortCodeLength, shortCodeHandle, &shortCodeHandleLength);
45
- if (err) return err;
46
-
47
- std::cout << " Visit " << " https://www.mixer.com/go?code=" << shortCode;
48
-
49
- // Wait for OAuth token response.
50
- char refreshTokenBuffer[1024 ];
51
- size_t refreshTokenLength = sizeof (refreshTokenBuffer);
52
- err = interactive_auth_wait_short_code (CLIENT_ID, nullptr , shortCodeHandle, refreshTokenBuffer, &refreshTokenLength);
53
- if (err)
42
+ std::wstring mixerRelyingParty = L" https://mixer.com" ;
43
+ std::wstring authRequestHeaders = L" " ;
44
+ auto platformHttp = ref new Platform::String (L" POST" );
45
+ auto platformUrl = ref new Platform::String (mixerRelyingParty.c_str ());
46
+ auto platformHeaders = ref new Platform::String (authRequestHeaders.c_str ());
47
+
48
+ std::wstring wstrReturnedToken = L" " ;
49
+
50
+ HRESULT hr = S_OK;
51
+
52
+ // Note: This would fail certification. You must pop TCUI and allow a user to be chosen.
53
+ Windows::Xbox::System::User^ currentUser = Windows::Xbox::System::User::Users->GetAt (0 );
54
+ if (nullptr == currentUser)
54
55
{
55
- if (MIXER_ERROR_TIMED_OUT == err)
56
+ OutputDebugStringA (" No user signed in. Please sign in a user and try this sample again." );
57
+ return E_ABORT;
58
+ }
59
+
60
+ try
61
+ {
62
+ // Make platform call to get token.
63
+ auto asyncOp = currentUser->GetTokenAndSignatureAsync (platformHttp, platformUrl, platformHeaders);
64
+
65
+ // Construct an object that waits for the AsyncOperation to finish
66
+ task<GetTokenAndSignatureResult^> asyncTask = create_task (asyncOp);
67
+
68
+ // Capture the async then so we can ensure the lambda finishes before continuing
69
+ auto asyncFinalise = asyncTask.then (
70
+ [&wstrReturnedToken, &hr](
71
+ task<GetTokenAndSignatureResult^> operation)
56
72
{
57
- std::cout << " Authorization timed out, user did not approve access within the time limit." ;
58
- }
59
- else if (MIXER_ERROR_AUTH_DENIED == err)
73
+ try
74
+ {
75
+ GetTokenAndSignatureResult^ result = operation.get ();
76
+
77
+ if (result->Token ->IsEmpty ())
78
+ {
79
+ hr = E_UNEXPECTED;
80
+ return ;
81
+ }
82
+
83
+ wstrReturnedToken = result->Token ->Data ();
84
+ hr = S_OK;
85
+ }
86
+ catch (Platform::Exception ^ e)
87
+ {
88
+ hr = e->HResult ;
89
+ }
90
+ });
91
+
92
+ // Clean up the async task
93
+ asyncTask.wait ();
94
+ asyncOp->Close ();
95
+
96
+ // Wait for the lambda to finish.
97
+ asyncFinalise.wait ();
98
+
99
+ // Check for any failures
100
+ if (FAILED (hr))
60
101
{
61
- std::cout << " User denied access. " ;
102
+ return hr ;
62
103
}
63
104
64
- return err;
105
+ // Convert data to utf8
106
+ token = converter.to_bytes (wstrReturnedToken);
107
+ }
108
+ catch (Platform::Exception^ e)
109
+ {
110
+ return e->HResult ;
65
111
}
66
112
67
- /*
68
- * TODO: This is where you would serialize the refresh token for future use in a way that is associated with the current user.
69
- * Future calls would then only need to check if the token is stale, refresh it if so, and then parse the new authorization header.
70
- */
71
-
72
- // Extract the authorization header from the refresh token.
73
- char authBuffer[1024 ];
74
- size_t authBufferLength = sizeof (authBuffer);
75
- err = interactive_auth_parse_refresh_token (refreshTokenBuffer, authBuffer, &authBufferLength);
76
- if (err) return err;
77
-
78
- authorization = std::string (authBuffer, authBufferLength);
79
- return 0 ;
113
+ return S_OK;
80
114
}
81
115
82
116
@@ -100,7 +134,7 @@ void Game::Initialize(IUnknown* window)
100
134
101
135
// Get an authorization token for the user to pass to the connect function.
102
136
std::string authorization;
103
- err = authorize (authorization);
137
+ err = GetXToken (authorization);
104
138
if (err)
105
139
{
106
140
throw err;
@@ -140,15 +174,15 @@ void Game::Initialize(IUnknown* window)
140
174
Game* game = (Game*)context;
141
175
if (errorCode)
142
176
{
143
- std::cerr << errorMessage << " (" << std::to_string (errorCode) << " )" << std::endl ;
177
+ OutputDebugStringA (( std::string ( " ERROR: " ) + errorMessage + " (" + std::to_string (errorCode) + " )" ). c_str ()) ;
144
178
}
145
179
else
146
180
{
147
181
// Transaction was captured, now execute the most super awesome interactive functionality!
148
182
std::string controlId = game->m_controlsById [transactionId];
149
183
if (0 == strcmp (" GiveHealth" , controlId.c_str ()))
150
184
{
151
- std::cout << " Giving health to the player!" << std::endl ;
185
+ OutputDebugStringA ( " Giving health to the player!\n " ) ;
152
186
}
153
187
}
154
188
@@ -199,7 +233,7 @@ void Game::Update(DX::StepTimer const& timer)
199
233
int err = interactive_run (m_interactiveSession, 1 );
200
234
if (err)
201
235
{
202
- std::cerr << " Failed to process interactive event, error : " << std::to_string (err);
236
+ OutputDebugStringA (( std::string ( " ERROR: Failed to process interactive event: " ) + std::to_string (err)). c_str () );
203
237
}
204
238
205
239
PIXEndEvent ();
0 commit comments