the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2
3#include "XboxLeaderboardManager.h"
4
5#include "..\Network\NetworkPlayerXbox.h"
6
7#ifdef _XBOX
8LeaderboardManager *LeaderboardManager::m_instance = new XboxLeaderboardManager(); //Singleton instance of the LeaderboardManager
9#endif
10
11const XboxLeaderboardManager::LeaderboardDescriptor XboxLeaderboardManager::LEADERBOARD_DESCRIPTORS[XboxLeaderboardManager::NUM_LEADERBOARDS][4] = {
12 {
13 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_TRAVELLING_PEACEFUL, 4, STATS_COLUMN_TRAVELLING_PEACEFUL_WALKED, STATS_COLUMN_TRAVELLING_PEACEFUL_FALLEN, STATS_COLUMN_TRAVELLING_PEACEFUL_MINECART, STATS_COLUMN_TRAVELLING_PEACEFUL_BOAT, NULL, NULL, NULL,NULL),
14 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_TRAVELLING_EASY, 4, STATS_COLUMN_TRAVELLING_EASY_WALKED, STATS_COLUMN_TRAVELLING_EASY_FALLEN, STATS_COLUMN_TRAVELLING_EASY_MINECART, STATS_COLUMN_TRAVELLING_EASY_BOAT, NULL, NULL, NULL,NULL),
15 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_TRAVELLING_NORMAL, 4, STATS_COLUMN_TRAVELLING_NORMAL_WALKED, STATS_COLUMN_TRAVELLING_NORMAL_FALLEN, STATS_COLUMN_TRAVELLING_NORMAL_MINECART, STATS_COLUMN_TRAVELLING_NORMAL_BOAT, NULL, NULL, NULL,NULL),
16 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_TRAVELLING_HARD, 4, STATS_COLUMN_TRAVELLING_HARD_WALKED, STATS_COLUMN_TRAVELLING_HARD_FALLEN, STATS_COLUMN_TRAVELLING_HARD_MINECART, STATS_COLUMN_TRAVELLING_HARD_BOAT, NULL, NULL, NULL,NULL),
17 }, {
18 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_MINING_BLOCKS_PEACEFUL, 7, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_DIRT, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_STONE, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_SAND, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_COBBLESTONE, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_GRAVEL, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_CLAY, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_OBSIDIAN, NULL ),
19 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_MINING_BLOCKS_EASY, 7, STATS_COLUMN_MINING_BLOCKS_EASY_DIRT, STATS_COLUMN_MINING_BLOCKS_EASY_STONE, STATS_COLUMN_MINING_BLOCKS_EASY_SAND, STATS_COLUMN_MINING_BLOCKS_EASY_COBBLESTONE, STATS_COLUMN_MINING_BLOCKS_EASY_GRAVEL, STATS_COLUMN_MINING_BLOCKS_EASY_CLAY, STATS_COLUMN_MINING_BLOCKS_EASY_OBSIDIAN, NULL ),
20 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_MINING_BLOCKS_NORMAL, 7, STATS_COLUMN_MINING_BLOCKS_NORMAL_DIRT, STATS_COLUMN_MINING_BLOCKS_NORMAL_STONE, STATS_COLUMN_MINING_BLOCKS_NORMAL_SAND, STATS_COLUMN_MINING_BLOCKS_NORMAL_COBBLESTONE, STATS_COLUMN_MINING_BLOCKS_NORMAL_GRAVEL, STATS_COLUMN_MINING_BLOCKS_NORMAL_CLAY, STATS_COLUMN_MINING_BLOCKS_NORMAL_OBSIDIAN, NULL ),
21 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_MINING_BLOCKS_HARD, 7, STATS_COLUMN_MINING_BLOCKS_HARD_DIRT, STATS_COLUMN_MINING_BLOCKS_HARD_STONE, STATS_COLUMN_MINING_BLOCKS_HARD_SAND, STATS_COLUMN_MINING_BLOCKS_HARD_COBBLESTONE, STATS_COLUMN_MINING_BLOCKS_HARD_GRAVEL, STATS_COLUMN_MINING_BLOCKS_HARD_CLAY, STATS_COLUMN_MINING_BLOCKS_HARD_OBSIDIAN, NULL ),
22 }, {
23 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_FARMING_PEACEFUL, 6, STATS_COLUMN_FARMING_PEACEFUL_EGGS, STATS_COLUMN_FARMING_PEACEFUL_WHEAT, STATS_COLUMN_FARMING_PEACEFUL_MUSHROOMS,STATS_COLUMN_FARMING_PEACEFUL_SUGARCANE,STATS_COLUMN_FARMING_PEACEFUL_MILK, STATS_COLUMN_FARMING_PEACEFUL_PUMPKINS, NULL, NULL ),
24 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_FARMING_EASY, 6, STATS_COLUMN_FARMING_EASY_EGGS, STATS_COLUMN_FARMING_PEACEFUL_WHEAT, STATS_COLUMN_FARMING_EASY_MUSHROOMS, STATS_COLUMN_FARMING_EASY_SUGARCANE, STATS_COLUMN_FARMING_EASY_MILK, STATS_COLUMN_FARMING_EASY_PUMPKINS, NULL, NULL ),
25 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_FARMING_NORMAL, 6, STATS_COLUMN_FARMING_NORMAL_EGGS, STATS_COLUMN_FARMING_NORMAL_WHEAT, STATS_COLUMN_FARMING_NORMAL_MUSHROOMS, STATS_COLUMN_FARMING_NORMAL_SUGARCANE, STATS_COLUMN_FARMING_NORMAL_MILK, STATS_COLUMN_FARMING_NORMAL_PUMPKINS, NULL, NULL ),
26 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_FARMING_HARD, 6, STATS_COLUMN_FARMING_HARD_EGGS, STATS_COLUMN_FARMING_HARD_WHEAT, STATS_COLUMN_FARMING_HARD_MUSHROOMS, STATS_COLUMN_FARMING_HARD_SUGARCANE, STATS_COLUMN_FARMING_HARD_MILK, STATS_COLUMN_FARMING_HARD_PUMPKINS, NULL, NULL ),
27 }, {
28 XboxLeaderboardManager::LeaderboardDescriptor( NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ),
29 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_KILLS_EASY, 7, STATS_COLUMN_KILLS_EASY_ZOMBIES, STATS_COLUMN_KILLS_EASY_SKELETONS, STATS_COLUMN_KILLS_EASY_CREEPERS, STATS_COLUMN_KILLS_EASY_SPIDERS, STATS_COLUMN_KILLS_EASY_SPIDERJOCKEYS, STATS_COLUMN_KILLS_EASY_ZOMBIEPIGMEN, STATS_COLUMN_KILLS_EASY_SLIME, NULL ),
30 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_KILLS_NORMAL, 7, STATS_COLUMN_KILLS_NORMAL_ZOMBIES, STATS_COLUMN_KILLS_NORMAL_SKELETONS, STATS_COLUMN_KILLS_NORMAL_CREEPERS, STATS_COLUMN_KILLS_NORMAL_SPIDERS, STATS_COLUMN_KILLS_NORMAL_SPIDERJOCKEYS, STATS_COLUMN_KILLS_NORMAL_ZOMBIEPIGMEN, STATS_COLUMN_KILLS_NORMAL_SLIME, NULL ),
31 XboxLeaderboardManager::LeaderboardDescriptor( STATS_VIEW_KILLS_HARD, 7, STATS_COLUMN_KILLS_HARD_ZOMBIES, STATS_COLUMN_KILLS_HARD_SKELETONS, STATS_COLUMN_KILLS_HARD_CREEPERS, STATS_COLUMN_KILLS_HARD_SPIDERS, STATS_COLUMN_KILLS_HARD_SPIDERJOCKEYS, STATS_COLUMN_KILLS_HARD_ZOMBIEPIGMEN, STATS_COLUMN_KILLS_HARD_SLIME, NULL ),
32 },
33};
34
35XboxLeaderboardManager::XboxLeaderboardManager()
36{
37 m_eStatsState = eStatsState_Idle;
38 m_statsRead = false;
39
40 m_hSession = NULL;
41 m_spec = NULL;
42 m_stats = NULL;
43
44 m_isQNetSession = false;
45 m_endingSession = false;
46}
47
48XboxLeaderboardManager::~XboxLeaderboardManager() {}
49
50void XboxLeaderboardManager::Tick()
51{
52 if( m_eStatsState == eStatsState_Getting )
53 {
54
55 /*if( IsStatsReadComplete() )
56 if( m_readCompleteCallback != NULL )
57 m_readCompleteCallback(m_readCompleteUserdata);*/
58
59 if ( IsStatsReadComplete() )
60 if (m_readListener != NULL)
61 {
62 // 4J Stu - If the state is other than ready, then we don't have any stats to sort
63 if(m_eFilterMode == LeaderboardManager::eFM_Friends && m_eStatsState == eStatsState_Ready) SortFriendStats();
64
65 bool ret = m_readListener->OnStatsReadComplete(m_eStatsState==eStatsState_Ready, 0, m_stats); // TODO
66 if (ret) m_eStatsState = eStatsState_Idle;
67 }
68 }
69
70 if( m_endingSession )
71 {
72 if( XHasOverlappedIoCompleted( &m_endSessionOverlapped ))
73 {
74 DeleteSession();
75 m_endingSession = false;
76 }
77 }
78}
79
80bool XboxLeaderboardManager::OpenSession()
81{
82 //Can't create a new session when deleting a previous one
83 if (m_endingSession) return false;
84
85 //We've already got an open session
86 if (m_hSession != NULL) return true;
87
88 int lockedProfile = ProfileManager.GetLockedProfile();
89 if( lockedProfile == -1 )
90 {
91 m_hSession = NULL;
92 return false;
93 }
94
95 XUserGetXUID(lockedProfile, &m_myXUID);
96 XUserSetContext(lockedProfile, X_CONTEXT_GAME_TYPE, X_CONTEXT_GAME_TYPE_STANDARD);
97
98 //We already have a QNet session (ie we are joining/in/leaving a multiplayer game)
99 if(g_NetworkManager.IsInSession())
100 {
101 if(g_NetworkManager.IsInStatsEnabledSession())
102 {
103 m_isQNetSession = true;
104 return true;
105 }
106 //else
107 //{
108 // return false;
109 //}
110 }
111
112 XSESSION_INFO sessionInfo;
113 ULONGLONG sessionNonce;
114
115 DWORD ret = XSessionCreate(XSESSION_CREATE_USES_STATS | XSESSION_CREATE_HOST, lockedProfile, 8, 8, &sessionNonce, &sessionInfo, NULL, &m_hSession);
116 if( ret != ERROR_SUCCESS )
117 {
118 m_hSession = NULL;
119 return false;
120 }
121
122 DWORD userIndices[1] = { lockedProfile };
123 BOOL privateSlots[1] = { FALSE };
124 ret = XSessionJoinLocal(m_hSession, 1, userIndices, privateSlots, NULL);
125 if( ret != ERROR_SUCCESS )
126 {
127 m_hSession = NULL;
128 return false;
129 }
130
131 ret = XSessionStart(m_hSession, 0, NULL);
132 if( ret != ERROR_SUCCESS )
133 {
134 m_hSession = NULL;
135 return false;
136 }
137
138 return true;
139}
140
141void XboxLeaderboardManager::CloseSession()
142{
143 if( !m_endingSession )
144 {
145 if (!XHasOverlappedIoCompleted(&m_overlapped))
146 XCancelOverlapped(&m_overlapped);
147
148 if (m_isQNetSession == true)
149 {
150 m_isQNetSession = false;
151 return;
152 }
153
154 if (m_hSession == NULL) return;
155
156 memset(&m_endSessionOverlapped, 0, sizeof(m_endSessionOverlapped));
157
158 DWORD ret = XSessionEnd( m_hSession, &m_endSessionOverlapped );
159 if (ret == ERROR_SUCCESS || ret == ERROR_IO_PENDING)
160 {
161 m_endingSession = true;
162 }
163 else
164 {
165 //Failed so just delete the session
166 if (ret != ERROR_SUCCESS) DeleteSession();
167 }
168
169 m_readListener = NULL;
170 }
171}
172
173void XboxLeaderboardManager::DeleteSession()
174{
175 XSessionDelete(m_hSession, NULL);
176 CloseHandle(m_hSession);
177 m_hSession = NULL;
178}
179
180bool XboxLeaderboardManager::WriteStats(unsigned int viewCount, ViewIn views)
181{
182 DWORD ret = S_OK;
183
184 // some debug code to catch the leaderboard write with 7 views
185#ifndef _CONTENT_PACKAGE
186 if(viewCount>5) __debugbreak();
187#endif
188
189 // 4J Stu - If we are online we already have a session, so use that
190 if(m_isQNetSession == true)
191 {
192 INetworkPlayer *player = g_NetworkManager.GetPlayerByXuid(m_myXUID);
193 if(player != NULL)
194 {
195 ret = ((NetworkPlayerXbox *)player)->GetQNetPlayer()->WriteStats(viewCount,views);
196 //printf("Wrote stats to QNet player\n");
197 }
198 else
199 {
200 ret = ERROR_NO_SUCH_USER;
201 assert(false && "Failed to write stats to a QNET session as no player exists with that XUID");
202 app.DebugPrintf("Failed to write stats to a QNET session as no player exists with that XUID\n");
203 }
204 }
205 else
206 {
207 ret = XSessionWriteStats(m_hSession, m_myXUID, viewCount, views, NULL);
208 }
209 if (ret != ERROR_SUCCESS) return false;
210 return true;
211}
212
213void XboxLeaderboardManager::CancelOperation()
214{
215 //Need to have a session open
216 if( m_hSession == NULL )
217 if( !OpenSession() )
218 return;
219
220 //Abort any current read operation
221 if( m_eStatsState == eStatsState_Getting )
222 if( !XHasOverlappedIoCompleted( &m_overlapped ))
223 XCancelOverlapped( &m_overlapped );
224
225 m_eStatsState = eStatsState_Idle;
226}
227
228bool XboxLeaderboardManager::ReadStats_MyScore(LeaderboardReadListener *callback, int difficulty, EStatsType type, PlayerUID myUID, unsigned int readCount)
229{
230 if (!readStats(difficulty,type)) return false;
231 if (!LeaderboardManager::ReadStats_MyScore(callback, difficulty, type, myUID, readCount)) return false;
232
233 HANDLE hEnumerator;
234 DWORD ret;
235
236 //DWORD readCount = 0;
237
238 m_numStats = 0;
239 ret = XUserCreateStatsEnumeratorByXuid(
240 0,
241 m_myXUID,
242 readCount,
243 1, //specCount,
244 m_spec,
245 &m_numStats,
246 &hEnumerator);
247
248 if( ret != ERROR_SUCCESS ) return false;
249
250 //Allocate a buffer for the stats
251 m_stats = (PXUSER_STATS_READ_RESULTS) new BYTE[m_numStats];
252 if (m_stats == NULL) return false;
253
254 memset(m_stats, 0, m_numStats);
255 memset(&m_overlapped, 0, sizeof(m_overlapped));
256
257 ret = XEnumerate(
258 hEnumerator, // Enumeration handle
259 m_stats, // Buffer
260 m_numStats, // Size of buffer
261 NULL, // Number of rows returned; not used for async
262 &m_overlapped ); // Overlapped structure; not used for sync
263
264 if ( (ret!=ERROR_SUCCESS) && (ret!=ERROR_IO_PENDING) ) return false;
265
266 m_eStatsState = eStatsState_Getting;
267 return true;
268}
269
270bool XboxLeaderboardManager::ReadStats_Friends(LeaderboardReadListener *callback, int difficulty, EStatsType type, PlayerUID myUID, unsigned int startIndex, unsigned int readCount)
271{
272 if (!readStats(difficulty,type)) return false;
273 if (!LeaderboardManager::ReadStats_Friends(callback, difficulty, type, myUID, startIndex, readCount)) return false;
274
275 HANDLE hEnumerator;
276 DWORD ret;
277
278 unsigned int friendCount;
279 XUID *friends;
280
281 getFriends(friendCount, &friends);
282
283 if(friendCount == 0 || friends == NULL)
284 {
285 app.DebugPrintf("XboxLeaderboardManager::ReadStats_Friends - No friends found. Possibly you are offline?\n");
286 return false;
287 }
288 assert(friendCount > 0 && friends != NULL);
289
290 m_numStats = 0;
291 ret = XUserReadStats(
292 0,
293 friendCount,
294 friends,
295 1, //specCount,
296 m_spec,
297 &m_numStats,
298 NULL,
299 NULL
300 );
301
302 //Annoyingly, this returns ERROR_INSUFFICIENT_BUFFER when it is being asked to calculate the size of the buffer by passing zero resultsSize
303 if ( (ret!=ERROR_SUCCESS) && (ret!=ERROR_INSUFFICIENT_BUFFER) ) return false;
304
305 //Allocate a buffer for the stats
306 m_stats = (PXUSER_STATS_READ_RESULTS) new BYTE[m_numStats];
307 if (m_stats == NULL) return false;
308
309 memset(m_stats, 0, m_numStats);
310 memset(&m_overlapped, 0, sizeof(m_overlapped));
311
312 ret = XUserReadStats(
313 0,
314 friendCount,
315 friends,
316 1,
317 m_spec,
318 &m_numStats,
319 m_stats,
320 &m_overlapped);
321
322 if( (ret!=ERROR_SUCCESS) && (ret!=ERROR_IO_PENDING) ) return false;
323
324 m_eStatsState = eStatsState_Getting;
325 return true;
326}
327
328bool XboxLeaderboardManager::ReadStats_TopRank(LeaderboardReadListener *callback, int difficulty, EStatsType type , unsigned int startIndex, unsigned int readCount)
329{
330 if (!readStats(difficulty,type)) return false;
331 if (!LeaderboardManager::ReadStats_TopRank(callback, difficulty, type, startIndex, readCount)) return false;
332
333 HANDLE hEnumerator;
334
335 m_numStats = 0;
336 DWORD ret = XUserCreateStatsEnumeratorByRank(
337 0, // Current title ID
338 startIndex, // Index to start enumerating from
339 readCount, // Number of rows to retrieve
340 1, // Number of stats specs
341 m_spec, // Stats spec,
342 &m_numStats, // Size of buffer
343 &hEnumerator ); // Enumeration handle
344
345 if( ret != ERROR_SUCCESS ) return false;
346
347 //Allocate a buffer for the stats
348 m_stats = (PXUSER_STATS_READ_RESULTS) new BYTE[m_numStats];
349 if (m_stats == NULL) return false;
350
351 memset(m_stats, 0, m_numStats);
352 memset(&m_overlapped, 0, sizeof(m_overlapped));
353
354 ret = XEnumerate(
355 hEnumerator, // Enumeration handle
356 m_stats, // Buffer
357 m_numStats, // Size of buffer
358 NULL, // Number of rows returned; not used for async
359 &m_overlapped ); // Overlapped structure; not used for sync
360
361 if( (ret!=ERROR_SUCCESS) && (ret!=ERROR_IO_PENDING) ) return false;
362
363 m_eStatsState = eStatsState_Getting;
364 return true;
365}
366
367bool XboxLeaderboardManager::readStats(int difficulty, EStatsType type)
368{
369 //Need to have a session open
370 if (m_hSession==NULL) if(!OpenSession()) return false;
371
372 m_eStatsState = eStatsState_Failed;
373 m_statsRead = false;
374
375 if (m_stats) delete [] m_stats;
376
377 //Setup the spec structure for the read request
378 m_spec = new XUSER_STATS_SPEC[1];
379 m_spec[0].dwViewId = LEADERBOARD_DESCRIPTORS[(int)type][difficulty].m_viewId;
380 m_spec[0].dwNumColumnIds = LEADERBOARD_DESCRIPTORS[(int)type][difficulty].m_columnCount;
381 for (unsigned int i=0; i<m_spec[0].dwNumColumnIds; ++i)
382 m_spec[0].rgwColumnIds[i] = LEADERBOARD_DESCRIPTORS[(int)type][difficulty].m_columnIds[i];
383
384 return true;
385}
386
387void XboxLeaderboardManager::FlushStats()
388{
389 if( m_hSession == NULL || m_isQNetSession ) return;
390 memset(&m_flushStatsOverlapped, 0, sizeof(m_flushStatsOverlapped));
391 XSessionFlushStats(m_hSession, &m_flushStatsOverlapped);
392}
393
394bool XboxLeaderboardManager::IsStatsReadComplete()
395{
396 //If the read has completed
397 if( XHasOverlappedIoCompleted( &m_overlapped ) )
398 {
399 //If we've had an error
400 if( XGetOverlappedExtendedError( &m_overlapped ) != ERROR_SUCCESS )
401 {
402 m_eStatsState = eStatsState_Failed;
403 if( m_stats )
404 {
405 delete [] m_stats;
406 m_stats = NULL;
407 }
408 }
409 else
410 {
411 //If we've not got any results
412 if( !m_stats || m_stats->dwNumViews == 0 || m_stats->pViews[0].dwNumRows == 0 )
413 {
414 m_eStatsState = eStatsState_NoResults;
415 if( m_stats )
416 {
417 delete [] m_stats;
418 m_stats = NULL;
419 }
420 }
421 else
422 {
423 m_eStatsState = eStatsState_Ready;
424 }
425 }
426 return true;
427 }
428
429 return false;
430}
431
432int XboxLeaderboardManager::FriendSortFunction(const void* a, const void* b)
433{
434 return ((int)((XUSER_STATS_ROW*)a)->dwRank) - ((int)((XUSER_STATS_ROW*)b)->dwRank);
435}
436
437void XboxLeaderboardManager::SortFriendStats()
438{
439 for( unsigned int leaderboardIndex=0 ; leaderboardIndex<m_stats->dwNumViews ; ++leaderboardIndex )
440 {
441 //First filter out any friends who aren't in the leaderboard
442 XUSER_STATS_ROW* pRow = m_stats->pViews[leaderboardIndex].pRows;
443 //View rows is returned not including XUIDs that aren't in this leaderboard, but we want to recalculate that sort of thing
444 m_stats->pViews[leaderboardIndex].dwTotalViewRows = m_stats->pViews[leaderboardIndex].dwNumRows;
445 for( unsigned int rowIndex=0 ; rowIndex<m_stats->pViews[leaderboardIndex].dwTotalViewRows ; )
446 {
447 if( pRow->dwRank == 0 )
448 {
449 memmove( pRow, pRow + 1, ( ( m_stats->pViews[leaderboardIndex].dwTotalViewRows - rowIndex ) - 1 ) * sizeof(XUSER_STATS_ROW) );
450 m_stats->pViews[leaderboardIndex].dwTotalViewRows--;
451 }
452 else
453 {
454 rowIndex++;
455 pRow++;
456 }
457 }
458
459 //Then sort by rank
460 qsort( m_stats->pViews[leaderboardIndex].pRows, m_stats->pViews[leaderboardIndex].dwTotalViewRows, sizeof(XUSER_STATS_ROW), FriendSortFunction );
461 m_stats->pViews[leaderboardIndex].dwNumRows = m_stats->pViews[leaderboardIndex].dwTotalViewRows;
462 }
463}
464
465#if 0
466void XboxLeaderboardManager::SetStatsRetrieved(bool success)
467{
468 if( m_stats != NULL )
469 {
470 delete [] m_stats;
471 m_stats = NULL;
472 }
473
474 m_statsRead = success;
475 m_eStatsState = eStatsState_Idle;
476}
477#endif
478
479
480// 4J-JEV: Adapted/stolen from 'XUI_Leaderboards'.
481bool XboxLeaderboardManager::getFriends(unsigned int &friendsCount, PlayerUID** friends)
482{
483 DWORD resultsSize;
484 HANDLE hEnumerator;
485 DWORD ret;
486 DWORD numFriends;
487
488 //First, get a list of (up to 100) friends (this is the maximum that the enumerator currently supports)
489 ret = XFriendsCreateEnumerator( ProfileManager.GetLockedProfile(), 0, 100, &resultsSize, &hEnumerator);
490 if(ret!=ERROR_SUCCESS) return false;
491
492 XONLINE_FRIEND *xonlineFriends = (XONLINE_FRIEND*) new BYTE[resultsSize];
493
494 ret = XEnumerate(
495 hEnumerator,
496 xonlineFriends,
497 resultsSize,
498 &numFriends,
499 NULL
500 );
501
502 if (ret!=ERROR_SUCCESS) friendsCount = 0;
503
504 PlayerUID *filteredFriends = new PlayerUID[numFriends+1];
505
506 friendsCount = 0;
507 for (unsigned int friendIndex=0; friendIndex<numFriends; ++friendIndex)
508 {
509 if( ( xonlineFriends[friendIndex].dwFriendState & (XONLINE_FRIENDSTATE_FLAG_SENTREQUEST | XONLINE_FRIENDSTATE_FLAG_RECEIVEDREQUEST) ) == 0 )
510 {
511 filteredFriends[friendsCount++] = xonlineFriends[friendIndex].xuid;
512 }
513 }
514
515 filteredFriends[friendsCount++] = m_myXUID; //m_filteredFriends[m_numFilteredFriends++] = LeaderboardManager::Instance()->GetMyXUID();
516
517 // Return.
518 *friends = filteredFriends;
519 return true;
520}