forked from BoyC/GW2TacO
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Achievements.cpp
94 lines (77 loc) · 3.8 KB
/
Achievements.cpp
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
#include "Achievements.h"
#include "GW2API.h"
#include "ThirdParty/BugSplat/inc/BugSplat.h"
#include "Bedrock/UtilLib/jsonxx.h"
using namespace jsonxx;
bool Achievements::beingFetched = false;
TS32 Achievements::lastFetchTime = 0;
std::thread Achievements::fetchThread;
bool Achievements::fetched = false;
CDictionary<TS32, Achievement> Achievements::achievements;
LIGHTWEIGHT_CRITICALSECTION Achievements::critSec;
void Achievements::FetchAchievements()
{
if ( GW2::apiKeyManager.GetStatus() != GW2::APIKeyManager::Status::OK )
return;
GW2::APIKey* key = GW2::apiKeyManager.GetIdentifiedAPIKey();
if ( key && key->valid && ( globalTimer.GetTime() - lastFetchTime > 150000 || !lastFetchTime ) && !beingFetched && !fetchThread.joinable() )
{
beingFetched = true;
fetchThread = std::thread( [key]()
{
SetPerThreadCRTExceptionBehavior();
CheckFestivalActive();
CString dungeonFrequenterStatus = CString( "{\"achievements\":" ) + key->QueryAPI( "v2/account/achievements" ) + "}";
Object json;
json.parse( dungeonFrequenterStatus.GetPointer() );
if ( json.has<Array>( "achievements" ) )
{
auto achiData = json.get<Array>( "achievements" ).values();
CDictionary<TS32, Achievement> incoming;
for ( unsigned int x = 0; x < achiData.size(); x++ )
{
if ( !achiData[ x ]->is<Object>() )
continue;
auto& data = achiData[ x ]->get<Object>();
if ( !data.has<Boolean>( "done" ) )
continue;
TBOOL done = data.get<Boolean>( "done" );
if ( !data.has<Number>( "id" ) )
continue;
TS32 achiId = TS32( data.get<Number>( "id" ) );
incoming[ achiId ].done = done;
if ( !done && data.has<Array>( "bits" ) )
{
auto& bitArray = incoming[ achiId ].bits;
auto bits = data.get<Array>( "bits" ).values();
for ( unsigned int y = 0; y < bits.size(); y++ )
{
if ( !bits[ y ]->is<Number>() )
continue;
bitArray += TS32( bits[ y ]->get<Number>() );
}
}
else
if ( done )
incoming[ achiId ].bits.FlushFast();
}
{
CLightweightCriticalSection cs( &critSec );
achievements = incoming;
}
}
beingFetched = false;
fetched = true;
} );
}
if ( !beingFetched && fetchThread.joinable() )
{
lastFetchTime = globalTimer.GetTime();
fetchThread.join();
}
}
void Achievements::WaitForFetch()
{
if ( fetchThread.joinable() )
fetchThread.join();
}