diff options
Diffstat (limited to 'Minecraft.Client/Common/XUI/XUI_PauseMenu.cpp')
| -rw-r--r-- | Minecraft.Client/Common/XUI/XUI_PauseMenu.cpp | 1219 |
1 files changed, 1219 insertions, 0 deletions
diff --git a/Minecraft.Client/Common/XUI/XUI_PauseMenu.cpp b/Minecraft.Client/Common/XUI/XUI_PauseMenu.cpp new file mode 100644 index 00000000..4de74d1f --- /dev/null +++ b/Minecraft.Client/Common/XUI/XUI_PauseMenu.cpp @@ -0,0 +1,1219 @@ +// Minecraft.cpp : Defines the entry point for the application. +// + +#include "stdafx.h" + +#include <assert.h> +#include "..\..\..\Minecraft.World\AABB.h" +#include "..\..\..\Minecraft.World\Vec3.h" +#include "..\..\..\Minecraft.World\net.minecraft.stats.h" +#include "..\..\..\Minecraft.Client\StatsCounter.h" +#include "..\..\..\Minecraft.World\Entity.h" +#include "..\..\..\Minecraft.World\Level.h" +#include "..\..\..\Minecraft.Client\MultiplayerLocalPlayer.h" +#include "..\..\MinecraftServer.h" +#include "..\..\MultiPlayerLevel.h" +#include "..\..\ProgressRenderer.h" +#include "..\..\..\Minecraft.World\DisconnectPacket.h" +#include "..\..\Minecraft.h" +#include "..\..\Options.h" +#include "..\..\..\Minecraft.World\compression.h" +#include "..\..\TexturePackRepository.h" +#include "..\..\TexturePack.h" +#include "..\..\DLCTexturePack.h" + +#define IGNORE_KEYPRESS_TIMERID 0 +#define IGNORE_KEYPRESS_TIME 100 + +//---------------------------------------------------------------------------------- +// Performs initialization tasks - retrieves controls. +//---------------------------------------------------------------------------------- +HRESULT UIScene_PauseMenu::OnInit( XUIMessageInit* pInitData, BOOL& bHandled ) +{ + m_bIgnoreInput=true; + m_iPad = *(int *)pInitData->pvInitData; + bool bUserisClientSide = ProfileManager.IsSignedInLive(m_iPad); + + app.DebugPrintf("PAUSE PRESS PROCESSING - ipad = %d, UIScene_PauseMenu::OnInit\n",m_iPad); + + bool bIsisPrimaryHost=g_NetworkManager.IsHost() && (ProfileManager.GetPrimaryPad()==m_iPad); + bool bDisplayBanTip = !g_NetworkManager.IsLocalGame() && !bIsisPrimaryHost && !ProfileManager.IsGuest(m_iPad); + + MapChildControls(); + + XuiControlSetText(m_Buttons[BUTTON_PAUSE_RESUMEGAME],app.GetString(IDS_RESUME_GAME)); + XuiControlSetText(m_Buttons[BUTTON_PAUSE_HELPANDOPTIONS],app.GetString(IDS_HELP_AND_OPTIONS)); + XuiControlSetText(m_Buttons[BUTTON_PAUSE_LEADERBOARDS],app.GetString(IDS_LEADERBOARDS)); + XuiControlSetText(m_Buttons[BUTTON_PAUSE_ACHIEVEMENTS],app.GetString(IDS_ACHIEVEMENTS)); + XuiControlSetText(m_Buttons[BUTTON_PAUSE_SAVEGAME],app.GetString(IDS_SAVE_GAME)); + XuiControlSetText(m_Buttons[BUTTON_PAUSE_EXITGAME],app.GetString(IDS_EXIT_GAME)); + + if(app.GetLocalPlayerCount()>1) + { + m_bSplitscreen = true; + app.AdjustSplitscreenScene(m_hObj,&m_OriginalPosition,m_iPad,false); + CXuiSceneBase::ShowLogo( m_iPad, FALSE ); + } + else + { + m_bSplitscreen = false; + CXuiSceneBase::ShowLogo( m_iPad, TRUE ); + } + + // test award the theme + //ProfileManager.Award( ProfileManager.GetPrimaryPad(), eAward_socialPost ); + // Display the tooltips, we are only allowed to display "SHARE" if we have the capability (TCR). + + if(!ProfileManager.IsFullVersion()) + { + ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK); + // hide the trial timer + CXuiSceneBase::ShowTrialTimer(FALSE); + } + else if(StorageManager.GetSaveDisabled()) + { + if( CSocialManager::Instance()->IsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() && bUserisClientSide ) + { + 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); + } + else + { + ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,bIsisPrimaryHost?IDS_TOOLTIPS_SELECTDEVICE:-1,-1,-1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1); + } + } + else + { + if( CSocialManager::Instance()->IsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() && bUserisClientSide) + { + 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); + } + else + { + ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,bIsisPrimaryHost?IDS_TOOLTIPS_CHANGEDEVICE:-1,-1, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1); + } + } + + CXuiSceneBase::ShowDarkOverlay( m_iPad, TRUE ); + + // are we the primary player? + // 4J-PB - fix for 7844 & 7845 - + // TCR # 128: XLA Pause Menu: When in a multiplayer game as a client the Pause Menu does not have a Leaderboards option. + // TCR # 128: XLA Pause Menu: When in a multiplayer game as a client the Pause Menu does not have an Achievements option. + if(ProfileManager.GetPrimaryPad()==m_iPad) // && g_NetworkManager.IsHost()) + { + // are we in splitscreen? + // how many local players do we have? + + D3DXVECTOR3 vPos; + if( app.GetLocalPlayerCount()>1 ) + { + m_Buttons[BUTTON_PAUSE_LEADERBOARDS].GetPosition(&vPos); + m_Buttons[BUTTON_PAUSE_SAVEGAME].SetPosition(&vPos); + m_Buttons[BUTTON_PAUSE_ACHIEVEMENTS].GetPosition(&vPos); + m_Buttons[BUTTON_PAUSE_EXITGAME].SetPosition(&vPos); + // Hide the BUTTON_PAUSE_LEADERBOARDS and BUTTON_PAUSE_ACHIEVEMENTS + XuiElementSetShow(m_Buttons[BUTTON_PAUSE_LEADERBOARDS],FALSE); + XuiElementSetShow(m_Buttons[BUTTON_PAUSE_ACHIEVEMENTS],FALSE); + } + + if( !g_NetworkManager.IsHost() ) + { + m_Buttons[BUTTON_PAUSE_SAVEGAME].GetPosition(&vPos); + m_Buttons[BUTTON_PAUSE_EXITGAME].SetPosition(&vPos); + // Hide the BUTTON_PAUSE_SAVEGAME + XuiElementSetShow(m_Buttons[BUTTON_PAUSE_SAVEGAME],FALSE); + } + } + else + { + D3DXVECTOR3 vPos; + m_Buttons[BUTTON_PAUSE_LEADERBOARDS].GetPosition(&vPos); + m_Buttons[BUTTON_PAUSE_EXITGAME].SetPosition(&vPos); + // Hide the BUTTON_PAUSE_LEADERBOARDS, BUTTON_PAUSE_ACHIEVEMENTS and BUTTON_PAUSE_SAVEGAME + XuiElementSetShow(m_Buttons[BUTTON_PAUSE_LEADERBOARDS],FALSE); + XuiElementSetShow(m_Buttons[BUTTON_PAUSE_ACHIEVEMENTS],FALSE); + XuiElementSetShow(m_Buttons[BUTTON_PAUSE_SAVEGAME],FALSE); + } + + // is saving disabled? + if(StorageManager.GetSaveDisabled()) + { + // disable save button + m_Buttons[BUTTON_PAUSE_SAVEGAME].SetEnable(FALSE); + m_Buttons[BUTTON_PAUSE_SAVEGAME].EnableInput(FALSE); + } + + m_iLastButtonPressed=0; + + // get rid of the quadrant display if it's on + CXuiSceneBase::HidePressStart(); + + XuiSetTimer(m_hObj,IGNORE_KEYPRESS_TIMERID,IGNORE_KEYPRESS_TIME); + + if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) + { + app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)TRUE); + } + + TelemetryManager->RecordMenuShown(m_iPad, eUIScene_PauseMenu, 0); + TelemetryManager->RecordPauseOrInactive(m_iPad); + + return S_OK; +} + +//---------------------------------------------------------------------------------- +// Handler for the button press message. +//---------------------------------------------------------------------------------- +HRESULT UIScene_PauseMenu::OnNotifyPressEx(HXUIOBJ hObjPressed, XUINotifyPress* pNotifyPressData, BOOL& rfHandled) +{ + if(m_bIgnoreInput) return S_OK; + + // This assumes all buttons can only be pressed with the A button + ui.AnimateKeyPress(pNotifyPressData->UserIndex, VK_PAD_A); + + unsigned int uiButtonCounter=0; + + while((uiButtonCounter<BUTTONS_PAUSE_MAX) && (m_Buttons[uiButtonCounter]!=hObjPressed)) uiButtonCounter++; + + Minecraft *pMinecraft=Minecraft::GetInstance(); + + // ignore buttons not from this user + //if(pNotifyPressData->UserIndex!=pMinecraft->player->GetXboxPad()) return S_OK; + + // Determine which button was pressed, + // and call the appropriate function. + + // store the last button pressed, so on a nav back we can set the focus properly + m_iLastButtonPressed=uiButtonCounter; + switch(uiButtonCounter) + { + case BUTTON_PAUSE_RESUMEGAME: + if( m_iPad == ProfileManager.GetPrimaryPad() && g_NetworkManager.IsLocalGame() ) + { + app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE); + } + app.CloseXuiScenes(pNotifyPressData->UserIndex); + break; + + case BUTTON_PAUSE_LEADERBOARDS: + { + UINT uiIDA[1]; + uiIDA[0]=IDS_OK; + + //4J Gordon: Being used for the leaderboards proper now + // guests can't look at leaderboards + if(ProfileManager.IsGuest(pNotifyPressData->UserIndex)) + { + StorageManager.RequestMessageBox(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); + } + else if(!ProfileManager.IsSignedInLive(pNotifyPressData->UserIndex)) + { + StorageManager.RequestMessageBox(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_XBOXLIVE_NOTIFICATION, uiIDA, 1); + } + else + { + app.NavigateToScene(pNotifyPressData->UserIndex, eUIScene_LeaderboardsMenu); + } + } + break; + case BUTTON_PAUSE_ACHIEVEMENTS: + // guests can't look at achievements + if(ProfileManager.IsGuest(pNotifyPressData->UserIndex)) + { + UINT uiIDA[1]; + uiIDA[0]=IDS_OK; + StorageManager.RequestMessageBox(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1); + } + else + { + XShowAchievementsUI( pNotifyPressData->UserIndex ); + } + + break; + case BUTTON_PAUSE_HELPANDOPTIONS: + if(app.GetLocalPlayerCount()>1) + { + app.NavigateToScene(pNotifyPressData->UserIndex,eUIScene_HelpAndOptionsMenu); + } + else + { + app.NavigateToScene(pNotifyPressData->UserIndex,eUIScene_HelpAndOptionsMenu); + } + break; + + case BUTTON_PAUSE_SAVEGAME: + { + // 4J-PB - Is the player trying to save but they are using a trial texturepack ? + if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin()) + { + TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); + DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; + + m_pDLCPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack(); + + if(!m_pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) + { + // upsell + ULONGLONG ullOfferID_Full; + // get the dlc texture pack + DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; + + app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullOfferID_Full); + + // tell sentient about the upsell of the full version of the texture pack + TelemetryManager->RecordUpsellPresented(pNotifyPressData->UserIndex, eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF); + + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_OK; + uiIDA[1]=IDS_CONFIRM_CANCEL; + + // Give the player a warning about the trial version of the texture pack + StorageManager.RequestMessageBox(IDS_WARNING_DLC_TRIALTEXTUREPACK_TITLE, IDS_WARNING_DLC_TRIALTEXTUREPACK_TEXT, uiIDA, 2, pNotifyPressData->UserIndex,&UIScene_PauseMenu::WarningTrialTexturePackReturned,this,app.GetStringTable()); + + return S_OK; + } + } + + // does the save exist? + bool bSaveExists; + C4JStorage::ELoadGameStatus result=StorageManager.DoesSaveExist(&bSaveExists); + + if(result == C4JStorage::ELoadGame_DeviceRemoved) + { + // this will be a tester trying to be clever + UINT uiIDA[2]; + uiIDA[0]=IDS_SELECTANEWDEVICE; + uiIDA[1]=IDS_NODEVICE_DECLINE; + + StorageManager.RequestMessageBox(IDS_STORAGEDEVICEPROBLEM_TITLE, IDS_FAILED_TO_LOADSAVE_TEXT, uiIDA, 2, pNotifyPressData->UserIndex,&UIScene_PauseMenu::DeviceRemovedDialogReturned,this); + } + else + { + // we need to ask if they are sure they want to overwrite the existing game + if(bSaveExists) + { + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + StorageManager.RequestMessageBox(IDS_TITLE_SAVE_GAME, IDS_CONFIRM_SAVE_GAME, uiIDA, 2, pNotifyPressData->UserIndex,&UIScene_PauseMenu::SaveGameDialogReturned,this, app.GetStringTable()); + } + else + { + // flag a app action of save game + app.SetAction(pNotifyPressData->UserIndex,eAppAction_SaveGame); + } + } + } + + break; + case BUTTON_PAUSE_EXITGAME: + { + // Check if it's the trial version + if(ProfileManager.IsFullVersion()) + { + UINT uiIDA[3]; + + // is it the primary player exiting? + if(pNotifyPressData->UserIndex==ProfileManager.GetPrimaryPad()) + { + int playTime = -1; + if( pMinecraft->localplayers[pNotifyPressData->UserIndex] != NULL ) + { + playTime = (int)pMinecraft->localplayers[pNotifyPressData->UserIndex]->getSessionTimer(); + } + + if(StorageManager.GetSaveDisabled()) + { + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + StorageManager.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME_PROGRESS_LOST, uiIDA, 2, pNotifyPressData->UserIndex,&UIScene_PauseMenu::ExitGameDialogReturned,this, app.GetStringTable()); + } + else + { + if( g_NetworkManager.IsHost() ) + { + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_EXIT_GAME_SAVE; + uiIDA[2]=IDS_EXIT_GAME_NO_SAVE; + + if(g_NetworkManager.GetPlayerCount()>1) + { + StorageManager.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME_CONFIRM_DISCONNECT_SAVE, uiIDA, 3, pNotifyPressData->UserIndex,&UIScene_PauseMenu::ExitGameSaveDialogReturned,this, app.GetStringTable()); + } + else + { + StorageManager.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 3, pNotifyPressData->UserIndex,&UIScene_PauseMenu::ExitGameSaveDialogReturned,this, app.GetStringTable()); + } + } + else + { + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + + StorageManager.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 2, pNotifyPressData->UserIndex,&UIScene_PauseMenu::ExitGameDialogReturned,this, app.GetStringTable()); + } + } + } + else + { + int playTime = -1; + if( pMinecraft->localplayers[pNotifyPressData->UserIndex] != NULL ) + { + playTime = (int)pMinecraft->localplayers[pNotifyPressData->UserIndex]->getSessionTimer(); + } + + TelemetryManager->RecordLevelExit(pNotifyPressData->UserIndex, eSen_LevelExitStatus_Exited); + + + // just exit the player + app.SetAction(pNotifyPressData->UserIndex,eAppAction_ExitPlayer); + } + } + else + { + // is it the primary player exiting? + if(pNotifyPressData->UserIndex==ProfileManager.GetPrimaryPad()) + { + int playTime = -1; + if( pMinecraft->localplayers[pNotifyPressData->UserIndex] != NULL ) + { + playTime = (int)pMinecraft->localplayers[pNotifyPressData->UserIndex]->getSessionTimer(); + } + + // adjust the trial time played + CXuiSceneBase::ReduceTrialTimerValue(); + + // exit the level + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + StorageManager.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME_PROGRESS_LOST, uiIDA, 2, pNotifyPressData->UserIndex,&UIScene_PauseMenu::ExitGameDialogReturned,this, app.GetStringTable()); + } + else + { + int playTime = -1; + if( pMinecraft->localplayers[pNotifyPressData->UserIndex] != NULL ) + { + playTime = (int)pMinecraft->localplayers[pNotifyPressData->UserIndex]->getSessionTimer(); + } + + TelemetryManager->RecordLevelExit(pNotifyPressData->UserIndex, eSen_LevelExitStatus_Exited); + + // just exit the player + app.SetAction(pNotifyPressData->UserIndex,eAppAction_ExitPlayer); + } + } + } + break; + default: + break; + } + + return S_OK; +} + +HRESULT UIScene_PauseMenu::OnKeyDown(XUIMessageInput* pInputData, BOOL& rfHandled) +{ + if(m_bIgnoreInput) return S_OK; + // ignore repeated start presses to avoid the scene closing before it's opened + if((pInputData->dwKeyCode==VK_PAD_START) &&(pInputData->dwFlags&XUI_INPUT_FLAG_REPEAT )) + { + rfHandled = TRUE; + return S_OK; + } + + bool bIsisPrimaryHost=g_NetworkManager.IsHost() && (ProfileManager.GetPrimaryPad()==m_iPad); + bool bDisplayBanTip = !g_NetworkManager.IsLocalGame() && !bIsisPrimaryHost && !ProfileManager.IsGuest(m_iPad); + bool bUserisClientSide = ProfileManager.IsSignedInLive(m_iPad); + + ui.AnimateKeyPress(pInputData->UserIndex, pInputData->dwKeyCode); + + app.DebugPrintf("PAUSE- Keydown in the xui %d flags = %d\n",pInputData->dwKeyCode,pInputData->dwFlags); + + + switch(pInputData->dwKeyCode) + { + + case VK_PAD_B: + case VK_PAD_START: + case VK_ESCAPE: + app.DebugPrintf("PAUSE PRESS PROCESSING - ipad = %d, UIScene_PauseMenu::OnKeyDown - LEAVING PAUSE MENU\n",m_iPad); + + if( m_iPad == ProfileManager.GetPrimaryPad() && g_NetworkManager.IsLocalGame() ) + { + app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE); + } + + CXuiSceneBase::PlayUISFX(eSFX_Back); + app.CloseXuiScenes(pInputData->UserIndex); + if(!ProfileManager.IsFullVersion()) + { + CXuiSceneBase::ShowTrialTimer(TRUE); + } + rfHandled = TRUE; + + break; + + case VK_PAD_X: + // Change device + if(bIsisPrimaryHost) + { + // we need a function to deal with the return from this - if it changes, we need to update the pause menu and tooltips + // Fix for #12531 - TCR 001: BAS Game Stability: When a player selects to change a storage + // device, and repeatedly backs out of the SD screen, disconnects from LIVE, and then selects a SD, the title crashes. + m_bIgnoreInput=true; + + StorageManager.SetSaveDevice(&UIScene_PauseMenu::DeviceSelectReturned,this,true); + } + rfHandled = TRUE; + break; + + + case VK_PAD_Y: + { + if(bUserisClientSide) + { + // 4J Stu - Added check in 1.8.2 bug fix (TU6) to stop repeat key presses + bool bCanScreenshot = true; + for(int j=0; j < XUSER_MAX_COUNT;++j) + { + if(app.GetXuiAction(j) == eAppAction_SocialPostScreenshot) + { + bCanScreenshot = false; + break; + } + } + if(bCanScreenshot) app.SetAction(pInputData->UserIndex,eAppAction_SocialPost); + } + rfHandled = TRUE; + } + break; + + case VK_PAD_RSHOULDER: + if( bDisplayBanTip ) + { + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + StorageManager.RequestMessageBox(IDS_ACTION_BAN_LEVEL_TITLE, IDS_ACTION_BAN_LEVEL_DESCRIPTION, uiIDA, 2, pInputData->UserIndex,&UIScene_PauseMenu::BanGameDialogReturned,this, app.GetStringTable()); + + rfHandled = TRUE; + } + break; + + // 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 + case VK_RETURN: + // call OnNotifyPressEx directly to trigger the button press action + + HXUIOBJ hObjPressed=TreeGetFocus(); + XUINotifyPress NotifyPressData; + BOOL rfHandled=FALSE; + + NotifyPressData.UserIndex=pInputData->UserIndex; + OnNotifyPressEx(hObjPressed,&NotifyPressData,rfHandled); + + break; + } + + return S_OK; +} + +HRESULT UIScene_PauseMenu::OnNavReturn(HXUIOBJ hObj,BOOL& rfHandled) +{ + bool bIsisPrimaryHost=g_NetworkManager.IsHost() && (ProfileManager.GetPrimaryPad()==m_iPad); + bool bDisplayBanTip = !g_NetworkManager.IsLocalGame() && !bIsisPrimaryHost && !ProfileManager.IsGuest(m_iPad); + bool bUserisClientSide = ProfileManager.IsSignedInLive(m_iPad); + + // Display the tooltips, we are only allowed to display "SHARE" if we have the capability (TCR). + if(StorageManager.GetSaveDisabled()) + { + if( ProfileManager.IsFullVersion() && CSocialManager::Instance()->IsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() && bUserisClientSide) + { + 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); + } + else + { + ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,-1,-1, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1); + } + } + else + { + if( CSocialManager::Instance()->IsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() && bUserisClientSide) + { + 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); + + } + else + { + ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,bIsisPrimaryHost?IDS_TOOLTIPS_CHANGEDEVICE:-1,-1, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1); + } + } + + // set the focus to the last button we were on + XuiElementSetUserFocus(m_Buttons[m_iLastButtonPressed],m_iPad); + + CXuiSceneBase::ShowBackground( m_iPad, FALSE ); + CXuiSceneBase::ShowDarkOverlay( m_iPad, TRUE ); + + bool isWrongSize = false; + if(app.GetLocalPlayerCount()==1) + { + // If we were created as a splitscreen scene, then it's now going to be in the wrong place. Get rid of this scene. + if(m_bSplitscreen) + { + CXuiSceneBase::ShowLogo( m_iPad, FALSE ); + isWrongSize = true; + } + else + { + CXuiSceneBase::ShowLogo( m_iPad, TRUE ); + } + } + else + { + CXuiSceneBase::ShowLogo( m_iPad, FALSE ); + if(!m_bSplitscreen) isWrongSize = true; + } + + if(isWrongSize) + { + if( m_iPad == ProfileManager.GetPrimaryPad() && g_NetworkManager.IsLocalGame() ) + { + app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE); + } + + app.CloseXuiScenes(m_iPad); + if(!ProfileManager.IsFullVersion()) + { + CXuiSceneBase::ShowTrialTimer(TRUE); + } + } + + return S_OK; +} + +HRESULT UIScene_PauseMenu::OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled) +{ + pControlNavigateData->hObjDest=XuiControlGetNavigation(pControlNavigateData->hObjSource,pControlNavigateData->nControlNavigate,TRUE,TRUE); + + if(pControlNavigateData->hObjDest!=NULL) + { + bHandled=TRUE; + } + + return S_OK; +} + +int UIScene_PauseMenu::BanGameDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + // results switched for this dialog + if(result==C4JStorage::EMessage_ResultDecline) + { + // 4J Stu - Only do this if we are currently idle, don't want the (relatively) low priority ban task overriding something else + if(app.GetXuiAction(iPad) == eAppAction_Idle) app.SetAction(iPad,eAppAction_BanLevel); + } + return 0; +} + +int UIScene_PauseMenu::DeviceSelectReturned(void *pParam,bool bContinue) +{ + // Has someone pulled the ethernet cable and caused the pause menu to be closed before this callback returns? + if(!app.IsPauseMenuDisplayed(ProfileManager.GetPrimaryPad())) + { + return 0; + } + + UIScene_PauseMenu* pClass = (UIScene_PauseMenu*)pParam; + bool bIsisPrimaryHost=g_NetworkManager.IsHost() && (ProfileManager.GetPrimaryPad()==pClass->m_iPad); + bool bDisplayBanTip = !g_NetworkManager.IsLocalGame() && !bIsisPrimaryHost && !ProfileManager.IsGuest(pClass->m_iPad); + bool bUserisClientSide = ProfileManager.IsSignedInLive(pClass->m_iPad); + + //Whatever happen, we need to update the pause menu and the tooltips + // Display the tooltips, we are only allowed to display "SHARE" if we have the capability (TCR). + if(StorageManager.GetSaveDisabled()) + { + if( ProfileManager.IsFullVersion() && CSocialManager::Instance()->IsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() && bUserisClientSide) + { + 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); + } + else + { + ui.SetTooltips( pClass->m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,-1,-1, -1,-1,-1,bDisplayBanTip?IDS_TOOLTIPS_BANLEVEL:-1); + } + // disable save button + // set the focus on to another button + pClass->m_Buttons[BUTTON_PAUSE_SAVEGAME].SetEnable(FALSE); + pClass->m_Buttons[BUTTON_PAUSE_SAVEGAME].EnableInput(FALSE); + + pClass->m_Buttons[BUTTON_PAUSE_RESUMEGAME].InitFocus(pClass->m_iPad); + } + else + { + if( CSocialManager::Instance()->IsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() && bUserisClientSide) + { + 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); + } + else + { + 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); + } + // enable save button + pClass->m_Buttons[BUTTON_PAUSE_SAVEGAME].SetEnable(TRUE); + pClass->m_Buttons[BUTTON_PAUSE_SAVEGAME].EnableInput(TRUE); + + } + + pClass->m_bIgnoreInput=false; + return 0; +} + +HRESULT UIScene_PauseMenu::OnCustomMessage_Splitscreenplayer(bool bJoining, BOOL& bHandled) +{ + bHandled=true; + return app.AdjustSplitscreenScene_PlayerChanged(m_hObj,&m_OriginalPosition,m_iPad,bJoining,false); +} + +HRESULT UIScene_PauseMenu::OnTimer(XUIMessageTimer *pData,BOOL& rfHandled) +{ + if(pData->nId==IGNORE_KEYPRESS_TIMERID) + { + XuiKillTimer(m_hObj,IGNORE_KEYPRESS_TIMERID); + + // 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 + if(app.StartInstallDLCProcess(m_iPad)==true) + { + // not doing a mount, so enable input + m_bIgnoreInput=true; + } + else + { + m_bIgnoreInput=false; + } + } + + return S_OK; +} + + +HRESULT UIScene_PauseMenu::OnDestroy() +{ + //XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_AUTO); + TelemetryManager->RecordUnpauseOrActive(m_iPad); + + if( m_iPad == ProfileManager.GetPrimaryPad() && g_NetworkManager.IsLocalGame() ) + { + app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE); + } + + return S_OK; +} + +int UIScene_PauseMenu::DeviceRemovedDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + + // results switched for this dialog + if(result==C4JStorage::EMessage_ResultDecline) + { + // continue without saving + StorageManager.SetSaveDisabled(true); + StorageManager.SetSaveDeviceSelected(ProfileManager.GetPrimaryPad(),false); + + // Has someone pulled the ethernet cable and caused the pause menu to be closed before this callback returns? + if(app.IsPauseMenuDisplayed(ProfileManager.GetPrimaryPad())) + { + UIScene_PauseMenu* pClass = (UIScene_PauseMenu*)pParam; + + // use the device select returned function to wipe the saves list and change the tooltip + pClass->DeviceSelectReturned(pClass,true); + } + } + else + { + // Change device + if(app.IsPauseMenuDisplayed(ProfileManager.GetPrimaryPad())) + { + UIScene_PauseMenu* pClass = (UIScene_PauseMenu*)pParam; + StorageManager.SetSaveDevice(&UIScene_PauseMenu::DeviceSelectReturned,pClass,true); + } + } + return 0; +} + +HRESULT UIScene_PauseMenu::OnCustomMessage_DLCInstalled() +{ + // mounted DLC may have changed + if(app.StartInstallDLCProcess(m_iPad)==false) + { + // not doing a mount, so re-enable input + m_bIgnoreInput=false; + } + else + { + m_bIgnoreInput=true; + } + // this will send a CustomMessage_DLCMountingComplete when done + return S_OK; +} + +HRESULT UIScene_PauseMenu::OnCustomMessage_DLCMountingComplete() +{ + m_bIgnoreInput=false; + app.m_dlcManager.checkForCorruptDLCAndAlert(); + XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_AUTO); + return S_OK; +} + +void UIScene_PauseMenu::ShowScene(bool show) +{ + SetShow(show?TRUE:FALSE); +} + +int UIScene_PauseMenu::WarningTrialTexturePackReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + UIScene_PauseMenu* pScene = (UIScene_PauseMenu*)pParam; + + //pScene->m_bIgnoreInput = false; + pScene->ShowScene( true ); + if(result==C4JStorage::EMessage_ResultAccept) + { + if(ProfileManager.IsSignedIn(iPad)) + { + ULONGLONG ullIndexA[1]; + + TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); + // get the dlc texture pack + DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; + + // Need to get the parent packs id, since this may be one of many child packs with their own ids + app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullIndexA[0]); + + // 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... + XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); + + StorageManager.InstallOffer(1,ullIndexA,NULL,NULL); + } + } + else + { + TelemetryManager->RecordUpsellResponded(iPad, eSet_UpsellID_Texture_DLC, ( pScene->m_pDLCPack->getPurchaseOfferId() & 0xFFFFFFFF ), eSen_UpsellOutcome_Declined); + } + + + return 0; +} + +int UIScene_PauseMenu::ExitGameSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + UIScene_PauseMenu *pClass = (UIScene_PauseMenu *)pParam; + // Exit with or without saving + // Decline means save in this dialog + if(result==C4JStorage::EMessage_ResultDecline || result==C4JStorage::EMessage_ResultThirdOption) + { + if( result==C4JStorage::EMessage_ResultDecline ) // Save + { + // 4J-PB - Is the player trying to save but they are using a trial texturepack ? + if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin()) + { + TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); + DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; + + DLCPack *pDLCPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack(); + if(!pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) + { +#ifdef _XBOX + // upsell + ULONGLONG ullOfferID_Full; + // get the dlc texture pack + DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; + + app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullOfferID_Full); + + // tell sentient about the upsell of the full version of the skin pack + TelemetryManager->RecordUpsellPresented(iPad, eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF); +#endif + + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_OK; + uiIDA[1]=IDS_CONFIRM_CANCEL; + + // Give the player a warning about the trial version of the texture pack + ui.RequestMessageBox(IDS_WARNING_DLC_TRIALTEXTUREPACK_TITLE, IDS_WARNING_DLC_TRIALTEXTUREPACK_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad() ,&UIScene_PauseMenu::WarningTrialTexturePackReturned,pClass,app.GetStringTable()); + + return S_OK; + } + } + + // does the save exist? + bool bSaveExists; + StorageManager.DoesSaveExist(&bSaveExists); + // 4J-PB - we check if the save exists inside the libs + // we need to ask if they are sure they want to overwrite the existing game + if(bSaveExists) + { + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + ui.RequestMessageBox(IDS_TITLE_SAVE_GAME, IDS_CONFIRM_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&UIScene_PauseMenu::ExitGameAndSaveReturned,pClass, app.GetStringTable()); + return 0; + } + else + { + MinecraftServer::getInstance()->setSaveOnExit( true ); + } + } + else + { + // been a few requests for a confirm on exit without saving + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + 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()); + return 0; + } + + app.SetAction(iPad,eAppAction_ExitWorld); + } + return 0; +} + +int UIScene_PauseMenu::ExitGameDeclineSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + // results switched for this dialog + if(result==C4JStorage::EMessage_ResultDecline) + { + MinecraftServer::getInstance()->setSaveOnExit( false ); + // flag a app action of exit game + app.SetAction(iPad,eAppAction_ExitWorld); + } + else + { + // has someone disconnected the ethernet here, causing the pause menu to shut? + if(ui.IsPauseMenuDisplayed(ProfileManager.GetPrimaryPad())) + { + IUIScene_PauseMenu* pClass = (IUIScene_PauseMenu*)pParam; + UINT uiIDA[3]; + // you cancelled the save on exit after choosing exit and save? You go back to the Exit choices then. + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_EXIT_GAME_SAVE; + uiIDA[2]=IDS_EXIT_GAME_NO_SAVE; + + if(g_NetworkManager.GetPlayerCount()>1) + { + 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); + } + else + { + ui.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 3, ProfileManager.GetPrimaryPad(),&UIScene_PauseMenu::ExitGameSaveDialogReturned,pClass, app.GetStringTable(), 0, 0, false); + } + } + + } + return 0; +} + +int UIScene_PauseMenu::ExitGameAndSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + // 4J-PB - we won't come in here if we have a trial texture pack + + // results switched for this dialog + if(result==C4JStorage::EMessage_ResultDecline) + { + MinecraftServer::getInstance()->setSaveOnExit( true ); + // flag a app action of exit game + app.SetAction(iPad,eAppAction_ExitWorld); + } + else + { + // has someone disconnected the ethernet here, causing the pause menu to shut? + if(ui.IsPauseMenuDisplayed(ProfileManager.GetPrimaryPad())) + { + UIScene_PauseMenu* pClass = (UIScene_PauseMenu*)pParam; + UINT uiIDA[3]; + // you cancelled the save on exit after choosing exit and save? You go back to the Exit choices then. + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_EXIT_GAME_SAVE; + uiIDA[2]=IDS_EXIT_GAME_NO_SAVE; + + if(g_NetworkManager.GetPlayerCount()>1) + { + 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); + } + else + { + ui.RequestMessageBox(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 3, ProfileManager.GetPrimaryPad(),&UIScene_PauseMenu::ExitGameSaveDialogReturned,pClass, app.GetStringTable(), 0, 0, false); + } + } + + } + return 0; +} + +int UIScene_PauseMenu::SaveGameDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + // results switched for this dialog + if(result==C4JStorage::EMessage_ResultDecline) + { + // flag a app action of save game + app.SetAction(iPad,eAppAction_SaveGame); + } + return 0; +} + +int UIScene_PauseMenu::ExitGameDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + // results switched for this dialog + if(result==C4JStorage::EMessage_ResultDecline) + { + app.SetAction(iPad,eAppAction_ExitWorld); + } + return 0; +} + +int UIScene_PauseMenu::SaveWorldThreadProc( LPVOID lpParameter ) +{ + bool bAutosave=(bool)lpParameter; + if(bAutosave) + { + app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_AutoSaveGame); + } + else + { + app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_SaveGame); + } + + // 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 + AABB::UseDefaultThreadStorage(); + Vec3::UseDefaultThreadStorage(); + Compression::UseDefaultThreadStorage(); + + Minecraft *pMinecraft=Minecraft::GetInstance(); + + //wprintf(L"Loading world on thread\n"); + + if(ProfileManager.IsFullVersion()) + { + app.SetGameStarted(false); + + while( app.GetXuiServerAction(ProfileManager.GetPrimaryPad() ) != eXuiServerAction_Idle && !MinecraftServer::serverHalted() ) + { + Sleep(10); + } + + if(!MinecraftServer::serverHalted() && !app.GetChangingSessionType() ) app.SetGameStarted(true); + } + + HRESULT hr = S_OK; + if(app.GetChangingSessionType()) + { + // 4J Stu - This causes the fullscreenprogress scene to ignore the action it was given + hr = ERROR_CANCELLED; + } + return hr; +} + +int UIScene_PauseMenu::ExitWorldThreadProc( void* lpParameter ) +{ + // 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 + AABB::UseDefaultThreadStorage(); + Vec3::UseDefaultThreadStorage(); + Compression::UseDefaultThreadStorage(); + + //app.SetGameStarted(false); + + _ExitWorld(lpParameter); + + return S_OK; +} + +// This function performs the meat of exiting from a level. It should be called from a thread other than the main thread. +void UIScene_PauseMenu::_ExitWorld(LPVOID lpParameter) +{ + Minecraft *pMinecraft=Minecraft::GetInstance(); + + int exitReasonStringId = pMinecraft->progressRenderer->getCurrentTitle(); + int exitReasonTitleId = IDS_CONNECTION_LOST; + + bool saveStats = true; + if (pMinecraft->isClientSide() || g_NetworkManager.IsInSession()) + { + if(lpParameter != NULL ) + { + // 4J-PB - check if we have lost connection to Live + if(ProfileManager.GetLiveConnectionStatus()!=XONLINE_S_LOGON_CONNECTION_ESTABLISHED ) + { + exitReasonStringId = IDS_CONNECTION_LOST_LIVE; + } + else + { + switch( app.GetDisconnectReason() ) + { + case DisconnectPacket::eDisconnect_Kicked: + exitReasonStringId = IDS_DISCONNECTED_KICKED; + break; + case DisconnectPacket::eDisconnect_NoUGC_AllLocal: + exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL; + exitReasonTitleId = IDS_CONNECTION_FAILED; + break; + case DisconnectPacket::eDisconnect_NoUGC_Single_Local: + exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL; + exitReasonTitleId = IDS_CONNECTION_FAILED; + break; +#ifdef _XBOX + case DisconnectPacket::eDisconnect_NoUGC_Remote: + exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE; + exitReasonTitleId = IDS_CONNECTION_FAILED; + break; +#endif + case DisconnectPacket::eDisconnect_NoFlying: + exitReasonStringId = IDS_DISCONNECTED_FLYING; + break; + case DisconnectPacket::eDisconnect_Quitting: + exitReasonStringId = IDS_DISCONNECTED_SERVER_QUIT; + break; + case DisconnectPacket::eDisconnect_NoFriendsInGame: + exitReasonStringId = IDS_DISCONNECTED_NO_FRIENDS_IN_GAME; + exitReasonTitleId = IDS_CANTJOIN_TITLE; + break; + case DisconnectPacket::eDisconnect_Banned: + exitReasonStringId = IDS_DISCONNECTED_BANNED; + exitReasonTitleId = IDS_CANTJOIN_TITLE; + break; + case DisconnectPacket::eDisconnect_NotFriendsWithHost: + exitReasonStringId = IDS_NOTALLOWED_FRIENDSOFFRIENDS; + exitReasonTitleId = IDS_CANTJOIN_TITLE; + break; + case DisconnectPacket::eDisconnect_OutdatedServer: + exitReasonStringId = IDS_DISCONNECTED_SERVER_OLD; + exitReasonTitleId = IDS_CANTJOIN_TITLE; + break; + case DisconnectPacket::eDisconnect_OutdatedClient: + exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD; + exitReasonTitleId = IDS_CANTJOIN_TITLE; + break; + case DisconnectPacket::eDisconnect_ServerFull: + exitReasonStringId = IDS_DISCONNECTED_SERVER_FULL; + exitReasonTitleId = IDS_CANTJOIN_TITLE; + break; + default: + exitReasonStringId = IDS_CONNECTION_LOST_SERVER; + } + } + //pMinecraft->progressRenderer->progressStartNoAbort( exitReasonStringId ); + + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + // 4J Stu - Fix for #48669 - TU5: Code: Compliance: TCR #15: Incorrect/misleading messages after signing out a profile during online game session. + // 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 + if( ProfileManager.IsSignedIn(ProfileManager.GetPrimaryPad())) ui.RequestMessageBox( exitReasonTitleId, exitReasonStringId, uiIDA,1,ProfileManager.GetPrimaryPad(),NULL,NULL, app.GetStringTable()); + exitReasonStringId = -1; + + // 4J - Force a disconnection, this handles the situation that the server has already disconnected + if( pMinecraft->levels[0] != NULL ) pMinecraft->levels[0]->disconnect(false); + if( pMinecraft->levels[1] != NULL ) pMinecraft->levels[1]->disconnect(false); + if( pMinecraft->levels[2] != NULL ) pMinecraft->levels[2]->disconnect(false); + } + else + { + exitReasonStringId = IDS_EXITING_GAME; + pMinecraft->progressRenderer->progressStartNoAbort( IDS_EXITING_GAME ); + if( pMinecraft->levels[0] != NULL ) pMinecraft->levels[0]->disconnect(); + if( pMinecraft->levels[1] != NULL ) pMinecraft->levels[1]->disconnect(); + if( pMinecraft->levels[2] != NULL ) pMinecraft->levels[2]->disconnect(); + } + + // 4J Stu - This only does something if we actually have a server, so don't need to do any other checks + MinecraftServer::HaltServer(); + + // We need to call the stats & leaderboards save before we exit the session + // 4J We need to do this in a QNet callback where it is safe + //pMinecraft->forceStatsSave(); + saveStats = false; + + // 4J Stu - Leave the session once the disconnect packet has been sent + g_NetworkManager.LeaveGame(FALSE); + } + else + { + if(lpParameter != NULL && ProfileManager.IsSignedIn(ProfileManager.GetPrimaryPad()) ) + { + switch( app.GetDisconnectReason() ) + { + case DisconnectPacket::eDisconnect_Kicked: + exitReasonStringId = IDS_DISCONNECTED_KICKED; + break; + case DisconnectPacket::eDisconnect_NoUGC_AllLocal: + exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL; + exitReasonTitleId = IDS_CONNECTION_FAILED; + break; + case DisconnectPacket::eDisconnect_NoUGC_Single_Local: + exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL; + exitReasonTitleId = IDS_CONNECTION_FAILED; + break; +#ifdef _XBOX + case DisconnectPacket::eDisconnect_NoUGC_Remote: + exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE; + exitReasonTitleId = IDS_CONNECTION_FAILED; + break; +#endif + case DisconnectPacket::eDisconnect_Quitting: + exitReasonStringId = IDS_DISCONNECTED_SERVER_QUIT; + break; + case DisconnectPacket::eDisconnect_NoMultiplayerPrivilegesJoin: + exitReasonStringId = IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT; + break; + case DisconnectPacket::eDisconnect_OutdatedServer: + exitReasonStringId = IDS_DISCONNECTED_SERVER_OLD; + exitReasonTitleId = IDS_CANTJOIN_TITLE; + break; + case DisconnectPacket::eDisconnect_OutdatedClient: + exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD; + exitReasonTitleId = IDS_CANTJOIN_TITLE; + break; + case DisconnectPacket::eDisconnect_ServerFull: + exitReasonStringId = IDS_DISCONNECTED_SERVER_FULL; + exitReasonTitleId = IDS_CANTJOIN_TITLE; + break; + default: + exitReasonStringId = IDS_DISCONNECTED; + } + //pMinecraft->progressRenderer->progressStartNoAbort( exitReasonStringId ); + + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + ui.RequestMessageBox( exitReasonTitleId, exitReasonStringId, uiIDA,1,ProfileManager.GetPrimaryPad(),NULL,NULL, app.GetStringTable()); + exitReasonStringId = -1; + } + } + // 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. + while( g_NetworkManager.IsNetworkThreadRunning() ) + { + Sleep(1); + } + pMinecraft->setLevel(NULL,exitReasonStringId,nullptr,saveStats); + + TelemetryManager->Flush(); + + app.m_gameRules.unloadCurrentGameRules(); + //app.m_Audio.unloadCurrentAudioDetails(); + + MinecraftServer::resetFlags(); + + // Fix for #48385 - BLACK OPS :TU5: Functional: Client becomes pseudo soft-locked when returned to the main menu after a remote disconnect + // Make sure there is text explaining why the player is waiting + pMinecraft->progressRenderer->progressStart(IDS_EXITING_GAME); + + // Fix for #13259 - CRASH: Gameplay: loading process is halted when player loads saved data + // We can't start/join a new game until the session is destroyed, so wait for it to be idle again + while( g_NetworkManager.IsInSession() ) + { + Sleep(1); + } + + app.SetChangingSessionType(false); + app.SetReallyChangingSessionType(false); +} + +void UIScene_PauseMenu::SetIgnoreInput(bool ignoreInput) +{ + m_bIgnoreInput = ignoreInput; +}
\ No newline at end of file |
