ScoreloopSocialSession.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. #if defined(__QNX__) && defined(GP_USE_SOCIAL)
  2. #include "Base.h"
  3. #include "ScoreloopSocialSession.h"
  4. namespace gameplay
  5. {
  6. ScoreloopSocialSession* ScoreloopSocialSession::_session = NULL;
  7. ScoreloopSocialSession::ScoreloopSocialSession()
  8. : SocialSession(),
  9. _listener(NULL), _properties(NULL), _pendingResponse(false),
  10. _client(NULL), _userController(NULL), _usersController(NULL),
  11. _localAchievementsController(NULL), _scoresController(NULL), _scoreController(NULL),
  12. _key(NULL)
  13. {
  14. pthread_cond_init(&_channelCond, NULL);
  15. pthread_mutex_init(&_channelMutex, NULL);
  16. _userOp = USEROP_GET_LOCALUSER;
  17. }
  18. ScoreloopSocialSession::~ScoreloopSocialSession()
  19. {
  20. }
  21. SocialSessionListener* ScoreloopSocialSession::getListener()
  22. {
  23. return _listener;
  24. }
  25. void* ScoreloopSocialSession::platformEventCallback(void* data)
  26. {
  27. _session = (ScoreloopSocialSession*)data;
  28. int rc = bps_initialize();
  29. if (rc == BPS_FAILURE)
  30. GP_ERROR("ScoreloopSocialSession::platformEventHandler - bps_initialize failed.");
  31. pthread_mutex_lock(&_session->_channelMutex);
  32. pthread_mutex_unlock(&_session->_channelMutex);
  33. pthread_cond_signal(&_session->_channelCond);
  34. bps_event_t* event = NULL;
  35. while (true)
  36. {
  37. rc = bps_get_event(&event, -1);
  38. if (rc == BPS_FAILURE)
  39. GP_ERROR("ScoreloopSocialSession::platformEventHandler - bps_get_event failed.");
  40. if (bps_event_get_domain(event) == SC_GetBPSEventDomain(&_session->_initData))
  41. {
  42. SC_HandleBPSEvent(&_session->_initData, event);
  43. }
  44. }
  45. bps_shutdown();
  46. return 0;
  47. }
  48. void ScoreloopSocialSession::authenticate(SocialSessionListener* listener, Properties* properties)
  49. {
  50. if (_session)
  51. return;
  52. _session = new ScoreloopSocialSession();
  53. _session->_listener = listener;
  54. _session->_properties = properties;
  55. const char* gameId = properties->getString("game_id");
  56. const char* gameSecret = properties->getString("game_secret");
  57. const char* gameVersion = properties->getString("game_version");
  58. const char* gameCurrency = properties->getString("game_currency");
  59. const char* gameLanguage = properties->getString("gameLanguage");
  60. SC_InitData_Init(&_session->_initData);
  61. SC_Error_t rc = SC_Client_New(&_session->_client, &_session->_initData, gameId, gameSecret, gameVersion, gameCurrency, gameLanguage);
  62. if (rc != SC_OK)
  63. {
  64. listener->authenticateEvent(SocialSessionListener::ERROR_INITIALIZATION, NULL);
  65. return;
  66. }
  67. rc = SC_Client_CreateUserController(_session->_client, &_session->_userController, ScoreloopSocialSession::userCallback, _session);
  68. if (rc != SC_OK)
  69. {
  70. listener->authenticateEvent(SocialSessionListener::ERROR_INITIALIZATION, NULL);
  71. return;
  72. }
  73. rc = SC_UserController_LoadUser(_session->_userController);
  74. if (rc != SC_OK)
  75. {
  76. SC_UserController_Release(_session->_userController);
  77. _session->_userController = NULL;
  78. listener->authenticateEvent(SocialSessionListener::ERROR_INITIALIZATION, NULL);
  79. }
  80. // Create thread for platform event handler needed by Scoreloop
  81. pthread_mutex_lock(&_session->_channelMutex);
  82. pthread_create(NULL, NULL, platformEventCallback, _session);
  83. pthread_cond_wait(&_session->_channelCond, &_session->_channelMutex);
  84. pthread_mutex_unlock(&_session->_channelMutex);
  85. }
  86. void ScoreloopSocialSession::userCallback(void* cookie, SC_Error_t result)
  87. {
  88. ScoreloopSocialSession* session = (ScoreloopSocialSession*)cookie;
  89. switch (result)
  90. {
  91. case SC_OK:
  92. {
  93. switch(session->_userOp)
  94. {
  95. case USEROP_GET_LOCALUSER:
  96. {
  97. session->_user.handle = SC_UserController_GetUser(session->_userController);
  98. SC_String_h name = SC_User_GetLogin(session->_user.handle);
  99. session->_user.name = SC_String_GetData(name);
  100. session->getListener()->authenticateEvent(SocialSessionListener::SUCCESS, session);
  101. }
  102. break;
  103. case USEROP_WRITE_CONTEXT:
  104. {
  105. session->getListener()->submitSavedDataEvent(SocialSessionListener::SUCCESS);
  106. }
  107. break;
  108. case USEROP_READ_CONTEXT:
  109. {
  110. SC_Context_h context = SC_User_GetContext(session->_user.handle);
  111. SC_String_h str;
  112. SC_Error_t rc = SC_Context_Get(context, session->_key, &str);
  113. if (rc != SC_OK)
  114. {
  115. session->getListener()->loadSavedDataEvent(SocialSessionListener::ERROR_INVALID_ARG, "");
  116. }
  117. else
  118. {
  119. session->getListener()->loadSavedDataEvent(SocialSessionListener::SUCCESS, std::string(SC_String_GetData(str)));
  120. }
  121. }
  122. break;
  123. }
  124. }
  125. break;
  126. case SC_INVALID_USER_DATA:
  127. {
  128. switch(session->_userOp)
  129. {
  130. case USEROP_GET_LOCALUSER:
  131. session->getListener()->authenticateEvent(SocialSessionListener::ERROR_INVALID_USER, NULL);
  132. break;
  133. case USEROP_WRITE_CONTEXT:
  134. session->getListener()->submitSavedDataEvent(SocialSessionListener::ERROR_INVALID_USER);
  135. break;
  136. case USEROP_READ_CONTEXT:
  137. session->getListener()->loadSavedDataEvent(SocialSessionListener::ERROR_INVALID_USER, "");
  138. break;
  139. }
  140. }
  141. break;
  142. case SC_HTTP_SERVER_ERROR:
  143. {
  144. switch(session->_userOp)
  145. {
  146. case USEROP_GET_LOCALUSER:
  147. session->getListener()->authenticateEvent(SocialSessionListener::ERROR_SERVER, NULL);
  148. break;
  149. case USEROP_WRITE_CONTEXT:
  150. session->getListener()->submitSavedDataEvent(SocialSessionListener::ERROR_SERVER);
  151. break;
  152. case USEROP_READ_CONTEXT:
  153. session->getListener()->loadSavedDataEvent(SocialSessionListener::ERROR_SERVER, "");
  154. break;
  155. }
  156. }
  157. break;
  158. default:
  159. {
  160. switch(session->_userOp)
  161. {
  162. case USEROP_GET_LOCALUSER:
  163. session->getListener()->authenticateEvent(SocialSessionListener::ERROR_UNKNOWN, NULL);
  164. break;
  165. case USEROP_WRITE_CONTEXT:
  166. session->getListener()->submitSavedDataEvent(SocialSessionListener::ERROR_UNKNOWN);
  167. break;
  168. case USEROP_READ_CONTEXT:
  169. session->getListener()->loadSavedDataEvent(SocialSessionListener::ERROR_UNKNOWN, "");
  170. break;
  171. }
  172. }
  173. break;
  174. }
  175. session->_pendingResponse = false;
  176. }
  177. void ScoreloopSocialSession::loadFriends()
  178. {
  179. if (_pendingResponse)
  180. {
  181. _listener->loadFriendsEvent(SocialSessionListener::ERROR_PENDING_RESPONSE, _friends);
  182. return;
  183. }
  184. _pendingResponse = true;
  185. // Create a scoreloop users controller (for finding friends)
  186. SC_Error_t rc;
  187. if (_usersController == NULL)
  188. {
  189. rc = SC_Client_CreateUsersController(_client, &_usersController, ScoreloopSocialSession::loadFriendsCallback, this);
  190. if (rc != SC_OK)
  191. {
  192. _listener->loadFriendsEvent(SocialSessionListener::ERROR_INITIALIZATION, _friends);
  193. return;
  194. }
  195. }
  196. rc = SC_UsersController_LoadBuddies(_usersController, _user.handle);
  197. if (rc != SC_OK)
  198. {
  199. SC_UsersController_Release(_usersController);
  200. _usersController = NULL;
  201. _listener->loadFriendsEvent(SocialSessionListener::ERROR_INITIALIZATION, _friends);
  202. }
  203. }
  204. void ScoreloopSocialSession::loadFriendsCallback(void* cookie, SC_Error_t result)
  205. {
  206. ScoreloopSocialSession* session = (ScoreloopSocialSession*)cookie;
  207. switch (result)
  208. {
  209. case SC_OK:
  210. {
  211. SC_UserList_h usersList = SC_UsersController_GetUsers(session->_usersController);
  212. unsigned int usersCount = SC_UserList_GetCount(usersList);
  213. session->_friends.clear();
  214. for (unsigned int i = 0; i < usersCount; i++)
  215. {
  216. SocialPlayer player;
  217. player.handle = SC_UserList_GetAt(usersList, i);
  218. SC_UserController_GetUser(session->_userController);
  219. SC_String_h name = SC_User_GetLogin(player.handle);
  220. player.name = SC_String_GetData(name);
  221. session->_friends.push_back(player);
  222. }
  223. session->getListener()->loadFriendsEvent(SocialSessionListener::SUCCESS, session->_friends);
  224. }
  225. break;
  226. case SC_INVALID_USER_DATA:
  227. session->getListener()->loadFriendsEvent(SocialSessionListener::ERROR_INVALID_USER, session->_friends);
  228. break;
  229. case SC_HTTP_SERVER_ERROR:
  230. session->getListener()->loadFriendsEvent(SocialSessionListener::ERROR_SERVER, session->_friends);
  231. break;
  232. default:
  233. session->getListener()->loadFriendsEvent(SocialSessionListener::ERROR_UNKNOWN, session->_friends);
  234. break;
  235. }
  236. session->_pendingResponse = false;
  237. }
  238. void ScoreloopSocialSession::loadAchievements()
  239. {
  240. if (_pendingResponse)
  241. {
  242. _listener->loadAchievementsEvent(SocialSessionListener::ERROR_PENDING_RESPONSE, _achievements);
  243. return;
  244. }
  245. _pendingResponse = true;
  246. SC_Error_t rc;
  247. rc = SC_Client_CreateLocalAchievementsController(_client, &_localAchievementsController, ScoreloopSocialSession::loadAchievementsCallback, this);
  248. if (rc != SC_OK)
  249. {
  250. _listener->loadAchievementsEvent(SocialSessionListener::ERROR_INITIALIZATION, _achievements);
  251. return;
  252. }
  253. if (SC_LocalAchievementsController_ShouldSynchronize(_localAchievementsController))
  254. {
  255. rc = SC_LocalAchievementsController_Synchronize(_localAchievementsController);
  256. {
  257. SC_LocalAchievementsController_Release(_localAchievementsController);
  258. _localAchievementsController = NULL;
  259. _listener->loadAchievementsEvent(SocialSessionListener::ERROR_INITIALIZATION, _achievements);
  260. }
  261. }
  262. else
  263. {
  264. ScoreloopSocialSession::loadAchievementsCallback(this, SC_OK);
  265. }
  266. }
  267. void ScoreloopSocialSession::loadAchievementsCallback(void* cookie, SC_Error_t result)
  268. {
  269. ScoreloopSocialSession* session = (ScoreloopSocialSession*)cookie;
  270. switch (result)
  271. {
  272. case SC_OK:
  273. {
  274. SC_AchievementList_h achievementsList = SC_LocalAchievementsController_GetAchievements(session->_localAchievementsController);
  275. unsigned int achievementsCount = SC_AchievementList_GetCount(achievementsList);
  276. session->_achievements.clear();
  277. for (unsigned int i = 0; i < achievementsCount; i++)
  278. {
  279. SocialAchievement achievement;
  280. achievement.handle = SC_AchievementList_GetAt(achievementsList, i);
  281. SC_String_h id = SC_Achievement_GetIdentifier(achievement.handle);
  282. achievement.name = SC_String_GetData(id);
  283. achievement.value = (unsigned int) SC_Achievement_GetValue(achievement.handle);
  284. SC_Award_h award = SC_Achievement_GetAward(achievement.handle);
  285. achievement.total = SC_Award_GetAchievingValue(award);
  286. achievement.percentCompleted = achievement.value == 0 ? 0.0f : ((float)achievement.value / (float)achievement.total) * 100.f;
  287. SC_String_h dateTime = SC_Achievement_GetDate(achievement.handle);
  288. achievement.dateTimeAchieved = SC_String_GetData(id);
  289. session->_achievements.push_back(achievement);
  290. }
  291. session->getListener()->loadAchievementsEvent(SocialSessionListener::SUCCESS, _session->_achievements);
  292. }
  293. break;
  294. case SC_INVALID_USER_DATA:
  295. session->getListener()->loadAchievementsEvent(SocialSessionListener::ERROR_INVALID_USER, _session->_achievements);
  296. break;
  297. case SC_HTTP_SERVER_ERROR:
  298. session->getListener()->loadAchievementsEvent(SocialSessionListener::ERROR_SERVER, _session->_achievements);
  299. break;
  300. default:
  301. session->getListener()->loadAchievementsEvent(SocialSessionListener::ERROR_UNKNOWN, _session->_achievements);
  302. break;
  303. }
  304. session->_pendingResponse = false;
  305. }
  306. void ScoreloopSocialSession::submitAchievement(const char* achievementId, unsigned int value)
  307. {
  308. if (_pendingResponse)
  309. {
  310. _listener->submitAchievementEvent(SocialSessionListener::ERROR_PENDING_RESPONSE);
  311. return;
  312. }
  313. _pendingResponse = true;
  314. SC_Error_t rc;
  315. rc = SC_Client_CreateLocalAchievementsController(_client, &_localAchievementsController, ScoreloopSocialSession::submitAchievementCallback, this);
  316. if (rc != SC_OK)
  317. {
  318. _listener->submitAchievementEvent(SocialSessionListener::ERROR_INITIALIZATION);
  319. }
  320. SC_Bool_t achieved;
  321. rc = SC_LocalAchievementsController_SetValueForAwardIdentifier(_localAchievementsController, achievementId, value, &achieved);
  322. if (rc != SC_OK)
  323. {
  324. SC_LocalAchievementsController_Release(_localAchievementsController);
  325. _localAchievementsController = NULL;
  326. _listener->submitAchievementEvent(SocialSessionListener::ERROR_INITIALIZATION);
  327. }
  328. }
  329. void ScoreloopSocialSession::submitAchievementCallback(void* cookie, SC_Error_t result)
  330. {
  331. ScoreloopSocialSession* session = (ScoreloopSocialSession*)cookie;
  332. switch (result)
  333. {
  334. case SC_OK:
  335. session->getListener()->submitAchievementEvent(SocialSessionListener::SUCCESS);
  336. break;
  337. case SC_INVALID_USER_DATA:
  338. session->getListener()->submitAchievementEvent(SocialSessionListener::ERROR_INVALID_USER);
  339. break;
  340. case SC_HTTP_SERVER_ERROR:
  341. session->getListener()->submitAchievementEvent(SocialSessionListener::ERROR_SERVER);
  342. break;
  343. default:
  344. session->getListener()->submitAchievementEvent(SocialSessionListener::ERROR_UNKNOWN);
  345. break;
  346. }
  347. session->_pendingResponse = false;
  348. }
  349. void ScoreloopSocialSession::loadScores(const char* leaderboardId, CommunityScope community, TimeScope time, const SocialPlayer& player, unsigned int count)
  350. {
  351. if (_pendingResponse)
  352. {
  353. _listener->loadScoresEvent(SocialSessionListener::ERROR_PENDING_RESPONSE, _scores);
  354. return;
  355. }
  356. _pendingResponse = true;
  357. SC_Error_t rc;
  358. if (_scoresController == NULL)
  359. {
  360. rc = SC_Client_CreateScoresController(_client, &_scoresController, ScoreloopSocialSession::loadScoresCallback, this);
  361. if (rc != SC_OK)
  362. {
  363. _listener->loadScoresEvent(SocialSessionListener::ERROR_INITIALIZATION, _scores);
  364. return;
  365. }
  366. }
  367. // Lookup the mode to be mapped for the specified leaderboard id
  368. if (leaderboardId != NULL)
  369. {
  370. Properties* leaderboardMappings = _properties->getNamespace("leaderboard_mappings", false);
  371. if (leaderboardMappings)
  372. {
  373. int mode = leaderboardMappings->getInt(leaderboardId);
  374. if (mode >= 0)
  375. {
  376. SC_ScoresController_SetMode(_scoresController, (unsigned int)mode);
  377. }
  378. }
  379. }
  380. // Set the search list filter
  381. SC_ScoresSearchList_t searchList = SC_SCORES_SEARCH_LIST_USER_COUNTRY;
  382. switch(community)
  383. {
  384. case COMMUNITY_SCOPE_FRIENDS:
  385. searchList.usersSelector = SC_USERS_SELECTOR_BUDDYHOOD;
  386. break;
  387. case COMMUNITY_SCOPE_ALL:
  388. searchList.usersSelector = SC_USERS_SELECTOR_ALL;
  389. break;
  390. }
  391. switch(time)
  392. {
  393. case TIME_SCOPE_TODAY:
  394. searchList.timeInterval = SC_TIME_INTERVAL_24H;
  395. break;
  396. case TIME_SCOPE_WEEK:
  397. searchList.timeInterval = SC_TIME_INTERVAL_7DAYS;
  398. break;
  399. case TIME_SCOPE_ALL:
  400. searchList.timeInterval = SC_TIME_INTERVAL_ALL;
  401. break;
  402. }
  403. SC_ScoresController_SetSearchList(_scoresController, searchList);
  404. // Specify the player and range count to get the scores around
  405. SC_User_h user = player.handle;
  406. rc = SC_ScoresController_LoadScoresAroundUser(_scoresController, _user.handle, count);
  407. if (rc != SC_OK)
  408. {
  409. SC_ScoresController_Release(_scoresController);
  410. _scoresController = NULL;
  411. _listener->loadScoresEvent(SocialSessionListener::ERROR_INITIALIZATION, _scores);
  412. }
  413. }
  414. void ScoreloopSocialSession::loadScores(const char* leaderboardId, CommunityScope community, TimeScope time, unsigned int start, unsigned int count)
  415. {
  416. if (_pendingResponse)
  417. {
  418. _listener->loadScoresEvent(SocialSessionListener::ERROR_PENDING_RESPONSE, _scores);
  419. return;
  420. }
  421. _pendingResponse = true;
  422. SC_Error_t rc;
  423. if (_scoresController == NULL)
  424. {
  425. rc = SC_Client_CreateScoresController(_client, &_scoresController, ScoreloopSocialSession::loadScoresCallback, this);
  426. if (rc != SC_OK)
  427. {
  428. _listener->loadScoresEvent(SocialSessionListener::ERROR_INITIALIZATION, _scores);
  429. return;
  430. }
  431. }
  432. // Lookup the mode to be mapped for the specified leaderboard id
  433. if (leaderboardId != NULL)
  434. {
  435. Properties* leaderboardMappings = _properties->getNamespace("leaderboard_mappings", false);
  436. if (leaderboardMappings)
  437. {
  438. int mode = leaderboardMappings->getInt(leaderboardId);
  439. if (mode >= 0)
  440. {
  441. SC_ScoresController_SetMode(_scoresController, (unsigned int)mode);
  442. }
  443. }
  444. }
  445. // Set the search list filter
  446. SC_ScoresSearchList_t searchList = SC_SCORES_SEARCH_LIST_USER_COUNTRY;
  447. switch(community)
  448. {
  449. case COMMUNITY_SCOPE_FRIENDS:
  450. searchList.usersSelector = SC_USERS_SELECTOR_BUDDYHOOD;
  451. break;
  452. case COMMUNITY_SCOPE_ALL:
  453. searchList.usersSelector = SC_USERS_SELECTOR_ALL;
  454. break;
  455. }
  456. switch(time)
  457. {
  458. case TIME_SCOPE_TODAY:
  459. searchList.timeInterval = SC_TIME_INTERVAL_24H;
  460. break;
  461. case TIME_SCOPE_WEEK:
  462. searchList.timeInterval = SC_TIME_INTERVAL_7DAYS;
  463. break;
  464. case TIME_SCOPE_ALL:
  465. searchList.timeInterval = SC_TIME_INTERVAL_ALL;
  466. break;
  467. }
  468. SC_ScoresController_SetSearchList(_scoresController, searchList);
  469. // Set the search range
  470. SC_Range_t range;
  471. range.offset = start;
  472. range.length = count;
  473. rc = SC_ScoresController_LoadScores(_scoresController, range);
  474. if (rc != SC_OK)
  475. {
  476. SC_ScoresController_Release(_scoresController);
  477. _scoresController = NULL;
  478. _listener->loadScoresEvent(SocialSessionListener::ERROR_INITIALIZATION, _scores);
  479. }
  480. }
  481. void ScoreloopSocialSession::loadScoresCallback(void* cookie, SC_Error_t result)
  482. {
  483. ScoreloopSocialSession* session = (ScoreloopSocialSession*)cookie;
  484. switch (result)
  485. {
  486. case SC_OK:
  487. {
  488. SC_ScoreFormatter_h scoreFormatter = SC_Client_GetScoreFormatter(session->_client);
  489. SC_ScoreList_h scoresList = SC_ScoresController_GetScores(session->_scoresController);
  490. unsigned int scoresCount = SC_ScoreList_GetCount(scoresList);
  491. session->_scores.clear();
  492. for (unsigned int i = 0; i < scoresCount; i++)
  493. {
  494. SocialScore score;
  495. score.handle = SC_ScoreList_GetAt(scoresList, i);
  496. score.rank = SC_Score_GetRank(score.handle);
  497. score.value = (float)SC_Score_GetResult(score.handle);
  498. SC_String_h formatted;
  499. SC_ScoreFormatter_FormatScore(scoreFormatter, score.handle, SC_SCORE_FORMAT_DEFAULT, &formatted);
  500. score.valueFormatted = SC_String_GetData(formatted);
  501. SC_User_h player = SC_Score_GetUser(score.handle);
  502. SC_String_h playerStr = SC_User_GetLogin(player);
  503. score.playerName = SC_String_GetData(playerStr);
  504. session->_scores.push_back(score);
  505. }
  506. session->getListener()->loadScoresEvent(SocialSessionListener::SUCCESS, session->_scores);
  507. }
  508. break;
  509. case SC_INVALID_USER_DATA:
  510. session->getListener()->loadScoresEvent(SocialSessionListener::ERROR_INVALID_USER, session->_scores);
  511. break;
  512. case SC_HTTP_SERVER_ERROR:
  513. session->getListener()->loadScoresEvent(SocialSessionListener::ERROR_SERVER, session->_scores);
  514. break;
  515. default:
  516. session->getListener()->loadScoresEvent(SocialSessionListener::ERROR_UNKNOWN, session->_scores);
  517. break;
  518. }
  519. session->_pendingResponse = false;
  520. }
  521. void ScoreloopSocialSession::submitScore(const char* leaderboardId, float value)
  522. {
  523. if (_pendingResponse)
  524. {
  525. _listener->submitScoreEvent(SocialSessionListener::ERROR_PENDING_RESPONSE);
  526. return;
  527. }
  528. _pendingResponse = true;
  529. SC_Error_t rc;
  530. rc = SC_Client_CreateScoreController(_client, &_scoreController, ScoreloopSocialSession::submitScoreCallback, this);
  531. if (rc != SC_OK)
  532. {
  533. _listener->submitScoreEvent(SocialSessionListener::ERROR_INITIALIZATION);
  534. return;
  535. }
  536. // Create a score to submit
  537. SC_Score_h score;
  538. rc = SC_Client_CreateScore(_client, &score);
  539. if (rc != SC_OK)
  540. {
  541. _listener->submitScoreEvent(SocialSessionListener::ERROR_INITIALIZATION);
  542. return;
  543. }
  544. // Set the leaderboard to associate this score with
  545. if (leaderboardId != NULL)
  546. {
  547. Properties* leaderboardMappings = _properties->getNamespace("leaderboard_mappings", false);
  548. if (leaderboardMappings)
  549. {
  550. int mode = leaderboardMappings->getInt(leaderboardId);
  551. if (mode >= 0)
  552. {
  553. SC_Score_SetMode(score, (unsigned int)mode);
  554. }
  555. }
  556. }
  557. // Set the score value and submit the score
  558. SC_Score_SetResult(score, value);
  559. rc = SC_ScoreController_SubmitScore(_scoreController, score);
  560. if (rc != SC_OK)
  561. {
  562. SC_ScoreController_Release(_scoreController);
  563. _scoreController = NULL;
  564. _listener->submitScoreEvent(SocialSessionListener::ERROR_INITIALIZATION);
  565. }
  566. SC_Score_Release(score);
  567. }
  568. void ScoreloopSocialSession::submitScoreCallback(void* cookie, SC_Error_t result)
  569. {
  570. ScoreloopSocialSession* session = (ScoreloopSocialSession*)cookie;
  571. switch (result)
  572. {
  573. case SC_OK:
  574. session->getListener()->submitScoreEvent(SocialSessionListener::SUCCESS);
  575. break;
  576. case SC_INVALID_USER_DATA:
  577. session->getListener()->submitScoreEvent(SocialSessionListener::ERROR_INVALID_USER);
  578. break;
  579. case SC_HTTP_SERVER_ERROR:
  580. session->getListener()->submitScoreEvent(SocialSessionListener::ERROR_SERVER);
  581. break;
  582. default:
  583. session->getListener()->submitScoreEvent(SocialSessionListener::ERROR_UNKNOWN);
  584. break;
  585. }
  586. session->_pendingResponse = false;
  587. }
  588. void ScoreloopSocialSession::loadSavedData(const char* key)
  589. {
  590. if (_pendingResponse)
  591. {
  592. _listener->loadSavedDataEvent(SocialSessionListener::ERROR_PENDING_RESPONSE, "");
  593. return;
  594. }
  595. SC_Error_t rc = SC_UserController_LoadUserContext(_userController);
  596. if (rc != SC_OK)
  597. {
  598. _listener->loadSavedDataEvent(SocialSessionListener::ERROR_INITIALIZATION, "");
  599. return;
  600. }
  601. _pendingResponse = true;
  602. _key = key;
  603. }
  604. void ScoreloopSocialSession::submitSavedData(const char* key, std::string data)
  605. {
  606. if (_pendingResponse)
  607. {
  608. _listener->submitSavedDataEvent(SocialSessionListener::ERROR_PENDING_RESPONSE);
  609. return;
  610. }
  611. _pendingResponse = true;
  612. SC_Context_h context;
  613. SC_Error_t rc = SC_Context_New(&context);
  614. if (rc != SC_OK)
  615. {
  616. _listener->submitSavedDataEvent(SocialSessionListener::ERROR_INITIALIZATION);
  617. return;
  618. }
  619. SC_String_h str;
  620. rc = SC_String_New(&str, data.c_str());
  621. if (rc != SC_OK)
  622. {
  623. _listener->submitSavedDataEvent(SocialSessionListener::ERROR_INITIALIZATION);
  624. return;
  625. }
  626. SC_Context_Put(context, key, str);
  627. SC_User_SetContext(_user.handle, context);
  628. SC_UserController_SetUser(_userController, _user.handle);
  629. rc = SC_UserController_UpdateUserContext(_userController);
  630. if (rc != SC_OK)
  631. {
  632. _listener->submitSavedDataEvent(SocialSessionListener::ERROR_INITIALIZATION);
  633. return;
  634. }
  635. }
  636. }
  637. #endif