aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Durango/Leaderboards/GameProgress.cpp
blob: dd07f3e965fd7ec729f5873af81762928706e856 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "stdafx.h"

#include "Durango\ServiceConfig\Events-XBLA.8-149E11AEEvents.h"

#include "..\Minecraft.World\DurangoStats.h"

#include "GameProgress.h"

namespace WFC = Windows::Foundation::Collections;
namespace MXSA = Microsoft::Xbox::Services::Achievements;
namespace CC = concurrency;

GameProgress *GameProgress::instance = NULL;

void GameProgress::Flush(int iPad)
{
	if (instance == NULL) 
		instance = new GameProgress();

	instance->updatePlayer(iPad);
}

void GameProgress::Tick()
{
	if (instance == NULL)
		instance = new GameProgress();

	long long currentTime = System::currentTimeMillis();
	if ( (currentTime - instance->m_lastUpdate) > (UPDATE_FREQUENCY / 4) )
	{
		instance->updatePlayer(instance->m_nextPad);
		instance->m_nextPad = ++instance->m_nextPad % MAX_LOCAL_PLAYERS;
		instance->m_lastUpdate = currentTime;
	}
}

GameProgress::GameProgress()
{
	m_nextPad = 0;
	m_lastUpdate = 0;
}

void GameProgress::updatePlayer(int iPad)
{
	if ( ProfileManager.IsGuest(iPad) || !ProfileManager.IsSignedInLive(iPad) ) return;
	
	PlayerUID uid;
	ProfileManager.GetXUID(iPad, &uid, true);

	WXS::User^ user = ProfileManager.GetUser(iPad);

	if (user == nullptr) return;

	MXS::XboxLiveContext ^xlc = ref new MXS::XboxLiveContext(user);

	// Get these while they are still valid.
	LPCGUID playerSession = DurangoStats::getPlayerSession();

	CC::create_task(
		xlc->AchievementService->GetAchievementsForTitleIdAsync(
			ref new Platform::String(uid.toString().c_str()),	// Xuid
			0x149E11AE,											// TitleId
			MXSA::AchievementType::Persistent,					// Use regular achievements (not challenges)
			false,												// Unlocked only
			MXSA::AchievementOrderBy::UnlockTime,				// Order (we don't really care)
			0,													// skipItems (start index)
			200													// MaxItems
			)
		).then( [this,iPad,uid,playerSession] (CC::task<MXSA::AchievementsResult^> resultTask)
		{
			try
			{
				int achievementsUnlocked = 0;

				MXSA::AchievementsResult^ result = resultTask.get();
				if(result)
				{
					for (unsigned int i = 0, iMax = result->Items->Size; i < iMax; i++)
					{
						MXSA::Achievement^ ach = result->Items->GetAt(i);
						if (ach->ProgressState == MXSA::AchievementProgressState::Achieved)
							achievementsUnlocked++;
					}

					float gameprogress;
					if (EventWriteGameProgress(
						uid.toString().c_str(),
						playerSession,
						gameprogress = calcGameProgress(achievementsUnlocked) )
						== 0)
					{
						app.DebugPrintf("<%ls> GameProgress(%.1f)\n", uid.toString().c_str(), gameprogress);
					}
				}
			}
			catch (Platform::Exception ^ex)
			{
				app.DebugPrintf("GameProgress:: Error, couldn't contact the achievments service (?): %ls", ex->Message->Data());
			}
		});
	
}

float GameProgress::calcGameProgress(int achievementsUnlocked)
{
	return (float) achievementsUnlocked / 0.60f;
}