4jcraft/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp
2026-03-26 13:37:01 -05:00

1328 lines
56 KiB
C++

// Minecraft.cpp : Defines the entry point for the application.
//
#include "../../Minecraft.World/Platform/stdafx.h"
#include <assert.h>
#include "../../Minecraft.World/Util/AABB.h"
#include "../../Minecraft.World/Util/Vec3.h"
#include "../../Minecraft.World/Headers/net.minecraft.stats.h"
#include "../../Minecraft.Client/GameState/StatsCounter.h"
#include "../../Minecraft.World/Entities/Entity.h"
#include "../../Minecraft.World/Level/Level.h"
#include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h"
#include "../../Minecraft.Client/MinecraftServer.h"
#include "../../Minecraft.Client/Level/MultiPlayerLevel.h"
#include "../../Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.h"
#include "../../Minecraft.World/Network/Packets/DisconnectPacket.h"
#include "../../Minecraft.Client/Minecraft.h"
#include "../../Minecraft.Client/GameState/Options.h"
#include "../../Minecraft.World/IO/Streams/Compression.h"
#include "../../Minecraft.Client/Textures/Packs/TexturePackRepository.h"
#include "../../Minecraft.Client/Textures/Packs/TexturePack.h"
#include "../../Minecraft.Client/Textures/Packs/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: {
unsigned int 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)) {
unsigned int 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);
unsigned int 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
unsigned int 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) {
unsigned int 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()) {
unsigned int 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
unsigned int 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) {
unsigned int 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
unsigned int 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) {
unsigned int 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
unsigned int 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;
unsigned int 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;
unsigned int 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();
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();
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 );
unsigned int 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 );
unsigned int 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;
}