#include "../../Minecraft.World/Platform/stdafx.h" #include "XUI_MultiGameCreate.h" #include "XUI_InGamePlayerOptions.h" #include "../../Minecraft.Client/Minecraft.h" #include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h" #include "../../Minecraft.Client/Network/ClientConnection.h" #include "../../Minecraft.World/Headers/net.minecraft.network.h" #include "../../Minecraft.World/Headers/net.minecraft.network.packet.h" #include "../../Minecraft.World/Headers/net.minecraft.world.entity.player.h" #include "XUI_InGameInfo.h" //---------------------------------------------------------------------------------- // Performs initialization tasks - retrieves controls. //---------------------------------------------------------------------------------- HRESULT CScene_InGamePlayerOptions::OnInit(XUIMessageInit* pInitData, BOOL& bHandled) { m_iPad = *(int*)pInitData->pvInitData; InGamePlayerOptionsInitData* initData = (InGamePlayerOptionsInitData*)pInitData->pvInitData; m_iPad = initData->iPad; m_networkSmallId = initData->networkSmallId; m_playerPrivileges = initData->playerPrivileges; MapChildControls(); m_focusElement = m_checkboxes[eControl_BuildAndMine].m_hObj; m_TeleportGroup.SetShow(false); INetworkPlayer* localPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(m_iPad); INetworkPlayer* editingPlayer = g_NetworkManager.GetPlayerBySmallId(m_networkSmallId); if (editingPlayer != NULL) { m_Gamertag.SetText(editingPlayer->GetOnlineName()); } bool trustPlayers = app.GetGameHostOption(eGameHostOption_TrustPlayers) != 0; bool cheats = app.GetGameHostOption(eGameHostOption_CheatsEnabled) != 0; m_editingSelf = (localPlayer != NULL && localPlayer == editingPlayer); if (m_editingSelf || trustPlayers || editingPlayer->IsHost()) { removeControl(m_checkboxes[eControl_BuildAndMine], true); removeControl(m_checkboxes[eControl_UseDoorsAndSwitches], true); removeControl(m_checkboxes[eControl_UseContainers], true); removeControl(m_checkboxes[eControl_AttackPlayers], true); removeControl(m_checkboxes[eControl_AttackAnimals], true); } else { bool checked = (Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CannotMine) == 0 && Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CannotBuild) == 0); m_checkboxes[eControl_BuildAndMine].SetText( app.GetString(IDS_CAN_BUILD_AND_MINE)); m_checkboxes[eControl_BuildAndMine].SetCheck(checked); checked = (Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanUseDoorsAndSwitches) != 0); m_checkboxes[eControl_UseDoorsAndSwitches].SetText( app.GetString(IDS_CAN_USE_DOORS_AND_SWITCHES)); m_checkboxes[eControl_UseDoorsAndSwitches].SetCheck(checked); checked = (Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanUseContainers) != 0); m_checkboxes[eControl_UseContainers].SetText( app.GetString(IDS_CAN_OPEN_CONTAINERS)); m_checkboxes[eControl_UseContainers].SetCheck(checked); checked = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CannotAttackPlayers) == 0; m_checkboxes[eControl_AttackPlayers].SetText( app.GetString(IDS_CAN_ATTACK_PLAYERS)); m_checkboxes[eControl_AttackPlayers].SetCheck(checked); checked = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CannotAttackAnimals) == 0; m_checkboxes[eControl_AttackAnimals].SetText( app.GetString(IDS_CAN_ATTACK_ANIMALS)); m_checkboxes[eControl_AttackAnimals].SetCheck(checked); } if (m_editingSelf) { #if (defined(_CONTENT_PACKAGE) || \ defined(_FINAL_BUILD) && !defined(_DEBUG_MENUS_ENABLED)) removeControl(m_checkboxes[eControl_Op], true); #else m_checkboxes[eControl_Op].SetText(L"DEBUG: Creative"); m_checkboxes[eControl_Op].SetCheck(Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CreativeMode)); #endif removeControl(m_buttonKick, true); removeControl(m_checkboxes[eControl_CheatTeleport], true); if (cheats) { bool canBeInvisible = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleInvisible) != 0; m_checkboxes[eControl_HostInvisible].SetEnable(canBeInvisible); bool checked = canBeInvisible && (Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_Invisible) != 0 && Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_Invulnerable) != 0); m_checkboxes[eControl_HostInvisible].SetText( app.GetString(IDS_INVISIBLE)); m_checkboxes[eControl_HostInvisible].SetCheck(checked); bool inCreativeMode = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CreativeMode) != 0; if (inCreativeMode) { removeControl(m_checkboxes[eControl_HostFly], true); removeControl(m_checkboxes[eControl_HostHunger], true); } else { bool canFly = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleFly); bool canChangeHunger = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleClassicHunger); m_checkboxes[eControl_HostFly].SetEnable(canFly); checked = canFly && Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanFly) != 0; m_checkboxes[eControl_HostFly].SetText( app.GetString(IDS_CAN_FLY)); m_checkboxes[eControl_HostFly].SetCheck(checked); m_checkboxes[eControl_HostHunger].SetEnable(canChangeHunger); checked = canChangeHunger && Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_ClassicHunger) != 0; m_checkboxes[eControl_HostHunger].SetText( app.GetString(IDS_DISABLE_EXHAUSTION)); m_checkboxes[eControl_HostHunger].SetCheck(checked); } } else { removeControl(m_checkboxes[eControl_HostInvisible], true); removeControl(m_checkboxes[eControl_HostFly], true); removeControl(m_checkboxes[eControl_HostHunger], true); } } else { if (localPlayer->IsHost()) { // Only host can make people moderators, or enable teleporting for // them m_checkboxes[eControl_Op].SetText(app.GetString(IDS_MODERATOR)); m_checkboxes[eControl_Op].SetCheck( Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_Op) != 0); } else { removeControl(m_checkboxes[eControl_Op], true); } if (localPlayer->IsHost() && cheats) { m_checkboxes[eControl_HostInvisible].SetEnable(true); bool checked = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleInvisible) != 0; m_checkboxes[eControl_HostInvisible].SetText( app.GetString(IDS_CAN_INVISIBLE)); m_checkboxes[eControl_HostInvisible].SetCheck(checked); bool inCreativeMode = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CreativeMode) != 0; if (inCreativeMode) { removeControl(m_checkboxes[eControl_HostFly], true); removeControl(m_checkboxes[eControl_HostHunger], true); } else { m_checkboxes[eControl_HostFly].SetEnable(true); checked = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleFly) != 0; m_checkboxes[eControl_HostFly].SetText( app.GetString(IDS_CAN_FLY)); m_checkboxes[eControl_HostFly].SetCheck(checked); m_checkboxes[eControl_HostHunger].SetEnable(true); checked = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleClassicHunger) != 0; m_checkboxes[eControl_HostHunger].SetText( app.GetString(IDS_CAN_DISABLE_EXHAUSTION)); m_checkboxes[eControl_HostHunger].SetCheck(checked); } checked = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanTeleport) != 0; m_checkboxes[eControl_CheatTeleport].SetText( app.GetString(IDS_ENABLE_TELEPORT)); m_checkboxes[eControl_CheatTeleport].SetCheck(checked); } else { removeControl(m_checkboxes[eControl_HostInvisible], true); removeControl(m_checkboxes[eControl_HostFly], true); removeControl(m_checkboxes[eControl_HostHunger], true); removeControl(m_checkboxes[eControl_CheatTeleport], true); } // Can only kick people if they are not local, and not local to the host if (editingPlayer->IsLocal() != TRUE && editingPlayer->IsSameSystem(g_NetworkManager.GetHostPlayer()) != TRUE) { m_buttonKick.SetText(app.GetString(IDS_KICK_PLAYER)); } else { removeControl(m_buttonKick, true); } } if (app.GetLocalPlayerCount() > 1) { app.AdjustSplitscreenScene(m_hObj, &m_OriginalPosition, m_iPad); } ui.SetTooltips(m_iPad, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK); CXuiSceneBase::ShowLogo(m_iPad, FALSE); g_NetworkManager.RegisterPlayerChangedCallback( m_iPad, &CScene_InGamePlayerOptions::OnPlayerChanged, this); // SentientManager.RecordMenuShown(m_iPad, eUIScene_CreateWorldMenu, 0); resetCheatCheckboxes(); return S_OK; } HRESULT CScene_InGamePlayerOptions::OnDestroy() { g_NetworkManager.UnRegisterPlayerChangedCallback( m_iPad, &CScene_InGameInfo::OnPlayerChanged, this); return S_OK; } HRESULT CScene_InGamePlayerOptions::OnKeyDown(XUIMessageInput* pInputData, BOOL& rfHandled) { ui.AnimateKeyPress(pInputData->UserIndex, pInputData->dwKeyCode); // Explicitly handle B button presses switch (pInputData->dwKeyCode) { case VK_PAD_B: case VK_ESCAPE: { bool trustPlayers = app.GetGameHostOption(eGameHostOption_TrustPlayers) != 0; bool cheats = app.GetGameHostOption(eGameHostOption_CheatsEnabled) != 0; if (m_editingSelf) { #if (defined(_CONTENT_PACKAGE) || \ defined(_FINAL_BUILD) && !defined(_DEBUG_MENUS_ENABLED)) #else Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CreativeMode, m_checkboxes[eControl_Op].IsChecked()); #endif if (cheats) { bool canBeInvisible = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleInvisible) != 0; if (canBeInvisible) Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_Invisible, m_checkboxes[eControl_HostInvisible].IsChecked()); if (canBeInvisible) Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_Invulnerable, m_checkboxes[eControl_HostInvisible].IsChecked()); bool inCreativeMode = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CreativeMode) != 0; if (!inCreativeMode) { bool canFly = Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleFly); bool canChangeHunger = Player::getPlayerGamePrivilege( m_playerPrivileges, Player:: ePlayerGamePrivilege_CanToggleClassicHunger); if (canFly) Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanFly, m_checkboxes[eControl_HostFly].IsChecked()); if (canChangeHunger) Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_ClassicHunger, m_checkboxes[eControl_HostHunger].IsChecked()); } } } else { INetworkPlayer* editingPlayer = g_NetworkManager.GetPlayerBySmallId(m_networkSmallId); if (!trustPlayers && (editingPlayer != NULL && !editingPlayer->IsHost())) { Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CannotMine, !m_checkboxes[eControl_BuildAndMine].IsChecked()); Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CannotBuild, !m_checkboxes[eControl_BuildAndMine].IsChecked()); Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CannotAttackPlayers, !m_checkboxes[eControl_AttackPlayers].IsChecked()); Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CannotAttackAnimals, !m_checkboxes[eControl_AttackAnimals].IsChecked()); Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanUseDoorsAndSwitches, m_checkboxes[eControl_UseDoorsAndSwitches].IsChecked()); Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanUseContainers, m_checkboxes[eControl_UseContainers].IsChecked()); } INetworkPlayer* localPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(m_iPad); if (localPlayer->IsHost()) { if (cheats) { Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleInvisible, m_checkboxes[eControl_HostInvisible].IsChecked()); Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleFly, m_checkboxes[eControl_HostFly].IsChecked()); Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleClassicHunger, m_checkboxes[eControl_HostHunger].IsChecked()); Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanTeleport, m_checkboxes[eControl_CheatTeleport].IsChecked()); } Player::setPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_Op, m_checkboxes[eControl_Op].IsChecked()); } } unsigned int originalPrivileges = app.GetPlayerPrivileges(m_networkSmallId); if (originalPrivileges != m_playerPrivileges) { // Send update settings packet to server Minecraft* pMinecraft = Minecraft::GetInstance(); std::shared_ptr player = pMinecraft->localplayers[m_iPad]; if (player != NULL && player->connection) { player->connection->send( std::shared_ptr(new PlayerInfoPacket( m_networkSmallId, -1, m_playerPrivileges))); } } app.NavigateBack(pInputData->UserIndex); rfHandled = TRUE; } break; } return S_OK; } HRESULT CScene_InGamePlayerOptions::OnNotifyPressEx( HXUIOBJ hObjPressed, XUINotifyPress* pNotifyPressData, BOOL& rfHandled) { // HRESULT hr = S_OK; // This assumes all buttons can only be pressed with the A button ui.AnimateKeyPress(pNotifyPressData->UserIndex, VK_PAD_A); if (hObjPressed == m_buttonKick) { std::uint8_t* smallId = new std::uint8_t(); *smallId = m_networkSmallId; unsigned int uiIDA[2]; uiIDA[0] = IDS_CONFIRM_OK; uiIDA[1] = IDS_CONFIRM_CANCEL; StorageManager.RequestMessageBox( IDS_UNLOCK_KICK_PLAYER_TITLE, IDS_UNLOCK_KICK_PLAYER, uiIDA, 2, m_iPad, &CScene_InGamePlayerOptions::KickPlayerReturned, smallId, app.GetStringTable()); } else if (hObjPressed == m_checkboxes[eControl_Op]) { resetCheatCheckboxes(); } return S_OK; } HRESULT CScene_InGamePlayerOptions::OnControlNavigate( XUIMessageControlNavigate* pControlNavigateData, BOOL& bHandled) { pControlNavigateData->hObjDest = XuiControlGetNavigation( pControlNavigateData->hObjSource, pControlNavigateData->nControlNavigate, TRUE, TRUE); if (pControlNavigateData->hObjDest != NULL) { bHandled = TRUE; } return S_OK; } int CScene_InGamePlayerOptions::KickPlayerReturned( void* pParam, int iPad, C4JStorage::EMessageResult result) { std::uint8_t smallId = *static_cast(pParam); delete pParam; if (result == C4JStorage::EMessage_ResultAccept) { Minecraft* pMinecraft = Minecraft::GetInstance(); std::shared_ptr localPlayer = pMinecraft->localplayers[iPad]; if (localPlayer != NULL && localPlayer->connection) { localPlayer->connection->send(std::shared_ptr( new KickPlayerPacket(smallId))); } // Fix for #61494 - [CRASH]: TU7: Code: Multiplayer: Title may crash // while kicking a player from an online game. We cannot do a navigate // back here is this actually occurs on a thread other than the main // thread. On rare occasions this can clash with the XUI render and // causes a crash. The OnPlayerChanged event should perform the navigate // back on the main thread // app.NavigateBack(iPad); } return 0; } void CScene_InGamePlayerOptions::OnPlayerChanged(void* callbackParam, INetworkPlayer* pPlayer, bool leaving) { CScene_InGamePlayerOptions* scene = (CScene_InGamePlayerOptions*)callbackParam; HXUIOBJ hBackScene = scene->GetBackScene(); CScene_InGameInfo* infoScene; void* pObj; XuiObjectFromHandle(hBackScene, &pObj); infoScene = (CScene_InGameInfo*)pObj; if (infoScene != NULL) CScene_InGameInfo::OnPlayerChanged(infoScene, pPlayer, leaving); if (leaving && pPlayer != NULL && pPlayer->GetSmallId() == scene->m_networkSmallId) { app.NavigateBack(scene->m_iPad); } } HRESULT CScene_InGamePlayerOptions::OnTransitionStart( XUIMessageTransition* pTransition, BOOL& bHandled) { if (pTransition->dwTransType == XUI_TRANSITION_TO || pTransition->dwTransType == XUI_TRANSITION_BACKTO) { INetworkPlayer* editingPlayer = g_NetworkManager.GetPlayerBySmallId(m_networkSmallId); if (editingPlayer != NULL) { short colourIndex = app.GetPlayerColour(m_networkSmallId); switch (colourIndex) { case 1: m_Icon.PlayVisualRange(L"P1", NULL, L"P1"); break; case 2: m_Icon.PlayVisualRange(L"P2", NULL, L"P2"); break; case 3: m_Icon.PlayVisualRange(L"P3", NULL, L"P3"); break; case 4: m_Icon.PlayVisualRange(L"P4", NULL, L"P4"); break; case 5: m_Icon.PlayVisualRange(L"P5", NULL, L"P5"); break; case 6: m_Icon.PlayVisualRange(L"P6", NULL, L"P6"); break; case 7: m_Icon.PlayVisualRange(L"P7", NULL, L"P7"); break; case 8: m_Icon.PlayVisualRange(L"P8", NULL, L"P8"); break; case 9: m_Icon.PlayVisualRange(L"P9", NULL, L"P9"); break; case 10: m_Icon.PlayVisualRange(L"P10", NULL, L"P10"); break; case 11: m_Icon.PlayVisualRange(L"P11", NULL, L"P11"); break; case 12: m_Icon.PlayVisualRange(L"P12", NULL, L"P12"); break; case 13: m_Icon.PlayVisualRange(L"P13", NULL, L"P13"); break; case 14: m_Icon.PlayVisualRange(L"P14", NULL, L"P14"); break; case 15: m_Icon.PlayVisualRange(L"P15", NULL, L"P15"); break; case 0: default: m_Icon.PlayVisualRange(L"P0", NULL, L"P0"); break; }; } } return S_OK; } void CScene_InGamePlayerOptions::removeControl(HXUIOBJ hObjToRemove, bool center) { D3DXVECTOR3 pos; float fControlHeight, fTempHeight, fWidth; bool changeFocus = m_focusElement == hObjToRemove; XuiElementGetBounds(hObjToRemove, &fWidth, &fControlHeight); // Hide this control XuiControlSetEnable(hObjToRemove, FALSE); XuiElementSetShow(hObjToRemove, FALSE); // Move future downwards nav up HXUIOBJ controlToMove = hObjToRemove; while (controlToMove = XuiControlGetNavigation( controlToMove, XUI_CONTROL_NAVIGATE_DOWN, FALSE, TRUE)) { if (changeFocus && XuiElementIsShown(controlToMove)) { m_focusElement = controlToMove; XuiElementSetUserFocus(controlToMove, m_iPad); changeFocus = FALSE; } XuiElementGetPosition(controlToMove, &pos); pos.y -= fControlHeight; XuiElementSetPosition(controlToMove, &pos); } // Resize and move scene GetBounds(&fWidth, &fTempHeight); SetBounds(fWidth, fTempHeight - fControlHeight); GetPosition(&pos); pos.y += fControlHeight / 2; SetPosition(&pos); } void CScene_InGamePlayerOptions::resetCheatCheckboxes() { bool isModerator = m_checkboxes[eControl_Op].IsChecked(); // bool cheatsEnabled = // app.GetGameHostOption(eGameHostOption_CheatsEnabled) != 0; if (!m_editingSelf) { m_checkboxes[eControl_HostInvisible].SetEnable(isModerator); m_checkboxes[eControl_HostInvisible].SetCheck( isModerator && (Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleInvisible) != 0)); // NOT CREATIVE MODE. { m_checkboxes[eControl_HostFly].SetEnable(isModerator); m_checkboxes[eControl_HostFly].SetCheck( isModerator && (Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleFly) != 0)); m_checkboxes[eControl_HostHunger].SetEnable(isModerator); m_checkboxes[eControl_HostHunger].SetCheck( isModerator && (Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanToggleClassicHunger) != 0)); } m_checkboxes[eControl_CheatTeleport].SetEnable(isModerator); m_checkboxes[eControl_CheatTeleport].SetCheck( isModerator && (Player::getPlayerGamePrivilege( m_playerPrivileges, Player::ePlayerGamePrivilege_CanTeleport) != 0)); } }