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 "..\Minecraft.World\Tile.h"
4#include "..\Minecraft.World\Item.h"
5
6#include "..\Minecraft.World\DurangoStats.h"
7
8#include "..\Minecraft.World\EntityIO.h"
9
10#include "..\Minecraft.World\StringHelpers.h"
11
12#include "Common\Console_Awards_enum.h"
13
14#include "DurangoStatsDebugger.h"
15
16namespace WFC = Windows::Foundation::Collections;
17namespace CC = concurrency;
18
19StatParam::StatParam(const wstring &base)
20{
21 m_base = base;
22 //m_numArgs = numArgs;
23 m_args = vector<int>();
24
25 unsigned int count=0;
26 wstring::size_type pos =base.find(L"*");
27 while(pos!=string::npos)
28 {
29 count++;
30 pos=base.find(L"*",pos+1);
31 }
32
33 m_numArgs = count;
34}
35
36void StatParam::addArgs(int v1, ...)
37{
38 va_list argptr;
39 va_start(argptr, v1);
40 m_args.push_back(v1);
41 for (int i=0; i<(m_numArgs-1); i++)
42 {
43 int vi = va_arg(argptr, int);
44 m_args.push_back(vi);
45 }
46 va_end(argptr);
47}
48
49vector<wstring> *StatParam::getStats()
50{
51 vector<wstring> *out = new vector<wstring>();
52
53 static const int MAXSIZE = 256;
54 static const wstring SUBSTR = L"*";
55
56 wstring wstr_itr, wstr_num;
57
58 if (m_args.size() <= 0 || m_numArgs <= 0)
59 {
60 out->push_back(m_base);
61 }
62 else
63 {
64 for (int i = 0; i < m_args.size(); i += m_numArgs)
65 {
66 wstr_itr = m_base;
67
68 if (m_numArgs > 0)
69 {
70 for (int j=0; j<m_numArgs; j++)
71 {
72 wstr_num = to_wstring(m_args.at(i+j));
73 size_t sz = wstr_itr.find(SUBSTR);
74
75 if (sz != wstring::npos)
76 wstr_itr.replace(sz, SUBSTR.length(), wstr_num);
77 }
78 }
79
80 out->push_back( wstr_itr );
81 }
82 }
83
84 return out;
85}
86
87DurangoStatsDebugger *DurangoStatsDebugger::instance = NULL;
88
89DurangoStatsDebugger::DurangoStatsDebugger()
90{
91 InitializeCriticalSection(&m_retrievedStatsLock);
92}
93
94vector<wstring> *DurangoStatsDebugger::getStats()
95{
96 vector<wstring> *out = new vector<wstring>();
97
98 for (auto it = m_stats.begin(); it!=m_stats.end(); it++)
99 {
100 vector<wstring> *sublist = (*it)->getStats();
101 out->insert(out->end(), sublist->begin(), sublist->end());
102 }
103
104 return out;
105}
106
107DurangoStatsDebugger *DurangoStatsDebugger::Initialize()
108{
109 DurangoStatsDebugger *out = new DurangoStatsDebugger();
110
111 StatParam *sp = new StatParam(L"McItemAcquired.AcquisitionMethodId.*.ItemId.*.ItemAux.*");
112 sp->addArgs(1, Tile::dirt_Id, 0); // works
113 sp->addArgs(2, Tile::dirt_Id, 0); // works
114
115 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 0); // fixed (+ach 'Rainbow Collection')
116 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 1);
117 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 2);
118 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 3);
119 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 4);
120 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 5);
121 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 6);
122 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 7);
123 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 8);
124 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 9);
125 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 10);
126 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 11);
127 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 12);
128 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 13);
129 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 14);
130 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::cloth_Id, 15);
131
132 out->m_stats.push_back(sp);
133
134 sp = new StatParam(L"McItemAcquired.AcquisitionMethodId.*.ItemId.*");
135 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Tile::dirt_Id); // works
136 sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::milk_Id); // works.
137 sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Tile::dirt_Id); // works.
138 sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::porkChop_cooked_Id); // BROKEN! (ach 'Pork Chop' configured incorrectly)
139 sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::cake_Id); // works. (ach 'The Lie' configured incorrectly)
140 sp->addArgs(DsItemEvent::eAcquisitionMethod_Bought, Item::emerald_Id); // fixed (+ach)
141 sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::ironIngot_Id); // works. (+ach 'Acquired Hardware')
142 sp->addArgs(DsItemEvent::eAcquisitionMethod_Pickedup, Item::fish_raw_Id); // works. (+ach 'Delicious Fish')
143 sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::fish_cooked_Id); // works. (+ach 'Delicious Fish')
144 sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::sign_Id);
145 sp->addArgs(DsItemEvent::eAcquisitionMethod_Crafted, Item::flowerPot_Id); // FIXING!
146 out->m_stats.push_back(sp);
147
148 sp = new StatParam(L"McItemAcquired.DifficultyLevelId.*.AcquisitionMethodId.*.ItemId.*");
149 sp->addArgs(1, 1, Tile::dirt_Id); // works
150 sp->addArgs(2, 2, Tile::dirt_Id); // works
151 out->m_stats.push_back(sp);
152
153 sp = new StatParam(L"McItemUsed.ItemId.*.ItemAux.*");
154 //sp->addArgs(Item::apple_Id, 0);
155 //sp->addArgs(Item::cake_Id, 0);
156 sp->addArgs(Item::beef_raw_Id, 0); // works
157 sp->addArgs(Item::porkChop_cooked_Id, 0); // works
158 out->m_stats.push_back(sp);
159
160 sp = new StatParam(L"MinHungerWhenEaten.ItemId.*");
161 //sp->addArgs(Item::apple_Id);
162 //sp->addArgs(Item::cake_Id);
163 sp->addArgs(Item::beef_raw_Id); // works
164 sp->addArgs(Item::rotten_flesh_Id); // works (+ach IronBelly)
165 out->m_stats.push_back(sp);
166
167 sp = new StatParam(L"BlockBroken.BlockId.*");
168 sp->addArgs( Tile::dirt_Id );
169 sp->addArgs( Tile::rock_Id );
170 sp->addArgs( Tile::emeraldOre_Id );
171 out->m_stats.push_back(sp);
172
173 sp = new StatParam(L"BlockBroken.BlockId.*.BlockAux.*");
174 sp->addArgs( Tile::dirt_Id, 0 );
175 sp->addArgs( Tile::rock_Id, 0 );
176 out->m_stats.push_back(sp);
177
178 sp = new StatParam(L"BlockBroken.DifficultyLevelId.*.BlockId.*");
179 sp->addArgs( 1, Tile::dirt_Id );
180 sp->addArgs( 2, Tile::dirt_Id );
181 sp->addArgs( 1, Tile::rock_Id );
182 sp->addArgs( 2, Tile::rock_Id );
183 out->m_stats.push_back(sp);
184
185 sp = new StatParam(L"BlockBroken");
186 sp->addArgs( -1 );
187 out->m_stats.push_back(sp);
188
189 sp = new StatParam(L"BlockPlaced.BlockId.*");
190 sp->addArgs( Tile::dirt_Id );
191 sp->addArgs( Tile::stoneBrick_Id );
192 sp->addArgs( Tile::sand_Id ); // works
193 sp->addArgs( Tile::sign_Id ); // fixed
194 sp->addArgs( Tile::wallSign_Id ); // fixed
195 out->m_stats.push_back(sp);
196
197 sp = new StatParam(L"MobKilled.KillTypeId.*.EnemyRoleId.*.PlayerWeaponId.*"); // BROKEN!
198 sp->addArgs( /*MELEE*/ 0, ioid_Cow, 0 );
199 sp->addArgs( /*MELEE*/ 0, ioid_Cow, Item::sword_stone_Id );
200 sp->addArgs( /*MELEE*/ 0, ioid_Pig, Item::sword_stone_Id );
201 out->m_stats.push_back(sp);
202
203 sp = new StatParam(L"MaxKillDistance.KillTypeId.*.EnemyRoleId.*.PlayerWeaponId.*"); // BROKEN!
204 sp->addArgs( /*MELEE*/ 0, ioid_Cow, Item::sword_stone_Id );
205 sp->addArgs( /*MELEE*/ 0, ioid_Pig, Item::sword_stone_Id );
206 sp->addArgs( /*RANGE*/ 1, ioid_Creeper, ioid_Arrow ); // FIXING!
207 out->m_stats.push_back(sp);
208
209 sp = new StatParam(L"MobKilled.KillTypeId.*.EnemyRoleId.*"); // BROKEN!
210 sp->addArgs( /*MELEE*/ 0, ioid_Cow );
211 sp->addArgs( /*MELEE*/ 0, ioid_Pig );
212 out->m_stats.push_back(sp);
213
214 sp = new StatParam(L"MobKilled.EnemyRoleId.*"); // BROKEN!
215 sp->addArgs( ioid_Cow );
216 sp->addArgs( ioid_Pig );
217 sp->addArgs( ioid_Zombie );
218 sp->addArgs( ioid_Spiderjocky );
219 out->m_stats.push_back(sp);
220
221 sp = new StatParam(L"MobKilledTotal.DifficultyLevelId.*.EnemyRoleId.*"); // BROKEN!
222 sp->addArgs( 1, ioid_Cow );
223 sp->addArgs( 2, ioid_Cow );
224 out->m_stats.push_back(sp);
225
226 sp = new StatParam(L"MobKilledTotal"); // BROKEN!
227 sp->addArgs(-1);
228 out->m_stats.push_back(sp);
229
230 sp = new StatParam(L"MobInteract.MobId.*.Interaction.*");
231 // sp->addArgs( ioid_Cow, /*MILKED*/ 6 ); no longer an interaction type.
232 sp->addArgs( ioid_Cow, /*BRED*/ 1 ); // fixed (+ach)
233 sp->addArgs( ioid_Sheep, /*SHEARED*/ 5 ); // works (+ach)
234 sp->addArgs( ioid_VillagerGolem, /*CRAFTED*/ 4 ); // works (+ach)
235 sp->addArgs( ioid_Ozelot, /*TAMED*/ 2 ); // works (+ach)
236 sp->addArgs( ioid_Zombie, /*CURED*/ 3 ); // fixed (+ach)
237 out->m_stats.push_back(sp);
238
239 sp = new StatParam(L"EnteredNewBiome.BiomeId.*");
240 for (int i=0; i<20; i++)
241 sp->addArgs( i );
242 out->m_stats.push_back(sp);
243
244 sp = new StatParam(L"AchievementGet.AchievementId.*");
245 sp->addArgs( eAward_TakingInventory ); // works (+ach)
246 sp->addArgs( eAward_WhenPigsFly ); // works (+ach)
247 sp->addArgs( eAward_InToTheNether ); // works (+ach)
248 sp->addArgs( eAward_theEnd ); // works (+ach)
249 sp->addArgs( eAward_winGame ); // fixed (+ach)
250 sp->addArgs( eAward_diamondsToYou );
251 sp->addArgs( eAward_stayinFrosty ); // works (achievement configured incorrectly)
252 sp->addArgs( eAward_ironMan ); // fixed (+ach)
253 sp->addArgs( eAward_renewableEnergy );
254 out->m_stats.push_back(sp);
255
256 sp = new StatParam(L"TimePlayed.DifficultyLevelId.*"); // BROKEN!
257 for (int i=0; i<4; i++) sp->addArgs(i); // Difficulty Levels.
258 out->m_stats.push_back(sp);
259
260 sp = new StatParam(L"DistanceTravelled.DifficultyLevelId.*.TravelMethodId.*");
261 for (int i = 0; i<4; i++)
262 {
263 sp->addArgs( i, DsTravel::eMethod_walk );
264 sp->addArgs( i, DsTravel::eMethod_climb );
265 sp->addArgs( i, DsTravel::eMethod_fall );
266 sp->addArgs( i, DsTravel::eMethod_minecart );
267 sp->addArgs( i, DsTravel::eMethod_swim );
268 sp->addArgs( i, DsTravel::eMethod_pig );
269 }
270 out->m_stats.push_back(sp);
271
272 sp = new StatParam(L"DistanceTravelled");
273 sp->addArgs( /*NO ARGUMENTS*/ -1 );
274 out->m_stats.push_back(sp);
275
276 sp = new StatParam(L"PlayedMusicDisc.DiscId.*"); // works (+ach)
277 for (int i = 2256; i < 2268; i++)
278 sp->addArgs( i );
279 out->m_stats.push_back(sp);
280
281 sp = new StatParam(L"ChestfulOfCobblestone"); // works. (+ach)
282 sp->addArgs( /*NO ARGUMENTS*/ -1 );
283 out->m_stats.push_back(sp);
284
285 sp = new StatParam(L"Overkill"); // works. (+ach)
286 sp->addArgs( /*NO ARGUMENTS*/ -1 );
287 out->m_stats.push_back(sp);
288
289 sp = new StatParam(L"OnARail"); // works. (+ach)
290 sp->addArgs( /*NO ARGUMENTS*/ -1 );
291 out->m_stats.push_back(sp);
292
293 sp = new StatParam(L"Leaderboard.LeaderboardId.*.DifficultyLevelId.*");
294 for (int i = 0; i < 4; i++)
295 {
296 sp->addArgs( eLeaderboardId_FARMING, i );
297 sp->addArgs( eLeaderboardId_MINING, i );
298 sp->addArgs( eLeaderboardId_TRAVELLING, i );
299 sp->addArgs( eLeaderboardId_KILLING, i );
300 }
301 out->m_stats.push_back(sp);
302
303
304 // Debugging 1 //
305
306 sp = new StatParam(L"DistanceTravelled");
307 sp->addArgs( /*NO ARGUMENTS*/ -1 );
308 out->m_stats.push_back(sp);
309
310 sp = new StatParam(L"BlockBroken");
311 sp->addArgs( /*NO ARGUMENTS*/ -1 );
312 out->m_stats.push_back(sp);
313
314 sp = new StatParam(L"MobKilledTotal");
315 sp->addArgs( /*NO ARGUMENTS*/ -1 );
316 out->m_stats.push_back(sp);
317
318 return out;
319}
320
321void DurangoStatsDebugger::PrintStats(int iPad)
322{
323 if (instance == NULL) instance = Initialize();
324
325 vector<wstring> *tmp = instance->getStats();
326 instance->m_printQueue.insert(instance->m_printQueue.end(), tmp->begin(), tmp->end());
327
328 // app.DebugPrintf("[DEBUG] START\n");
329 // for (wstring t : *tmp) app.DebugPrintf("[DEBUG] %s\n", wstringtofilename(t));
330 // app.DebugPrintf("[DEBUG] END\n");
331
332 instance->retrieveStats(iPad);
333
334 app.DebugPrintf("[DurangoStatsDebugger] (%i) Results returned, starting printing.\n", instance->m_retrievedStats.size());
335 for (StatResult result : instance->m_retrievedStats)
336 {
337 app.DebugPrintf("[DSB] '%s' == ", wstringtofilename(result.m_statName));
338 app.DebugPrintf("%s\n", wstringtofilename(result.m_score));
339 }
340
341 // Empty list.
342 EnterCriticalSection(&instance->m_retrievedStatsLock);
343 instance->m_retrievedStats.erase(
344 instance->m_retrievedStats.begin(),
345 instance->m_retrievedStats.end()
346 );
347 LeaveCriticalSection(&instance->m_retrievedStatsLock);
348
349}
350
351void DurangoStatsDebugger::retrieveStats(int iPad)
352{
353 MXS::XboxLiveContext ^xboxLiveContext;
354 try
355 {
356 WFC::IVectorView<Windows::Xbox::System::User^>^ userList = Windows::Xbox::System::User::Users;
357 if( userList != nullptr )
358 {
359 for (Windows::Xbox::System::User^ user : userList)
360 {
361 if( user->IsSignedIn && !user->IsGuest )
362 {
363 xboxLiveContext = ref new MXS::XboxLiveContext(user);
364 break;
365 }
366 }
367
368 if (xboxLiveContext == nullptr)
369 {
370 app.DebugPrintf("[DurangoStatsDebugger] Problem occured while creating 'XboxLiveContext'.\n"); return;
371 }
372 }
373 }
374 catch (Platform::Exception^ ex)
375 {
376 app.DebugPrintf("[DurangoStatsDebugger] Problem occured while creating 'XboxLiveContext'.\n"); return;
377 }
378
379 if ( xboxLiveContext ) { app.DebugPrintf("[DurangoStatsDebugger] 'XboxLiveContext' created successfully.\n"); }
380 else { app.DebugPrintf("[DurangoStatsDebugger] 'XboxLiveContext' not created.\n"); return; }
381
382 PlayerUID xuid;
383 ProfileManager.GetXUID(iPad, &xuid, true);
384
385 const int readCount = 1, difficulty = 1, type = 0;
386
387 // ----------------------------------------- //
388
389 byte runningThreads = 0;
390 byte *r_runningThreads = &runningThreads;
391
392 if (xuid.toString().compare(L"") == 0)
393 {
394 app.DebugPrintf("[DurangoStatsDebugger] NO LOGGED IN USER!\n");
395 return;
396 }
397
398 string plrname= wstringtofilename(xuid.toString());
399 app.DebugPrintf(
400 "[DurangoStatsDebugger] Retrieving (%i) stats for '%s'.\n",
401 m_printQueue.size(),
402 plrname.c_str()
403 );
404
405 static const unsigned short R_SIZE = 20;
406
407 // Create Stat retrieval threads until there is no long any stats to start retrieving.
408 while ( !instance->m_printQueue.empty() )
409 {
410 vector<wstring> *printing = new vector<wstring>();
411
412 if (m_printQueue.size() > R_SIZE)
413 {
414 printing->insert( printing->end(), m_printQueue.begin(), m_printQueue.begin() + R_SIZE );
415 m_printQueue.erase( m_printQueue.begin(), m_printQueue.begin() + R_SIZE );
416 }
417 else
418 {
419 printing->insert( printing->end(), m_printQueue.begin(), m_printQueue.end() );
420 m_printQueue.erase( m_printQueue.begin(), m_printQueue.end() );
421 }
422
423 // ------------------------------------------ //
424
425 app.DebugPrintf("[DurangoStatsDebugger] Starting retrieval operation (%i/%i stats).\n", printing->size(), R_SIZE);
426
427 runningThreads++;
428
429 // Fill statNames string.
430 PC::Vector<P::String^>^ statNames = ref new PC::Vector<P::String^>();
431 for ( auto it = printing->begin(); it != printing->end(); it++ )
432 statNames->Append( ref new P::String(it->c_str()) );
433
434 // Create vector of the XboxId we want.
435 PC::Vector<P::String^>^ xboxUserIds = ref new PC::Vector<P::String^>();
436 xboxUserIds->Append(ref new P::String(xuid.toString().c_str()));
437
438 auto asyncOp = xboxLiveContext->UserStatisticsService->GetMultipleUserStatisticsAsync(
439 xboxUserIds->GetView(), // the collection of Xbox user IDs whose stats we want to retrieve
440 SERVICE_CONFIG_ID, // the service config that contains the stats we want
441 statNames->GetView() // a list of stat names we want
442 );
443
444 CC::create_task(asyncOp)
445 .then( [this,printing,iPad,r_runningThreads] (CC::task<WFC::IVectorView<MXS::UserStatistics::UserStatisticsResult^>^> resultListTask)
446 {
447 try
448 {
449 WFC::IVectorView<MXS::UserStatistics::UserStatisticsResult^>^ resultList = resultListTask.get();
450 int userIndex = 0;
451 for( MXS::UserStatistics::UserStatisticsResult^ result : resultList )
452 {
453 for( UINT index = 0; index<result->ServiceConfigurationStatistics->Size; index++ )
454 {
455 MXS::UserStatistics::ServiceConfigurationStatistic^ configStat = result->ServiceConfigurationStatistics->GetAt(index);
456
457 app.DebugPrintf("[DurangoStatsDebugger] Retrieve complete, %i results returned.\n", configStat->Statistics->Size);
458
459 for (auto result : configStat->Statistics)
460 {
461 StatResult sr = { iPad, result->StatisticName->Data(), result->Value->Data() };
462 this->addRetrievedStat(sr);
463 }
464 }
465 ++userIndex;
466 }
467
468
469 }
470 catch (Platform::Exception ^ex)
471 {
472 app.DebugPrintf("[DurangoStatsDebugger] resultListTask.get() encountered an exception:\n\t'%s'\n", ex->ToString()->Data() );
473 }
474
475 (*r_runningThreads)--;
476 });
477 }
478
479 while (runningThreads > 0) Sleep(5);
480}
481
482void DurangoStatsDebugger::addRetrievedStat(StatResult result)
483{
484 EnterCriticalSection(&m_retrievedStatsLock);
485 m_retrievedStats.push_back(result);
486 LeaveCriticalSection(&m_retrievedStatsLock);
487}