the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1// Minecraft.cpp : Defines the entry point for the application.
2//
3
4#include "stdafx.h"
5
6#include <assert.h>
7#include "..\..\..\Minecraft.World\AABB.h"
8#include "..\..\..\Minecraft.World\Vec3.h"
9#include "..\..\..\Minecraft.World\net.minecraft.stats.h"
10#include "..\..\..\Minecraft.Client\StatsCounter.h"
11#include "..\..\..\Minecraft.World\Entity.h"
12#include "..\..\..\Minecraft.World\Level.h"
13#include "..\..\..\Minecraft.Client\MultiplayerLocalPlayer.h"
14#include "..\..\MinecraftServer.h"
15#include "..\..\MultiPlayerLevel.h"
16#include "..\..\ProgressRenderer.h"
17#include "..\..\..\Minecraft.World\DisconnectPacket.h"
18#include "..\..\Minecraft.h"
19#include "..\..\Options.h"
20#include "..\..\..\Minecraft.World\compression.h"
21#include "..\..\TexturePackRepository.h"
22#include "..\..\TexturePack.h"
23#include "..\..\DLCTexturePack.h"
24
25#define IGNORE_KEYPRESS_TIMERID 0
26#define IGNORE_KEYPRESS_TIME 100
27
28//----------------------------------------------------------------------------------
29// Performs initialization tasks - retrieves controls.
30//----------------------------------------------------------------------------------
31HRESULT UIScene_PauseMenu::OnInit( XUIMessageInit* pInitData, BOOL& bHandled )
32{
33 m_bIgnoreInput=true;
34 m_iPad = *(int *)pInitData->pvInitData;
35 bool bUserisClientSide = ProfileManager.IsSignedInLive(m_iPad);
36
37 app.DebugPrintf("PAUSE PRESS PROCESSING - ipad = %d, UIScene_PauseMenu::OnInit\n",m_iPad);
38
39 bool bIsisPrimaryHost=g_NetworkManager.IsHost() && (ProfileManager.GetPrimaryPad()==m_iPad);
40 bool bDisplayBanTip = !g_NetworkManager.IsLocalGame() && !bIsisPrimaryHost && !ProfileManager.IsGuest(m_iPad);
41
42 MapChildControls();
43
44 XuiControlSetText(m_Buttons[BUTTON_PAUSE_RESUMEGAME],app.GetString(IDS_RESUME_GAME));
45 XuiControlSetText(m_Buttons[BUTTON_PAUSE_HELPANDOPTIONS],app.GetString(IDS_HELP_AND_OPTIONS));
46 XuiControlSetText(m_Buttons[BUTTON_PAUSE_LEADERBOARDS],app.GetString(IDS_LEADERBOARDS));
47 XuiControlSetText(m_Buttons[BUTTON_PAUSE_ACHIEVEMENTS],app.GetString(IDS_ACHIEVEMENTS));
48 XuiControlSetText(m_Buttons[BUTTON_PAUSE_SAVEGAME],app.GetString(IDS_SAVE_GAME));
49 XuiControlSetText(m_Buttons[BUTTON_PAUSE_EXITGAME],app.GetString(IDS_EXIT_GAME));
50
51 if(app.GetLocalPlayerCount()>1)
52 {
53 m_bSplitscreen = true;
54 app.AdjustSplitscreenScene(m_hObj,&m_OriginalPosition,m_iPad,false);
55 CXuiSceneBase::ShowLogo( m_iPad, FALSE );
56 }
57 else
58 {
59 m_bSplitscreen = false;
60 CXuiSceneBase::ShowLogo( m_iPad, TRUE );
61 }
62
63 // test award the theme
64 //ProfileManager.Award( ProfileManager.GetPrimaryPad(), eAward_socialPost );
65 // Display the tooltips, we are only allowed to display "SHARE" if we have the capability (TCR).
66
67 if(!ProfileManager.IsFullVersion())
68 {
69 ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK);
70 // hide the trial timer
71 CXuiSceneBase::ShowTrialTimer(FALSE);
72 }
73 else if(StorageManager.GetSaveDisabled())
74 {
75 if( CSocialManager::Instance()->IsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() && bUserisClientSide )
76 {
77 ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,bIsisPrimaryHost?IDS_TOOLTIPS_SELECTDEVICE:-1,IDS_TOOLTIPS_SHARE, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1);
78 }
79 else
80 {
81 ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,bIsisPrimaryHost?IDS_TOOLTIPS_SELECTDEVICE:-1,-1,-1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1);
82 }
83 }
84 else
85 {
86 if( CSocialManager::Instance()->IsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() && bUserisClientSide)
87 {
88 ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,bIsisPrimaryHost?IDS_TOOLTIPS_CHANGEDEVICE:-1,IDS_TOOLTIPS_SHARE, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1);
89 }
90 else
91 {
92 ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,bIsisPrimaryHost?IDS_TOOLTIPS_CHANGEDEVICE:-1,-1, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1);
93 }
94 }
95
96 CXuiSceneBase::ShowDarkOverlay( m_iPad, TRUE );
97
98 // are we the primary player?
99 // 4J-PB - fix for 7844 & 7845 -
100 // TCR # 128: XLA Pause Menu: When in a multiplayer game as a client the Pause Menu does not have a Leaderboards option.
101 // TCR # 128: XLA Pause Menu: When in a multiplayer game as a client the Pause Menu does not have an Achievements option.
102 if(ProfileManager.GetPrimaryPad()==m_iPad) // && g_NetworkManager.IsHost())
103 {
104 // are we in splitscreen?
105 // how many local players do we have?
106
107 D3DXVECTOR3 vPos;
108 if( app.GetLocalPlayerCount()>1 )
109 {
110 m_Buttons[BUTTON_PAUSE_LEADERBOARDS].GetPosition(&vPos);
111 m_Buttons[BUTTON_PAUSE_SAVEGAME].SetPosition(&vPos);
112 m_Buttons[BUTTON_PAUSE_ACHIEVEMENTS].GetPosition(&vPos);
113 m_Buttons[BUTTON_PAUSE_EXITGAME].SetPosition(&vPos);
114 // Hide the BUTTON_PAUSE_LEADERBOARDS and BUTTON_PAUSE_ACHIEVEMENTS
115 XuiElementSetShow(m_Buttons[BUTTON_PAUSE_LEADERBOARDS],FALSE);
116 XuiElementSetShow(m_Buttons[BUTTON_PAUSE_ACHIEVEMENTS],FALSE);
117 }
118
119 if( !g_NetworkManager.IsHost() )
120 {
121 m_Buttons[BUTTON_PAUSE_SAVEGAME].GetPosition(&vPos);
122 m_Buttons[BUTTON_PAUSE_EXITGAME].SetPosition(&vPos);
123 // Hide the BUTTON_PAUSE_SAVEGAME
124 XuiElementSetShow(m_Buttons[BUTTON_PAUSE_SAVEGAME],FALSE);
125 }
126 }
127 else
128 {
129 D3DXVECTOR3 vPos;
130 m_Buttons[BUTTON_PAUSE_LEADERBOARDS].GetPosition(&vPos);
131 m_Buttons[BUTTON_PAUSE_EXITGAME].SetPosition(&vPos);
132 // Hide the BUTTON_PAUSE_LEADERBOARDS, BUTTON_PAUSE_ACHIEVEMENTS and BUTTON_PAUSE_SAVEGAME
133 XuiElementSetShow(m_Buttons[BUTTON_PAUSE_LEADERBOARDS],FALSE);
134 XuiElementSetShow(m_Buttons[BUTTON_PAUSE_ACHIEVEMENTS],FALSE);
135 XuiElementSetShow(m_Buttons[BUTTON_PAUSE_SAVEGAME],FALSE);
136 }
137
138 // is saving disabled?
139 if(StorageManager.GetSaveDisabled())
140 {
141 // disable save button
142 m_Buttons[BUTTON_PAUSE_SAVEGAME].SetEnable(FALSE);
143 m_Buttons[BUTTON_PAUSE_SAVEGAME].EnableInput(FALSE);
144 }
145
146 m_iLastButtonPressed=0;
147
148 // get rid of the quadrant display if it's on
149 CXuiSceneBase::HidePressStart();
150
151 XuiSetTimer(m_hObj,IGNORE_KEYPRESS_TIMERID,IGNORE_KEYPRESS_TIME);
152
153 if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 )
154 {
155 app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)TRUE);
156 }
157
158 TelemetryManager->RecordMenuShown(m_iPad, eUIScene_PauseMenu, 0);
159 TelemetryManager->RecordPauseOrInactive(m_iPad);
160
161 return S_OK;
162}
163
164//----------------------------------------------------------------------------------
165// Handler for the button press message.
166//----------------------------------------------------------------------------------
167HRESULT UIScene_PauseMenu::OnNotifyPressEx(HXUIOBJ hObjPressed, XUINotifyPress* pNotifyPressData, BOOL& rfHandled)
168{
169 if(m_bIgnoreInput) return S_OK;
170
171 // This assumes all buttons can only be pressed with the A button
172 ui.AnimateKeyPress(pNotifyPressData->UserIndex, VK_PAD_A);
173
174 unsigned int uiButtonCounter=0;
175
176 while((uiButtonCounter<BUTTONS_PAUSE_MAX) && (m_Buttons[uiButtonCounter]!=hObjPressed)) uiButtonCounter++;
177
178 Minecraft *pMinecraft=Minecraft::GetInstance();
179
180 // ignore buttons not from this user
181 //if(pNotifyPressData->UserIndex!=pMinecraft->player->GetXboxPad()) return S_OK;
182
183 // Determine which button was pressed,
184 // and call the appropriate function.
185
186 // store the last button pressed, so on a nav back we can set the focus properly
187 m_iLastButtonPressed=uiButtonCounter;
188 switch(uiButtonCounter)
189 {
190 case BUTTON_PAUSE_RESUMEGAME:
191 if( m_iPad == ProfileManager.GetPrimaryPad() && g_NetworkManager.IsLocalGame() )
192 {
193 app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE);
194 }
195 app.CloseXuiScenes(pNotifyPressData->UserIndex);
196 break;
197
198 case BUTTON_PAUSE_LEADERBOARDS:
199 {
200 UINT uiIDA[1];
201 uiIDA[0]=IDS_OK;
202
203 //4J Gordon: Being used for the leaderboards proper now
204 // guests can't look at leaderboards
205 if(ProfileManager.IsGuest(pNotifyPressData->UserIndex))
206 {
207 StorageManager.RequestMessageBox(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1);
208 }
209 else if(!ProfileManager.IsSignedInLive(pNotifyPressData->UserIndex))
210 {
211 StorageManager.RequestMessageBox(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_XBOXLIVE_NOTIFICATION, uiIDA, 1);
212 }
213 else
214 {
215 app.NavigateToScene(pNotifyPressData->UserIndex, eUIScene_LeaderboardsMenu);
216 }
217 }
218 break;
219 case BUTTON_PAUSE_ACHIEVEMENTS:
220 // guests can't look at achievements
221 if(ProfileManager.IsGuest(pNotifyPressData->UserIndex))
222 {
223 UINT uiIDA[1];
224 uiIDA[0]=IDS_OK;
225 StorageManager.RequestMessageBox(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1);
226 }
227 else
228 {
229 XShowAchievementsUI( pNotifyPressData->UserIndex );
230 }
231
232 break;
233 case BUTTON_PAUSE_HELPANDOPTIONS:
234 if(app.GetLocalPlayerCount()>1)
235 {
236 app.NavigateToScene(pNotifyPressData->UserIndex,eUIScene_HelpAndOptionsMenu);
237 }
238 else
239 {
240 app.NavigateToScene(pNotifyPressData->UserIndex,eUIScene_HelpAndOptionsMenu);
241 }
242 break;
243
244 case BUTTON_PAUSE_SAVEGAME:
245 {
246 // 4J-PB - Is the player trying to save but they are using a trial texturepack ?
247 if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin())
248 {
249 TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected();
250 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack;
251
252 m_pDLCPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack();
253
254 if(!m_pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" ))
255 {
256 // upsell
257 ULONGLONG ullOfferID_Full;
258 // get the dlc texture pack
259 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack;
260
261 app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullOfferID_Full);
262
263 // tell sentient about the upsell of the full version of the texture pack
264 TelemetryManager->RecordUpsellPresented(pNotifyPressData->UserIndex, eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF);
265
266 UINT uiIDA[2];
267 uiIDA[0]=IDS_CONFIRM_OK;
268 uiIDA[1]=IDS_CONFIRM_CANCEL;
269
270 // Give the player a warning about the trial version of the texture pack
271 StorageManager.RequestMessageBox(IDS_WARNING_DLC_TRIALTEXTUREPACK_TITLE, IDS_WARNING_DLC_TRIALTEXTUREPACK_TEXT, uiIDA, 2, pNotifyPressData->UserIndex,&UIScene_PauseMenu::WarningTrialTexturePackReturned,this,app.GetStringTable());
272
273 return S_OK;
274 }
275 }
276
277 // does the save exist?
278 bool bSaveExists;
279 C4JStorage::ELoadGameStatus result=StorageManager.DoesSaveExist(&bSaveExists);
280
281 if(result == C4JStorage::ELoadGame_DeviceRemoved)
282 {
283 // this will be a tester trying to be clever
284 UINT uiIDA[2];
285 uiIDA[0]=IDS_SELECTANEWDEVICE;
286 uiIDA[1]=IDS_NODEVICE_DECLINE;
287
288 StorageManager.RequestMessageBox(IDS_STORAGEDEVICEPROBLEM_TITLE, IDS_FAILED_TO_LOADSAVE_TEXT, uiIDA, 2, pNotifyPressData->UserIndex,&UIScene_PauseMenu::DeviceRemovedDialogReturned,this);
289 }
290 else
291 {
292 // we need to ask if they are sure they want to overwrite the existing game
293 if(bSaveExists)
294 {
295 UINT uiIDA[2];
296 uiIDA[0]=IDS_CONFIRM_CANCEL;
297 uiIDA[1]=IDS_CONFIRM_OK;
298 StorageManager.RequestMessageBox(IDS_TITLE_SAVE_GAME, IDS_CONFIRM_SAVE_GAME, uiIDA, 2, pNotifyPressData->UserIndex,&UIScene_PauseMenu::SaveGameDialogReturned,this, app.GetStringTable());
299 }
300 else
301 {
302 // flag a app action of save game
303 app.SetAction(pNotifyPressData->UserIndex,eAppAction_SaveGame);
304 }
305 }
306 }
307
308 break;
309 case BUTTON_PAUSE_EXITGAME:
310 {
311 // Check if it's the trial version
312 if(ProfileManager.IsFullVersion())
313 {
314 UINT uiIDA[3];
315
316 // is it the primary player exiting?
317 if(pNotifyPressData->UserIndex==ProfileManager.GetPrimaryPad())
318 {
319 int playTime = -1;
320 if( pMinecraft->localplayers[pNotifyPressData->UserIndex] != NULL )
321 {
322 playTime = (int)pMinecraft->localplayers[pNotifyPressData->UserIndex]->getSessionTimer();
323 }
324
325 if(StorageManager.GetSaveDisabled())
326 {
327 uiIDA[0]=IDS_CONFIRM_CANCEL;
328 uiIDA[1]=IDS_CONFIRM_OK;
329 StorageManager.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME_PROGRESS_LOST, uiIDA, 2, pNotifyPressData->UserIndex,&UIScene_PauseMenu::ExitGameDialogReturned,this, app.GetStringTable());
330 }
331 else
332 {
333 if( g_NetworkManager.IsHost() )
334 {
335 uiIDA[0]=IDS_CONFIRM_CANCEL;
336 uiIDA[1]=IDS_EXIT_GAME_SAVE;
337 uiIDA[2]=IDS_EXIT_GAME_NO_SAVE;
338
339 if(g_NetworkManager.GetPlayerCount()>1)
340 {
341 StorageManager.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME_CONFIRM_DISCONNECT_SAVE, uiIDA, 3, pNotifyPressData->UserIndex,&UIScene_PauseMenu::ExitGameSaveDialogReturned,this, app.GetStringTable());
342 }
343 else
344 {
345 StorageManager.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 3, pNotifyPressData->UserIndex,&UIScene_PauseMenu::ExitGameSaveDialogReturned,this, app.GetStringTable());
346 }
347 }
348 else
349 {
350 uiIDA[0]=IDS_CONFIRM_CANCEL;
351 uiIDA[1]=IDS_CONFIRM_OK;
352
353 StorageManager.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 2, pNotifyPressData->UserIndex,&UIScene_PauseMenu::ExitGameDialogReturned,this, app.GetStringTable());
354 }
355 }
356 }
357 else
358 {
359 int playTime = -1;
360 if( pMinecraft->localplayers[pNotifyPressData->UserIndex] != NULL )
361 {
362 playTime = (int)pMinecraft->localplayers[pNotifyPressData->UserIndex]->getSessionTimer();
363 }
364
365 TelemetryManager->RecordLevelExit(pNotifyPressData->UserIndex, eSen_LevelExitStatus_Exited);
366
367
368 // just exit the player
369 app.SetAction(pNotifyPressData->UserIndex,eAppAction_ExitPlayer);
370 }
371 }
372 else
373 {
374 // is it the primary player exiting?
375 if(pNotifyPressData->UserIndex==ProfileManager.GetPrimaryPad())
376 {
377 int playTime = -1;
378 if( pMinecraft->localplayers[pNotifyPressData->UserIndex] != NULL )
379 {
380 playTime = (int)pMinecraft->localplayers[pNotifyPressData->UserIndex]->getSessionTimer();
381 }
382
383 // adjust the trial time played
384 CXuiSceneBase::ReduceTrialTimerValue();
385
386 // exit the level
387 UINT uiIDA[2];
388 uiIDA[0]=IDS_CONFIRM_CANCEL;
389 uiIDA[1]=IDS_CONFIRM_OK;
390 StorageManager.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME_PROGRESS_LOST, uiIDA, 2, pNotifyPressData->UserIndex,&UIScene_PauseMenu::ExitGameDialogReturned,this, app.GetStringTable());
391 }
392 else
393 {
394 int playTime = -1;
395 if( pMinecraft->localplayers[pNotifyPressData->UserIndex] != NULL )
396 {
397 playTime = (int)pMinecraft->localplayers[pNotifyPressData->UserIndex]->getSessionTimer();
398 }
399
400 TelemetryManager->RecordLevelExit(pNotifyPressData->UserIndex, eSen_LevelExitStatus_Exited);
401
402 // just exit the player
403 app.SetAction(pNotifyPressData->UserIndex,eAppAction_ExitPlayer);
404 }
405 }
406 }
407 break;
408 default:
409 break;
410 }
411
412 return S_OK;
413}
414
415HRESULT UIScene_PauseMenu::OnKeyDown(XUIMessageInput* pInputData, BOOL& rfHandled)
416{
417 if(m_bIgnoreInput) return S_OK;
418 // ignore repeated start presses to avoid the scene closing before it's opened
419 if((pInputData->dwKeyCode==VK_PAD_START) &&(pInputData->dwFlags&XUI_INPUT_FLAG_REPEAT ))
420 {
421 rfHandled = TRUE;
422 return S_OK;
423 }
424
425 bool bIsisPrimaryHost=g_NetworkManager.IsHost() && (ProfileManager.GetPrimaryPad()==m_iPad);
426 bool bDisplayBanTip = !g_NetworkManager.IsLocalGame() && !bIsisPrimaryHost && !ProfileManager.IsGuest(m_iPad);
427 bool bUserisClientSide = ProfileManager.IsSignedInLive(m_iPad);
428
429 ui.AnimateKeyPress(pInputData->UserIndex, pInputData->dwKeyCode);
430
431 app.DebugPrintf("PAUSE- Keydown in the xui %d flags = %d\n",pInputData->dwKeyCode,pInputData->dwFlags);
432
433
434 switch(pInputData->dwKeyCode)
435 {
436
437 case VK_PAD_B:
438 case VK_PAD_START:
439 case VK_ESCAPE:
440 app.DebugPrintf("PAUSE PRESS PROCESSING - ipad = %d, UIScene_PauseMenu::OnKeyDown - LEAVING PAUSE MENU\n",m_iPad);
441
442 if( m_iPad == ProfileManager.GetPrimaryPad() && g_NetworkManager.IsLocalGame() )
443 {
444 app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE);
445 }
446
447 CXuiSceneBase::PlayUISFX(eSFX_Back);
448 app.CloseXuiScenes(pInputData->UserIndex);
449 if(!ProfileManager.IsFullVersion())
450 {
451 CXuiSceneBase::ShowTrialTimer(TRUE);
452 }
453 rfHandled = TRUE;
454
455 break;
456
457 case VK_PAD_X:
458 // Change device
459 if(bIsisPrimaryHost)
460 {
461 // we need a function to deal with the return from this - if it changes, we need to update the pause menu and tooltips
462 // Fix for #12531 - TCR 001: BAS Game Stability: When a player selects to change a storage
463 // device, and repeatedly backs out of the SD screen, disconnects from LIVE, and then selects a SD, the title crashes.
464 m_bIgnoreInput=true;
465
466 StorageManager.SetSaveDevice(&UIScene_PauseMenu::DeviceSelectReturned,this,true);
467 }
468 rfHandled = TRUE;
469 break;
470
471
472 case VK_PAD_Y:
473 {
474 if(bUserisClientSide)
475 {
476 // 4J Stu - Added check in 1.8.2 bug fix (TU6) to stop repeat key presses
477 bool bCanScreenshot = true;
478 for(int j=0; j < XUSER_MAX_COUNT;++j)
479 {
480 if(app.GetXuiAction(j) == eAppAction_SocialPostScreenshot)
481 {
482 bCanScreenshot = false;
483 break;
484 }
485 }
486 if(bCanScreenshot) app.SetAction(pInputData->UserIndex,eAppAction_SocialPost);
487 }
488 rfHandled = TRUE;
489 }
490 break;
491
492 case VK_PAD_RSHOULDER:
493 if( bDisplayBanTip )
494 {
495 UINT uiIDA[2];
496 uiIDA[0]=IDS_CONFIRM_CANCEL;
497 uiIDA[1]=IDS_CONFIRM_OK;
498 StorageManager.RequestMessageBox(IDS_ACTION_BAN_LEVEL_TITLE, IDS_ACTION_BAN_LEVEL_DESCRIPTION, uiIDA, 2, pInputData->UserIndex,&UIScene_PauseMenu::BanGameDialogReturned,this, app.GetStringTable());
499
500 rfHandled = TRUE;
501 }
502 break;
503
504 // handle a keyboard Return specifically, because we've turned off the VK_A_OR_START for the pause menu, since this should exit the menu, rather than cause the button to be activated
505 case VK_RETURN:
506 // call OnNotifyPressEx directly to trigger the button press action
507
508 HXUIOBJ hObjPressed=TreeGetFocus();
509 XUINotifyPress NotifyPressData;
510 BOOL rfHandled=FALSE;
511
512 NotifyPressData.UserIndex=pInputData->UserIndex;
513 OnNotifyPressEx(hObjPressed,&NotifyPressData,rfHandled);
514
515 break;
516 }
517
518 return S_OK;
519}
520
521HRESULT UIScene_PauseMenu::OnNavReturn(HXUIOBJ hObj,BOOL& rfHandled)
522{
523 bool bIsisPrimaryHost=g_NetworkManager.IsHost() && (ProfileManager.GetPrimaryPad()==m_iPad);
524 bool bDisplayBanTip = !g_NetworkManager.IsLocalGame() && !bIsisPrimaryHost && !ProfileManager.IsGuest(m_iPad);
525 bool bUserisClientSide = ProfileManager.IsSignedInLive(m_iPad);
526
527 // Display the tooltips, we are only allowed to display "SHARE" if we have the capability (TCR).
528 if(StorageManager.GetSaveDisabled())
529 {
530 if( ProfileManager.IsFullVersion() && CSocialManager::Instance()->IsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() && bUserisClientSide)
531 {
532 ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,bIsisPrimaryHost?IDS_TOOLTIPS_SELECTDEVICE:-1,IDS_TOOLTIPS_SHARE, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1);
533 }
534 else
535 {
536 ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,-1,-1, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1);
537 }
538 }
539 else
540 {
541 if( CSocialManager::Instance()->IsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() && bUserisClientSide)
542 {
543 ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,bIsisPrimaryHost?IDS_TOOLTIPS_CHANGEDEVICE:-1,IDS_TOOLTIPS_SHARE, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1);
544
545 }
546 else
547 {
548 ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,bIsisPrimaryHost?IDS_TOOLTIPS_CHANGEDEVICE:-1,-1, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1);
549 }
550 }
551
552 // set the focus to the last button we were on
553 XuiElementSetUserFocus(m_Buttons[m_iLastButtonPressed],m_iPad);
554
555 CXuiSceneBase::ShowBackground( m_iPad, FALSE );
556 CXuiSceneBase::ShowDarkOverlay( m_iPad, TRUE );
557
558 bool isWrongSize = false;
559 if(app.GetLocalPlayerCount()==1)
560 {
561 // If we were created as a splitscreen scene, then it's now going to be in the wrong place. Get rid of this scene.
562 if(m_bSplitscreen)
563 {
564 CXuiSceneBase::ShowLogo( m_iPad, FALSE );
565 isWrongSize = true;
566 }
567 else
568 {
569 CXuiSceneBase::ShowLogo( m_iPad, TRUE );
570 }
571 }
572 else
573 {
574 CXuiSceneBase::ShowLogo( m_iPad, FALSE );
575 if(!m_bSplitscreen) isWrongSize = true;
576 }
577
578 if(isWrongSize)
579 {
580 if( m_iPad == ProfileManager.GetPrimaryPad() && g_NetworkManager.IsLocalGame() )
581 {
582 app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE);
583 }
584
585 app.CloseXuiScenes(m_iPad);
586 if(!ProfileManager.IsFullVersion())
587 {
588 CXuiSceneBase::ShowTrialTimer(TRUE);
589 }
590 }
591
592 return S_OK;
593}
594
595HRESULT UIScene_PauseMenu::OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled)
596{
597 pControlNavigateData->hObjDest=XuiControlGetNavigation(pControlNavigateData->hObjSource,pControlNavigateData->nControlNavigate,TRUE,TRUE);
598
599 if(pControlNavigateData->hObjDest!=NULL)
600 {
601 bHandled=TRUE;
602 }
603
604 return S_OK;
605}
606
607int UIScene_PauseMenu::BanGameDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
608{
609 // results switched for this dialog
610 if(result==C4JStorage::EMessage_ResultDecline)
611 {
612 // 4J Stu - Only do this if we are currently idle, don't want the (relatively) low priority ban task overriding something else
613 if(app.GetXuiAction(iPad) == eAppAction_Idle) app.SetAction(iPad,eAppAction_BanLevel);
614 }
615 return 0;
616}
617
618int UIScene_PauseMenu::DeviceSelectReturned(void *pParam,bool bContinue)
619{
620 // Has someone pulled the ethernet cable and caused the pause menu to be closed before this callback returns?
621 if(!app.IsPauseMenuDisplayed(ProfileManager.GetPrimaryPad()))
622 {
623 return 0;
624 }
625
626 UIScene_PauseMenu* pClass = (UIScene_PauseMenu*)pParam;
627 bool bIsisPrimaryHost=g_NetworkManager.IsHost() && (ProfileManager.GetPrimaryPad()==pClass->m_iPad);
628 bool bDisplayBanTip = !g_NetworkManager.IsLocalGame() && !bIsisPrimaryHost && !ProfileManager.IsGuest(pClass->m_iPad);
629 bool bUserisClientSide = ProfileManager.IsSignedInLive(pClass->m_iPad);
630
631 //Whatever happen, we need to update the pause menu and the tooltips
632 // Display the tooltips, we are only allowed to display "SHARE" if we have the capability (TCR).
633 if(StorageManager.GetSaveDisabled())
634 {
635 if( ProfileManager.IsFullVersion() && CSocialManager::Instance()->IsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() && bUserisClientSide)
636 {
637 ui.SetTooltips( pClass->m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,bIsisPrimaryHost?IDS_TOOLTIPS_SELECTDEVICE:-1,IDS_TOOLTIPS_SHARE, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1);
638 }
639 else
640 {
641 ui.SetTooltips( pClass->m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,-1,-1, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1);
642 }
643 // disable save button
644 // set the focus on to another button
645 pClass->m_Buttons[BUTTON_PAUSE_SAVEGAME].SetEnable(FALSE);
646 pClass->m_Buttons[BUTTON_PAUSE_SAVEGAME].EnableInput(FALSE);
647
648 pClass->m_Buttons[BUTTON_PAUSE_RESUMEGAME].InitFocus(pClass->m_iPad);
649 }
650 else
651 {
652 if( CSocialManager::Instance()->IsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() && bUserisClientSide)
653 {
654 ui.SetTooltips(pClass->m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,bIsisPrimaryHost?IDS_TOOLTIPS_CHANGEDEVICE:-1,IDS_TOOLTIPS_SHARE, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1);
655 }
656 else
657 {
658 ui.SetTooltips( pClass->m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,bIsisPrimaryHost?IDS_TOOLTIPS_CHANGEDEVICE:-1,-1, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1);
659 }
660 // enable save button
661 pClass->m_Buttons[BUTTON_PAUSE_SAVEGAME].SetEnable(TRUE);
662 pClass->m_Buttons[BUTTON_PAUSE_SAVEGAME].EnableInput(TRUE);
663
664 }
665
666 pClass->m_bIgnoreInput=false;
667 return 0;
668}
669
670HRESULT UIScene_PauseMenu::OnCustomMessage_Splitscreenplayer(bool bJoining, BOOL& bHandled)
671{
672 bHandled=true;
673 return app.AdjustSplitscreenScene_PlayerChanged(m_hObj,&m_OriginalPosition,m_iPad,bJoining,false);
674}
675
676HRESULT UIScene_PauseMenu::OnTimer(XUIMessageTimer *pData,BOOL& rfHandled)
677{
678 if(pData->nId==IGNORE_KEYPRESS_TIMERID)
679 {
680 XuiKillTimer(m_hObj,IGNORE_KEYPRESS_TIMERID);
681
682 // block input if we're waiting for DLC to install, and wipe the saves list. The end of dlc mounting custom message will fill the list again
683 if(app.StartInstallDLCProcess(m_iPad)==true)
684 {
685 // not doing a mount, so enable input
686 m_bIgnoreInput=true;
687 }
688 else
689 {
690 m_bIgnoreInput=false;
691 }
692 }
693
694 return S_OK;
695}
696
697
698HRESULT UIScene_PauseMenu::OnDestroy()
699{
700 //XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_AUTO);
701 TelemetryManager->RecordUnpauseOrActive(m_iPad);
702
703 if( m_iPad == ProfileManager.GetPrimaryPad() && g_NetworkManager.IsLocalGame() )
704 {
705 app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE);
706 }
707
708 return S_OK;
709}
710
711int UIScene_PauseMenu::DeviceRemovedDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
712{
713
714 // results switched for this dialog
715 if(result==C4JStorage::EMessage_ResultDecline)
716 {
717 // continue without saving
718 StorageManager.SetSaveDisabled(true);
719 StorageManager.SetSaveDeviceSelected(ProfileManager.GetPrimaryPad(),false);
720
721 // Has someone pulled the ethernet cable and caused the pause menu to be closed before this callback returns?
722 if(app.IsPauseMenuDisplayed(ProfileManager.GetPrimaryPad()))
723 {
724 UIScene_PauseMenu* pClass = (UIScene_PauseMenu*)pParam;
725
726 // use the device select returned function to wipe the saves list and change the tooltip
727 pClass->DeviceSelectReturned(pClass,true);
728 }
729 }
730 else
731 {
732 // Change device
733 if(app.IsPauseMenuDisplayed(ProfileManager.GetPrimaryPad()))
734 {
735 UIScene_PauseMenu* pClass = (UIScene_PauseMenu*)pParam;
736 StorageManager.SetSaveDevice(&UIScene_PauseMenu::DeviceSelectReturned,pClass,true);
737 }
738 }
739 return 0;
740}
741
742HRESULT UIScene_PauseMenu::OnCustomMessage_DLCInstalled()
743{
744 // mounted DLC may have changed
745 if(app.StartInstallDLCProcess(m_iPad)==false)
746 {
747 // not doing a mount, so re-enable input
748 m_bIgnoreInput=false;
749 }
750 else
751 {
752 m_bIgnoreInput=true;
753 }
754 // this will send a CustomMessage_DLCMountingComplete when done
755 return S_OK;
756}
757
758HRESULT UIScene_PauseMenu::OnCustomMessage_DLCMountingComplete()
759{
760 m_bIgnoreInput=false;
761 app.m_dlcManager.checkForCorruptDLCAndAlert();
762 XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_AUTO);
763 return S_OK;
764}
765
766void UIScene_PauseMenu::ShowScene(bool show)
767{
768 SetShow(show?TRUE:FALSE);
769}
770
771int UIScene_PauseMenu::WarningTrialTexturePackReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
772{
773 UIScene_PauseMenu* pScene = (UIScene_PauseMenu*)pParam;
774
775 //pScene->m_bIgnoreInput = false;
776 pScene->ShowScene( true );
777 if(result==C4JStorage::EMessage_ResultAccept)
778 {
779 if(ProfileManager.IsSignedIn(iPad))
780 {
781 ULONGLONG ullIndexA[1];
782
783 TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected();
784 // get the dlc texture pack
785 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack;
786
787 // Need to get the parent packs id, since this may be one of many child packs with their own ids
788 app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullIndexA[0]);
789
790 // need to allow downloads here, or the player would need to quit the game to let the download of a texture pack happen. This might affect the network traffic, since the download could take all the bandwidth...
791 XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW);
792
793 StorageManager.InstallOffer(1,ullIndexA,NULL,NULL);
794 }
795 }
796 else
797 {
798 TelemetryManager->RecordUpsellResponded(iPad, eSet_UpsellID_Texture_DLC, ( pScene->m_pDLCPack->getPurchaseOfferId() & 0xFFFFFFFF ), eSen_UpsellOutcome_Declined);
799 }
800
801
802 return 0;
803}
804
805int UIScene_PauseMenu::ExitGameSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
806{
807 UIScene_PauseMenu *pClass = (UIScene_PauseMenu *)pParam;
808 // Exit with or without saving
809 // Decline means save in this dialog
810 if(result==C4JStorage::EMessage_ResultDecline || result==C4JStorage::EMessage_ResultThirdOption)
811 {
812 if( result==C4JStorage::EMessage_ResultDecline ) // Save
813 {
814 // 4J-PB - Is the player trying to save but they are using a trial texturepack ?
815 if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin())
816 {
817 TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected();
818 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack;
819
820 DLCPack *pDLCPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack();
821 if(!pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" ))
822 {
823#ifdef _XBOX
824 // upsell
825 ULONGLONG ullOfferID_Full;
826 // get the dlc texture pack
827 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack;
828
829 app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullOfferID_Full);
830
831 // tell sentient about the upsell of the full version of the skin pack
832 TelemetryManager->RecordUpsellPresented(iPad, eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF);
833#endif
834
835 UINT uiIDA[2];
836 uiIDA[0]=IDS_CONFIRM_OK;
837 uiIDA[1]=IDS_CONFIRM_CANCEL;
838
839 // Give the player a warning about the trial version of the texture pack
840 ui.RequestMessageBox(IDS_WARNING_DLC_TRIALTEXTUREPACK_TITLE, IDS_WARNING_DLC_TRIALTEXTUREPACK_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad() ,&UIScene_PauseMenu::WarningTrialTexturePackReturned,pClass,app.GetStringTable());
841
842 return S_OK;
843 }
844 }
845
846 // does the save exist?
847 bool bSaveExists;
848 StorageManager.DoesSaveExist(&bSaveExists);
849 // 4J-PB - we check if the save exists inside the libs
850 // we need to ask if they are sure they want to overwrite the existing game
851 if(bSaveExists)
852 {
853 UINT uiIDA[2];
854 uiIDA[0]=IDS_CONFIRM_CANCEL;
855 uiIDA[1]=IDS_CONFIRM_OK;
856 ui.RequestMessageBox(IDS_TITLE_SAVE_GAME, IDS_CONFIRM_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&UIScene_PauseMenu::ExitGameAndSaveReturned,pClass, app.GetStringTable());
857 return 0;
858 }
859 else
860 {
861 MinecraftServer::getInstance()->setSaveOnExit( true );
862 }
863 }
864 else
865 {
866 // been a few requests for a confirm on exit without saving
867 UINT uiIDA[2];
868 uiIDA[0]=IDS_CONFIRM_CANCEL;
869 uiIDA[1]=IDS_CONFIRM_OK;
870 ui.RequestMessageBox(IDS_TITLE_DECLINE_SAVE_GAME, IDS_CONFIRM_DECLINE_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&UIScene_PauseMenu::ExitGameDeclineSaveReturned, dynamic_cast<IUIScene_PauseMenu*>(pClass), app.GetStringTable());
871 return 0;
872 }
873
874 app.SetAction(iPad,eAppAction_ExitWorld);
875 }
876 return 0;
877}
878
879int UIScene_PauseMenu::ExitGameDeclineSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
880{
881 // results switched for this dialog
882 if(result==C4JStorage::EMessage_ResultDecline)
883 {
884 MinecraftServer::getInstance()->setSaveOnExit( false );
885 // flag a app action of exit game
886 app.SetAction(iPad,eAppAction_ExitWorld);
887 }
888 else
889 {
890 // has someone disconnected the ethernet here, causing the pause menu to shut?
891 if(ui.IsPauseMenuDisplayed(ProfileManager.GetPrimaryPad()))
892 {
893 IUIScene_PauseMenu* pClass = (IUIScene_PauseMenu*)pParam;
894 UINT uiIDA[3];
895 // you cancelled the save on exit after choosing exit and save? You go back to the Exit choices then.
896 uiIDA[0]=IDS_CONFIRM_CANCEL;
897 uiIDA[1]=IDS_EXIT_GAME_SAVE;
898 uiIDA[2]=IDS_EXIT_GAME_NO_SAVE;
899
900 if(g_NetworkManager.GetPlayerCount()>1)
901 {
902 ui.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME_CONFIRM_DISCONNECT_SAVE, uiIDA, 3, ProfileManager.GetPrimaryPad(),&UIScene_PauseMenu::ExitGameSaveDialogReturned,pClass, app.GetStringTable(), 0, 0, false);
903 }
904 else
905 {
906 ui.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 3, ProfileManager.GetPrimaryPad(),&UIScene_PauseMenu::ExitGameSaveDialogReturned,pClass, app.GetStringTable(), 0, 0, false);
907 }
908 }
909
910 }
911 return 0;
912}
913
914int UIScene_PauseMenu::ExitGameAndSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
915{
916 // 4J-PB - we won't come in here if we have a trial texture pack
917
918 // results switched for this dialog
919 if(result==C4JStorage::EMessage_ResultDecline)
920 {
921 MinecraftServer::getInstance()->setSaveOnExit( true );
922 // flag a app action of exit game
923 app.SetAction(iPad,eAppAction_ExitWorld);
924 }
925 else
926 {
927 // has someone disconnected the ethernet here, causing the pause menu to shut?
928 if(ui.IsPauseMenuDisplayed(ProfileManager.GetPrimaryPad()))
929 {
930 UIScene_PauseMenu* pClass = (UIScene_PauseMenu*)pParam;
931 UINT uiIDA[3];
932 // you cancelled the save on exit after choosing exit and save? You go back to the Exit choices then.
933 uiIDA[0]=IDS_CONFIRM_CANCEL;
934 uiIDA[1]=IDS_EXIT_GAME_SAVE;
935 uiIDA[2]=IDS_EXIT_GAME_NO_SAVE;
936
937 if(g_NetworkManager.GetPlayerCount()>1)
938 {
939 ui.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME_CONFIRM_DISCONNECT_SAVE, uiIDA, 3, ProfileManager.GetPrimaryPad(),&UIScene_PauseMenu::ExitGameSaveDialogReturned,pClass, app.GetStringTable(), 0, 0, false);
940 }
941 else
942 {
943 ui.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 3, ProfileManager.GetPrimaryPad(),&UIScene_PauseMenu::ExitGameSaveDialogReturned,pClass, app.GetStringTable(), 0, 0, false);
944 }
945 }
946
947 }
948 return 0;
949}
950
951int UIScene_PauseMenu::SaveGameDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
952{
953 // results switched for this dialog
954 if(result==C4JStorage::EMessage_ResultDecline)
955 {
956 // flag a app action of save game
957 app.SetAction(iPad,eAppAction_SaveGame);
958 }
959 return 0;
960}
961
962int UIScene_PauseMenu::ExitGameDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
963{
964 // results switched for this dialog
965 if(result==C4JStorage::EMessage_ResultDecline)
966 {
967 app.SetAction(iPad,eAppAction_ExitWorld);
968 }
969 return 0;
970}
971
972int UIScene_PauseMenu::SaveWorldThreadProc( LPVOID lpParameter )
973{
974 bool bAutosave=(bool)lpParameter;
975 if(bAutosave)
976 {
977 app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_AutoSaveGame);
978 }
979 else
980 {
981 app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_SaveGame);
982 }
983
984 // Share AABB & Vec3 pools with default (main thread) - should be ok as long as we don't tick the main thread whilst this thread is running
985 AABB::UseDefaultThreadStorage();
986 Vec3::UseDefaultThreadStorage();
987 Compression::UseDefaultThreadStorage();
988
989 Minecraft *pMinecraft=Minecraft::GetInstance();
990
991 //wprintf(L"Loading world on thread\n");
992
993 if(ProfileManager.IsFullVersion())
994 {
995 app.SetGameStarted(false);
996
997 while( app.GetXuiServerAction(ProfileManager.GetPrimaryPad() ) != eXuiServerAction_Idle && !MinecraftServer::serverHalted() )
998 {
999 Sleep(10);
1000 }
1001
1002 if(!MinecraftServer::serverHalted() && !app.GetChangingSessionType() ) app.SetGameStarted(true);
1003 }
1004
1005 HRESULT hr = S_OK;
1006 if(app.GetChangingSessionType())
1007 {
1008 // 4J Stu - This causes the fullscreenprogress scene to ignore the action it was given
1009 hr = ERROR_CANCELLED;
1010 }
1011 return hr;
1012}
1013
1014int UIScene_PauseMenu::ExitWorldThreadProc( void* lpParameter )
1015{
1016 // Share AABB & Vec3 pools with default (main thread) - should be ok as long as we don't tick the main thread whilst this thread is running
1017 AABB::UseDefaultThreadStorage();
1018 Vec3::UseDefaultThreadStorage();
1019 Compression::UseDefaultThreadStorage();
1020
1021 //app.SetGameStarted(false);
1022
1023 _ExitWorld(lpParameter);
1024
1025 return S_OK;
1026}
1027
1028// This function performs the meat of exiting from a level. It should be called from a thread other than the main thread.
1029void UIScene_PauseMenu::_ExitWorld(LPVOID lpParameter)
1030{
1031 Minecraft *pMinecraft=Minecraft::GetInstance();
1032
1033 int exitReasonStringId = pMinecraft->progressRenderer->getCurrentTitle();
1034 int exitReasonTitleId = IDS_CONNECTION_LOST;
1035
1036 bool saveStats = true;
1037 if (pMinecraft->isClientSide() || g_NetworkManager.IsInSession())
1038 {
1039 if(lpParameter != NULL )
1040 {
1041 // 4J-PB - check if we have lost connection to Live
1042 if(ProfileManager.GetLiveConnectionStatus()!=XONLINE_S_LOGON_CONNECTION_ESTABLISHED )
1043 {
1044 exitReasonStringId = IDS_CONNECTION_LOST_LIVE;
1045 }
1046 else
1047 {
1048 switch( app.GetDisconnectReason() )
1049 {
1050 case DisconnectPacket::eDisconnect_Kicked:
1051 exitReasonStringId = IDS_DISCONNECTED_KICKED;
1052 break;
1053 case DisconnectPacket::eDisconnect_NoUGC_AllLocal:
1054 exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL;
1055 exitReasonTitleId = IDS_CONNECTION_FAILED;
1056 break;
1057 case DisconnectPacket::eDisconnect_NoUGC_Single_Local:
1058 exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL;
1059 exitReasonTitleId = IDS_CONNECTION_FAILED;
1060 break;
1061#ifdef _XBOX
1062 case DisconnectPacket::eDisconnect_NoUGC_Remote:
1063 exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE;
1064 exitReasonTitleId = IDS_CONNECTION_FAILED;
1065 break;
1066#endif
1067 case DisconnectPacket::eDisconnect_NoFlying:
1068 exitReasonStringId = IDS_DISCONNECTED_FLYING;
1069 break;
1070 case DisconnectPacket::eDisconnect_Quitting:
1071 exitReasonStringId = IDS_DISCONNECTED_SERVER_QUIT;
1072 break;
1073 case DisconnectPacket::eDisconnect_NoFriendsInGame:
1074 exitReasonStringId = IDS_DISCONNECTED_NO_FRIENDS_IN_GAME;
1075 exitReasonTitleId = IDS_CANTJOIN_TITLE;
1076 break;
1077 case DisconnectPacket::eDisconnect_Banned:
1078 exitReasonStringId = IDS_DISCONNECTED_BANNED;
1079 exitReasonTitleId = IDS_CANTJOIN_TITLE;
1080 break;
1081 case DisconnectPacket::eDisconnect_NotFriendsWithHost:
1082 exitReasonStringId = IDS_NOTALLOWED_FRIENDSOFFRIENDS;
1083 exitReasonTitleId = IDS_CANTJOIN_TITLE;
1084 break;
1085 case DisconnectPacket::eDisconnect_OutdatedServer:
1086 exitReasonStringId = IDS_DISCONNECTED_SERVER_OLD;
1087 exitReasonTitleId = IDS_CANTJOIN_TITLE;
1088 break;
1089 case DisconnectPacket::eDisconnect_OutdatedClient:
1090 exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD;
1091 exitReasonTitleId = IDS_CANTJOIN_TITLE;
1092 break;
1093 case DisconnectPacket::eDisconnect_ServerFull:
1094 exitReasonStringId = IDS_DISCONNECTED_SERVER_FULL;
1095 exitReasonTitleId = IDS_CANTJOIN_TITLE;
1096 break;
1097 default:
1098 exitReasonStringId = IDS_CONNECTION_LOST_SERVER;
1099 }
1100 }
1101 //pMinecraft->progressRenderer->progressStartNoAbort( exitReasonStringId );
1102
1103 UINT uiIDA[1];
1104 uiIDA[0]=IDS_CONFIRM_OK;
1105 // 4J Stu - Fix for #48669 - TU5: Code: Compliance: TCR #15: Incorrect/misleading messages after signing out a profile during online game session.
1106 // If the primary player is signed out, then that is most likely the cause of the disconnection so don't display a message box. This will allow the message box requested by the libraries to be brought up
1107 if( ProfileManager.IsSignedIn(ProfileManager.GetPrimaryPad())) ui.RequestMessageBox( exitReasonTitleId, exitReasonStringId, uiIDA,1,ProfileManager.GetPrimaryPad(),NULL,NULL, app.GetStringTable());
1108 exitReasonStringId = -1;
1109
1110 // 4J - Force a disconnection, this handles the situation that the server has already disconnected
1111 if( pMinecraft->levels[0] != NULL ) pMinecraft->levels[0]->disconnect(false);
1112 if( pMinecraft->levels[1] != NULL ) pMinecraft->levels[1]->disconnect(false);
1113 if( pMinecraft->levels[2] != NULL ) pMinecraft->levels[2]->disconnect(false);
1114 }
1115 else
1116 {
1117 exitReasonStringId = IDS_EXITING_GAME;
1118 pMinecraft->progressRenderer->progressStartNoAbort( IDS_EXITING_GAME );
1119 if( pMinecraft->levels[0] != NULL ) pMinecraft->levels[0]->disconnect();
1120 if( pMinecraft->levels[1] != NULL ) pMinecraft->levels[1]->disconnect();
1121 if( pMinecraft->levels[2] != NULL ) pMinecraft->levels[2]->disconnect();
1122 }
1123
1124 // 4J Stu - This only does something if we actually have a server, so don't need to do any other checks
1125 MinecraftServer::HaltServer();
1126
1127 // We need to call the stats & leaderboards save before we exit the session
1128 // 4J We need to do this in a QNet callback where it is safe
1129 //pMinecraft->forceStatsSave();
1130 saveStats = false;
1131
1132 // 4J Stu - Leave the session once the disconnect packet has been sent
1133 g_NetworkManager.LeaveGame(FALSE);
1134 }
1135 else
1136 {
1137 if(lpParameter != NULL && ProfileManager.IsSignedIn(ProfileManager.GetPrimaryPad()) )
1138 {
1139 switch( app.GetDisconnectReason() )
1140 {
1141 case DisconnectPacket::eDisconnect_Kicked:
1142 exitReasonStringId = IDS_DISCONNECTED_KICKED;
1143 break;
1144 case DisconnectPacket::eDisconnect_NoUGC_AllLocal:
1145 exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL;
1146 exitReasonTitleId = IDS_CONNECTION_FAILED;
1147 break;
1148 case DisconnectPacket::eDisconnect_NoUGC_Single_Local:
1149 exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL;
1150 exitReasonTitleId = IDS_CONNECTION_FAILED;
1151 break;
1152#ifdef _XBOX
1153 case DisconnectPacket::eDisconnect_NoUGC_Remote:
1154 exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE;
1155 exitReasonTitleId = IDS_CONNECTION_FAILED;
1156 break;
1157#endif
1158 case DisconnectPacket::eDisconnect_Quitting:
1159 exitReasonStringId = IDS_DISCONNECTED_SERVER_QUIT;
1160 break;
1161 case DisconnectPacket::eDisconnect_NoMultiplayerPrivilegesJoin:
1162 exitReasonStringId = IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT;
1163 break;
1164 case DisconnectPacket::eDisconnect_OutdatedServer:
1165 exitReasonStringId = IDS_DISCONNECTED_SERVER_OLD;
1166 exitReasonTitleId = IDS_CANTJOIN_TITLE;
1167 break;
1168 case DisconnectPacket::eDisconnect_OutdatedClient:
1169 exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD;
1170 exitReasonTitleId = IDS_CANTJOIN_TITLE;
1171 break;
1172 case DisconnectPacket::eDisconnect_ServerFull:
1173 exitReasonStringId = IDS_DISCONNECTED_SERVER_FULL;
1174 exitReasonTitleId = IDS_CANTJOIN_TITLE;
1175 break;
1176 default:
1177 exitReasonStringId = IDS_DISCONNECTED;
1178 }
1179 //pMinecraft->progressRenderer->progressStartNoAbort( exitReasonStringId );
1180
1181 UINT uiIDA[1];
1182 uiIDA[0]=IDS_CONFIRM_OK;
1183 ui.RequestMessageBox( exitReasonTitleId, exitReasonStringId, uiIDA,1,ProfileManager.GetPrimaryPad(),NULL,NULL, app.GetStringTable());
1184 exitReasonStringId = -1;
1185 }
1186 }
1187 // Fix for #93148 - TCR 001: BAS Game Stability: Title will crash for the multiplayer client if host of the game will exit during the clients loading to created world.
1188 while( g_NetworkManager.IsNetworkThreadRunning() )
1189 {
1190 Sleep(1);
1191 }
1192 pMinecraft->setLevel(NULL,exitReasonStringId,nullptr,saveStats);
1193
1194 TelemetryManager->Flush();
1195
1196 app.m_gameRules.unloadCurrentGameRules();
1197 //app.m_Audio.unloadCurrentAudioDetails();
1198
1199 MinecraftServer::resetFlags();
1200
1201 // Fix for #48385 - BLACK OPS :TU5: Functional: Client becomes pseudo soft-locked when returned to the main menu after a remote disconnect
1202 // Make sure there is text explaining why the player is waiting
1203 pMinecraft->progressRenderer->progressStart(IDS_EXITING_GAME);
1204
1205 // Fix for #13259 - CRASH: Gameplay: loading process is halted when player loads saved data
1206 // We can't start/join a new game until the session is destroyed, so wait for it to be idle again
1207 while( g_NetworkManager.IsInSession() )
1208 {
1209 Sleep(1);
1210 }
1211
1212 app.SetChangingSessionType(false);
1213 app.SetReallyChangingSessionType(false);
1214}
1215
1216void UIScene_PauseMenu::SetIgnoreInput(bool ignoreInput)
1217{
1218 m_bIgnoreInput = ignoreInput;
1219}