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 "MultiPlayerLocalPlayer.h"
4
5#include "..\Minecraft.World\LevelSettings.h"
6#include "..\Minecraft.World\LevelData.h"
7#include "..\Minecraft.World\Level.h"
8
9#include "TelemetryManager.h"
10
11#if !defined(_DURANGO) && !defined(_XBOX)
12
13CTelemetryManager *TelemetryManager = new CTelemetryManager();
14
15#endif
16
17HRESULT CTelemetryManager::Init()
18{
19 return S_OK;
20}
21
22HRESULT CTelemetryManager::Tick()
23{
24 return S_OK;
25}
26
27HRESULT CTelemetryManager::Flush()
28{
29 return S_OK;
30}
31
32bool CTelemetryManager::RecordPlayerSessionStart(int iPad)
33{
34 return true;
35}
36
37bool CTelemetryManager::RecordPlayerSessionExit(int iPad, int exitStatus)
38{
39 return true;
40}
41
42bool CTelemetryManager::RecordHeartBeat(int iPad)
43{
44 return true;
45}
46
47bool CTelemetryManager::RecordLevelStart(int iPad, ESen_FriendOrMatch friendsOrMatch, ESen_CompeteOrCoop competeOrCoop, int difficulty, int numberOfLocalPlayers, int numberOfOnlinePlayers)
48{
49 if(iPad == ProfileManager.GetPrimaryPad() ) m_bFirstFlush = true;
50
51 ++m_levelInstanceID;
52 m_fLevelStartTime[iPad] = app.getAppTime();
53
54 return true;
55}
56
57bool CTelemetryManager::RecordLevelExit(int iPad, ESen_LevelExitStatus levelExitStatus)
58{
59 return true;
60}
61
62bool CTelemetryManager::RecordLevelSaveOrCheckpoint(int iPad, int saveOrCheckPointID, int saveSizeInBytes)
63{
64 return true;
65}
66
67bool CTelemetryManager::RecordLevelResume(int iPad, ESen_FriendOrMatch friendsOrMatch, ESen_CompeteOrCoop competeOrCoop, int difficulty, int numberOfLocalPlayers, int numberOfOnlinePlayers, int saveOrCheckPointID)
68{
69 return true;
70}
71
72bool CTelemetryManager::RecordPauseOrInactive(int iPad)
73{
74 return true;
75}
76
77bool CTelemetryManager::RecordUnpauseOrActive(int iPad)
78{
79 return true;
80}
81
82bool CTelemetryManager::RecordMenuShown(int iPad, EUIScene menuID, int optionalMenuSubID)
83{
84 return true;
85}
86
87bool CTelemetryManager::RecordAchievementUnlocked(int iPad, int achievementID, int achievementGamerscore)
88{
89 return true;
90}
91
92bool CTelemetryManager::RecordMediaShareUpload(int iPad, ESen_MediaDestination mediaDestination, ESen_MediaType mediaType)
93{
94 return true;
95}
96
97bool CTelemetryManager::RecordUpsellPresented(int iPad, ESen_UpsellID upsellId, int marketplaceOfferID)
98{
99 return true;
100}
101
102bool CTelemetryManager::RecordUpsellResponded(int iPad, ESen_UpsellID upsellId, int marketplaceOfferID, ESen_UpsellOutcome upsellOutcome)
103{
104 return true;
105}
106
107bool CTelemetryManager::RecordPlayerDiedOrFailed(int iPad, int lowResMapX, int lowResMapY, int lowResMapZ, int mapID, int playerWeaponID, int enemyWeaponID, ETelemetryChallenges enemyTypeID)
108{
109 return true;
110}
111
112bool CTelemetryManager::RecordEnemyKilledOrOvercome(int iPad, int lowResMapX, int lowResMapY, int lowResMapZ, int mapID, int playerWeaponID, int enemyWeaponID, ETelemetryChallenges enemyTypeID)
113{
114 return true;
115}
116
117bool CTelemetryManager::RecordTexturePackLoaded(int iPad, int texturePackId, bool purchased)
118{
119 return true;
120}
121
122bool CTelemetryManager::RecordSkinChanged(int iPad, int dwSkinId)
123{
124 return true;
125}
126
127bool CTelemetryManager::RecordBanLevel(int iPad)
128{
129 return true;
130}
131
132bool CTelemetryManager::RecordUnBanLevel(int iPad)
133{
134 return true;
135}
136
137
138 ///////////////////////////////////////////////////////////////////
139 // 4J-JEV: FOLLOWING LOGIC TAKEN FROM XBOX 'SentientManager.cpp' //
140 ///////////////////////////////////////////////////////////////////
141
142
143/*
144Number of seconds elapsed since Sentient initialize.
145Title needs to track this and report it as a property.
146These times will be used to create timelines and understand durations.
147This should be tracked independently of saved games (restoring a save should not reset the seconds since initialize)
148*/
149INT CTelemetryManager::GetSecondsSinceInitialize()
150{
151 return (INT)(app.getAppTime() - m_initialiseTime);
152}
153
154/*
155An in-game setting that significantly differentiates the play style of the game.
156(This should be captured as an integer and correspond to mode specific to the game.)
157Teams will have to provide the game mappings that correspond to the integers.
158The intent is to allow teams to capture data on the highest level categories of gameplay in their game.
159For example, a game mode could be the name of the specific mini game (eg: golf vs darts) or a specific multiplayer mode (eg: hoard vs beast.) ModeID = 0 means undefined or unknown.
160The intent is to answer the question "How are players playing your game?"
161*/
162INT CTelemetryManager::GetMode(DWORD dwUserId)
163{
164 INT mode = (INT)eTelem_ModeId_Undefined;
165
166 Minecraft *pMinecraft = Minecraft::GetInstance();
167
168 if( pMinecraft->localplayers[dwUserId] != NULL && pMinecraft->localplayers[dwUserId]->level != NULL && pMinecraft->localplayers[dwUserId]->level->getLevelData() != NULL )
169 {
170 GameType *gameType = pMinecraft->localplayers[dwUserId]->level->getLevelData()->getGameType();
171
172 if (gameType->isSurvival())
173 {
174 mode = (INT)eTelem_ModeId_Survival;
175 }
176 else if (gameType->isCreative())
177 {
178 mode = (INT)eTelem_ModeId_Creative;
179 }
180 else
181 {
182 mode = (INT)eTelem_ModeId_Undefined;
183 }
184 }
185 return mode;
186}
187
188/*
189Used when a title has more heirarchy required.
190OptionalSubMode ID = 0 means undefined or unknown.
191For titles that have sub-modes (Sports/Football).
192Mode is always an indicator of "How is the player choosing to play my game?" so these do not have to be consecutive.
193LevelIDs and SubLevelIDs can be reused as they will always be paired with a Mode/SubModeID, Mode should be unique - SubMode can be shared between modes.
194*/
195INT CTelemetryManager::GetSubMode(DWORD dwUserId)
196{
197 INT subMode = (INT)eTelem_SubModeId_Undefined;
198
199 if(Minecraft::GetInstance()->isTutorial())
200 {
201 subMode = (INT)eTelem_SubModeId_Tutorial;
202 }
203 else
204 {
205 subMode = (INT)eTelem_SubModeId_Normal;
206 }
207
208 return subMode;
209}
210
211/*
212This is a more granular view of mode, allowing teams to get a sense of the levels or maps players are playing and providing some insight into how players progress through a game.
213Teams will have to provide the game mappings that correspond to the integers.
214The intent is that a level is highest level at which modes can be dissected and provides an indication of player progression in a game.
215The intent is that level start and ends do not occur more than every 2 minutes or so, otherwise the data reported will be difficult to understand.
216Levels are unique only within a given modeID - so you can have a ModeID =1, LevelID =1 and a different ModeID=2, LevelID = 1 indicate two completely different levels.
217LevelID = 0 means undefined or unknown.
218*/
219INT CTelemetryManager::GetLevelId(DWORD dwUserId)
220{
221 INT levelId = (INT)eTelem_LevelId_Undefined;
222
223 levelId = (INT)eTelem_LevelId_PlayerGeneratedLevel;
224
225 return levelId;
226}
227
228/*
229Used when a title has more heirarchy required. OptionalSubLevel ID = 0 means undefined or unknown.
230For titles that have sub-levels.
231Level is always an indicator of "How far has the player progressed." so when possible these should be consecutive or at least monotonically increasing.
232LevelIDs and SubLevelIDs can be reused as they will always be paired with a Mode/SubModeID
233*/
234INT CTelemetryManager::GetSubLevelId(DWORD dwUserId)
235{
236 INT subLevelId = (INT)eTelem_SubLevelId_Undefined;
237
238 Minecraft *pMinecraft = Minecraft::GetInstance();
239
240 if(pMinecraft->localplayers[dwUserId] != NULL)
241 {
242 switch(pMinecraft->localplayers[dwUserId]->dimension)
243 {
244 case 0:
245 subLevelId = (INT)eTelem_SubLevelId_Overworld;
246 break;
247 case -1:
248 subLevelId = (INT)eTelem_SubLevelId_Nether;
249 break;
250 case 1:
251 subLevelId = (INT)eTelem_SubLevelId_End;
252 break;
253 };
254 }
255
256 return subLevelId;
257}
258
259/*
260Build version of the title, used to track changes in development as well as patches/title updates
261Allows developer to separate out stats from different builds
262*/
263INT CTelemetryManager::GetTitleBuildId()
264{
265 return (INT)VER_PRODUCTBUILD;
266}
267
268/*
269Generated by the game every time LevelStart or LevelResume is called.
270This should be a unique ID (can be sequential) within a session.
271Helps differentiate level attempts when a play plays the same mode/level - especially with aggregated stats
272*/
273INT CTelemetryManager::GetLevelInstanceID()
274{
275 return (INT)m_levelInstanceID;
276}
277
278/*
279MultiplayerinstanceID is a title-generated value that is the same for all players in the same multiplayer session.
280Link up players into a single multiplayer session ID.
281*/
282INT CTelemetryManager::GetMultiplayerInstanceID()
283{
284 return m_multiplayerInstanceID;
285}
286
287INT CTelemetryManager::GenerateMultiplayerInstanceId()
288{
289#if defined(_DURANGO) || defined(_XBOX)
290 FILETIME SystemTimeAsFileTime;
291 GetSystemTimeAsFileTime( &SystemTimeAsFileTime );
292 return *((INT *)&SystemTimeAsFileTime.dwLowDateTime);
293#else
294 return 0;
295#endif
296}
297
298void CTelemetryManager::SetMultiplayerInstanceId(INT value)
299{
300 m_multiplayerInstanceID = value;
301}
302
303/*
304Indicates whether the game is being played in single or multiplayer mode and whether multiplayer is being played locally or over live.
305How social is your game? How do people play it?
306*/
307INT CTelemetryManager::GetSingleOrMultiplayer()
308{
309 INT singleOrMultiplayer = (INT)eSen_SingleOrMultiplayer_Undefined;
310
311 // Unused
312 //eSen_SingleOrMultiplayer_Single_Player
313 //eSen_SingleOrMultiplayer_Multiplayer_Live
314
315 if(app.GetLocalPlayerCount() == 1 && g_NetworkManager.GetOnlinePlayerCount() == 0)
316 {
317 singleOrMultiplayer = (INT)eSen_SingleOrMultiplayer_Single_Player;
318 }
319 else if(app.GetLocalPlayerCount() > 1 && g_NetworkManager.GetOnlinePlayerCount() == 0)
320 {
321 singleOrMultiplayer = (INT)eSen_SingleOrMultiplayer_Multiplayer_Local;
322 }
323 else if(app.GetLocalPlayerCount() == 1 && g_NetworkManager.GetOnlinePlayerCount() > 0)
324 {
325 singleOrMultiplayer = (INT)eSen_SingleOrMultiplayer_Multiplayer_Live;
326 }
327 else if(app.GetLocalPlayerCount() > 1 && g_NetworkManager.GetOnlinePlayerCount() > 0)
328 {
329 singleOrMultiplayer = (INT)eSen_SingleOrMultiplayer_Multiplayer_Both_Local_and_Live;
330 }
331
332 return singleOrMultiplayer;
333}
334
335/*
336An in-game setting that differentiates the challenge imposed on the user.
337Normalized to a standard 5-point scale. Are players changing the difficulty?
338*/
339INT CTelemetryManager::GetDifficultyLevel(INT diff)
340{
341 INT difficultyLevel = (INT)eSen_DifficultyLevel_Undefined;
342
343 switch(diff)
344 {
345 case 0:
346 difficultyLevel = (INT)eSen_DifficultyLevel_Easiest;
347 break;
348 case 1:
349 difficultyLevel = (INT)eSen_DifficultyLevel_Easier;
350 break;
351 case 2:
352 difficultyLevel = (INT)eSen_DifficultyLevel_Normal;
353 break;
354 case 3:
355 difficultyLevel = (INT)eSen_DifficultyLevel_Harder;
356 break;
357 }
358
359 // Unused
360 //eSen_DifficultyLevel_Hardest = 5,
361
362 return difficultyLevel;
363}
364
365/*
366Differentiates trial/demo from full purchased titles
367Is this a full title or demo?
368*/
369INT CTelemetryManager::GetLicense()
370{
371 INT license = eSen_License_Undefined;
372
373 if(ProfileManager.IsFullVersion())
374 {
375 license = (INT)eSen_License_Full_Purchased_Title;
376 }
377 else
378 {
379 license = (INT)eSen_License_Trial_or_Demo;
380 }
381 return license;
382}
383
384/*
385This is intended to capture whether players played using default control scheme or customized the control scheme.
386Are players customizing your controls?
387*/
388INT CTelemetryManager::GetDefaultGameControls()
389{
390 INT defaultGameControls = eSen_DefaultGameControls_Undefined;
391
392 // Unused
393 //eSen_DefaultGameControls_Custom_controls
394
395 defaultGameControls = eSen_DefaultGameControls_Default_controls;
396
397 return defaultGameControls;
398}
399
400/*
401Are players changing default audio settings?
402This is intended to capture whether players are playing with or without volume and whether they make changes from the default audio settings.
403*/
404INT CTelemetryManager::GetAudioSettings(DWORD dwUserId)
405{
406 INT audioSettings = (INT)eSen_AudioSettings_Undefined;
407
408 if(dwUserId == ProfileManager.GetPrimaryPad())
409 {
410 BYTE volume = app.GetGameSettings(dwUserId,eGameSetting_SoundFXVolume);
411
412 if(volume == 0)
413 {
414 audioSettings = (INT)eSen_AudioSettings_Off;
415 }
416 else if(volume == DEFAULT_VOLUME_LEVEL)
417 {
418 audioSettings = (INT)eSen_AudioSettings_On_Default;
419 }
420 else
421 {
422 audioSettings = (INT)eSen_AudioSettings_On_CustomSetting;
423 }
424 }
425 return audioSettings;
426}
427
428/*
429Refers to the highest level performance metric for your game.
430For example, a performance metric could points earned, race time, total kills, etc.
431This is entirely up to you and will help us understand how well the player performed, or how far the player progressed �in the level before exiting.
432How far did users progress before failing/exiting the level?
433*/
434INT CTelemetryManager::GetLevelExitProgressStat1()
435{
436 // 4J Stu - Unused
437 return 0;
438}
439
440/*
441Refers to the highest level performance metric for your game.
442For example, a performance metric could points earned, race time, total kills, etc.
443This is entirely up to you and will help us understand how well the player performed, or how far the player progressed �in the level before exiting.
444How far did users progress before failing/exiting the level?
445*/
446INT CTelemetryManager::GetLevelExitProgressStat2()
447{
448 // 4J Stu - Unused
449 return 0;
450}