#include "stdafx.h" #include "..\..\Minecraft.World\net.minecraft.world.entity.item.h" #include "..\..\Minecraft.World\net.minecraft.world.entity.player.h" #include "..\..\Minecraft.World\net.minecraft.world.level.tile.entity.h" #include "..\..\Minecraft.World\net.minecraft.world.phys.h" #include "..\..\Minecraft.World\InputOutputStream.h" #include "..\..\Minecraft.World\compression.h" #include "..\Options.h" #include "..\MinecraftServer.h" #include "..\MultiPlayerLevel.h" #include "..\GameRenderer.h" #include "..\ProgressRenderer.h" #include "..\LevelRenderer.h" #include "..\MobSkinMemTextureProcessor.h" #include "..\Minecraft.h" #include "..\ClientConnection.h" #include "..\MultiPlayerLocalPlayer.h" #include "..\LocalPlayer.h" #include "..\..\Minecraft.World\Player.h" #include "..\..\Minecraft.World\Inventory.h" #include "..\..\Minecraft.World\Level.h" #include "..\..\Minecraft.World\FurnaceTileEntity.h" #include "..\..\Minecraft.World\Container.h" #include "..\..\Minecraft.World\DispenserTileEntity.h" #include "..\..\Minecraft.World\SignTileEntity.h" #include "..\StatsCounter.h" #include "..\GameMode.h" #include "..\Xbox\Social\SocialManager.h" #include "Tutorial\TutorialMode.h" #if defined _XBOX || defined _WINDOWS64 #include "..\Xbox\XML\ATGXmlParser.h" #include "..\Xbox\XML\xmlFilesCallback.h" #endif #include "Minecraft_Macros.h" #include "..\PlayerList.h" #include "..\ServerPlayer.h" #include "GameRules\ConsoleGameRules.h" #include "GameRules\ConsoleSchematicFile.h" #include "..\User.h" #include "..\..\Minecraft.World\LevelData.h" #include "..\..\Minecraft.World\net.minecraft.world.entity.player.h" #include "..\EntityRenderDispatcher.h" #include "..\..\Minecraft.World\compression.h" #include "..\TexturePackRepository.h" #include "..\DLCTexturePack.h" #include "DLC\DLCPack.h" #include "..\StringTable.h" #ifndef _XBOX #include "..\ArchiveFile.h" #endif #include "..\Minecraft.h" #ifdef _XBOX #include "..\Xbox\GameConfig\Minecraft.spa.h" #include "..\Xbox\Network\NetworkPlayerXbox.h" #include "XUI\XUI_TextEntry.h" #include "XUI\XUI_XZP_Icons.h" #include "XUI\XUI_PauseMenu.h" #else #include "UI\UI.h" #include "UI\UIScene_PauseMenu.h" #endif #ifdef __PS3__ #include #endif #ifdef __ORBIS__ #include #endif #include "..\Common\Leaderboards\LeaderboardManager.h" //CMinecraftApp app; unsigned int CMinecraftApp::m_uiLastSignInData = 0; const float CMinecraftApp::fSafeZoneX = 64.0f; // 5% of 1280 const float CMinecraftApp::fSafeZoneY = 36.0f; // 5% of 720 int CMinecraftApp::s_iHTMLFontSizesA[eHTMLSize_COUNT] = { #ifdef _XBOX 14,12,14,24 #else //20,15,20,24 20,13,20,26 #endif }; CMinecraftApp::CMinecraftApp() { if(GAME_SETTINGS_PROFILE_DATA_BYTES != sizeof(GAME_SETTINGS)) { // 4J Stu - See comment for GAME_SETTINGS_PROFILE_DATA_BYTES in Xbox_App.h DebugPrintf("WARNING: The size of the profile GAME_SETTINGS struct has changed, so all stat data is likely incorrect. Is: %d, Should be: %d\n",sizeof(GAME_SETTINGS),GAME_SETTINGS_PROFILE_DATA_BYTES); #ifndef _CONTENT_PACKAGE __debugbreak(); #endif } for(int i=0;i; } LocaleAndLanguageInit(); #ifdef _XBOX_ONE m_hasReachedMainMenu = false; #endif } void CMinecraftApp::DebugPrintf(const char *szFormat, ...) { #ifndef _FINAL_BUILD char buf[1024]; va_list ap; va_start(ap, szFormat); vsnprintf(buf, sizeof(buf), szFormat, ap); va_end(ap); OutputDebugStringA(buf); #endif } void CMinecraftApp::DebugPrintf(int user, const char *szFormat, ...) { #ifndef _FINAL_BUILD if(user == USER_NONE) return; char buf[1024]; va_list ap; va_start(ap, szFormat); vsnprintf(buf, sizeof(buf), szFormat, ap); va_end(ap); #ifdef __PS3__ unsigned int writelen; sys_tty_write(SYS_TTYP_USER1 + ( user - 1 ), buf, strlen(buf), &writelen ); #elif defined __PSVITA__ switch(user) { case 0: { SceUID tty2 = sceIoOpen("tty2:", SCE_O_WRONLY, 0); if(tty2>=0) { std::string string1(buf); sceIoWrite(tty2, string1.c_str(), string1.length()); sceIoClose(tty2); } } break; case 1: { SceUID tty3 = sceIoOpen("tty3:", SCE_O_WRONLY, 0); if(tty3>=0) { std::string string1(buf); sceIoWrite(tty3, string1.c_str(), string1.length()); sceIoClose(tty3); } } break; default: OutputDebugStringA(buf); break; } #else OutputDebugStringA(buf); #endif #ifndef _XBOX if(user == USER_UI) { ui.logDebugString(buf); } #endif #endif } LPCWSTR CMinecraftApp::GetString(int iID) { //return L"Değişiklikler ve Yenilikler"; //return L"ÕÕÕÕÖÖÖÖ"; return app.m_stringTable->getString(iID); } void CMinecraftApp::SetAction(int iPad, eXuiAction action, LPVOID param) { if( ( m_eXuiAction[iPad] == eAppAction_ReloadTexturePack ) && ( action == eAppAction_EthernetDisconnected ) ) { app.DebugPrintf("Invalid change of App action for pad %d from %d to %d, ignoring\n", iPad, m_eXuiAction[iPad], action); } else if( ( m_eXuiAction[iPad] == eAppAction_ReloadTexturePack ) && ( action == eAppAction_ExitWorld ) ) { app.DebugPrintf("Invalid change of App action for pad %d from %d to %d, ignoring\n", iPad, m_eXuiAction[iPad], action); } else if(m_eXuiAction[iPad] == eAppAction_ExitWorldCapturedThumbnail && action != eAppAction_Idle) { app.DebugPrintf("Invalid change of App action for pad %d from %d to %d, ignoring\n", iPad, m_eXuiAction[iPad], action); } else { app.DebugPrintf("Changing App action for pad %d from %d to %d\n", iPad, m_eXuiAction[iPad], action); m_eXuiAction[iPad]=action; m_eXuiActionParam[iPad] = param; } } bool CMinecraftApp::IsAppPaused() { #if defined(_XBOX_ONE) || defined(__ORBIS__) bool paused = m_bIsAppPaused; EnterCriticalSection(&m_saveNotificationCriticalSection); if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) { paused |= m_saveNotificationDepth > 0; } LeaveCriticalSection(&m_saveNotificationCriticalSection); return paused; #else return m_bIsAppPaused; #endif } void CMinecraftApp::SetAppPaused(bool val) { m_bIsAppPaused = val; } void CMinecraftApp::HandleButtonPresses() { for(int i=0;i<4;i++) { HandleButtonPresses(i); } } void CMinecraftApp::HandleButtonPresses(int iPad) { // // test an update of the profile data // void *pData=ProfileManager.GetGameDefinedProfileData(iPad); // // unsigned char *pchData= (unsigned char *)pData; // int iCount=0; // for(int i=0;i player,bool bNavigateBack) { bool success = true; InventoryScreenInput* initData = new InventoryScreenInput(); initData->player = player; initData->bNavigateBack=bNavigateBack; initData->iPad = iPad; if(app.GetLocalPlayerCount()>1) { initData->bSplitscreen=true; success = ui.NavigateToScene(iPad,eUIScene_InventoryMenu,initData); } else { initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_InventoryMenu,initData); } return success; } bool CMinecraftApp::LoadCreativeMenu(int iPad,shared_ptr player,bool bNavigateBack) { bool success = true; InventoryScreenInput* initData = new InventoryScreenInput(); initData->player = player; initData->bNavigateBack=bNavigateBack; initData->iPad = iPad; if(app.GetLocalPlayerCount()>1) { initData->bSplitscreen=true; success = ui.NavigateToScene(iPad,eUIScene_CreativeMenu,initData); } else { initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_CreativeMenu,initData); } return success; } bool CMinecraftApp::LoadCrafting2x2Menu(int iPad,shared_ptr player) { bool success = true; CraftingPanelScreenInput* initData = new CraftingPanelScreenInput(); initData->player = player; initData->iContainerType=RECIPE_TYPE_2x2; initData->iPad = iPad; initData->x = 0; initData->y = 0; initData->z = 0; if(app.GetLocalPlayerCount()>1) { initData->bSplitscreen=true; success = ui.NavigateToScene(iPad,eUIScene_Crafting2x2Menu, initData); } else { initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_Crafting2x2Menu, initData); } return success; } bool CMinecraftApp::LoadCrafting3x3Menu(int iPad,shared_ptr player, int x, int y, int z) { bool success = true; CraftingPanelScreenInput* initData = new CraftingPanelScreenInput(); initData->player = player; initData->iContainerType=RECIPE_TYPE_3x3; initData->iPad = iPad; initData->x = x; initData->y = y; initData->z = z; if(app.GetLocalPlayerCount()>1) { initData->bSplitscreen=true; success = ui.NavigateToScene(iPad,eUIScene_Crafting3x3Menu, initData); } else { initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_Crafting3x3Menu, initData); } return success; } bool CMinecraftApp::LoadFireworksMenu(int iPad,shared_ptr player, int x, int y, int z) { bool success = true; FireworksScreenInput* initData = new FireworksScreenInput(); initData->player = player; initData->iPad = iPad; initData->x = x; initData->y = y; initData->z = z; if(app.GetLocalPlayerCount()>1) { initData->bSplitscreen=true; success = ui.NavigateToScene(iPad,eUIScene_FireworksMenu, initData); } else { initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_FireworksMenu, initData); } return success; } bool CMinecraftApp::LoadEnchantingMenu(int iPad,shared_ptr inventory, int x, int y, int z, Level *level, const wstring &name) { bool success = true; EnchantingScreenInput* initData = new EnchantingScreenInput(); initData->inventory = inventory; initData->level = level; initData->x = x; initData->y = y; initData->z = z; initData->iPad = iPad; initData->name = name; if(app.GetLocalPlayerCount()>1) { initData->bSplitscreen=true; success = ui.NavigateToScene(iPad,eUIScene_EnchantingMenu, initData); } else { initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_EnchantingMenu, initData); } return success; } bool CMinecraftApp::LoadFurnaceMenu(int iPad,shared_ptr inventory, shared_ptr furnace) { bool success = true; FurnaceScreenInput* initData = new FurnaceScreenInput(); initData->furnace = furnace; initData->inventory = inventory; initData->iPad = iPad; // Load the scene. if(app.GetLocalPlayerCount()>1) { initData->bSplitscreen=true; success = ui.NavigateToScene(iPad,eUIScene_FurnaceMenu, initData); } else { initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_FurnaceMenu, initData); } return success; } bool CMinecraftApp::LoadBrewingStandMenu(int iPad,shared_ptr inventory, shared_ptr brewingStand) { bool success = true; BrewingScreenInput* initData = new BrewingScreenInput(); initData->brewingStand = brewingStand; initData->inventory = inventory; initData->iPad = iPad; // Load the scene. if(app.GetLocalPlayerCount()>1) { initData->bSplitscreen=true; success = ui.NavigateToScene(iPad,eUIScene_BrewingStandMenu, initData); } else { initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_BrewingStandMenu, initData); } return success; } bool CMinecraftApp::LoadContainerMenu(int iPad,shared_ptr inventory, shared_ptr container) { bool success = true; ContainerScreenInput* initData = new ContainerScreenInput(); initData->inventory = inventory; initData->container = container; initData->iPad = iPad; // Load the scene. if(app.GetLocalPlayerCount()>1) { initData->bSplitscreen=true; bool bLargeChest = (initData->container->getContainerSize() > 3*9)?true:false; if(bLargeChest) { success = ui.NavigateToScene(iPad,eUIScene_LargeContainerMenu,initData); } else { success = ui.NavigateToScene(iPad,eUIScene_ContainerMenu,initData); } } else { initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_ContainerMenu,initData); } return success; } bool CMinecraftApp::LoadTrapMenu(int iPad,shared_ptr inventory, shared_ptr trap) { bool success = true; TrapScreenInput* initData = new TrapScreenInput(); initData->inventory = inventory; initData->trap = trap; initData->iPad = iPad; // Load the scene. if(app.GetLocalPlayerCount()>1) { initData->bSplitscreen=true; success = ui.NavigateToScene(iPad,eUIScene_DispenserMenu, initData); } else { initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_DispenserMenu, initData); } return success; } bool CMinecraftApp::LoadSignEntryMenu(int iPad,shared_ptr sign) { bool success = true; SignEntryScreenInput* initData = new SignEntryScreenInput(); initData->sign = sign; initData->iPad = iPad; success = ui.NavigateToScene(iPad,eUIScene_SignEntryMenu, initData); delete initData; return success; } bool CMinecraftApp::LoadRepairingMenu(int iPad,shared_ptr inventory, Level *level, int x, int y, int z) { bool success = true; AnvilScreenInput *initData = new AnvilScreenInput(); initData->inventory = inventory; initData->level = level; initData->x = x; initData->y = y; initData->z = z; initData->iPad = iPad; if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; else initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_AnvilMenu, initData); return success; } bool CMinecraftApp::LoadTradingMenu(int iPad, shared_ptr inventory, shared_ptr trader, Level *level, const wstring &name) { bool success = true; TradingScreenInput *initData = new TradingScreenInput(); initData->inventory = inventory; initData->trader = trader; initData->level = level; initData->iPad = iPad; if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; else initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_TradingMenu, initData); return success; } bool CMinecraftApp::LoadHopperMenu(int iPad ,shared_ptr inventory, shared_ptr hopper) { bool success = true; HopperScreenInput *initData = new HopperScreenInput(); initData->inventory = inventory; initData->hopper = hopper; initData->iPad = iPad; if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; else initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_HopperMenu, initData); return success; } bool CMinecraftApp::LoadHopperMenu(int iPad ,shared_ptr inventory, shared_ptr hopper) { bool success = true; HopperScreenInput *initData = new HopperScreenInput(); initData->inventory = inventory; initData->hopper = dynamic_pointer_cast(hopper); initData->iPad = iPad; if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; else initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_HopperMenu, initData); return success; } bool CMinecraftApp::LoadHorseMenu(int iPad ,shared_ptr inventory, shared_ptr container, shared_ptr horse) { bool success = true; HorseScreenInput *initData = new HorseScreenInput(); initData->inventory = inventory; initData->container = container; initData->horse = horse; initData->iPad = iPad; if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; else initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_HorseMenu, initData); return success; } bool CMinecraftApp::LoadBeaconMenu(int iPad ,shared_ptr inventory, shared_ptr beacon) { bool success = true; BeaconScreenInput *initData = new BeaconScreenInput(); initData->inventory = inventory; initData->beacon = beacon; initData->iPad = iPad; if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; else initData->bSplitscreen=false; success = ui.NavigateToScene(iPad,eUIScene_BeaconMenu, initData); return success; } ////////////////////////////////////////////// // GAME SETTINGS ////////////////////////////////////////////// #ifdef _WINDOWS64 static void Win64_GetSettingsPath(char *outPath, DWORD size) { GetModuleFileNameA(NULL, outPath, size); char *lastSlash = strrchr(outPath, '\\'); if (lastSlash) *(lastSlash + 1) = '\0'; strncat_s(outPath, size, "settings.dat", _TRUNCATE); } static void Win64_SaveSettings(GAME_SETTINGS *gs) { if (!gs) return; char filePath[MAX_PATH] = {}; Win64_GetSettingsPath(filePath, MAX_PATH); FILE *f = NULL; if (fopen_s(&f, filePath, "wb") == 0 && f) { fwrite(gs, sizeof(GAME_SETTINGS), 1, f); fclose(f); } } static void Win64_LoadSettings(GAME_SETTINGS *gs) { if (!gs) return; char filePath[MAX_PATH] = {}; Win64_GetSettingsPath(filePath, MAX_PATH); FILE *f = NULL; if (fopen_s(&f, filePath, "rb") == 0 && f) { GAME_SETTINGS temp = {}; if (fread(&temp, sizeof(GAME_SETTINGS), 1, f) == 1) memcpy(gs, &temp, sizeof(GAME_SETTINGS)); fclose(f); } } #endif void CMinecraftApp::InitGameSettings() { for(int i=0;ibSettingsChanged=false; //SetDefaultGameSettings(i); - done on a callback from the profile manager // 4J-PB - adding in for Windows & PS3 to set the defaults for the joypad #if defined _WINDOWS64// || defined __PSVITA__ C_4JProfile::PROFILESETTINGS *pProfileSettings=ProfileManager.GetDashboardProfileSettings(i); // clear this for now - it will come from reading the system values memset(pProfileSettings,0,sizeof(C_4JProfile::PROFILESETTINGS)); SetDefaultOptions(pProfileSettings,i); Win64_LoadSettings(GameSettingsA[i]); ApplyGameSettingsChanged(i); #elif defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ C4JStorage::PROFILESETTINGS *pProfileSettings=StorageManager.GetDashboardProfileSettings(i); // 4J-PB - don't cause an options write to happen here SetDefaultOptions(pProfileSettings,i,false); #endif } } #if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) int CMinecraftApp::SetDefaultOptions(C4JStorage::PROFILESETTINGS *pSettings,const int iPad,bool bWriteProfile) #else int CMinecraftApp::SetDefaultOptions(C_4JProfile::PROFILESETTINGS *pSettings,const int iPad) #endif { SetGameSettings(iPad,eGameSetting_MusicVolume,DEFAULT_VOLUME_LEVEL); SetGameSettings(iPad,eGameSetting_SoundFXVolume,DEFAULT_VOLUME_LEVEL); SetGameSettings(iPad,eGameSetting_Gamma,50); SetGameSettings(iPad,eGameSetting_FOV,0); // 4J-PB - Don't reset the difficult level if we're in-game if(Minecraft::GetInstance()->level==NULL) { app.DebugPrintf("SetDefaultOptions - Difficulty = 1\n"); SetGameSettings(iPad,eGameSetting_Difficulty,1); } SetGameSettings(iPad,eGameSetting_Sensitivity_InGame,100); SetGameSettings(iPad,eGameSetting_ViewBob,1); SetGameSettings(iPad,eGameSetting_ControlScheme,0); SetGameSettings(iPad,eGameSetting_ControlInvertLook,(pSettings->iYAxisInversion!=0)?1:0); SetGameSettings(iPad,eGameSetting_ControlSouthPaw,pSettings->bSwapSticks?1:0); SetGameSettings(iPad,eGameSetting_SplitScreenVertical,0); SetGameSettings(iPad,eGameSetting_GamertagsVisible,1); // Interim TU 1.6.6 SetGameSettings(iPad,eGameSetting_Sensitivity_InMenu,100); SetGameSettings(iPad,eGameSetting_DisplaySplitscreenGamertags,1); SetGameSettings(iPad,eGameSetting_Hints,1); SetGameSettings(iPad,eGameSetting_Autosave,2); SetGameSettings(iPad,eGameSetting_Tooltips,1); SetGameSettings(iPad,eGameSetting_InterfaceOpacity,80); // TU 5 SetGameSettings(iPad,eGameSetting_Clouds,1); SetGameSettings(iPad,eGameSetting_Online,1); SetGameSettings(iPad,eGameSetting_InviteOnly,0); SetGameSettings(iPad,eGameSetting_FriendsOfFriends,1); // default the update changes message to zero // 4J-PB - We'll only display the message if the profile is pre-TU5 //SetGameSettings(iPad,eGameSetting_DisplayUpdateMessage,0); // TU 6 SetGameSettings(iPad,eGameSetting_BedrockFog,0); SetGameSettings(iPad,eGameSetting_DisplayHUD,1); SetGameSettings(iPad,eGameSetting_DisplayHand,1); // TU 7 SetGameSettings(iPad,eGameSetting_CustomSkinAnim,1); // TU 9 SetGameSettings(iPad,eGameSetting_DeathMessages,1); SetGameSettings(iPad,eGameSetting_UISize,1); SetGameSettings(iPad,eGameSetting_UISizeSplitscreen,2); SetGameSettings(iPad,eGameSetting_AnimatedCharacter,1); // TU 12 GameSettingsA[iPad]->ucCurrentFavoriteSkinPos=0; for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; } // TU 13 GameSettingsA[iPad]->uiMashUpPackWorldsDisplay=0xFFFFFFFF; // 1.6.4 app.SetGameHostOption(eGameHostOption_MobGriefing, 1); app.SetGameHostOption(eGameHostOption_KeepInventory, 0); app.SetGameHostOption(eGameHostOption_DoMobSpawning, 1 ); app.SetGameHostOption(eGameHostOption_DoMobLoot, 1 ); app.SetGameHostOption(eGameHostOption_DoTileDrops, 1 ); app.SetGameHostOption(eGameHostOption_NaturalRegeneration, 1 ); app.SetGameHostOption(eGameHostOption_DoDaylightCycle, 1 ); // 4J-PB - leave these in, or remove from everywhere they are referenced! // Although probably best to leave in unless we split the profile settings into platform specific classes - having different meaning per platform for the same bitmask could get confusing //#ifdef __PS3__ // PS3DEC13 SetGameSettings(iPad,eGameSetting_PS3_EULA_Read,0); // EULA not read // PS3 1.05 - added Greek // 4J-JEV: We cannot change these in-game, as they could affect localised strings and font. // XB1: Fix for #172947 - Content: Gameplay: While playing in language different form system default one and resetting options to their defaults in active gameplay causes in-game language to change and HUD to disappear if (!app.GetGameStarted()) { GameSettingsA[iPad]->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language GameSettingsA[iPad]->ucLocale = MINECRAFT_LANGUAGE_DEFAULT; // use the system locale } //#endif #if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) GameSettingsA[iPad]->bSettingsChanged=bWriteProfile; #endif return 0; } #if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) int CMinecraftApp::DefaultOptionsCallback(LPVOID pParam,C4JStorage::PROFILESETTINGS *pSettings, const int iPad) #else int CMinecraftApp::DefaultOptionsCallback(LPVOID pParam,C_4JProfile::PROFILESETTINGS *pSettings, const int iPad) #endif { CMinecraftApp *pApp=(CMinecraftApp *)pParam; // flag the default options to be set pApp->DebugPrintf("Setting default options for player %d", iPad); pApp->SetAction(iPad,eAppAction_SetDefaultOptions, (LPVOID)pSettings); //pApp->SetDefaultOptions(pSettings,iPad); // if the profile data has been changed, then force a profile write // It seems we're allowed to break the 5 minute rule if it's the result of a user action //pApp->CheckGameSettingsChanged(); return 0; } #if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) wstring CMinecraftApp::toStringOptionsStatus(const C4JStorage::eOptionsCallback &eStatus) { #ifndef _CONTENT_PACKAGE switch(eStatus) { case C4JStorage::eOptions_Callback_Idle: return L"Idle"; case C4JStorage::eOptions_Callback_Write: return L"Write"; case C4JStorage::eOptions_Callback_Write_Fail_NoSpace: return L"Write_Fail_NoSpace"; case C4JStorage::eOptions_Callback_Write_Fail: return L"Write_Fail"; case C4JStorage::eOptions_Callback_Read: return L"Read"; case C4JStorage::eOptions_Callback_Read_Fail: return L"Read_Fail"; case C4JStorage::eOptions_Callback_Read_FileNotFound: return L"Read_FileNotFound"; case C4JStorage::eOptions_Callback_Read_Corrupt: return L"Read_Corrupt"; case C4JStorage::eOptions_Callback_Read_CorruptDeletePending: return L"Read_CorruptDeletePending"; case C4JStorage::eOptions_Callback_Read_CorruptDeleted: return L"Read_CorruptDeleted"; default: return L"[UNRECOGNISED_OPTIONS_STATUS]"; } #else return L""; #endif } #ifdef __ORBIS__ int CMinecraftApp::OptionsDataCallback(LPVOID pParam,int iPad,unsigned short usVersion,C4JStorage::eOptionsCallback eStatus,int iBlocksRequired) { CMinecraftApp *pApp=(CMinecraftApp *)pParam; pApp->m_eOptionsStatusA[iPad]=eStatus; pApp->m_eOptionsBlocksRequiredA[iPad]=iBlocksRequired; return 0; } int CMinecraftApp::GetOptionsBlocksRequired(int iPad) { return m_eOptionsBlocksRequiredA[iPad]; } #else int CMinecraftApp::OptionsDataCallback(LPVOID pParam,int iPad,unsigned short usVersion,C4JStorage::eOptionsCallback eStatus) { CMinecraftApp *pApp=(CMinecraftApp *)pParam; #ifndef _CONTENT_PACKAGE pApp->DebugPrintf("[OptionsDataCallback] Pad_%i: new status == %ls(%i).\n", iPad, pApp->toStringOptionsStatus(eStatus).c_str(), (int) eStatus); #endif pApp->m_eOptionsStatusA[iPad] = eStatus; return 0; } #endif C4JStorage::eOptionsCallback CMinecraftApp::GetOptionsCallbackStatus(int iPad) { return m_eOptionsStatusA[iPad]; } void CMinecraftApp::SetOptionsCallbackStatus(int iPad, C4JStorage::eOptionsCallback eStatus) { m_eOptionsStatusA[iPad]=eStatus; } #endif int CMinecraftApp::OldProfileVersionCallback(LPVOID pParam,unsigned char *pucData, const unsigned short usVersion, const int iPad) { // check what needs to be done with this version to update to the current one switch(usVersion) { #ifdef _XBOX case PROFILE_VERSION_1: case PROFILE_VERSION_2: // need to fill in values for the new profile data. No need to save the profile - that'll happen if they get changed, or if the auto save for the profile kicks in { GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; pGameSettings->ucMenuSensitivity=100; //eGameSetting_Sensitivity_InMenu pGameSettings->ucInterfaceOpacity=80; //eGameSetting_Sensitivity_InMenu pGameSettings->usBitmaskValues|=0x0200; //eGameSetting_DisplaySplitscreenGamertags - on pGameSettings->usBitmaskValues|=0x0400; //eGameSetting_Hints - on pGameSettings->usBitmaskValues|=0x1000; //eGameSetting_Autosave - 2 pGameSettings->usBitmaskValues|=0x8000; //eGameSetting_Tooltips - on // 4J-PB - Let's also award all the achievements they have again because of the profile bug that seemed to stop the awards of some // Changing this to check the system achievements at sign-in and award any that the game says we have and the system says we haven't //ProfileManager.ReAwardAchievements(iPad); pGameSettings->uiBitmaskValues=0L; // reset pGameSettings->uiBitmaskValues|=GAMESETTING_CLOUDS; //eGameSetting_Clouds - on pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on //eGameSetting_GameSetting_Invite - off pGameSettings->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) // TU6 pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on // TU7 pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on // TU9 pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on // TU12 // favorite skins added, but only set in TU12 - set to FFs for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; } pGameSettings->ucCurrentFavoriteSkinPos=0; // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; // PS3 1.05 - added Greek pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language } break; case PROFILE_VERSION_3: { GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; pGameSettings->uiBitmaskValues=0L; // reset pGameSettings->uiBitmaskValues|=GAMESETTING_CLOUDS; //eGameSetting_Clouds - on pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on //eGameSetting_GameSetting_Invite - off pGameSettings->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) // TU6 pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on // TU7 pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on // TU9 pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on // TU12 // favorite skins added, but only set in TU12 - set to FFs for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; } pGameSettings->ucCurrentFavoriteSkinPos=0; // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; // PS3 1.05 - added Greek pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language } break; case PROFILE_VERSION_4: { GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on // TU7 pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on // TU9 pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on // Set the online flag to on, so it's not saved if a game starts offline when the user didn't change it to be offline (xbox disconnected from LIVE) pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on // TU12 // favorite skins added, but only set in TU12 - set to FFs for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; } pGameSettings->ucCurrentFavoriteSkinPos=0; // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; // PS3 1.05 - added Greek pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language } break; case PROFILE_VERSION_5: { GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; // reset the display new message counter pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) // TU7 pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on // TU9 pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on // Set the online flag to on, so it's not saved if a game starts offline when the user didn't change it to be offline (xbox disconnected from LIVE) pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on // TU12 // favorite skins added, but only set in TU12 - set to FFs for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; } pGameSettings->ucCurrentFavoriteSkinPos=0; // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; // PS3 1.05 - added Greek pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language } break; case PROFILE_VERSION_6: { GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; // Added gui size for splitscreen and fullscreen // Added death messages toggle // reset the display new message counter pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) // TU9 pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on // Set the online flag to on, so it's not saved if a game starts offline when the user didn't change it to be offline (xbox disconnected from LIVE) pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on // TU12 // favorite skins added, but only set in TU12 - set to FFs for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; } pGameSettings->ucCurrentFavoriteSkinPos=0; // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; // PS3 1.05 - added Greek pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language } break; case PROFILE_VERSION_7: { GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; // reset the display new message counter pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) // TU12 // favorite skins added, but only set in TU12 - set to FFs for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; } pGameSettings->ucCurrentFavoriteSkinPos=0; // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; // PS3 1.05 - added Greek pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language } break; #endif case PROFILE_VERSION_8: { GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; // reset the display new message counter pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; // PS3DEC13 pGameSettings->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off // PS3 1.05 - added Greek pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language } break; case PROFILE_VERSION_9: // PS3DEC13 { GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) pGameSettings->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off // PS3 1.05 - added Greek pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language } break; case PROFILE_VERSION_10: { GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language } break; case PROFILE_VERSION_11: { GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) } break; case PROFILE_VERSION_12: { GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) } break; default: { // This might be from a version during testing of new profile updates app.DebugPrintf("Don't know what to do with this profile version!\n"); #ifndef _CONTENT_PACKAGE // __debugbreak(); #endif GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; pGameSettings->ucMenuSensitivity=100; //eGameSetting_Sensitivity_InMenu pGameSettings->ucInterfaceOpacity=80; //eGameSetting_Sensitivity_InMenu pGameSettings->usBitmaskValues|=0x0200; //eGameSetting_DisplaySplitscreenGamertags - on pGameSettings->usBitmaskValues|=0x0400; //eGameSetting_Hints - on pGameSettings->usBitmaskValues|=0x1000; //eGameSetting_Autosave - 2 pGameSettings->usBitmaskValues|=0x8000; //eGameSetting_Tooltips - on pGameSettings->uiBitmaskValues=0L; // reset pGameSettings->uiBitmaskValues|=GAMESETTING_CLOUDS; //eGameSetting_Clouds - on pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on //eGameSetting_GameSetting_Invite - off pGameSettings->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on // TU12 // favorite skins added, but only set in TU12 - set to FFs for(int i=0;iuiFavoriteSkinA[i]=0xFFFFFFFF; } pGameSettings->ucCurrentFavoriteSkinPos=0; // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; // PS3DEC13 pGameSettings->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off // PS3 1.05 - added Greek pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language } break; } return 0; } void CMinecraftApp::ApplyGameSettingsChanged(int iPad) { ActionGameSettings(iPad,eGameSetting_MusicVolume ); ActionGameSettings(iPad,eGameSetting_SoundFXVolume ); ActionGameSettings(iPad,eGameSetting_Gamma ); ActionGameSettings(iPad,eGameSetting_FOV ); ActionGameSettings(iPad,eGameSetting_Difficulty ); ActionGameSettings(iPad,eGameSetting_Sensitivity_InGame ); ActionGameSettings(iPad,eGameSetting_ViewBob ); ActionGameSettings(iPad,eGameSetting_ControlScheme ); ActionGameSettings(iPad,eGameSetting_ControlInvertLook); ActionGameSettings(iPad,eGameSetting_ControlSouthPaw); ActionGameSettings(iPad,eGameSetting_SplitScreenVertical); ActionGameSettings(iPad,eGameSetting_GamertagsVisible); // Interim TU 1.6.6 ActionGameSettings(iPad,eGameSetting_Sensitivity_InMenu ); ActionGameSettings(iPad,eGameSetting_DisplaySplitscreenGamertags); ActionGameSettings(iPad,eGameSetting_Hints); ActionGameSettings(iPad,eGameSetting_InterfaceOpacity); ActionGameSettings(iPad,eGameSetting_Tooltips); ActionGameSettings(iPad,eGameSetting_Clouds); ActionGameSettings(iPad,eGameSetting_BedrockFog); ActionGameSettings(iPad,eGameSetting_DisplayHUD); ActionGameSettings(iPad,eGameSetting_DisplayHand); ActionGameSettings(iPad,eGameSetting_CustomSkinAnim); ActionGameSettings(iPad,eGameSetting_DeathMessages); ActionGameSettings(iPad,eGameSetting_UISize); ActionGameSettings(iPad,eGameSetting_UISizeSplitscreen); ActionGameSettings(iPad,eGameSetting_AnimatedCharacter); ActionGameSettings(iPad,eGameSetting_PS3_EULA_Read); } void CMinecraftApp::ActionGameSettings(int iPad,eGameSetting eVal) { Minecraft *pMinecraft=Minecraft::GetInstance(); switch(eVal) { case eGameSetting_MusicVolume: if(iPad==ProfileManager.GetPrimaryPad()) { pMinecraft->options->set(Options::Option::MUSIC,((float)GameSettingsA[iPad]->ucMusicVolume)/100.0f); } break; case eGameSetting_SoundFXVolume: if(iPad==ProfileManager.GetPrimaryPad()) { pMinecraft->options->set(Options::Option::SOUND,((float)GameSettingsA[iPad]->ucSoundFXVolume)/100.0f); } break; case eGameSetting_Gamma: if(iPad==ProfileManager.GetPrimaryPad()) { #if defined(_WIN64) || defined(_WINDOWS64) pMinecraft->options->set(Options::Option::GAMMA, ((float)GameSettingsA[iPad]->ucGamma) / 100.0f); #else // ucGamma range is 0-100, UpdateGamma is 0 - 32768 float fVal=((float)GameSettingsA[iPad]->ucGamma)*327.68f; RenderManager.UpdateGamma((unsigned short)fVal); #endif } break; case eGameSetting_FOV: if(iPad==ProfileManager.GetPrimaryPad()) { float fovDeg = 70.0f + (float)GameSettingsA[iPad]->ucFov * 40.0f / 100.0f; pMinecraft->gameRenderer->SetFovVal(fovDeg); pMinecraft->options->set(Options::Option::FOV, (float)GameSettingsA[iPad]->ucFov / 100.0f); } break; case eGameSetting_Difficulty: if(iPad==ProfileManager.GetPrimaryPad()) { pMinecraft->options->toggle(Options::Option::DIFFICULTY,GameSettingsA[iPad]->usBitmaskValues&0x03); app.DebugPrintf("Difficulty toggle to %d\n",GameSettingsA[iPad]->usBitmaskValues&0x03); // Update the Game Host setting app.SetGameHostOption(eGameHostOption_Difficulty,pMinecraft->options->difficulty); // send this to the other players if we are in-game bool bInGame=pMinecraft->level!=NULL; // Game Host only (and for now we can't change the diff while in game, so this shouldn't happen) if(bInGame && g_NetworkManager.IsHost() && (iPad==ProfileManager.GetPrimaryPad())) { app.SetXuiServerAction(iPad,eXuiServerAction_ServerSettingChanged_Difficulty); } } else { app.DebugPrintf("NOT ACTIONING DIFFICULTY - Primary pad is %d, This pad is %d\n",ProfileManager.GetPrimaryPad(),iPad); } break; case eGameSetting_Sensitivity_InGame: // 4J-PB - we don't use the options value // tell the input that we've changed the sensitivity - range of the slider is 0 to 200, default is 100 pMinecraft->options->set(Options::Option::SENSITIVITY,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); //InputManager.SetJoypadSensitivity(iPad,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); break; case eGameSetting_ViewBob: // 4J-PB - not handled here any more - it's read from the gamesettings per player //pMinecraft->options->toggle(Options::Option::VIEW_BOBBING,GameSettingsA[iPad]->usBitmaskValues&0x04); break; case eGameSetting_ControlScheme: InputManager.SetJoypadMapVal(iPad,(GameSettingsA[iPad]->usBitmaskValues&0x30)>>4); break; case eGameSetting_ControlInvertLook: // Nothing specific to do for this setting. break; case eGameSetting_ControlSouthPaw: // What is the setting? if ( GameSettingsA[iPad]->usBitmaskValues & 0x80 ) { // Southpaw. InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LX, AXIS_MAP_RX ); InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LY, AXIS_MAP_RY ); InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RX, AXIS_MAP_LX ); InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RY, AXIS_MAP_LY ); InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_0, TRIGGER_MAP_1 ); InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_1, TRIGGER_MAP_0 ); } else { // Right handed. InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LX, AXIS_MAP_LX ); InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LY, AXIS_MAP_LY ); InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RX, AXIS_MAP_RX ); InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RY, AXIS_MAP_RY ); InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_0, TRIGGER_MAP_0 ); InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_1, TRIGGER_MAP_1 ); } break; case eGameSetting_SplitScreenVertical: if(iPad==ProfileManager.GetPrimaryPad()) { pMinecraft->updatePlayerViewportAssignments(); } break; case eGameSetting_GamertagsVisible: { bool bInGame=pMinecraft->level!=NULL; // Game Host only if(bInGame && g_NetworkManager.IsHost() && (iPad==ProfileManager.GetPrimaryPad())) { // Update the Game Host setting if you are the host and you are in-game app.SetGameHostOption(eGameHostOption_Gamertags,((GameSettingsA[iPad]->usBitmaskValues&0x0008)!=0)?1:0); app.SetXuiServerAction(iPad,eXuiServerAction_ServerSettingChanged_Gamertags); PlayerList *players = MinecraftServer::getInstance()->getPlayerList(); for( auto& decorationPlayer : players->players ) { decorationPlayer->setShowOnMaps((app.GetGameHostOption(eGameHostOption_Gamertags)!=0)?true:false); } } } break; // Interim TU 1.6.6 case eGameSetting_Sensitivity_InMenu: // 4J-PB - we don't use the options value // tell the input that we've changed the sensitivity - range of the slider is 0 to 200, default is 100 //pMinecraft->options->set(Options::Option::SENSITIVITY,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); //InputManager.SetJoypadSensitivity(iPad,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); break; case eGameSetting_DisplaySplitscreenGamertags: for( BYTE idx = 0; idx < XUSER_MAX_COUNT; ++idx) { if(pMinecraft->localplayers[idx] != NULL) { if(pMinecraft->localplayers[idx]->m_iScreenSection==C4JRender::VIEWPORT_TYPE_FULLSCREEN) { ui.DisplayGamertag(idx,false); } else { ui.DisplayGamertag(idx,true); } } } break; case eGameSetting_InterfaceOpacity: // update the tooltips display ui.RefreshTooltips( iPad); break; case eGameSetting_Hints: //nothing to do here break; case eGameSetting_Tooltips: if((GameSettingsA[iPad]->usBitmaskValues&0x8000)!=0) { ui.SetEnableTooltips(iPad,TRUE); } else { ui.SetEnableTooltips(iPad,FALSE); } break; case eGameSetting_Clouds: //nothing to do here break; case eGameSetting_Online: //nothing to do here break; case eGameSetting_InviteOnly: //nothing to do here break; case eGameSetting_FriendsOfFriends: //nothing to do here break; case eGameSetting_BedrockFog: { bool bInGame=pMinecraft->level!=NULL; // Game Host only if(bInGame && g_NetworkManager.IsHost() && (iPad==ProfileManager.GetPrimaryPad())) { // Update the Game Host setting if you are the host and you are in-game app.SetGameHostOption(eGameHostOption_BedrockFog,GetGameSettings(iPad,eGameSetting_BedrockFog)?1:0); app.SetXuiServerAction(iPad,eXuiServerAction_ServerSettingChanged_BedrockFog); } } break; case eGameSetting_DisplayHUD: //nothing to do here break; case eGameSetting_DisplayHand: //nothing to do here break; case eGameSetting_CustomSkinAnim: //nothing to do here break; case eGameSetting_DeathMessages: //nothing to do here break; case eGameSetting_UISize: //nothing to do here break; case eGameSetting_UISizeSplitscreen: //nothing to do here break; case eGameSetting_AnimatedCharacter: //nothing to do here break; case eGameSetting_PS3_EULA_Read: //nothing to do here break; case eGameSetting_PSVita_NetworkModeAdhoc: //nothing to do here break; } } void CMinecraftApp::SetPlayerSkin(int iPad,const wstring &name) { DWORD skinId = app.getSkinIdFromPath(name); SetPlayerSkin(iPad,skinId); } void CMinecraftApp::SetPlayerSkin(int iPad,DWORD dwSkinId) { DebugPrintf("Setting skin for %d to %08X\n", iPad, dwSkinId); GameSettingsA[iPad]->dwSelectedSkin = dwSkinId; GameSettingsA[iPad]->bSettingsChanged = true; TelemetryManager->RecordSkinChanged(iPad, GameSettingsA[iPad]->dwSelectedSkin); if(Minecraft::GetInstance()->localplayers[iPad]!=NULL) Minecraft::GetInstance()->localplayers[iPad]->setAndBroadcastCustomSkin(dwSkinId); } wstring CMinecraftApp::GetPlayerSkinName(int iPad) { return app.getSkinPathFromId(GameSettingsA[iPad]->dwSelectedSkin); } DWORD CMinecraftApp::GetPlayerSkinId(int iPad) { // 4J-PB -check the user has rights to use this skin - they may have had at some point but the entitlement has been removed. DLCPack *Pack=NULL; DLCSkinFile *skinFile=NULL; DWORD dwSkin=GameSettingsA[iPad]->dwSelectedSkin; wchar_t chars[256]; if( GET_IS_DLC_SKIN_FROM_BITMASK(dwSkin) ) { // 4J Stu - DLC skins are numbered using decimal rather than hex to make it easier to number manually swprintf(chars, 256, L"dlcskin%08d.png", GET_DLC_SKIN_ID_FROM_BITMASK(dwSkin)); Pack=app.m_dlcManager.getPackContainingSkin(chars); if(Pack) { skinFile = Pack->getSkinFile(chars); bool bSkinIsFree = skinFile->getParameterAsBool( DLCManager::e_DLCParamType_Free ); bool bLicensed = Pack->hasPurchasedFile( DLCManager::e_DLCType_Skin, skinFile->getPath() ); if(bSkinIsFree || bLicensed) { return dwSkin; } else { return 0; } } } return dwSkin; } DWORD CMinecraftApp::GetAdditionalModelParts(int iPad) { return m_dwAdditionalModelParts[iPad]; } void CMinecraftApp::SetPlayerCape(int iPad,const wstring &name) { DWORD capeId = Player::getCapeIdFromPath(name); SetPlayerCape(iPad,capeId); } void CMinecraftApp::SetPlayerCape(int iPad,DWORD dwCapeId) { DebugPrintf("Setting cape for %d to %08X\n", iPad, dwCapeId); GameSettingsA[iPad]->dwSelectedCape = dwCapeId; GameSettingsA[iPad]->bSettingsChanged = true; //SentientManager.RecordSkinChanged(iPad, GameSettingsA[iPad]->dwSelectedSkin); if(Minecraft::GetInstance()->localplayers[iPad]!=NULL) Minecraft::GetInstance()->localplayers[iPad]->setAndBroadcastCustomCape(dwCapeId); } wstring CMinecraftApp::GetPlayerCapeName(int iPad) { return Player::getCapePathFromId(GameSettingsA[iPad]->dwSelectedCape); } DWORD CMinecraftApp::GetPlayerCapeId(int iPad) { return GameSettingsA[iPad]->dwSelectedCape; } void CMinecraftApp::SetPlayerFavoriteSkin(int iPad, int iIndex,unsigned int uiSkinID) { DebugPrintf("Setting favorite skin for %d to %08X\n", iPad, uiSkinID); GameSettingsA[iPad]->uiFavoriteSkinA[iIndex] = uiSkinID; GameSettingsA[iPad]->bSettingsChanged = true; } unsigned int CMinecraftApp::GetPlayerFavoriteSkin(int iPad,int iIndex) { return GameSettingsA[iPad]->uiFavoriteSkinA[iIndex]; } unsigned char CMinecraftApp::GetPlayerFavoriteSkinsPos(int iPad) { return GameSettingsA[iPad]->ucCurrentFavoriteSkinPos; } void CMinecraftApp::SetPlayerFavoriteSkinsPos(int iPad, int iPos) { GameSettingsA[iPad]->ucCurrentFavoriteSkinPos=(unsigned char)iPos; GameSettingsA[iPad]->bSettingsChanged = true; } unsigned int CMinecraftApp::GetPlayerFavoriteSkinsCount(int iPad) { unsigned int uiCount=0; for(int i=0;iuiFavoriteSkinA[i]!=0xFFFFFFFF) { uiCount++; } else { break; } } return uiCount; } void CMinecraftApp::ValidateFavoriteSkins(int iPad) { unsigned int uiCount=GetPlayerFavoriteSkinsCount(iPad); // remove invalid skins unsigned int uiValidSkin=0; wchar_t chars[256]; for(unsigned int i=0;igetFile(DLCManager::e_DLCType_Skin,chars); DLCSkinFile *pSkinFile = pDLCPack->getSkinFile(chars); if( pDLCPack->hasPurchasedFile(DLCManager::e_DLCType_Skin, L"") || (pSkinFile && pSkinFile->isFree())) { GameSettingsA[iPad]->uiFavoriteSkinA[uiValidSkin++]=GameSettingsA[iPad]->uiFavoriteSkinA[i]; } } } for(unsigned int i=uiValidSkin;iuiFavoriteSkinA[i]=0xFFFFFFFF; } } // Mash-up pack worlds void CMinecraftApp::HideMashupPackWorld(int iPad, unsigned int iMashupPackID) { unsigned int uiPackID=iMashupPackID - 1024; // mash-up ids start at 1024 GameSettingsA[iPad]->uiMashUpPackWorldsDisplay&=~(1<bSettingsChanged = true; } void CMinecraftApp::EnableMashupPackWorlds(int iPad) { GameSettingsA[iPad]->uiMashUpPackWorldsDisplay=0xFFFFFFFF; GameSettingsA[iPad]->bSettingsChanged = true; } unsigned int CMinecraftApp::GetMashupPackWorlds(int iPad) { return GameSettingsA[iPad]->uiMashUpPackWorldsDisplay; } void CMinecraftApp::SetMinecraftLanguage(int iPad, unsigned char ucLanguage) { GameSettingsA[iPad]->ucLanguage = ucLanguage; GameSettingsA[iPad]->bSettingsChanged = true; } unsigned char CMinecraftApp::GetMinecraftLanguage(int iPad) { // if there are no game settings read yet, return the default language if(GameSettingsA[iPad]==NULL) { return 0; } else { return GameSettingsA[iPad]->ucLanguage; } } void CMinecraftApp::SetMinecraftLocale(int iPad, unsigned char ucLocale) { GameSettingsA[iPad]->ucLocale = ucLocale; GameSettingsA[iPad]->bSettingsChanged = true; } unsigned char CMinecraftApp::GetMinecraftLocale(int iPad) { // if there are no game settings read yet, return the default language if(GameSettingsA[iPad]==NULL) { return 0; } else { return GameSettingsA[iPad]->ucLocale; } } void CMinecraftApp::SetGameSettings(int iPad,eGameSetting eVal,unsigned char ucVal) { //Minecraft *pMinecraft=Minecraft::GetInstance(); switch(eVal) { case eGameSetting_MusicVolume: if(GameSettingsA[iPad]->ucMusicVolume!=ucVal) { GameSettingsA[iPad]->ucMusicVolume=ucVal; if(iPad==ProfileManager.GetPrimaryPad()) { ActionGameSettings(iPad,eVal); } GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_SoundFXVolume: if(GameSettingsA[iPad]->ucSoundFXVolume!=ucVal) { GameSettingsA[iPad]->ucSoundFXVolume=ucVal; if(iPad==ProfileManager.GetPrimaryPad()) { ActionGameSettings(iPad,eVal); } GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_Gamma: if(GameSettingsA[iPad]->ucGamma!=ucVal) { GameSettingsA[iPad]->ucGamma=ucVal; if(iPad==ProfileManager.GetPrimaryPad()) { ActionGameSettings(iPad,eVal); } GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_FOV: if(GameSettingsA[iPad]->ucFov!=ucVal) { GameSettingsA[iPad]->ucFov=ucVal; if(iPad==ProfileManager.GetPrimaryPad()) { ActionGameSettings(iPad,eVal); } GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_Difficulty: if((GameSettingsA[iPad]->usBitmaskValues&0x03)!=(ucVal&0x03)) { GameSettingsA[iPad]->usBitmaskValues&=~0x03; GameSettingsA[iPad]->usBitmaskValues|=ucVal&0x03; if(iPad==ProfileManager.GetPrimaryPad()) { ActionGameSettings(iPad,eVal); } GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_Sensitivity_InGame: if(GameSettingsA[iPad]->ucSensitivity!=ucVal) { GameSettingsA[iPad]->ucSensitivity=ucVal; ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_ViewBob: if((GameSettingsA[iPad]->usBitmaskValues&0x0004)!=((ucVal&0x01)<<2)) { if(ucVal!=0) { GameSettingsA[iPad]->usBitmaskValues|=0x0004; } else { GameSettingsA[iPad]->usBitmaskValues&=~0x0004; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_ControlScheme: // bits 5 and 6 if((GameSettingsA[iPad]->usBitmaskValues&0x30)!=((ucVal&0x03)<<4)) { GameSettingsA[iPad]->usBitmaskValues&=~0x0030; if(ucVal!=0) { GameSettingsA[iPad]->usBitmaskValues|=(ucVal&0x03)<<4; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_ControlInvertLook: if((GameSettingsA[iPad]->usBitmaskValues&0x0040)!=((ucVal&0x01)<<6)) { if(ucVal!=0) { GameSettingsA[iPad]->usBitmaskValues|=0x0040; } else { GameSettingsA[iPad]->usBitmaskValues&=~0x0040; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_ControlSouthPaw: if((GameSettingsA[iPad]->usBitmaskValues&0x0080)!=((ucVal&0x01)<<7)) { if(ucVal!=0) { GameSettingsA[iPad]->usBitmaskValues|=0x0080; } else { GameSettingsA[iPad]->usBitmaskValues&=~0x0080; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_SplitScreenVertical: if((GameSettingsA[iPad]->usBitmaskValues&0x0100)!=((ucVal&0x01)<<8)) { if(ucVal!=0) { GameSettingsA[iPad]->usBitmaskValues|=0x0100; } else { GameSettingsA[iPad]->usBitmaskValues&=~0x0100; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_GamertagsVisible: if((GameSettingsA[iPad]->usBitmaskValues&0x0008)!=((ucVal&0x01)<<3)) { if(ucVal!=0) { GameSettingsA[iPad]->usBitmaskValues|=0x0008; } else { GameSettingsA[iPad]->usBitmaskValues&=~0x0008; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; // 4J-PB - Added for Interim TU for 1.6.6 case eGameSetting_Sensitivity_InMenu: if(GameSettingsA[iPad]->ucMenuSensitivity!=ucVal) { GameSettingsA[iPad]->ucMenuSensitivity=ucVal; ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_DisplaySplitscreenGamertags: if((GameSettingsA[iPad]->usBitmaskValues&0x0200)!=((ucVal&0x01)<<9)) { if(ucVal!=0) { GameSettingsA[iPad]->usBitmaskValues|=0x0200; } else { GameSettingsA[iPad]->usBitmaskValues&=~0x0200; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_Hints: if((GameSettingsA[iPad]->usBitmaskValues&0x0400)!=((ucVal&0x01)<<10)) { if(ucVal!=0) { GameSettingsA[iPad]->usBitmaskValues|=0x0400; } else { GameSettingsA[iPad]->usBitmaskValues&=~0x0400; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_Autosave: if((GameSettingsA[iPad]->usBitmaskValues&0x7800)!=((ucVal&0x0F)<<11)) { GameSettingsA[iPad]->usBitmaskValues&=~0x7800; if(ucVal!=0) { GameSettingsA[iPad]->usBitmaskValues|=(ucVal&0x0F)<<11; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_Tooltips: if((GameSettingsA[iPad]->usBitmaskValues&0x8000)!=((ucVal&0x01)<<15)) { if(ucVal!=0) { GameSettingsA[iPad]->usBitmaskValues|=0x8000; } else { GameSettingsA[iPad]->usBitmaskValues&=~0x8000; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_InterfaceOpacity: if(GameSettingsA[iPad]->ucInterfaceOpacity!=ucVal) { GameSettingsA[iPad]->ucInterfaceOpacity=ucVal; ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_Clouds: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CLOUDS)!=(ucVal&0x01)) { if(ucVal==1) { GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_CLOUDS; } else { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_CLOUDS; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_Online: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ONLINE)!=(ucVal&0x01)<<1) { if(ucVal==1) { GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_ONLINE; } else { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_ONLINE; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_InviteOnly: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_INVITEONLY)!=(ucVal&0x01)<<2) { if(ucVal==1) { GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_INVITEONLY; } else { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_INVITEONLY; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_FriendsOfFriends: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_FRIENDSOFFRIENDS)!=(ucVal&0x01)<<3) { if(ucVal==1) { GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; } else { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_FRIENDSOFFRIENDS; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_DisplayUpdateMessage: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYUPDATEMSG)!=(ucVal&0x03)<<4) { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DISPLAYUPDATEMSG; if(ucVal>0) { GameSettingsA[iPad]->uiBitmaskValues|=(ucVal&0x03)<<4; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_BedrockFog: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_BEDROCKFOG)!=(ucVal&0x01)<<6) { if(ucVal==1) { GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_BEDROCKFOG; } else { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_DisplayHUD: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHUD)!=(ucVal&0x01)<<7) { if(ucVal==1) { GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; } else { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DISPLAYHUD; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_DisplayHand: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHAND)!=(ucVal&0x01)<<8) { if(ucVal==1) { GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; } else { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DISPLAYHAND; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_CustomSkinAnim: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CUSTOMSKINANIM)!=(ucVal&0x01)<<9) { if(ucVal==1) { GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; } else { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_CUSTOMSKINANIM; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; // TU9 case eGameSetting_DeathMessages: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DEATHMESSAGES)!=(ucVal&0x01)<<10) { if(ucVal==1) { GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; } else { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DEATHMESSAGES; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_UISize: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE)!=((ucVal&0x03)<<11)) { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_UISIZE; if(ucVal!=0) { GameSettingsA[iPad]->uiBitmaskValues|=(ucVal&0x03)<<11; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_UISizeSplitscreen: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE_SPLITSCREEN)!=((ucVal&0x03)<<13)) { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_UISIZE_SPLITSCREEN; if(ucVal!=0) { GameSettingsA[iPad]->uiBitmaskValues|=(ucVal&0x03)<<13; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_AnimatedCharacter: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ANIMATEDCHARACTER)!=(ucVal&0x01)<<15) { if(ucVal==1) { GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; } else { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_ANIMATEDCHARACTER; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_PS3_EULA_Read: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PS3EULAREAD)!=(ucVal&0x01)<<16) { if(ucVal==1) { GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_PS3EULAREAD; } else { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; case eGameSetting_PSVita_NetworkModeAdhoc: if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PSVITANETWORKMODEADHOC)!=(ucVal&0x01)<<17) { if(ucVal==1) { GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_PSVITANETWORKMODEADHOC; } else { GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_PSVITANETWORKMODEADHOC; } ActionGameSettings(iPad,eVal); GameSettingsA[iPad]->bSettingsChanged=true; } break; } } unsigned char CMinecraftApp::GetGameSettings(eGameSetting eVal) { int iPad=ProfileManager.GetPrimaryPad(); return GetGameSettings(iPad,eVal); } unsigned char CMinecraftApp::GetGameSettings(int iPad,eGameSetting eVal) { switch(eVal) { case eGameSetting_MusicVolume: return GameSettingsA[iPad]->ucMusicVolume; break; case eGameSetting_SoundFXVolume: return GameSettingsA[iPad]->ucSoundFXVolume; break; case eGameSetting_Gamma: return GameSettingsA[iPad]->ucGamma; break; case eGameSetting_FOV: return GameSettingsA[iPad]->ucFov; break; case eGameSetting_Difficulty: return GameSettingsA[iPad]->usBitmaskValues&0x0003; break; case eGameSetting_Sensitivity_InGame: return GameSettingsA[iPad]->ucSensitivity; break; case eGameSetting_ViewBob: return ((GameSettingsA[iPad]->usBitmaskValues&0x0004)>>2); break; case eGameSetting_GamertagsVisible: return ((GameSettingsA[iPad]->usBitmaskValues&0x0008)>>3); break; case eGameSetting_ControlScheme: return ((GameSettingsA[iPad]->usBitmaskValues&0x0030)>>4); // 2 bits break; case eGameSetting_ControlInvertLook: return ((GameSettingsA[iPad]->usBitmaskValues&0x0040)>>6); break; case eGameSetting_ControlSouthPaw: return ((GameSettingsA[iPad]->usBitmaskValues&0x0080)>>7); break; case eGameSetting_SplitScreenVertical: return ((GameSettingsA[iPad]->usBitmaskValues&0x0100)>>8); break; // 4J-PB - Added for Interim TU for 1.6.6 case eGameSetting_Sensitivity_InMenu: return GameSettingsA[iPad]->ucMenuSensitivity; break; case eGameSetting_DisplaySplitscreenGamertags: return ((GameSettingsA[iPad]->usBitmaskValues&0x0200)>>9); break; case eGameSetting_Hints: return ((GameSettingsA[iPad]->usBitmaskValues&0x0400)>>10); break; case eGameSetting_Autosave: { unsigned char ucVal=(GameSettingsA[iPad]->usBitmaskValues&0x7800)>>11; return ucVal; } break; case eGameSetting_Tooltips: return ((GameSettingsA[iPad]->usBitmaskValues&0x8000)>>15); break; case eGameSetting_InterfaceOpacity: return GameSettingsA[iPad]->ucInterfaceOpacity; break; case eGameSetting_Clouds: return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CLOUDS); break; case eGameSetting_Online: return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ONLINE)>>1; break; case eGameSetting_InviteOnly: return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_INVITEONLY)>>2; break; case eGameSetting_FriendsOfFriends: return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_FRIENDSOFFRIENDS)>>3; break; case eGameSetting_DisplayUpdateMessage: return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYUPDATEMSG)>>4; break; case eGameSetting_BedrockFog: return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_BEDROCKFOG)>>6; break; case eGameSetting_DisplayHUD: return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHUD)>>7; break; case eGameSetting_DisplayHand: return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHAND)>>8; break; case eGameSetting_CustomSkinAnim: return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CUSTOMSKINANIM)>>9; break; // TU9 case eGameSetting_DeathMessages: return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DEATHMESSAGES)>>10; break; case eGameSetting_UISize: { unsigned char ucVal=(GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE)>>11; return ucVal; } break; case eGameSetting_UISizeSplitscreen: { unsigned char ucVal=(GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE_SPLITSCREEN)>>13; return ucVal; } break; case eGameSetting_AnimatedCharacter: return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ANIMATEDCHARACTER)>>15; case eGameSetting_PS3_EULA_Read: return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PS3EULAREAD)>>16; case eGameSetting_PSVita_NetworkModeAdhoc: return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PSVITANETWORKMODEADHOC)>>17; } return 0; } void CMinecraftApp::CheckGameSettingsChanged(bool bOverride5MinuteTimer, int iPad) { // If the settings have changed, write them to the profile if(iPad==XUSER_INDEX_ANY) { for(int i=0;ibSettingsChanged) { #if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ ) StorageManager.WriteToProfile(i,true, bOverride5MinuteTimer); #else ProfileManager.WriteToProfile(i,true, bOverride5MinuteTimer); #ifdef _WINDOWS64 Win64_SaveSettings(GameSettingsA[i]); #endif #endif GameSettingsA[i]->bSettingsChanged=false; } } } else { if(GameSettingsA[iPad]->bSettingsChanged) { #if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) StorageManager.WriteToProfile(iPad,true, bOverride5MinuteTimer); #else ProfileManager.WriteToProfile(iPad,true, bOverride5MinuteTimer); #ifdef _WINDOWS64 Win64_SaveSettings(GameSettingsA[iPad]); #endif #endif GameSettingsA[iPad]->bSettingsChanged=false; } } } void CMinecraftApp::ClearGameSettingsChangedFlag(int iPad) { GameSettingsA[iPad]->bSettingsChanged=false; } /////////////////////////// // // Remove the debug settings in the release build // //////////////////////////// #ifndef _DEBUG unsigned int CMinecraftApp::GetGameSettingsDebugMask(int iPad,bool bOverridePlayer) //bOverridePlayer is to force the send for the server to get the read options { return 0; } void CMinecraftApp::SetGameSettingsDebugMask(int iPad, unsigned int uiVal) { } void CMinecraftApp::ActionDebugMask(int iPad,bool bSetAllClear) { } #else unsigned int CMinecraftApp::GetGameSettingsDebugMask(int iPad,bool bOverridePlayer) //bOverridePlayer is to force the send for the server to get the read options { if(iPad==-1) { iPad=ProfileManager.GetPrimaryPad(); } if(iPad < 0) iPad = 0; shared_ptr player = Minecraft::GetInstance()->localplayers[iPad]; if(bOverridePlayer || player==NULL) { return GameSettingsA[iPad]->uiDebugBitmask; } else { return player->GetDebugOptions(); } } void CMinecraftApp::SetGameSettingsDebugMask(int iPad, unsigned int uiVal) { #ifndef _CONTENT_PACKAGE GameSettingsA[iPad]->bSettingsChanged=true; GameSettingsA[iPad]->uiDebugBitmask=uiVal; // update the value so the network server can use it shared_ptr player = Minecraft::GetInstance()->localplayers[iPad]; if(player) { Minecraft::GetInstance()->localgameModes[iPad]->handleDebugOptions(uiVal,player); } #endif } void CMinecraftApp::ActionDebugMask(int iPad,bool bSetAllClear) { unsigned int ulBitmask=app.GetGameSettingsDebugMask(iPad); if(bSetAllClear) ulBitmask=0L; // these settings should only be actioned for the primary player if(ProfileManager.GetPrimaryPad()!=iPad) return; for(int i=0;iiPad, actionInfo->action); } void CMinecraftApp::HandleXuiActions(void) { eXuiAction eAction; eTMSAction eTMS; LPVOID param; Minecraft *pMinecraft=Minecraft::GetInstance(); shared_ptr player; // are there any global actions to deal with? eAction = app.GetGlobalXuiAction(); if(eAction!=eAppAction_Idle) { switch(eAction) { case eAppAction_DisplayLavaMessage: // Display a warning about placing lava in the spawn area { UINT uiIDA[1]; uiIDA[0]=IDS_CONFIRM_OK; C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_CANT_PLACE_NEAR_SPAWN_TITLE, IDS_CANT_PLACE_NEAR_SPAWN_TEXT, uiIDA,1,XUSER_INDEX_ANY); if(result != C4JStorage::EMessage_Busy) SetGlobalXuiAction(eAppAction_Idle); } break; default: break; } } // are there any app actions to deal with? for(int i=0;iIsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() ) { // disable character name tags for the shot //m_bwasHidingGui = pMinecraft->options->hideGui; // 4J Stu - Removed 1.8.2 bug fix (TU6) as don't need this pMinecraft->options->hideGui = true; SetAction(i,eAppAction_SocialPostScreenshot); } else { SetAction(i,eAppAction_Idle); } } else { SetAction(i,eAppAction_Idle); } break; case eAppAction_SocialPostScreenshot: { SetAction(i,eAppAction_Idle); bool bKeepHiding = false; for(int j=0; j < XUSER_MAX_COUNT;++j) { if(app.GetXuiAction(j) == eAppAction_SocialPostScreenshot) { bKeepHiding = true; break; } } pMinecraft->options->hideGui=bKeepHiding; // Facebook Share if(app.GetLocalPlayerCount()>1) { ui.NavigateToScene(i,eUIScene_SocialPost); } else { ui.NavigateToScene(i,eUIScene_SocialPost); } } break; case eAppAction_SaveGame: SetAction(i,eAppAction_Idle); if(!GetChangingSessionType()) { // If this is the trial game, do an upsell if(ProfileManager.IsFullVersion()) { // flag the render to capture the screenshot for the save SetAction(i,eAppAction_SaveGameCapturedThumbnail); } else { // ask the player if they would like to upgrade, or they'll lose the level UINT uiIDA[2]; uiIDA[0]=IDS_CONFIRM_OK; uiIDA[1]=IDS_CONFIRM_CANCEL; ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_TOSAVE_TEXT, uiIDA, 2,i,&CMinecraftApp::UnlockFullSaveReturned,this); } } break; case eAppAction_AutosaveSaveGame: { // Need to run a check to see if the save exists in order to stop the dialog asking if we want to overwrite it coming up on an autosave bool bSaveExists; StorageManager.DoesSaveExist(&bSaveExists); SetAction(i,eAppAction_Idle); if(!GetChangingSessionType()) { // flag the render to capture the screenshot for the save SetAction(i,eAppAction_AutosaveSaveGameCapturedThumbnail); } } break; case eAppAction_SaveGameCapturedThumbnail: // reset the autosave timer app.SetAutosaveTimerTime(); SetAction(i,eAppAction_Idle); // Check that there is a name for the save - if we're saving from the tutorial and this is the first save from the tutorial, we'll not have a name /*if(StorageManager.GetSaveName()==NULL) { app.NavigateToScene(i,eUIScene_SaveWorld); } else*/ { // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen ui.HideAllGameUIElements(); // Hide the other players scenes ui.ShowOtherPlayersBaseScene(ProfileManager.GetPrimaryPad(), false); //INT saveOrCheckpointId = 0; //bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId); //SentientManager.RecordLevelSaveOrCheckpoint(ProfileManager.GetPrimaryPad(), saveOrCheckpointId); LoadingInputParams *loadingParams = new LoadingInputParams(); loadingParams->func = &UIScene_PauseMenu::SaveWorldThreadProc; loadingParams->lpParam = (LPVOID)false; // 4J-JEV - PS4: Fix for #5708 - [ONLINE] - If the user pulls their network cable out while saving the title will hang. loadingParams->waitForThreadToDelete = true; UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); completionData->bShowBackground=TRUE; completionData->bShowLogo=TRUE; completionData->type = e_ProgressCompletion_NavigateBackToScene; completionData->iPad = ProfileManager.GetPrimaryPad(); if( ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) { completionData->scene = eUIScene_EndPoem; } else { completionData->scene = eUIScene_PauseMenu; } loadingParams->completionData = completionData; // 4J Stu - Xbox only #ifdef _XBOX // Temporarily make this scene fullscreen CXuiSceneBase::SetPlayerBaseScenePosition( ProfileManager.GetPrimaryPad(), CXuiSceneBase::e_BaseScene_Fullscreen ); #endif ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams , eUILayer_Fullscreen, eUIGroup_Fullscreen); } break; case eAppAction_AutosaveSaveGameCapturedThumbnail: { app.SetAutosaveTimerTime(); SetAction(i,eAppAction_Idle); #if defined(_XBOX_ONE) || defined(__ORBIS__) app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_AutoSaveGame); if(app.GetGameHostOption(eGameHostOption_DisableSaving)) StorageManager.SetSaveDisabled(true); #else // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen ui.HideAllGameUIElements(); //app.CloseAllPlayersXuiScenes(); // Hide the other players scenes ui.ShowOtherPlayersBaseScene(ProfileManager.GetPrimaryPad(), false); // This just allows it to be shown if(pMinecraft->localgameModes[ProfileManager.GetPrimaryPad()] != NULL) pMinecraft->localgameModes[ProfileManager.GetPrimaryPad()]->getTutorial()->showTutorialPopup(false); //INT saveOrCheckpointId = 0; //bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId); //SentientManager.RecordLevelSaveOrCheckpoint(ProfileManager.GetPrimaryPad(), saveOrCheckpointId); LoadingInputParams *loadingParams = new LoadingInputParams(); loadingParams->func = &UIScene_PauseMenu::SaveWorldThreadProc; loadingParams->lpParam = (LPVOID)true; UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); completionData->bShowBackground=TRUE; completionData->bShowLogo=TRUE; completionData->type = e_ProgressCompletion_AutosaveNavigateBack; completionData->iPad = ProfileManager.GetPrimaryPad(); //completionData->bAutosaveWasMenuDisplayed=ui.GetMenuDisplayed(ProfileManager.GetPrimaryPad()); loadingParams->completionData = completionData; // 4J Stu - Xbox only #ifdef _XBOX // Temporarily make this scene fullscreen CXuiSceneBase::SetPlayerBaseScenePosition( ProfileManager.GetPrimaryPad(), CXuiSceneBase::e_BaseScene_Fullscreen ); #endif ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams , eUILayer_Fullscreen, eUIGroup_Fullscreen); #endif } break; case eAppAction_ExitPlayer: // a secondary player has chosen to quit { int iPlayerC=g_NetworkManager.GetPlayerCount(); // Since the player is exiting, let's flush any profile writes for them, and hope we're not breaking TCR 136... #if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) StorageManager.ForceQueuedProfileWrites(i); LeaderboardManager::Instance()->OpenSession(); for (int j = 0; j < XUSER_MAX_COUNT; j++) { if( ProfileManager.IsSignedIn(j) ) { app.DebugPrintf("Stats save for an offline game for the player at index %d\n", 0); Minecraft::GetInstance()->forceStatsSave(j); } } LeaderboardManager::Instance()->CloseSession(); #else ProfileManager.ForceQueuedProfileWrites(i); #endif // not required - it's done within the removeLocalPlayerIdx // if(pMinecraft->level->isClientSide) // { // // we need to remove the qnetplayer, or this player won't be able to get back into the game until qnet times out and removes them // g_NetworkManager.NotifyPlayerLeaving(g_NetworkManager.GetLocalPlayerByUserIndex(i)); // } // if there are any tips showing, we need to close them pMinecraft->gui->clearMessages(i); // Make sure we've not got this player selected as current - this shouldn't be the case anyway pMinecraft->setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); pMinecraft->removeLocalPlayerIdx(i); #ifdef _XBOX // tell the xui scenes a splitscreen player left - has to come after removeLocalPlayerIdx which calls updatePlayerViewportAssignments XUIMessage xuiMsg; CustomMessage_Splitscreenplayer_Struct myMsgData; CustomMessage_Splitscreenplayer( &xuiMsg, &myMsgData, false); // send the message for(int idx=0;idxlocalplayers[idx]!=NULL)) { XuiBroadcastMessage( CXuiSceneBase::GetPlayerBaseScene(idx), &xuiMsg ); } } #endif #ifndef _XBOX // Wipe out the tooltips ui.SetTooltips(i, -1); #endif // Change the presence info // Are we offline or online, and how many players are there if(iPlayerC>2) // one player is about to leave here - they'll be set to idle in the qnet manager player leave { for(int iPlayer=0;iPlayerlocalplayers[iPlayer]) { if(g_NetworkManager.IsLocalGame()) { ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); } else { ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER,false); } } } } else { for(int iPlayer=0;iPlayerlocalplayers[iPlayer]) { if(g_NetworkManager.IsLocalGame()) { ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); } else { ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); } } } } #ifdef _DURANGO ProfileManager.RemoveGamepadFromGame(i); #endif SetAction(i,eAppAction_Idle); } break; case eAppAction_ExitPlayerPreLogin: { int iPlayerC=g_NetworkManager.GetPlayerCount(); // Since the player is exiting, let's flush any profile writes for them, and hope we're not breaking TCR 136... #if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) StorageManager.ForceQueuedProfileWrites(i); #else ProfileManager.ForceQueuedProfileWrites(i); #endif // if there are any tips showing, we need to close them pMinecraft->gui->clearMessages(i); // Make sure we've not got this player selected as current - this shouldn't be the case anyway pMinecraft->setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); pMinecraft->removeLocalPlayerIdx(i); #ifdef _XBOX // tell the xui scenes a splitscreen player left - has to come after removeLocalPlayerIdx which calls updatePlayerViewportAssignments XUIMessage xuiMsg; CustomMessage_Splitscreenplayer_Struct myMsgData; CustomMessage_Splitscreenplayer( &xuiMsg, &myMsgData, false); // send the message for(int idx=0;idxlocalplayers[idx]!=NULL)) { XuiBroadcastMessage( CXuiSceneBase::GetPlayerBaseScene(idx), &xuiMsg ); } } #endif #ifndef _XBOX // Wipe out the tooltips ui.SetTooltips(i, -1); #endif // Change the presence info // Are we offline or online, and how many players are there if(iPlayerC>2) // one player is about to leave here - they'll be set to idle in the qnet manager player leave { for(int iPlayer=0;iPlayerlocalplayers[iPlayer]) { if(g_NetworkManager.IsLocalGame()) { ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); } else { ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER,false); } } } } else { for(int iPlayer=0;iPlayerlocalplayers[iPlayer]) { if(g_NetworkManager.IsLocalGame()) { ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); } else { ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); } } } } SetAction(i,eAppAction_Idle); } break; #ifdef __ORBIS__ case eAppAction_OptionsSaveNoSpace: { SetAction(i,eAppAction_Idle); SceSaveDataDialogParam param; SceSaveDataDialogSystemMessageParam sysParam; SceSaveDataDialogItems items; SceSaveDataDirName dirName; sceSaveDataDialogParamInitialize(¶m); param.mode = SCE_SAVE_DATA_DIALOG_MODE_SYSTEM_MSG; param.dispType = SCE_SAVE_DATA_DIALOG_TYPE_SAVE; memset(&sysParam,0,sizeof(sysParam)); param.sysMsgParam = &sysParam; param.sysMsgParam->sysMsgType = SCE_SAVE_DATA_DIALOG_SYSMSG_TYPE_NOSPACE_CONTINUABLE; param.sysMsgParam->value = app.GetOptionsBlocksRequired(i); memset(&items, 0, sizeof(items)); param.items = &items; param.items->userId = ProfileManager.getUserID(i); int ret = sceSaveDataDialogInitialize(); ret = sceSaveDataDialogOpen(¶m); app.SetOptionsSaveDataDialogRunning(true);//m_bOptionsSaveDataDialogRunning = true; //pClass->m_eSaveIncompleteType = saveIncompleteType; //StorageManager.SetSaveDisabled(true); //pClass->EnterSaveNotificationSection(); } break; #endif case eAppAction_ExitWorld: SetAction(i,eAppAction_Idle); // If we're already leaving don't exit if (g_NetworkManager.IsLeavingGame()) { break; } pMinecraft->gui->clearMessages(); // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen ui.HideAllGameUIElements(); // reset the flag stopping new dlc message being shown if you've seen the message before DisplayNewDLCTipAgain(); // clear the autosave timer that might be on screen ui.ShowAutosaveCountdownTimer(false); // Hide the selected item text ui.HideAllGameUIElements(); // Since the player forced the exit, let's flush any profile writes, and hope we're not breaking TCR 136... #if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) StorageManager.ForceQueuedProfileWrites(); LeaderboardManager::Instance()->OpenSession(); for (int j = 0; j < XUSER_MAX_COUNT; j++) { if( ProfileManager.IsSignedIn(j) ) { app.DebugPrintf("Stats save for an offline game for the player at index %d\n", 0); Minecraft::GetInstance()->forceStatsSave(j); } } LeaderboardManager::Instance()->CloseSession(); #elif (defined _XBOX) ProfileManager.ForceQueuedProfileWrites(); #endif // 4J-PB - cancel any possible string verifications queued with LIVE //InputManager.CancelAllVerifyInProgress(); if(ProfileManager.IsFullVersion()) { // In a split screen, only the primary player actually quits the game, others just remove their players if( i != ProfileManager.GetPrimaryPad() ) { // Make sure we've not got this player selected as current - this shouldn't be the case anyway pMinecraft->setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); pMinecraft->removeLocalPlayerIdx(i); #ifdef _DURANGO ProfileManager.RemoveGamepadFromGame(i); #endif SetAction(i,eAppAction_Idle); return; } // flag to capture the save thumbnail SetAction(i,eAppAction_ExitWorldCapturedThumbnail, param); } else { // ask the player if they would like to upgrade, or they'll lose the level UINT uiIDA[2]; uiIDA[0]=IDS_CONFIRM_OK; uiIDA[1]=IDS_CONFIRM_CANCEL; ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_TOSAVE_TEXT, uiIDA, 2, i,&CMinecraftApp::UnlockFullExitReturned,this); } // Change the presence info // Are we offline or online, and how many players are there if(g_NetworkManager.GetPlayerCount()>1) { for(int j=0;jlocalplayers[j]) { if(g_NetworkManager.IsLocalGame()) { app.SetRichPresenceContext(j,CONTEXT_GAME_STATE_BLANK); ProfileManager.SetCurrentGameActivity(j,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); } else { app.SetRichPresenceContext(j,CONTEXT_GAME_STATE_BLANK); ProfileManager.SetCurrentGameActivity(j,CONTEXT_PRESENCE_MULTIPLAYER,false); } TelemetryManager->RecordLevelExit(j, eSen_LevelExitStatus_Exited); } } } else { app.SetRichPresenceContext(i,CONTEXT_GAME_STATE_BLANK); if(g_NetworkManager.IsLocalGame()) { ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); } else { ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); } TelemetryManager->RecordLevelExit(i, eSen_LevelExitStatus_Exited); } break; case eAppAction_ExitWorldCapturedThumbnail: { SetAction(i,eAppAction_Idle); // Stop app running SetGameStarted(false); SetChangingSessionType(true); // Added to stop handling ethernet disconnects ui.CloseAllPlayersScenes(); // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen ui.HideAllGameUIElements(); // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) { #ifdef _XBOX app.TutorialSceneNavigateBack(idx,true); #endif // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial // It doesn't matter if they were in the tutorial already pMinecraft->playerLeftTutorial( idx ); } LoadingInputParams *loadingParams = new LoadingInputParams(); loadingParams->func = &UIScene_PauseMenu::ExitWorldThreadProc; loadingParams->lpParam = param; UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); // If param is non-null then this is a forced exit by the server, so make sure the player knows why // 4J Stu - Changed - Don't use the FullScreenProgressScreen for action, use a dialog instead completionData->bRequiresUserAction = FALSE;//(param != NULL) ? TRUE : FALSE; completionData->bShowTips = (param != NULL) ? FALSE : TRUE; completionData->bShowBackground=TRUE; completionData->bShowLogo=TRUE; completionData->type = e_ProgressCompletion_NavigateToHomeMenu; completionData->iPad = DEFAULT_XUI_MENU_USER; loadingParams->completionData = completionData; ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); } break; case eAppAction_ExitWorldTrial: { SetAction(i,eAppAction_Idle); pMinecraft->gui->clearMessages(); // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen ui.HideAllGameUIElements(); // Stop app running SetGameStarted(false); ui.CloseAllPlayersScenes(); // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) { #ifdef _XBOX app.TutorialSceneNavigateBack(idx,true); #endif // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial // It doesn't matter if they were in the tutorial already pMinecraft->playerLeftTutorial( idx ); } LoadingInputParams *loadingParams = new LoadingInputParams(); loadingParams->func = &UIScene_PauseMenu::ExitWorldThreadProc; loadingParams->lpParam = param; UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); completionData->bShowBackground=TRUE; completionData->bShowLogo=TRUE; completionData->type = e_ProgressCompletion_NavigateToHomeMenu; completionData->iPad = DEFAULT_XUI_MENU_USER; loadingParams->completionData = completionData; ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); } break; case eAppAction_ExitTrial: //XLaunchNewImage(XLAUNCH_KEYWORD_DASH_ARCADE, 0); ExitGame(); break; case eAppAction_Respawn: { ConnectionProgressParams *param = new ConnectionProgressParams(); param->iPad = i; param->stringId = IDS_PROGRESS_RESPAWNING; param->showTooltips = false; param->setFailTimer = false; ui.NavigateToScene(i,eUIScene_ConnectingProgress, param); // Need to reset this incase the player has already died and respawned pMinecraft->localplayers[i]->SetPlayerRespawned(false); SetAction(i,eAppAction_WaitForRespawnComplete); if( app.GetLocalPlayerCount()>1 ) { // In split screen mode, we don't want to do any async loading or flushing of the cache, just a simple respawn pMinecraft->localplayers[i]->respawn(); // If the respawn requires a dimension change then the action will have changed //if(app.GetXuiAction(i) == eAppAction_Respawn) //{ // SetAction(i,eAppAction_Idle); // CloseXuiScenes(i); //} } else { //SetAction(i,eAppAction_WaitForRespawnComplete); //LoadingInputParams *loadingParams = new LoadingInputParams(); //loadingParams->func = &CScene_Death::RespawnThreadProc; //loadingParams->lpParam = (LPVOID)i; // Disable game & update thread whilst we do any of this //app.SetGameStarted(false); pMinecraft->gameRenderer->DisableUpdateThread(); // 4J Stu - We don't need this on a thread in multiplayer as respawning is asynchronous. pMinecraft->localplayers[i]->respawn(); //app.SetGameStarted(true); pMinecraft->gameRenderer->EnableUpdateThread(); //UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); //completionData->bShowBackground=TRUE; //completionData->bShowLogo=TRUE; //completionData->type = e_ProgressCompletion_CloseUIScenes; //completionData->iPad = i; //loadingParams->completionData = completionData; //app.NavigateToScene(i,eUIScene_FullscreenProgress, loadingParams, true); } } break; case eAppAction_WaitForRespawnComplete: player = pMinecraft->localplayers[i]; if(player != NULL && player->GetPlayerRespawned()) { SetAction(i,eAppAction_Idle); if(ui.IsSceneInStack(i, eUIScene_EndPoem)) { ui.NavigateBack(i,false,eUIScene_EndPoem); } else { ui.CloseUIScenes(i); } // clear the progress messages // pMinecraft->progressRenderer->progressStart(-1); // pMinecraft->progressRenderer->progressStage(-1); } else if(!g_NetworkManager.IsInGameplay()) { SetAction(i,eAppAction_Idle); } break; case eAppAction_WaitForDimensionChangeComplete: player = pMinecraft->localplayers[i]; if(player != NULL && player->connection && player->connection->isStarted()) { SetAction(i,eAppAction_Idle); ui.CloseUIScenes(i); } else if(!g_NetworkManager.IsInGameplay()) { SetAction(i,eAppAction_Idle); } break; case eAppAction_PrimaryPlayerSignedOut: { //SetAction(i,eAppAction_Idle); // clear the autosavetimer that might be displayed ui.ShowAutosaveCountdownTimer(false); // If the player signs out before the game started the server can be killed a bit earlier to stop // the loading or saving of a new game continuing running while the UI/Guide is up if(!app.GetGameStarted()) MinecraftServer::HaltServer(true); // inform the player they are being returned to the menus because they signed out StorageManager.SetSaveDeviceSelected(i,false); // need to clear the player stats - can't assume it'll be done in setlevel - we may not be in the game StatsCounter* pStats = Minecraft::GetInstance()->stats[ i ]; pStats->clear(); // 4J-PB - the libs will display the Returned to Title screen // UINT uiIDA[1]; // uiIDA[0]=IDS_CONFIRM_OK; // // ui.RequestMessageBox(IDS_RETURNEDTOMENU_TITLE, IDS_RETURNEDTOTITLESCREEN_TEXT, uiIDA, 1, i,&CMinecraftApp::PrimaryPlayerSignedOutReturned,this,app.GetStringTable()); if( g_NetworkManager.IsInSession() ) { app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned); } else { app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned_Menus); MinecraftServer::resetFlags(); } } break; case eAppAction_EthernetDisconnected: { app.DebugPrintf("Handling eAppAction_EthernetDisconnected\n"); SetAction(i,eAppAction_Idle); // 4J Stu - Fix for #12530 -TCR 001 BAS Game Stability: Title will crash if the player disconnects while starting a new world and then opts to play the tutorial once they have been returned to the Main Menu. if(!g_NetworkManager.IsLeavingGame()) { app.DebugPrintf("Handling eAppAction_EthernetDisconnected - Not leaving game\n"); // 4J-PB - not the same as a signout. We should only leave the game if this machine is not the host. We shouldn't get rid of the save device either. if( g_NetworkManager.IsHost() ) { app.DebugPrintf("Handling eAppAction_EthernetDisconnected - Is Host\n"); // If it's already a local game, then an ethernet disconnect should have no effect if( !g_NetworkManager.IsLocalGame() && g_NetworkManager.IsInGameplay() ) { // Change the session to an offline session SetAction(i,eAppAction_ChangeSessionType); } else if(!g_NetworkManager.IsLocalGame() && !g_NetworkManager.IsInGameplay() ) { // There are two cases here, either: // 1. We're early enough in the create/load game that we can do a really minimal shutdown or // 2. We're far enough in (game has started but the actual game started flag hasn't been set) that we should just wait until we're in the game and switch to offline mode // If there's a non-null level then, for our purposes, the game has started bool gameStarted = false; for(int j = 0; j < pMinecraft->levels.length; j++) { if (pMinecraft->levels.data[i] != nullptr) { gameStarted = true; break; } } if (!gameStarted) { // 1. Exit MinecraftServer::HaltServer(); // Fix for #12530 - TCR 001 BAS Game Stability: Title will crash if the player disconnects while starting a new world and then opts to play the tutorial once they have been returned to the Main Menu. // 4J Stu - Leave the session g_NetworkManager.LeaveGame(FALSE); // need to clear the player stats - can't assume it'll be done in setlevel - we may not be in the game StatsCounter* pStats = Minecraft::GetInstance()->stats[ i ]; pStats->clear(); UINT uiIDA[1]; uiIDA[0]=IDS_CONFIRM_OK; ui.RequestErrorMessage(g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST), g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST_LIVE), uiIDA, 1, i,&CMinecraftApp::EthernetDisconnectReturned,this); } else { // 2. Switch to offline SetAction(i,eAppAction_ChangeSessionType); } } } else { #if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ if(UIScene_LoadOrJoinMenu::isSaveTransferRunning()) { // the save transfer is still in progress, delay jumping back to the main menu until we've cleaned up SetAction(i,eAppAction_EthernetDisconnected); } else #endif { app.DebugPrintf("Handling eAppAction_EthernetDisconnected - Not host\n"); // need to clear the player stats - can't assume it'll be done in setlevel - we may not be in the game StatsCounter* pStats = Minecraft::GetInstance()->stats[ i ]; pStats->clear(); UINT uiIDA[1]; uiIDA[0]=IDS_CONFIRM_OK; ui.RequestErrorMessage(g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST), g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST_LIVE), uiIDA, 1, i,&CMinecraftApp::EthernetDisconnectReturned,this); } } } } break; // We currently handle both these returns the same way. case eAppAction_EthernetDisconnectedReturned: case eAppAction_PrimaryPlayerSignedOutReturned: { SetAction(i,eAppAction_Idle); pMinecraft->gui->clearMessages(); // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen ui.HideAllGameUIElements(); // set the state back to pre-game ProfileManager.ResetProfileProcessState(); if( g_NetworkManager.IsLeavingGame() ) { // 4J Stu - If we are already leaving the game, then we just need to signal that the player signed out to stop saves pMinecraft->progressRenderer->progressStartNoAbort( IDS_EXITING_GAME ); pMinecraft->progressRenderer->progressStage(-1); // This has no effect on client machines MinecraftServer::HaltServer(true); } else { // Stop app running SetGameStarted(false); // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen ui.HideAllGameUIElements(); ui.CloseAllPlayersScenes(); // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) { #ifdef _XBOX app.TutorialSceneNavigateBack(idx,true); #endif // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial // It doesn't matter if they were in the tutorial already pMinecraft->playerLeftTutorial( idx ); } LoadingInputParams *loadingParams = new LoadingInputParams(); loadingParams->func = &CMinecraftApp::SignoutExitWorldThreadProc; UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); completionData->bShowBackground=TRUE; completionData->bShowLogo=TRUE; completionData->iPad=DEFAULT_XUI_MENU_USER; completionData->type = e_ProgressCompletion_NavigateToHomeMenu; loadingParams->completionData = completionData; ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); } } break; case eAppAction_PrimaryPlayerSignedOutReturned_Menus: SetAction(i,eAppAction_Idle); // set the state back to pre-game ProfileManager.ResetProfileProcessState(); // clear the save device StorageManager.SetSaveDeviceSelected(i,false); ui.UpdatePlayerBasePositions(); // there are multiple layers in the help menu, so a navigate back isn't enough ui.NavigateToHomeMenu(); break; case eAppAction_EthernetDisconnectedReturned_Menus: SetAction(i,eAppAction_Idle); // set the state back to pre-game ProfileManager.ResetProfileProcessState(); ui.UpdatePlayerBasePositions(); // there are multiple layers in the help menu, so a navigate back isn't enough ui.NavigateToHomeMenu(); break; case eAppAction_TrialOver: { SetAction(i,eAppAction_Idle); UINT uiIDA[2]; uiIDA[0]=IDS_UNLOCK_TITLE; uiIDA[1]=IDS_EXIT_GAME; ui.RequestErrorMessage(IDS_TRIALOVER_TITLE, IDS_TRIALOVER_TEXT, uiIDA, 2, i,&CMinecraftApp::TrialOverReturned,this); } break; // INVITES case eAppAction_DashboardTrialJoinFromInvite: { TelemetryManager->RecordUpsellPresented(i, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID); SetAction(i,eAppAction_Idle); UINT uiIDA[2]; uiIDA[0]=IDS_CONFIRM_OK; uiIDA[1]=IDS_CONFIRM_CANCEL; ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_ACCEPT_INVITE, uiIDA, 2, i,&CMinecraftApp::UnlockFullInviteReturned,this); } break; case eAppAction_ExitAndJoinFromInvite: { UINT uiIDA[3]; SetAction(i,eAppAction_Idle); // Check the player really wants to do this #if defined(_XBOX_ONE) || defined(__ORBIS__) // Show save option is saves ARE disabled if(ProfileManager.IsFullVersion() && StorageManager.GetSaveDisabled() && i==ProfileManager.GetPrimaryPad() && g_NetworkManager.IsHost() && GetGameStarted() ) { uiIDA[0]=IDS_CONFIRM_CANCEL; uiIDA[1]=IDS_EXIT_GAME_SAVE; uiIDA[2]=IDS_EXIT_GAME_NO_SAVE; ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_LEAVE_VIA_INVITE, uiIDA, 3, i,&CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned,this); } else #else if(ProfileManager.IsFullVersion() && !StorageManager.GetSaveDisabled() && i==ProfileManager.GetPrimaryPad() && g_NetworkManager.IsHost() && GetGameStarted() ) { uiIDA[0]=IDS_CONFIRM_CANCEL; uiIDA[1]=IDS_EXIT_GAME_SAVE; uiIDA[2]=IDS_EXIT_GAME_NO_SAVE; ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_LEAVE_VIA_INVITE, uiIDA, 3, i,&CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned,this); } else #endif { if(!ProfileManager.IsFullVersion()) { TelemetryManager->RecordUpsellPresented(i, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID); // upsell uiIDA[0]=IDS_CONFIRM_OK; uiIDA[1]=IDS_CONFIRM_CANCEL; ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_ACCEPT_INVITE, uiIDA, 2, i,&CMinecraftApp::UnlockFullInviteReturned,this); } else { uiIDA[0]=IDS_CONFIRM_CANCEL; uiIDA[1]=IDS_CONFIRM_OK; ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_LEAVE_VIA_INVITE, uiIDA, 2,i,&CMinecraftApp::ExitAndJoinFromInvite,this); } } } break; case eAppAction_ExitAndJoinFromInviteConfirmed: { SetAction(i,eAppAction_Idle); pMinecraft->gui->clearMessages(); // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen ui.HideAllGameUIElements(); // Stop app running SetGameStarted(false); ui.CloseAllPlayersScenes(); // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) { #ifdef _XBOX app.TutorialSceneNavigateBack(idx,true); #endif // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial // It doesn't matter if they were in the tutorial already pMinecraft->playerLeftTutorial( idx ); } // 4J-PB - may have been using a texture pack with audio , so clean up anything texture pack related here // unload any texture pack audio // if there is audio in use, clear out the audio, and unmount the pack TexturePack *pTexPack=Minecraft::GetInstance()->skins->getSelected(); DLCTexturePack *pDLCTexPack=NULL; if(pTexPack->hasAudio()) { // get the dlc texture pack, and store it pDLCTexPack=(DLCTexturePack *)pTexPack; } // change to the default texture pack pMinecraft->skins->selectTexturePackById(TexturePackRepository::DEFAULT_TEXTURE_PACK_ID); if(pTexPack->hasAudio()) { // need to stop the streaming audio - by playing streaming audio from the default texture pack now // reset the streaming sounds back to the normal ones #ifndef _XBOX pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, eStream_Nether1,eStream_Nether4, eStream_end_dragon,eStream_end_end, eStream_CD_1); #endif pMinecraft->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1); #ifdef _XBOX if(pDLCTexPack->m_pStreamedWaveBank!=NULL) { pDLCTexPack->m_pStreamedWaveBank->Destroy(); } if(pDLCTexPack->m_pSoundBank!=NULL) { pDLCTexPack->m_pSoundBank->Destroy(); } #endif #ifdef _DURANGO DWORD result = StorageManager.UnmountInstalledDLC(L"TPACK"); #else DWORD result = StorageManager.UnmountInstalledDLC("TPACK"); #endif app.DebugPrintf("Unmount result is %d\n",result); } #ifdef _XBOX_ONE // 4J Stu - It's possible that we can sign in/remove players between the mask initially being set and this point m_InviteData.dwLocalUsersMask = 0; for(unsigned int index = 0; index < XUSER_MAX_COUNT; ++index) { if(ProfileManager.IsSignedIn(index) ) { if(index==i || pMinecraft->localplayers[index]!=NULL ) { m_InviteData.dwLocalUsersMask |= g_NetworkManager.GetLocalPlayerMask( index ); } } } #endif LoadingInputParams *loadingParams = new LoadingInputParams(); loadingParams->func = &CGameNetworkManager::ExitAndJoinFromInviteThreadProc; loadingParams->lpParam = (LPVOID)&m_InviteData; UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); completionData->bShowBackground=TRUE; completionData->bShowLogo=TRUE; completionData->iPad=DEFAULT_XUI_MENU_USER; completionData->type = e_ProgressCompletion_NoAction; loadingParams->completionData = completionData; ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); } break; case eAppAction_JoinFromInvite: { SetAction(i,eAppAction_Idle); // 4J Stu - Move this state block from CPlatformNetworkManager::ExitAndJoinFromInviteThreadProc, as g_NetworkManager.JoinGameFromInviteInfo ultimately can call NavigateToScene, /// and we should only be calling that from the main thread app.SetTutorialMode( false ); g_NetworkManager.SetLocalGame(false); JoinFromInviteData *inviteData = (JoinFromInviteData *)param; // 4J-PB - clear any previous connection errors Minecraft::GetInstance()->clearConnectionFailed(); app.DebugPrintf( "Changing Primary Pad on an invite accept - pad was %d, and is now %d\n", ProfileManager.GetPrimaryPad(), inviteData->dwUserIndex ); ProfileManager.SetLockedProfile(inviteData->dwUserIndex); ProfileManager.SetPrimaryPad(inviteData->dwUserIndex); #ifdef _XBOX_ONE // 4J Stu - If a player is signed in (i.e. locked) but not in the mask, unlock them for(unsigned int index = 0; index < XUSER_MAX_COUNT; ++index) { if( index != inviteData->dwUserIndex && ProfileManager.IsSignedIn(index) ) { if( (m_InviteData.dwLocalUsersMask & g_NetworkManager.GetLocalPlayerMask( index ) ) == 0 ) { ProfileManager.RemoveGamepadFromGame(index); } } } #endif // change the minecraft player name Minecraft::GetInstance()->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); bool success = g_NetworkManager.JoinGameFromInviteInfo( inviteData->dwUserIndex, // dwUserIndex inviteData->dwLocalUsersMask, // dwUserMask inviteData->pInviteInfo ); // pInviteInfo if( !success ) { app.DebugPrintf( "Failed joining game from invite\n" ); //return hr; // 4J Stu - Copied this from XUI_FullScreenProgress to properly handle the fail case, as the thread will no longer be failing UINT uiIDA[1]; uiIDA[0]=IDS_CONFIRM_OK; ui.RequestErrorMessage( IDS_CONNECTION_FAILED, IDS_CONNECTION_LOST_SERVER, uiIDA,1,ProfileManager.GetPrimaryPad()); ui.NavigateToHomeMenu(); ui.UpdatePlayerBasePositions(); } } break; case eAppAction_ChangeSessionType: { // If we are not in gameplay yet, then wait until the server is setup before changing the session type if( g_NetworkManager.IsInGameplay() ) { // This kicks off a thread that waits for the server to end, then closes the current session, starts a new one and joins the local players into it SetAction(i,eAppAction_Idle); if( !GetChangingSessionType() && !g_NetworkManager.IsLocalGame() ) { SetGameStarted(false); SetChangingSessionType(true); SetReallyChangingSessionType(true); // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen ui.HideAllGameUIElements(); if( !ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) { ui.CloseAllPlayersScenes(); } ui.ShowOtherPlayersBaseScene(ProfileManager.GetPrimaryPad(), true); // Remove this line to fix: // #49084 - TU5: Code: Gameplay: The title crashes every time client navigates to 'Play game' menu and loads/creates new game after a "Connection to Xbox LIVE was lost" message has appeared. //app.NavigateToScene(0,eUIScene_Main); LoadingInputParams *loadingParams = new LoadingInputParams(); loadingParams->func = &CGameNetworkManager::ChangeSessionTypeThreadProc; loadingParams->lpParam = NULL; UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); #ifdef __PS3__ completionData->bRequiresUserAction=FALSE; #else completionData->bRequiresUserAction=TRUE; #endif completionData->bShowBackground=TRUE; completionData->bShowLogo=TRUE; completionData->iPad=DEFAULT_XUI_MENU_USER; if( ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) { completionData->type = e_ProgressCompletion_NavigateBackToScene; completionData->scene = eUIScene_EndPoem; } else { completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; } loadingParams->completionData = completionData; ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); } } else if( g_NetworkManager.IsLeavingGame() ) { // If we are leaving the game, then ignore the state change SetAction(i,eAppAction_Idle); } #if 0 // 4J-HG - Took this out since ChangeSessionType is only set in two places (both in EthernetDisconnected) and this case is handled there, plus this breaks // this if statements original purpose (to allow us to wait for IsInGameplay before actioning switching to offline // QNet must do this kind of thing automatically by itself, but on PS3 at least, we need the disconnection to definitely end up with us out of the game one way or another, // and the other two cases above don't catch the case where we are just starting the game and get a disconnection during the loading/creation else { if( g_NetworkManager.IsInSession() ) { g_NetworkManager._LeaveGame(); } } #endif } break; case eAppAction_SetDefaultOptions: SetAction(i,eAppAction_Idle); #if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) SetDefaultOptions((C4JStorage::PROFILESETTINGS *)param,i); #else SetDefaultOptions((C_4JProfile::PROFILESETTINGS *)param,i); #endif // if the profile data has been changed, then force a profile write // It seems we're allowed to break the 5 minute rule if it's the result of a user action CheckGameSettingsChanged(true,i); break; case eAppAction_RemoteServerSave: { // If the remote server save has already finished, don't complete the action if (GetGameStarted()) { SetAction(ProfileManager.GetPrimaryPad(), eAppAction_Idle); break; } SetAction(i,eAppAction_WaitRemoteServerSaveComplete); for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) { ui.CloseUIScenes(i, true); } // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen ui.HideAllGameUIElements(); LoadingInputParams *loadingParams = new LoadingInputParams(); loadingParams->func = &CMinecraftApp::RemoteSaveThreadProc; loadingParams->lpParam = NULL; UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); completionData->bRequiresUserAction=FALSE; completionData->bShowBackground=TRUE; completionData->bShowLogo=TRUE; completionData->iPad=DEFAULT_XUI_MENU_USER; if( ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) { completionData->type = e_ProgressCompletion_NavigateBackToScene; completionData->scene = eUIScene_EndPoem; } else { completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; } loadingParams->completionData = completionData; loadingParams->cancelFunc = &CMinecraftApp::ExitGameFromRemoteSave; loadingParams->cancelText = IDS_TOOLTIPS_EXIT; ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); } break; case eAppAction_WaitRemoteServerSaveComplete: // Do nothing break; case eAppAction_FailedToJoinNoPrivileges: { UINT uiIDA[1]; uiIDA[0]=IDS_CONFIRM_OK; C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_NO_MULTIPLAYER_PRIVILEGE_TITLE, IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT, uiIDA,1,ProfileManager.GetPrimaryPad()); if(result != C4JStorage::EMessage_Busy) SetAction(i,eAppAction_Idle); } break; case eAppAction_ProfileReadError: // Return player to the main menu - code largely copied from that for handling // eAppAction_PrimaryPlayerSignedOut, although I don't think we should have got as // far as needing to halt the server, or running the game, before returning to the menu if(!app.GetGameStarted()) MinecraftServer::HaltServer(true); if( g_NetworkManager.IsInSession() ) { app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned); } else { app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned_Menus); MinecraftServer::resetFlags(); } break; case eAppAction_BanLevel: { // It's possible that this state can get set after the game has been exited (e.g. by network disconnection) so we can't ban the level at that point if(g_NetworkManager.IsInGameplay() && !g_NetworkManager.IsLeavingGame()) { TelemetryManager->RecordBanLevel(i); #if defined _XBOX INetworkPlayer *pHost=g_NetworkManager.GetHostPlayer(); // write the level to the banned level list, and exit the world AddLevelToBannedLevelList(i,((NetworkPlayerXbox *)pHost)->GetUID(),GetUniqueMapName(),true); #elif defined _XBOX_ONE INetworkPlayer *pHost=g_NetworkManager.GetHostPlayer(); AddLevelToBannedLevelList(i,pHost->GetUID(),GetUniqueMapName(),true); #endif // primary player would exit the world, secondary would exit the player if(ProfileManager.GetPrimaryPad()==i) { SetAction(i,eAppAction_ExitWorld); } else { SetAction(i,eAppAction_ExitPlayer); } } } break; case eAppAction_LevelInBanLevelList: { UINT uiIDA[2]; uiIDA[0]=IDS_BUTTON_REMOVE_FROM_BAN_LIST; uiIDA[1]=IDS_EXIT_GAME; // pass in the gamertag format string WCHAR wchFormat[40]; INetworkPlayer *player = g_NetworkManager.GetLocalPlayerByUserIndex(i); // If not the primary player, but the primary player has banned this level and decided not to unban // then we may have left the game by now if(player) { swprintf(wchFormat, 40, L"%ls\n\n%%ls",player->GetOnlineName()); C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_BANNED_LEVEL_TITLE, IDS_PLAYER_BANNED_LEVEL, uiIDA,2,i,&CMinecraftApp::BannedLevelDialogReturned,this, wchFormat); if(result != C4JStorage::EMessage_Busy) SetAction(i,eAppAction_Idle); } else { SetAction(i,eAppAction_Idle); } } break; case eAppAction_DebugText: // launch the xui for text entry { #ifdef _XBOX CScene_TextEntry::XuiTextInputParams *pDebugTextParams= new CScene_TextEntry::XuiTextInputParams; pDebugTextParams->iPad=i; pDebugTextParams->wch=(WCHAR)param; app.NavigateToScene(i,eUIScene_TextEntry,pDebugTextParams); #endif SetAction(i,eAppAction_Idle); } break; case eAppAction_ReloadTexturePack: { SetAction(i,eAppAction_Idle); Minecraft *pMinecraft = Minecraft::GetInstance(); pMinecraft->textures->reloadAll(); pMinecraft->skins->updateUI(); if(!pMinecraft->skins->isUsingDefaultSkin()) { TexturePack *pTexturePack = pMinecraft->skins->getSelected(); DLCPack *pDLCPack=pTexturePack->getDLCPack(); bool purchased = false; // do we have a license? if(pDLCPack && pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) { purchased = true; } #ifdef _XBOX TelemetryManager->RecordTexturePackLoaded(i, pTexturePack->getId(), purchased?1:0); #endif } // 4J-PB - If the texture pack has audio, we need to switch to this if(pMinecraft->skins->getSelected()->hasAudio()) { Minecraft::GetInstance()->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1); } } break; case eAppAction_ReloadFont: { #ifndef _XBOX app.DebugPrintf( "[Consoles_App] eAppAction_ReloadFont, ingame='%s'.\n", app.GetGameStarted() ? "Yes" : "No" ); SetAction(i,eAppAction_Idle); ui.SetTooltips(i, -1); ui.ReloadSkin(); ui.StartReloadSkinThread(); ui.setCleanupOnReload(); #endif } break; case eAppAction_TexturePackRequired: { #if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ UINT uiIDA[2]; uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION; uiIDA[1]=IDS_CONFIRM_CANCEL; // let them continue without the texture pack here (as this is only really for r // Give the player a warning about the texture pack missing ui.RequestErrorMessage(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::TexturePackDialogReturned,this); SetAction(i,eAppAction_Idle); #else #ifdef _XBOX ULONGLONG ullOfferID_Full; app.GetDLCFullOfferIDForPackID(app.GetRequiredTexturePackID(),&ullOfferID_Full); TelemetryManager->RecordUpsellPresented(ProfileManager.GetPrimaryPad(), eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF); #endif UINT uiIDA[2]; uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION; uiIDA[1]=IDS_TEXTURE_PACK_TRIALVERSION; // Give the player a warning about the texture pack missing ui.RequestErrorMessage(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::TexturePackDialogReturned,this); SetAction(i,eAppAction_Idle); #endif } break; } } // Any TMS actions? eTMS = app.GetTMSAction(i); if(eTMS!=eTMSAction_Idle) { switch(eTMS) { // TMS++ actions case eTMSAction_TMSPP_RetrieveFiles_CreateLoad_SignInReturned: case eTMSAction_TMSPP_RetrieveFiles_RunPlayGame: #ifdef _XBOX app.TMSPP_SetTitleGroupID(GROUP_ID); SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList); #elif defined _XBOX_ONE SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList_Waiting); app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,eTMSAction_TMSPP_UserFileList); #else SetTMSAction(i,eTMSAction_TMSPP_UserFileList); #endif break; #ifdef _XBOX case eTMSAction_TMSPP_GlobalFileList: SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList_Waiting); app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,"\\",eTMSAction_TMSPP_UserFileList); break; #endif case eTMSAction_TMSPP_UserFileList: // retrieve the file list first #if defined _XBOX SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,"\\",eTMSAction_TMSPP_XUIDSFile); #elif defined _XBOX_ONE SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,eTMSAction_TMSPP_DLCFile); #else SetTMSAction(i,eTMSAction_TMSPP_XUIDSFile); #endif break; case eTMSAction_TMSPP_XUIDSFile: #ifdef _XBOX SetTMSAction(i,eTMSAction_TMSPP_XUIDSFile_Waiting); // pass in the next app action on the call or callback completing app.TMSPP_ReadXuidsFile(i,eTMSAction_TMSPP_DLCFile); #else SetTMSAction(i,eTMSAction_TMSPP_DLCFile); #endif break; case eTMSAction_TMSPP_DLCFile: #if defined _XBOX || defined _XBOX_ONE SetTMSAction(i,eTMSAction_TMSPP_DLCFile_Waiting); // pass in the next app action on the call or callback completing app.TMSPP_ReadDLCFile(i,eTMSAction_TMSPP_BannedListFile); #else SetTMSAction(i,eTMSAction_TMSPP_BannedListFile); #endif break; case eTMSAction_TMSPP_BannedListFile: // If we have one in TMSPP, then we can assume we can ignore TMS #if defined _XBOX SetTMSAction(i,eTMSAction_TMSPP_BannedListFile_Waiting); // pass in the next app action on the call or callback completing if(app.TMSPP_ReadBannedList(i,eTMSAction_TMS_RetrieveFiles_Complete)==false) { // we don't have a banned list in TMSPP, so we should check TMS app.ReadBannedList(i, eTMSAction_TMS_RetrieveFiles_Complete,true); } #elif defined _XBOX_ONE SetTMSAction(i,eTMSAction_TMSPP_BannedListFile_Waiting); // pass in the next app action on the call or callback completing app.TMSPP_ReadBannedList(i,eTMSAction_TMS_RetrieveFiles_Complete); #else SetTMSAction(i,eTMSAction_TMS_RetrieveFiles_Complete); #endif break; // SPECIAL CASE - where the user goes directly in to Help & Options from the main menu case eTMSAction_TMSPP_RetrieveFiles_HelpAndOptions: case eTMSAction_TMSPP_RetrieveFiles_DLCMain: // retrieve the file list first #if defined _XBOX // pass in the next app action on the call or callback completing SetTMSAction(i,eTMSAction_TMSPP_XUIDSFile_Waiting); app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,"\\",eTMSAction_TMSPP_DLCFileOnly); #elif defined _XBOX_ONE SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList_Waiting); app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,eTMSAction_TMSPP_RetrieveUserFilelist_DLCFileOnly); #else SetTMSAction(i,eTMSAction_TMSPP_DLCFileOnly); #endif break; case eTMSAction_TMSPP_RetrieveUserFilelist_DLCFileOnly: #if defined _XBOX SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,"\\",eTMSAction_TMSPP_XUIDSFile); #elif defined _XBOX_ONE //StorageManager.TMSPP_DeleteFile(i,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"TP06.png",NULL,NULL, 0); SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,eTMSAction_TMSPP_DLCFileOnly); #else SetTMSAction(i,eTMSAction_TMSPP_DLCFileOnly); #endif break; case eTMSAction_TMSPP_DLCFileOnly: #if defined _XBOX || defined _XBOX_ONE SetTMSAction(i,eTMSAction_TMSPP_DLCFile_Waiting); // pass in the next app action on the call or callback completing app.TMSPP_ReadDLCFile(i,eTMSAction_TMSPP_RetrieveFiles_Complete); #else SetTMSAction(i,eTMSAction_TMSPP_RetrieveFiles_Complete); #endif break; case eTMSAction_TMSPP_RetrieveFiles_Complete: SetTMSAction(i,eTMSAction_Idle); break; // TMS files /* case eTMSAction_TMS_RetrieveFiles_CreateLoad_SignInReturned: case eTMSAction_TMS_RetrieveFiles_RunPlayGame: #ifdef _XBOX SetTMSAction(i,eTMSAction_TMS_XUIDSFile_Waiting); // pass in the next app action on the call or callback completing app.ReadXuidsFileFromTMS(i,eTMSAction_TMS_DLCFile,true); #else SetTMSAction(i,eTMSAction_TMS_DLCFile); #endif break; case eTMSAction_TMS_DLCFile: #ifdef _XBOX SetTMSAction(i,eTMSAction_TMS_DLCFile_Waiting); // pass in the next app action on the call or callback completing app.ReadDLCFileFromTMS(i,eTMSAction_TMS_BannedListFile,true); #else SetTMSAction(i,eTMSAction_TMS_BannedListFile); #endif break; case eTMSAction_TMS_RetrieveFiles_HelpAndOptions: case eTMSAction_TMS_RetrieveFiles_DLCMain: #ifdef _XBOX SetTMSAction(i,eTMSAction_TMS_DLCFile_Waiting); // pass in the next app action on the call or callback completing app.ReadDLCFileFromTMS(i,eTMSAction_Idle,true); #else SetTMSAction(i,eTMSAction_Idle); #endif break; case eTMSAction_TMS_BannedListFile: #ifdef _XBOX SetTMSAction(i,eTMSAction_TMS_BannedListFile_Waiting); // pass in the next app action on the call or callback completing app.ReadBannedList(i, eTMSAction_TMS_RetrieveFiles_Complete,true); #else SetTMSAction(i,eTMSAction_TMS_RetrieveFiles_Complete); #endif break; */ case eTMSAction_TMS_RetrieveFiles_Complete: SetTMSAction(i,eTMSAction_Idle); // if(StorageManager.SetSaveDevice(&CScene_Main::DeviceSelectReturned,pClass)) // { // // save device already selected // // ensure we've applied this player's settings // app.ApplyGameSettingsChanged(ProfileManager.GetPrimaryPad()); // app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_MultiGameJoinLoad); // } break; } } } } int CMinecraftApp::BannedLevelDialogReturned(void *pParam,int iPad,const C4JStorage::EMessageResult result) { CMinecraftApp* pApp = (CMinecraftApp*)pParam; //Minecraft *pMinecraft=Minecraft::GetInstance(); if(result==C4JStorage::EMessage_ResultAccept) { #if defined _XBOX || defined _XBOX_ONE INetworkPlayer *pHost = g_NetworkManager.GetHostPlayer(); // unban the level if (pHost != NULL) { #if defined _XBOX pApp->RemoveLevelFromBannedLevelList(iPad,((NetworkPlayerXbox *)pHost)->GetUID(),pApp->GetUniqueMapName()); #else pApp->RemoveLevelFromBannedLevelList(iPad,pHost->GetUID(),pApp->GetUniqueMapName()); #endif } #endif } else { if( iPad == ProfileManager.GetPrimaryPad() ) { pApp->SetAction(iPad,eAppAction_ExitWorld); } else { pApp->SetAction(iPad,eAppAction_ExitPlayer); } } return 0; } void CMinecraftApp::loadMediaArchive() { wstring mediapath = L""; #ifdef __PS3__ mediapath = L"Common\\Media\\MediaPS3.arc"; #elif _WINDOWS64 mediapath = L"Common\\Media\\MediaWindows64.arc"; #elif __ORBIS__ mediapath = L"Common\\Media\\MediaOrbis.arc"; #elif _DURANGO mediapath = L"Common\\Media\\MediaDurango.arc"; #elif __PSVITA__ mediapath = L"Common\\Media\\MediaPSVita.arc"; #endif if (!mediapath.empty()) { m_mediaArchive = new ArchiveFile( File(mediapath) ); } #if 0 string path = "Common\\media.arc"; HANDLE hFile = CreateFile( path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL ); if( hFile != INVALID_HANDLE_VALUE ) { File fileHelper(convStringToWstring(path)); DWORD dwFileSize = fileHelper.length(); // Initialize memory. PBYTE m_fBody = new BYTE[ dwFileSize ]; ZeroMemory(m_fBody, dwFileSize); DWORD m_fSize = 0; BOOL hr = ReadFile( hFile, m_fBody, dwFileSize, &m_fSize, NULL ); assert( m_fSize == dwFileSize ); CloseHandle( hFile ); m_mediaArchive = new ArchiveFile(m_fBody, m_fSize); } else { assert( false ); // AHHHHHHHHHHHH m_mediaArchive = NULL; } #endif } void CMinecraftApp::loadStringTable() { #ifndef _XBOX if(m_stringTable!=NULL) { // we need to unload the current string table, this is a reload delete m_stringTable; } wstring localisationFile = L"languages.loc"; if (m_mediaArchive->hasFile(localisationFile)) { byteArray locFile = m_mediaArchive->getFile(localisationFile); m_stringTable = new StringTable(locFile.data, locFile.length); delete locFile.data; } else { m_stringTable = NULL; assert(false); // AHHHHHHHHH. } #endif } int CMinecraftApp::PrimaryPlayerSignedOutReturned(void *pParam,int iPad,const C4JStorage::EMessageResult) { //CMinecraftApp* pApp = (CMinecraftApp*)pParam; //Minecraft *pMinecraft=Minecraft::GetInstance(); // if the player is null, we're in the menus //if(Minecraft::GetInstance()->player!=NULL) // We always create a session before kicking of any of the game code, so even though we may still be joining/creating a game // at this point we want to handle it differently from just being in a menu if( g_NetworkManager.IsInSession() ) { app.SetAction(iPad,eAppAction_PrimaryPlayerSignedOutReturned); } else { app.SetAction(iPad,eAppAction_PrimaryPlayerSignedOutReturned_Menus); } return 0; } int CMinecraftApp::EthernetDisconnectReturned(void *pParam,int iPad,const C4JStorage::EMessageResult) { //CMinecraftApp* pApp = (CMinecraftApp*)pParam; Minecraft *pMinecraft=Minecraft::GetInstance(); // if the player is null, we're in the menus if(Minecraft::GetInstance()->player!=NULL) { app.SetAction(pMinecraft->player->GetXboxPad(),eAppAction_EthernetDisconnectedReturned); } else { // 4J-PB - turn off the PSN store icon just in case this happened when we were in one of the DLC menus #if defined __ORBIS__ || defined __PSVITA__ app.GetCommerce()->HidePsStoreIcon(); #endif app.SetAction(iPad,eAppAction_EthernetDisconnectedReturned_Menus); } return 0; } int CMinecraftApp::SignoutExitWorldThreadProc( 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); Minecraft *pMinecraft=Minecraft::GetInstance(); int exitReasonStringId = -1; bool saveStats = false; if (pMinecraft->isClientSide() || g_NetworkManager.IsInSession() ) { if(lpParameter != NULL ) { 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; break; case DisconnectPacket::eDisconnect_NoUGC_Single_Local: exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL; break; #ifdef _XBOX case DisconnectPacket::eDisconnect_NoUGC_Remote: exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE; break; #endif case DisconnectPacket::eDisconnect_NoFlying: exitReasonStringId = IDS_DISCONNECTED_FLYING; break; case DisconnectPacket::eDisconnect_OutdatedServer: exitReasonStringId = IDS_DISCONNECTED_SERVER_OLD; break; case DisconnectPacket::eDisconnect_OutdatedClient: exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD; break; default: exitReasonStringId = IDS_DISCONNECTED; } pMinecraft->progressRenderer->progressStartNoAbort( exitReasonStringId ); // 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); } 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(); } // 4J Stu - This only does something if we actually have a server, so don't need to do any other checks MinecraftServer::HaltServer(true); // We need to call the stats & leaderboards save before we exit the session //pMinecraft->forceStatsSave(); saveStats = false; // 4J Stu - Leave the session once the disconnect packet has been sent g_NetworkManager.LeaveGame(FALSE); } else { if(lpParameter != NULL ) { 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; break; case DisconnectPacket::eDisconnect_NoUGC_Single_Local: exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL; break; #if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) case DisconnectPacket::eDisconnect_ContentRestricted_AllLocal: exitReasonStringId = IDS_CONTENT_RESTRICTION_MULTIPLAYER; break; case DisconnectPacket::eDisconnect_ContentRestricted_Single_Local: exitReasonStringId = IDS_CONTENT_RESTRICTION; break; #endif #ifdef _XBOX case DisconnectPacket::eDisconnect_NoUGC_Remote: exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE; break; #endif case DisconnectPacket::eDisconnect_OutdatedServer: exitReasonStringId = IDS_DISCONNECTED_SERVER_OLD; break; case DisconnectPacket::eDisconnect_OutdatedClient: exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD; default: exitReasonStringId = IDS_DISCONNECTED; } pMinecraft->progressRenderer->progressStartNoAbort( exitReasonStringId ); } } pMinecraft->setLevel(NULL,exitReasonStringId,nullptr,saveStats,true); // 4J-JEV: Fix for #106402 - TCR #014 BAS Debug Output: // TU12: Mass Effect Mash-UP: Save file "Default_DisplayName" is created on all storage devices after signing out from a re-launched pre-generated world app.m_gameRules.unloadCurrentGameRules(); // MinecraftServer::resetFlags(); // 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); } return S_OK; } int CMinecraftApp::UnlockFullInviteReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) { //CMinecraftApp* pApp = (CMinecraftApp*)pParam; Minecraft *pMinecraft=Minecraft::GetInstance(); bool bNoPlayer; // bug 11285 - TCR 001: BAS Game Stability: CRASH - When trying to join a full version game with a trial version, the trial crashes // 4J-PB - we may be in the main menus here, and we don't have a pMinecraft->player if(pMinecraft->player==NULL) { bNoPlayer=true; } if(result==C4JStorage::EMessage_ResultAccept) { if(ProfileManager.IsSignedInLive(iPad)) { // 4J-PB - need to check this user can access the store #if defined(__PS3__) || defined(__PSVITA__) bool bContentRestricted; ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,NULL,&bContentRestricted,NULL); if(bContentRestricted) { UINT uiIDA[1]; uiIDA[0]=IDS_CONFIRM_OK; ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); } else #endif { ProfileManager.DisplayFullVersionPurchase(false,iPad,eSen_UpsellID_Full_Version_Of_Game); } } #if defined(__PS3__) else { // you're not signed in to PSN! UINT uiIDA[2]; uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); } #endif } else { TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); } return 0; } int CMinecraftApp::UnlockFullSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) { //CMinecraftApp* pApp = (CMinecraftApp*)pParam; Minecraft *pMinecraft=Minecraft::GetInstance(); if(result==C4JStorage::EMessage_ResultAccept) { if(ProfileManager.IsSignedInLive(pMinecraft->player->GetXboxPad())) { // 4J-PB - need to check this user can access the store #if defined(__PS3__) || defined(__PSVITA__) bool bContentRestricted; ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,NULL,&bContentRestricted,NULL); if(bContentRestricted) { UINT uiIDA[1]; uiIDA[0]=IDS_CONFIRM_OK; ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); } else #endif { ProfileManager.DisplayFullVersionPurchase(false,pMinecraft->player->GetXboxPad(),eSen_UpsellID_Full_Version_Of_Game); } } #if defined(__PS3__) else { // you're not signed in to PSN! UINT uiIDA[2]; uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); } #elif defined(__ORBIS__) else { // Determine why they're not "signed in live" if (ProfileManager.isSignedInPSN(iPad)) { // Signed in to PSN but not connected (no internet access) assert(!ProfileManager.isConnectedToPSN(iPad)); UINT uiIDA[1]; uiIDA[0] = IDS_OK; ui.RequestErrorMessage( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad); } else { // Not signed in to PSN UINT uiIDA[1]; uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; ui.RequestAlertMessage( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, iPad, &CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); } } #endif } else { TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); } return 0; } int CMinecraftApp::UnlockFullExitReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) { CMinecraftApp* pApp = (CMinecraftApp*)pParam; Minecraft *pMinecraft=Minecraft::GetInstance(); if(result==C4JStorage::EMessage_ResultAccept) { if(ProfileManager.IsSignedInLive(pMinecraft->player->GetXboxPad())) { // 4J-PB - need to check this user can access the store #if defined(__PS3__) || defined(__PSVITA__) bool bContentRestricted; ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,NULL,&bContentRestricted,NULL); if(bContentRestricted) { UINT uiIDA[1]; uiIDA[0]=IDS_CONFIRM_OK; ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); } else #endif { ProfileManager.DisplayFullVersionPurchase(false,pMinecraft->player->GetXboxPad(),eSen_UpsellID_Full_Version_Of_Game); #if defined __ORBIS__ || defined __PS3__ || defined __PSVITA__ // still need to exit the trial or we'll be in the Pause menu with input ignored pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); #endif } } #if defined(__PS3__) || defined __PSVITA__ else { // you're not signed in to PSN! UINT uiIDA[2]; uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturnedExitTrial,&app); } #elif defined(__ORBIS__) else { // Determine why they're not "signed in live" if (ProfileManager.isSignedInPSN(iPad)) { // Signed in to PSN but not connected (no internet access) assert(!ProfileManager.isConnectedToPSN(iPad)); UINT uiIDA[1]; uiIDA[0] = IDS_OK; ui.RequestErrorMessage( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad); // still need to exit the trial or we'll be in the Pause menu with input ignored pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); } else { // Not signed in to PSN UINT uiIDA[1]; uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; ui.RequestAlertMessage( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, iPad, &CMinecraftApp::MustSignInFullVersionPurchaseReturnedExitTrial,&app); } } #endif } else { TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); } return 0; } int CMinecraftApp::TrialOverReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) { CMinecraftApp* pApp = (CMinecraftApp*)pParam; Minecraft *pMinecraft=Minecraft::GetInstance(); if(result==C4JStorage::EMessage_ResultAccept) { // we need a signed in user for the unlock if(ProfileManager.IsSignedInLive(pMinecraft->player->GetXboxPad())) { // 4J-PB - need to check this user can access the store #if defined(__PS3__) || defined(__PSVITA__) bool bContentRestricted; ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,NULL,&bContentRestricted,NULL); if(bContentRestricted) { UINT uiIDA[1]; uiIDA[0]=IDS_CONFIRM_OK; ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); } else #endif { ProfileManager.DisplayFullVersionPurchase(false,pMinecraft->player->GetXboxPad(),eSen_UpsellID_Full_Version_Of_Game); } } else { #if defined(__PS3__) // you're not signed in to PSN! UINT uiIDA[2]; uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); // 4J Stu - We can't actually exit the game, so just exit back to the main menu //pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); #else pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitTrial); #endif } } else { TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); #if defined(__PS3__) || defined(__ORBIS__) // 4J Stu - We can't actually exit the game, so just exit back to the main menu pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); #else pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitTrial); #endif } return 0; } void CMinecraftApp::ProfileReadErrorCallback(void *pParam) { CMinecraftApp *pApp=(CMinecraftApp *)pParam; int iPrimaryPlayer=ProfileManager.GetPrimaryPad(); pApp->SetAction(iPrimaryPlayer, eAppAction_ProfileReadError); } void CMinecraftApp::ClearSignInChangeUsersMask() { // 4J-PB - When in the main menu, the user is on pad 0, and any change they make to their profile will be to pad 0 data // If they then go in as a secondary player to a splitscreen game, their profile will not be read again on pad 1 if they were previously in a splitscreen game // This is because m_uiLastSignInData remembers they were in previously, and doesn't read the profile data for them again // Fix this by resetting the m_uiLastSignInData on pressing play game for secondary users. The Primary user does a read profile on play game anyway int iPrimaryPlayer=ProfileManager.GetPrimaryPad(); if(m_uiLastSignInData!=0) { if(iPrimaryPlayer>=0) { m_uiLastSignInData=1<user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); #endif CMinecraftApp *pApp=(CMinecraftApp *)pParam; // check if the primary player signed out int iPrimaryPlayer=ProfileManager.GetPrimaryPad(); if((ProfileManager.GetLockedProfile()!=-1) && iPrimaryPlayer!=-1) { if ( ((uiSignInData & (1<SetAction(iPrimaryPlayer,eAppAction_PrimaryPlayerSignedOut); // 4J-PB - invalidate their banned level list pApp->InvalidateBannedList(iPrimaryPlayer); // need to ditch any DLCOffers info StorageManager.ClearDLCOffers(); pApp->ClearAndResetDLCDownloadQueue(); pApp->ClearDLCInstalled(); } else { unsigned int uiChangedPlayers = uiSignInData ^ m_uiLastSignInData; if( g_NetworkManager.IsInSession() ) { bool hasGuestIdChanged = false; for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) { DWORD guestNumber = 0; if(ProfileManager.IsSignedIn(i)) { XUSER_SIGNIN_INFO info; XUserGetSigninInfo(i,XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY ,&info); pApp->DebugPrintf("Player at index %d has guest number %d\n", i,info.dwGuestNumber ); guestNumber = info.dwGuestNumber; } if( pApp->m_currentSigninInfo[i].dwGuestNumber != 0 && guestNumber != 0 && pApp->m_currentSigninInfo[i].dwGuestNumber != guestNumber ) { hasGuestIdChanged = true; } } if( hasGuestIdChanged ) { UINT uiIDA[1]; uiIDA[0]=IDS_CONFIRM_OK; ui.RequestErrorMessage(IDS_GUEST_ORDER_CHANGED_TITLE, IDS_GUEST_ORDER_CHANGED_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad()); } // 4J Stu - On PS4 we can also cause to exit players if they are signed out here, but we shouldn't do that if // we are going to switch to an offline game as it will likely crash due to incompatible parallel processes bool switchToOffline = false; // If it's an online game, and the primary profile is no longer signed into LIVE then we act as if disconnected if( !ProfileManager.IsSignedInLive( ProfileManager.GetLockedProfile() ) && !g_NetworkManager.IsLocalGame() ) { switchToOffline = true; } //printf("Old: %x, New: %x, Changed: %x\n", m_ulLastSignInData, ulSignInData, changedPlayers); for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) { // Primary player shouldn't be subjected to these checks, and shouldn't call ExitPlayer if(i == iPrimaryPlayer) continue; // A guest a signed in or out, out of order which invalidates all the guest players we have in the game if(hasGuestIdChanged && pApp->m_currentSigninInfo[i].dwGuestNumber != 0 && g_NetworkManager.GetLocalPlayerByUserIndex(i)!=NULL) { pApp->DebugPrintf("Recommending removal of player at index %d because their guest id changed\n",i); pApp->SetAction(i, eAppAction_ExitPlayer); } else { XUSER_SIGNIN_INFO info; XUserGetSigninInfo(i,XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY ,&info); // 4J Stu - Also need to detect the case where the sign in mask is the same, but the player has swapped users (eg still signed in but xuid different) // Fix for #48451 - TU5: Code: UI: Splitscreen: Title crashes when switching to a profile previously signed out via splitscreen profile selection // 4J-PB - compiler complained about if below ('&&' within '||') - making it easier to read bool bPlayerChanged=(uiChangedPlayers&(1<m_currentSigninInfo[i].xuid, info.xuid) ) )) { // 4J-PB - invalidate their banned level list pApp->DebugPrintf("Player at index %d Left - invalidating their banned list\n",i); pApp->InvalidateBannedList(i); // 4J-HG: If either the player is in the network manager or in the game, need to exit player // TODO: Do we need to check the network manager? if (g_NetworkManager.GetLocalPlayerByUserIndex(i) != NULL || Minecraft::GetInstance()->localplayers[i] != NULL) { pApp->DebugPrintf("Player %d signed out\n", i); pApp->SetAction(i, eAppAction_ExitPlayer); } } } #ifdef __ORBIS__ // check if any of the addition players have signed out of PSN (primary player is handled below) if(!switchToOffline && i != ProfileManager.GetLockedProfile() && !g_NetworkManager.IsLocalGame()) { if(g_NetworkManager.GetLocalPlayerByUserIndex(i)!=NULL) { if(ProfileManager.IsSignedInLive(i) == false) { pApp->DebugPrintf("Recommending removal of player at index %d because they're no longer signed into PSNd\n",i); pApp->SetAction(i,eAppAction_ExitPlayer); } } } #endif } // If it's an online game, and the primary profile is no longer signed into LIVE then we act as if disconnected if( switchToOffline ) { pApp->SetAction(iPrimaryPlayer,eAppAction_EthernetDisconnected); } g_NetworkManager.HandleSignInChange(); } // Some menus require the player to be signed in to live, so if this callback happens and the primary player is // no longer signed in then nav back else if ( pApp->GetLiveLinkRequired() && !ProfileManager.IsSignedInLive( ProfileManager.GetLockedProfile() ) ) { #ifdef __PSVITA__ if(!CGameNetworkManager::usingAdhocMode()) // if we're in adhoc mode, we can ignore this #endif { pApp->SetAction(iPrimaryPlayer,eAppAction_EthernetDisconnected); } } #if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ ) // 4J-JEV: Need to kick of loading of profile data for sub-sign in players. for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) { if( i != iPrimaryPlayer && ( uiChangedPlayers & (1<InvalidateBannedList(iPrimaryPlayer); // need to ditch any DLCOffers info StorageManager.ClearDLCOffers(); pApp->ClearAndResetDLCDownloadQueue(); pApp->ClearDLCInstalled(); } // Update the guest numbers to the current state for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) { if(FAILED(XUserGetSigninInfo(i,XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY,&pApp->m_currentSigninInfo[i]))) { pApp->m_currentSigninInfo[i].xuid = INVALID_XUID; pApp->m_currentSigninInfo[i].dwGuestNumber = 0; } app.DebugPrintf("Player at index %d has guest number %d\n", i,pApp->m_currentSigninInfo[i].dwGuestNumber ); } } void CMinecraftApp::NotificationsCallback(LPVOID pParam,DWORD dwNotification, unsigned int uiParam) { CMinecraftApp* pClass = (CMinecraftApp*)pParam; // push these on to the notifications to be handled in qnet's dowork PNOTIFICATION pNotification = new NOTIFICATION; pNotification->dwNotification=dwNotification; pNotification->uiParam=uiParam; switch( dwNotification ) { case XN_SYS_SIGNINCHANGED: { pClass->DebugPrintf("Signing changed - %d\n", uiParam ); } break; case XN_SYS_INPUTDEVICESCHANGED: if(app.GetGameStarted() && g_NetworkManager.IsInSession()) { for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) { if(!InputManager.IsPadConnected(i) && Minecraft::GetInstance()->localplayers[i] != NULL && !ui.IsPauseMenuDisplayed(i) && !ui.IsSceneInStack(i, eUIScene_EndPoem) ) { ui.CloseUIScenes(i); ui.NavigateToScene(i,eUIScene_PauseMenu); } } } break; case XN_LIVE_CONTENT_INSTALLED: // Need to inform xuis that we've possibly had DLC installed { //app.m_dlcManager.SetNeedsUpdated(true); // Clear the DLC installed flag to cause a GetDLC to run if it's called app.ClearDLCInstalled(); ui.HandleDLCInstalled(ProfileManager.GetPrimaryPad()); } break; case XN_SYS_STORAGEDEVICESCHANGED: { #ifdef _XBOX // If the devices have changed, and we've got a dlc pack with audio selected, and that pack's content device is no longer valid... then pull the plug on // audio streaming, as if we leave this until later xact gets locked up attempting to destroy the streamed wave bank. TexturePack *pTexPack=Minecraft::GetInstance()->skins->getSelected(); if(pTexPack->hasAudio()) { DLCTexturePack *pDLCTexPack=(DLCTexturePack *)pTexPack; XCONTENTDEVICEID deviceID = pDLCTexPack->GetDLCDeviceID(); if( XContentGetDeviceState( deviceID, NULL ) != ERROR_SUCCESS ) { // Set texture pack flag so that it is now considered as not having audio - this is critical so that the next playStreaming does what it is meant to do, // and also so that we don't try and unmount this again, or play any sounds from it in the future pTexPack->setHasAudio(false); // need to stop the streaming audio - by playing streaming audio from the default texture pack now Minecraft::GetInstance()->soundEngine->playStreaming(L"", 0, 0, 0, 0, 0); if(pDLCTexPack->m_pStreamedWaveBank!=NULL) { pDLCTexPack->m_pStreamedWaveBank->Destroy(); } if(pDLCTexPack->m_pSoundBank!=NULL) { pDLCTexPack->m_pSoundBank->Destroy(); } DWORD result = StorageManager.UnmountInstalledDLC("TPACK"); app.DebugPrintf("Unmount result is %d\n",result); } } #endif } break; } pClass->m_vNotifications.push_back(pNotification); } #if defined __PS3__ || defined __PSVITA__ || defined __ORBIS__ int CMinecraftApp::MustSignInFullVersionPurchaseReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) { if(result==C4JStorage::EMessage_ResultAccept) { #ifdef __PS3__ SQRNetworkManager_PS3::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); #elif defined __PSVITA__ SQRNetworkManager_Vita::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); #else // __PS4__ SQRNetworkManager_Orbis::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); #endif } return 0; } #if defined __PS3__ || defined __PSVITA__ || defined __ORBIS__ int CMinecraftApp::MustSignInFullVersionPurchaseReturnedExitTrial(void *pParam,int iPad,C4JStorage::EMessageResult result) { if(result==C4JStorage::EMessage_ResultAccept) { #ifdef __PS3__ SQRNetworkManager_PS3::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); #elif defined __PSVITA__ SQRNetworkManager_Vita::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); #else // __PS4__ SQRNetworkManager_Orbis::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); #endif } //4J-PB - we need to exit the trial, or we'll be in the pause menu with ignore input true app.SetAction(iPad,eAppAction_ExitWorldTrial); return 0; } #endif int CMinecraftApp::NowDisplayFullVersionPurchase(void *pParam, bool bContinue, int iPad) { app.m_bDisplayFullVersionPurchase=true; return 0; } #endif void CMinecraftApp::UpsellReturnedCallback(LPVOID pParam, eUpsellType type, eUpsellResponse result, int iUserData) { ESen_UpsellID senType; ESen_UpsellOutcome senResponse; #ifdef __PS3__ UINT uiIDA[2]; #endif // Map the eUpsellResponse to the enum we use for sentient switch(result) { case eUpsellResponse_Accepted_NoPurchase: senResponse = eSen_UpsellOutcome_Went_To_Guide; break; case eUpsellResponse_Accepted_Purchase: senResponse = eSen_UpsellOutcome_Accepted; break; #ifdef __PS3__ // special case for people who are not signed in to the PSN while playing the trial game case eUpsellResponse_UserNotSignedInPSN: uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); return; case eUpsellResponse_NotAllowedOnline: // On earning a trophy in the trial version, where the user is underage and can't go online to buy the game, but they selected to buy the game on the trophy upsell uiIDA[0]=IDS_CONFIRM_OK; ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); break; #endif case eUpsellResponse_Declined: default: senResponse = eSen_UpsellOutcome_Declined; break; }; // Map the eUpsellType to the enum we use for sentient switch(type) { case eUpsellType_Custom: senType = eSen_UpsellID_Full_Version_Of_Game; break; default: senType = eSen_UpsellID_Undefined; break; }; // Always the primary pad that gets an upsell TelemetryManager->RecordUpsellResponded(ProfileManager.GetPrimaryPad(), eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, senResponse); } #ifdef _DEBUG_MENUS_ENABLED bool CMinecraftApp::DebugArtToolsOn() { return DebugSettingsOn() && (GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<m_bDebugOptions=!pClass->m_bDebugOptions; for(int i=0;ilocalplayers[i] != NULL) { iPlayerC++; } } return iPlayerC; } int CMinecraftApp::MarketplaceCountsCallback(LPVOID pParam,C4JStorage::DLC_TMS_DETAILS *pTMSDetails, int iPad) { app.DebugPrintf("Marketplace Counts= New - %d Total - %d\n",pTMSDetails->dwNewOffers,pTMSDetails->dwTotalOffers); if(pTMSDetails->dwNewOffers>0) { app.m_bNewDLCAvailable=true; app.m_bSeenNewDLCTip=false; } else { app.m_bNewDLCAvailable=false; app.m_bSeenNewDLCTip=true; } return 0; } bool CMinecraftApp::StartInstallDLCProcess(int iPad) { app.DebugPrintf("--- CMinecraftApp::StartInstallDLCProcess: pad=%i.\n", iPad); // If there is already a call to this in progress, then do nothing // If the app says dlc is installed, then there has been no new system message to tell us there's new DLC since the last call to StartInstallDLCProcess if((app.DLCInstallProcessCompleted()==false) && (m_bDLCInstallPending==false)) { app.m_dlcManager.resetUnnamedCorruptCount(); m_bDLCInstallPending = true; m_iTotalDLC = 0; m_iTotalDLCInstalled = 0; app.DebugPrintf("--- CMinecraftApp::StartInstallDLCProcess - StorageManager.GetInstalledDLC\n"); StorageManager.GetInstalledDLC(iPad,&CMinecraftApp::DLCInstalledCallback,this); return true; } else { app.DebugPrintf("--- CMinecraftApp::StartInstallDLCProcess - nothing to do\n"); return false; } } // Installed DLC callback int CMinecraftApp::DLCInstalledCallback(LPVOID pParam,int iInstalledC,int iPad) { app.DebugPrintf("--- CMinecraftApp::DLCInstalledCallback: totalDLC=%i, pad=%i.\n", iInstalledC, iPad); app.m_iTotalDLC = iInstalledC; app.MountNextDLC(iPad); return 0; } void CMinecraftApp::MountNextDLC(int iPad) { app.DebugPrintf("--- CMinecraftApp::MountNextDLC: pad=%i.\n", iPad); if(m_iTotalDLCInstalled < m_iTotalDLC) { // Mount it // We also need to match the ones the user wants to mount with the installed DLC // We're supposed to use a generic save game as a cache of these to do this, with XUSER_ANY if(StorageManager.MountInstalledDLC(iPad,m_iTotalDLCInstalled,&CMinecraftApp::DLCMountedCallback,this)!=ERROR_IO_PENDING ) { // corrupt DLC app.DebugPrintf("Failed to mount DLC %d for pad %d\n",m_iTotalDLCInstalled,iPad); ++m_iTotalDLCInstalled; app.MountNextDLC(iPad); } else { app.DebugPrintf("StorageManager.MountInstalledDLC ok\n"); } } else { /* Removed - now loading these on demand instead of as each pack is mounted if(m_iTotalDLCInstalled > 0) { Minecraft *pMinecraft=Minecraft::GetInstance(); pMinecraft->levelRenderer->AddDLCSkinsToMemTextures(); } */ m_bDLCInstallPending = false; m_bDLCInstallProcessCompleted=true; ui.HandleDLCMountingComplete(); #if defined(_XBOX_ONE) || defined(__ORBIS__) // Check if the current texture pack is now installed if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin()) { TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; DLCPack *pParentPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack(); if(pParentPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) { StorageManager.SetSaveDisabled(false); } } #endif #if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ { TexturePack* currentTPack = Minecraft::GetInstance()->skins->getSelected(); TexturePack* requiredTPack = Minecraft::GetInstance()->skins->getTexturePackById(app.GetRequiredTexturePackID()); if(currentTPack != requiredTPack) { Minecraft::GetInstance()->skins->selectTexturePackById(app.GetRequiredTexturePackID()); } } #endif } } // 4J-JEV: For the sake of clarity in DLCMountedCallback. #if defined(_XBOX) || defined(__PS3__) || defined(_WINDOWS64) #define CONTENT_DATA_DISPLAY_NAME(a) (a.szDisplayName) #else #define CONTENT_DATA_DISPLAY_NAME(a) (a.wszDisplayName) #endif int CMinecraftApp::DLCMountedCallback(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicenceMask) { #if defined(_XBOX) || defined(_DURANGO) || defined(__PS3__) || defined(__ORBIS__) || defined(_WINDOWS64) || defined (__PSVITA__) //Chris TODO app.DebugPrintf("--- CMinecraftApp::DLCMountedCallback\n"); if(dwErr!=ERROR_SUCCESS) { // corrupt DLC app.DebugPrintf("Failed to mount DLC for pad %d: %d\n",iPad,dwErr); app.m_dlcManager.incrementUnnamedCorruptCount(); } else { XCONTENT_DATA ContentData = StorageManager.GetDLC(app.m_iTotalDLCInstalled); DLCPack *pack = app.m_dlcManager.getPack( CONTENT_DATA_DISPLAY_NAME(ContentData) ); if( pack != NULL && pack->IsCorrupt() ) { app.DebugPrintf("Pack '%ls' is corrupt, removing it from the DLC Manager.\n", CONTENT_DATA_DISPLAY_NAME(ContentData)); app.m_dlcManager.removePack(pack); pack = NULL; } if(pack == NULL) { app.DebugPrintf("Pack \"%ls\" is not installed, so adding it\n", CONTENT_DATA_DISPLAY_NAME(ContentData)); #if defined(_XBOX) || defined(__PS3__) || defined(_WINDOWS64) pack = new DLCPack(ContentData.szDisplayName,dwLicenceMask); #elif defined _XBOX_ONE pack = new DLCPack(ContentData.wszDisplayName,ContentData.wszProductID,dwLicenceMask); #else pack = new DLCPack(ContentData.wszDisplayName,dwLicenceMask); #endif pack->SetDLCMountIndex(app.m_iTotalDLCInstalled); pack->SetDLCDeviceID(ContentData.DeviceID); app.m_dlcManager.addPack(pack); app.HandleDLC(pack); if(pack->getDLCItemsCount(DLCManager::e_DLCType_Texture) > 0) { Minecraft::GetInstance()->skins->addTexturePackFromDLC(pack, pack->GetPackId() ); } } else { app.DebugPrintf("Pack \"%ls\" is already installed. Updating license to %d\n", CONTENT_DATA_DISPLAY_NAME(ContentData), dwLicenceMask); pack->SetDLCMountIndex(app.m_iTotalDLCInstalled); pack->SetDLCDeviceID(ContentData.DeviceID); pack->updateLicenseMask(dwLicenceMask); } StorageManager.UnmountInstalledDLC(); } ++app.m_iTotalDLCInstalled; app.MountNextDLC(iPad); #endif // __PSVITA__ return 0; } #undef CONTENT_DATA_DISPLAY_NAME // void CMinecraftApp::InstallDefaultCape() // { // if(!m_bDefaultCapeInstallAttempted) // { // // we only attempt to install the cape once per launch of the game // m_bDefaultCapeInstallAttempted=true; // // wstring wTemp=L"Default_Cape.png"; // bool bRes=app.IsFileInMemoryTextures(wTemp); // // if the file is not already in the memory textures, then read it from TMS // if(!bRes) // { // BYTE *pBuffer=NULL; // DWORD dwSize=0; // // 4J-PB - out for now for DaveK so he doesn't get the birthday cape // #ifdef _CONTENT_PACKAGE // C4JStorage::ETMSStatus eTMSStatus; // eTMSStatus=StorageManager.ReadTMSFile(ProfileManager.GetPrimaryPad(),C4JStorage::eGlobalStorage_Title,C4JStorage::eTMS_FileType_Graphic, L"Default_Cape.png",&pBuffer, &dwSize); // if(eTMSStatus==C4JStorage::ETMSStatus_Idle) // { // app.AddMemoryTextureFile(wTemp,pBuffer,dwSize); // } // #endif // } // } // } void CMinecraftApp::HandleDLC(DLCPack *pack) { DWORD dwFilesProcessed = 0; #ifndef _XBOX #if defined(__PS3__) || defined(__ORBIS__) || defined(_WINDOWS64) || defined (__PSVITA__) std::vector dlcFilenames; #elif defined _DURANGO std::vector dlcFilenames; #endif StorageManager.GetMountedDLCFileList("DLCDrive", dlcFilenames); #ifdef __ORBIS__ // 4J Stu - I don't know why we handle more than one file here any more, however this doesn't seem to work with the PS4 patches if(dlcFilenames.size() > 0) m_dlcManager.readDLCDataFile(dwFilesProcessed, dlcFilenames[0], pack); #else for(int i=0; ieXuid==eXUID_Deadmau5) { return true; } } return false; } void CMinecraftApp::AddMemoryTextureFile(const wstring &wName,PBYTE pbData,DWORD dwBytes) { EnterCriticalSection(&csMemFilesLock); // check it's not already in PMEMDATA pData=NULL; auto it = m_MEM_Files.find(wName); if(it != m_MEM_Files.end()) { #ifndef _CONTENT_PACKAGE wprintf(L"Incrementing the memory texture file count for %ls\n", wName.c_str()); #endif pData = (*it).second; if(pData->dwBytes == 0 && dwBytes != 0) { // This should never be NULL if dwBytes is 0 if(pData->pbData!=NULL) delete [] pData->pbData; pData->pbData=pbData; pData->dwBytes=dwBytes; } ++pData->ucRefCount; LeaveCriticalSection(&csMemFilesLock); return; } #ifndef _CONTENT_PACKAGE //wprintf(L"Adding the memory texture file data for %ls\n", wName.c_str()); #endif // this is a texture (png) file // add this texture to the list of memory texture files - it will then be picked up by the level renderer's AddEntity pData = (PMEMDATA)new BYTE[sizeof(MEMDATA)]; ZeroMemory( pData, sizeof(MEMDATA) ); pData->pbData=pbData; pData->dwBytes=dwBytes; pData->ucRefCount = 1; // use the xuid to access the skin data m_MEM_Files[wName]=pData; LeaveCriticalSection(&csMemFilesLock); } void CMinecraftApp::RemoveMemoryTextureFile(const wstring &wName) { EnterCriticalSection(&csMemFilesLock); auto it = m_MEM_Files.find(wName); if(it != m_MEM_Files.end()) { #ifndef _CONTENT_PACKAGE wprintf(L"Decrementing the memory texture file count for %ls\n", wName.c_str()); #endif PMEMDATA pData = (*it).second; --pData->ucRefCount; if(pData->ucRefCount <= 0) { #ifndef _CONTENT_PACKAGE wprintf(L"Erasing the memory texture file data for %ls\n", wName.c_str()); #endif delete [] pData; m_MEM_Files.erase(wName); } } LeaveCriticalSection(&csMemFilesLock); } bool CMinecraftApp::DefaultCapeExists() { wstring wTex=L"Special_Cape.png"; bool val = false; EnterCriticalSection(&csMemFilesLock); auto it = m_MEM_Files.find(wTex); if(it != m_MEM_Files.end()) val = true; LeaveCriticalSection(&csMemFilesLock); return val; } bool CMinecraftApp::IsFileInMemoryTextures(const wstring &wName) { bool val = false; EnterCriticalSection(&csMemFilesLock); auto it = m_MEM_Files.find(wName); if(it != m_MEM_Files.end()) val = true; LeaveCriticalSection(&csMemFilesLock); return val; } void CMinecraftApp::GetMemFileDetails(const wstring &wName,PBYTE *ppbData,DWORD *pdwBytes) { EnterCriticalSection(&csMemFilesLock); auto it = m_MEM_Files.find(wName); if(it != m_MEM_Files.end()) { PMEMDATA pData = (*it).second; *ppbData=pData->pbData; *pdwBytes=pData->dwBytes; } LeaveCriticalSection(&csMemFilesLock); } void CMinecraftApp::AddMemoryTPDFile(int iConfig,PBYTE pbData,DWORD dwBytes) { EnterCriticalSection(&csMemTPDLock); // check it's not already in PMEMDATA pData=NULL; auto it = m_MEM_TPD.find(iConfig); if(it == m_MEM_TPD.end()) { pData = (PMEMDATA)new BYTE[sizeof(MEMDATA)]; ZeroMemory( pData, sizeof(MEMDATA) ); pData->pbData=pbData; pData->dwBytes=dwBytes; pData->ucRefCount = 1; m_MEM_TPD[iConfig]=pData; } LeaveCriticalSection(&csMemTPDLock); } void CMinecraftApp::RemoveMemoryTPDFile(int iConfig) { EnterCriticalSection(&csMemTPDLock); // check it's not already in PMEMDATA pData=NULL; auto it = m_MEM_TPD.find(iConfig); if(it != m_MEM_TPD.end()) { pData=m_MEM_TPD[iConfig]; delete [] pData; m_MEM_TPD.erase(iConfig); } LeaveCriticalSection(&csMemTPDLock); } #ifdef _XBOX int CMinecraftApp::GetTPConfigVal(WCHAR *pwchDataFile) { DLC_INFO *pDLCInfo=NULL; // run through the DLC info to find the right texture pack/mash-up pack for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i) { ULONGLONG ull=app.GetDLCInfoTexturesFullOffer(i); pDLCInfo=app.GetDLCInfoForFullOfferID(ull); if(wcscmp(pwchDataFile,pDLCInfo->wchDataFile)==0) { return pDLCInfo->iConfig; } } return -1; } #elif defined _XBOX_ONE int CMinecraftApp::GetTPConfigVal(WCHAR *pwchDataFile) { DLC_INFO *pDLCInfo=NULL; // run through the DLC info to find the right texture pack/mash-up pack for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i) { pDLCInfo=app.GetDLCInfoForFullOfferID((WCHAR *)app.GetDLCInfoTexturesFullOffer(i).c_str()); if(wcscmp(pwchDataFile,pDLCInfo->wchDataFile)==0) { return pDLCInfo->iConfig; } } return -1; } #elif defined _WINDOWS64 int CMinecraftApp::GetTPConfigVal(WCHAR *pwchDataFile) { return -1; } #endif bool CMinecraftApp::IsFileInTPD(int iConfig) { bool val = false; EnterCriticalSection(&csMemTPDLock); auto it = m_MEM_TPD.find(iConfig); if(it != m_MEM_TPD.end()) val = true; LeaveCriticalSection(&csMemTPDLock); return val; } void CMinecraftApp::GetTPD(int iConfig,PBYTE *ppbData,DWORD *pdwBytes) { EnterCriticalSection(&csMemTPDLock); auto it = m_MEM_TPD.find(iConfig); if(it != m_MEM_TPD.end()) { PMEMDATA pData = (*it).second; *ppbData=pData->pbData; *pdwBytes=pData->dwBytes; } LeaveCriticalSection(&csMemTPDLock); } // bool CMinecraftApp::UploadFileToGlobalStorage(int iQuadrant, C4JStorage::eGlobalStorage eStorageFacility, wstring *wsFile ) // { // bool bRes=false; // #ifndef _CONTENT_PACKAGE // // read the local file // File gtsFile( wsFile->c_str() ); // // int64_t fileSize = gtsFile.length(); // // if(fileSize!=0) // { // FileInputStream fis(gtsFile); // byteArray ba((int)fileSize); // fis.read(ba); // fis.close(); // // bRes=StorageManager.WriteTMSFile(iQuadrant,eStorageFacility,(WCHAR *)wsFile->c_str(),ba.data, ba.length); // // } // #endif // return bRes; // } void CMinecraftApp::StoreLaunchData() { } void CMinecraftApp::ExitGame() { } // Invites void CMinecraftApp::ProcessInvite(DWORD dwUserIndex, DWORD dwLocalUsersMask, const INVITE_INFO * pInviteInfo) { m_InviteData.dwUserIndex=dwUserIndex; m_InviteData.dwLocalUsersMask=dwLocalUsersMask; m_InviteData.pInviteInfo=pInviteInfo; //memcpy(&m_InviteData,pJoinData,sizeof(JoinFromInviteData)); SetAction(dwUserIndex,eAppAction_ExitAndJoinFromInvite); } int CMinecraftApp::ExitAndJoinFromInvite(void *pParam,int iPad,C4JStorage::EMessageResult result) { CMinecraftApp* pApp = (CMinecraftApp*)pParam; //Minecraft *pMinecraft=Minecraft::GetInstance(); // buttons are swapped on this menu if(result==C4JStorage::EMessage_ResultDecline) { pApp->SetAction(iPad,eAppAction_ExitAndJoinFromInviteConfirmed); } return 0; } int CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) { CMinecraftApp *pClass = (CMinecraftApp *)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 { // Check they have the full texture pack if they are using one // 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(); DLCPack * pDLCPack=tPack->getDLCPack(); if(!pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) { // upsell // get the dlc texture pack #ifdef _XBOX DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; ULONGLONG ullOfferID_Full; 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.RequestErrorMessage(IDS_WARNING_DLC_TRIALTEXTUREPACK_TITLE, IDS_WARNING_DLC_TRIALTEXTUREPACK_TEXT, uiIDA, 2, iPad,&CMinecraftApp::WarningTrialTexturePackReturned,pClass); return S_OK; } } #ifndef _XBOX_ONE // 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.RequestErrorMessage(IDS_TITLE_SAVE_GAME, IDS_CONFIRM_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::ExitAndJoinFromInviteAndSaveReturned,pClass); return 0; } else #endif { #if defined(_XBOX_ONE) || defined(__ORBIS__) StorageManager.SetSaveDisabled(false); #endif 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.RequestErrorMessage(IDS_TITLE_DECLINE_SAVE_GAME, IDS_CONFIRM_DECLINE_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::ExitAndJoinFromInviteDeclineSaveReturned,pClass); return 0; } app.SetAction(ProfileManager.GetPrimaryPad(),eAppAction_ExitAndJoinFromInviteConfirmed); } return 0; } int CMinecraftApp::WarningTrialTexturePackReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) { // 4J Stu - I added this in when fixing an X1 bug. We should probably add this as well but I don't have time to test all platforms atm #if 0 //defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) if(result==C4JStorage::EMessage_ResultAccept) { if(!ProfileManager.IsSignedInLive(iPad)) { // you're not signed in to PSN! } else { // 4J-PB - need to check this user can access the store bool bContentRestricted; ProfileManager.GetChatAndContentRestrictions(iPad,true,NULL,&bContentRestricted,NULL); if(bContentRestricted) { UINT uiIDA[1]; uiIDA[0]=IDS_CONFIRM_OK; ui.RequestAlertMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, iPad); } else { // need to get info on the pack to see if the user has already downloaded it TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; // retrieve the store name for the skin pack DLCPack *pDLCPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack(); const char *pchPackName=wstringtofilename(pDLCPack->getName()); app.DebugPrintf("Texture Pack - %s\n",pchPackName); SONYDLC *pSONYDLCInfo=app.GetSONYDLCInfo((char *)pchPackName); if(pSONYDLCInfo!=NULL) { char chName[42]; char chSkuID[SCE_NP_COMMERCE2_SKU_ID_LEN]; memset(chSkuID,0,SCE_NP_COMMERCE2_SKU_ID_LEN); // find the info on the skin pack // we have to retrieve the skuid from the store info, it can't be hardcoded since Sony may change it. // So we assume the first sku for the product is the one we want #ifdef __ORBIS__ sprintf(chName,"%s",pSONYDLCInfo->chDLCKeyname); #else sprintf(chName,"%s-%s",app.GetCommerceCategory(),pSONYDLCInfo->chDLCKeyname); #endif app.GetDLCSkuIDFromProductList(chName,chSkuID); // 4J-PB - need to check for an empty store #if defined __ORBIS__ || defined __PSVITA__ || defined __PS3__ if(app.CheckForEmptyStore(iPad)==false) #endif { if(app.DLCAlreadyPurchased(chSkuID)) { app.DownloadAlreadyPurchased(chSkuID); } else { app.Checkout(chSkuID); } } } } } } #endif // #ifdef _XBOX_ONE if(result==C4JStorage::EMessage_ResultAccept) { if(ProfileManager.IsSignedIn(iPad)) { if (ProfileManager.IsSignedInLive(iPad)) { TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); // get the dlc texture pack DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; DLCPack *pDLCPack=pDLCTexPack->getDLCInfoParentPack(); DLC_INFO *pDLCInfo=app.GetDLCInfoForProductName((WCHAR *)pDLCPack->getName().c_str()); StorageManager.InstallOffer(1,(WCHAR *)pDLCInfo->wsProductId.c_str(),NULL,NULL); // the license change coming in when the offer has been installed will cause this scene to refresh } else { // 4J-JEV: Fix for XB1: #165863 - XR-074: Compliance: With no active network connection user is unable to convert from Trial to Full texture pack and is not messaged why. UINT uiIDA[1] = { IDS_CONFIRM_OK }; ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_XBOXLIVE_NOTIFICATION, uiIDA, 1, iPad); } } } #endif #ifdef _XBOX CMinecraftApp* pClass = (CMinecraftApp*)pParam; TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); // get the dlc texture pack DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; ULONGLONG ullIndexA[1]; // 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]); if(result==C4JStorage::EMessage_ResultAccept) { if(ProfileManager.IsSignedIn(iPad)) { // 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, ( ullIndexA[0] & 0xFFFFFFFF ), eSen_UpsellOutcome_Declined); } #endif return 0; } int CMinecraftApp::ExitAndJoinFromInviteAndSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) { //CMinecraftApp* pClass = (CMinecraftApp*)pParam; // results switched for this dialog if(result==C4JStorage::EMessage_ResultDecline) { INT saveOrCheckpointId = 0; // Check they have the full texture pack if they are using one // 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(); DLCPack * pDLCPack=tPack->getDLCPack(); if(!pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) { // upsell // get the dlc texture pack #ifdef _XBOX DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; ULONGLONG ullOfferID_Full; 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.RequestErrorMessage(IDS_WARNING_DLC_TRIALTEXTUREPACK_TITLE, IDS_WARNING_DLC_TRIALTEXTUREPACK_TEXT, uiIDA, 2, iPad,&CMinecraftApp::WarningTrialTexturePackReturned,NULL); return S_OK; } } //bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId); //SentientManager.RecordLevelSaveOrCheckpoint(ProfileManager.GetPrimaryPad(), saveOrCheckpointId); MinecraftServer::getInstance()->setSaveOnExit( true ); // flag a app action of exit and join game from invite app.SetAction(iPad,eAppAction_ExitAndJoinFromInviteConfirmed); } return 0; } int CMinecraftApp::ExitAndJoinFromInviteDeclineSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) { // results switched for this dialog if(result==C4JStorage::EMessage_ResultDecline) { #if defined(_XBOX_ONE) || defined(__ORBIS__) StorageManager.SetSaveDisabled(false); #endif MinecraftServer::getInstance()->setSaveOnExit( false ); // flag a app action of exit and join game from invite app.SetAction(iPad,eAppAction_ExitAndJoinFromInviteConfirmed); } return 0; } ////////////////////////////////////////////////////////////////////////// // // FatalLoadError // // This is called when we can't load one of the required files at startup // It tends to mean the files have been corrupted. // We have to assume that we've not been able to load the text for the game. // ////////////////////////////////////////////////////////////////////////// void CMinecraftApp::FatalLoadError() { } TIPSTRUCT CMinecraftApp::m_GameTipA[MAX_TIPS_GAMETIP]= { { 0, IDS_TIPS_GAMETIP_1}, { 0, IDS_TIPS_GAMETIP_2}, { 0, IDS_TIPS_GAMETIP_3}, { 0, IDS_TIPS_GAMETIP_4}, { 0, IDS_TIPS_GAMETIP_5}, { 0, IDS_TIPS_GAMETIP_6}, { 0, IDS_TIPS_GAMETIP_7}, { 0, IDS_TIPS_GAMETIP_8}, { 0, IDS_TIPS_GAMETIP_9}, { 0, IDS_TIPS_GAMETIP_10}, { 0, IDS_TIPS_GAMETIP_11}, { 0, IDS_TIPS_GAMETIP_12}, { 0, IDS_TIPS_GAMETIP_13}, { 0, IDS_TIPS_GAMETIP_14}, { 0, IDS_TIPS_GAMETIP_15}, { 0, IDS_TIPS_GAMETIP_16}, { 0, IDS_TIPS_GAMETIP_17}, { 0, IDS_TIPS_GAMETIP_18}, { 0, IDS_TIPS_GAMETIP_19}, { 0, IDS_TIPS_GAMETIP_20}, { 0, IDS_TIPS_GAMETIP_21}, { 0, IDS_TIPS_GAMETIP_22}, { 0, IDS_TIPS_GAMETIP_23}, { 0, IDS_TIPS_GAMETIP_24}, { 0, IDS_TIPS_GAMETIP_25}, { 0, IDS_TIPS_GAMETIP_26}, { 0, IDS_TIPS_GAMETIP_27}, { 0, IDS_TIPS_GAMETIP_28}, { 0, IDS_TIPS_GAMETIP_29}, { 0, IDS_TIPS_GAMETIP_30}, { 0, IDS_TIPS_GAMETIP_31}, { 0, IDS_TIPS_GAMETIP_32}, { 0, IDS_TIPS_GAMETIP_33}, { 0, IDS_TIPS_GAMETIP_34}, { 0, IDS_TIPS_GAMETIP_35}, { 0, IDS_TIPS_GAMETIP_36}, { 0, IDS_TIPS_GAMETIP_37}, { 0, IDS_TIPS_GAMETIP_38}, { 0, IDS_TIPS_GAMETIP_39}, { 0, IDS_TIPS_GAMETIP_40}, { 0, IDS_TIPS_GAMETIP_41}, { 0, IDS_TIPS_GAMETIP_42}, { 0, IDS_TIPS_GAMETIP_43}, { 0, IDS_TIPS_GAMETIP_44}, { 0, IDS_TIPS_GAMETIP_45}, { 0, IDS_TIPS_GAMETIP_46}, { 0, IDS_TIPS_GAMETIP_47}, { 0, IDS_TIPS_GAMETIP_48}, { 0, IDS_TIPS_GAMETIP_49}, { 0, IDS_TIPS_GAMETIP_50}, }; TIPSTRUCT CMinecraftApp::m_TriviaTipA[MAX_TIPS_TRIVIATIP]= { { 0, IDS_TIPS_TRIVIA_1}, { 0, IDS_TIPS_TRIVIA_2}, { 0, IDS_TIPS_TRIVIA_3}, { 0, IDS_TIPS_TRIVIA_4}, { 0, IDS_TIPS_TRIVIA_5}, { 0, IDS_TIPS_TRIVIA_6}, { 0, IDS_TIPS_TRIVIA_7}, { 0, IDS_TIPS_TRIVIA_8}, { 0, IDS_TIPS_TRIVIA_9}, { 0, IDS_TIPS_TRIVIA_10}, { 0, IDS_TIPS_TRIVIA_11}, { 0, IDS_TIPS_TRIVIA_12}, { 0, IDS_TIPS_TRIVIA_13}, { 0, IDS_TIPS_TRIVIA_14}, { 0, IDS_TIPS_TRIVIA_15}, { 0, IDS_TIPS_TRIVIA_16}, { 0, IDS_TIPS_TRIVIA_17}, { 0, IDS_TIPS_TRIVIA_18}, { 0, IDS_TIPS_TRIVIA_19}, { 0, IDS_TIPS_TRIVIA_20}, }; Random *CMinecraftApp::TipRandom = new Random(); int CMinecraftApp::TipsSortFunction(const void* a, const void* b) { return ((TIPSTRUCT*)a)->iSortValue - ((TIPSTRUCT*)b)->iSortValue; } void CMinecraftApp::InitialiseTips() { // We'll randomise the tips at start up based on their priority ZeroMemory(m_TipIDA,sizeof(UINT)*MAX_TIPS_GAMETIP+MAX_TIPS_TRIVIATIP); // Make the first tip tell you that you can play splitscreen in HD modes if you are in SD if(!RenderManager.IsHiDef()) { m_GameTipA[0].uiStringID=IDS_TIPS_GAMETIP_0; } // randomise then quicksort // going to leave the multiplayer tip so it is always first // Only randomise the content package build #ifdef _CONTENT_PACKAGE for(int i=1;inextInt(); } qsort( &m_GameTipA[1], MAX_TIPS_GAMETIP-1, sizeof(TIPSTRUCT), TipsSortFunction ); #endif for(int i=0;inextInt(); } qsort( m_TriviaTipA, MAX_TIPS_TRIVIATIP, sizeof(TIPSTRUCT), TipsSortFunction ); int iCurrentGameTip=0; int iCurrentTriviaTip=0; for(int i=0;iskins->getSelected()->getColourTable()->getColour(colour); } int CMinecraftApp::GetHTMLFontSize(EHTMLFontSize size) { return s_iHTMLFontSizesA[size]; } wstring CMinecraftApp::FormatHTMLString(int iPad, const wstring &desc, int shadowColour /*= 0xFFFFFFFF*/) { wstring text(desc); wchar_t replacements[64]; // We will also insert line breaks here as couldn't figure out how to get them to come through from strings.resx ! text = replaceAll(text, L"{*B*}", L"
" ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_T1)); text = replaceAll(text, L"{*T1*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_T2)); text = replaceAll(text, L"{*T2*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_T3)); text = replaceAll(text, L"{*T3*}", replacements ); // for How To Play swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_Black)); text = replaceAll(text, L"{*ETB*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_White)); text = replaceAll(text, L"{*ETW*}", replacements ); text = replaceAll(text, L"{*EF*}", L"" ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_0), shadowColour); text = replaceAll(text, L"{*C0*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_1), shadowColour); text = replaceAll(text, L"{*C1*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_2), shadowColour); text = replaceAll(text, L"{*C2*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_3), shadowColour); text = replaceAll(text, L"{*C3*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_4), shadowColour); text = replaceAll(text, L"{*C4*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_5), shadowColour); text = replaceAll(text, L"{*C5*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_6), shadowColour); text = replaceAll(text, L"{*C6*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_7), shadowColour); text = replaceAll(text, L"{*C7*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_8), shadowColour); text = replaceAll(text, L"{*C8*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_9), shadowColour); text = replaceAll(text, L"{*C9*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_a), shadowColour); text = replaceAll(text, L"{*CA*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_b), shadowColour); text = replaceAll(text, L"{*CB*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_c), shadowColour); text = replaceAll(text, L"{*CC*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_d), shadowColour); text = replaceAll(text, L"{*CD*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_e), shadowColour); text = replaceAll(text, L"{*CE*}", replacements ); swprintf(replacements,64,L"", GetHTMLColour(eHTMLColor_f), shadowColour); text = replaceAll(text, L"{*CF*}", replacements ); // Swap for southpaw. if ( app.GetGameSettings(iPad,eGameSetting_ControlSouthPaw) ) { text = replaceAll(text, L"{*CONTROLLER_ACTION_MOVE*}", GetActionReplacement(iPad,MINECRAFT_ACTION_LOOK_RIGHT ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_LOOK*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RIGHT ) ); text = replaceAll(text, L"{*CONTROLLER_MENU_NAVIGATE*}", GetVKReplacement(VK_PAD_RTHUMB_LEFT) ); } else // Normal right handed. { text = replaceAll(text, L"{*CONTROLLER_ACTION_MOVE*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RIGHT ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_LOOK*}", GetActionReplacement(iPad,MINECRAFT_ACTION_LOOK_RIGHT ) ); text = replaceAll(text, L"{*CONTROLLER_MENU_NAVIGATE*}", GetVKReplacement(VK_PAD_LTHUMB_LEFT) ); } text = replaceAll(text, L"{*CONTROLLER_ACTION_JUMP*}", GetActionReplacement(iPad,MINECRAFT_ACTION_JUMP ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_SNEAK*}", GetActionReplacement(iPad,MINECRAFT_ACTION_SNEAK_TOGGLE ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_USE*}", GetActionReplacement(iPad,MINECRAFT_ACTION_USE ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_ACTION*}", GetActionReplacement(iPad,MINECRAFT_ACTION_ACTION ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_LEFT_SCROLL*}", GetActionReplacement(iPad,MINECRAFT_ACTION_LEFT_SCROLL ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_RIGHT_SCROLL*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RIGHT_SCROLL ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_INVENTORY*}", GetActionReplacement(iPad,MINECRAFT_ACTION_INVENTORY ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_CRAFTING*}", GetActionReplacement(iPad,MINECRAFT_ACTION_CRAFTING ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_DROP*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DROP ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_CAMERA*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RENDER_THIRD_PERSON ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_MENU_PAGEDOWN*}", GetActionReplacement(iPad,ACTION_MENU_PAGEDOWN ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_DISMOUNT*}", GetActionReplacement(iPad,MINECRAFT_ACTION_SNEAK_TOGGLE ) ); text = replaceAll(text, L"{*CONTROLLER_VK_A*}", GetVKReplacement(VK_PAD_A) ); text = replaceAll(text, L"{*CONTROLLER_VK_B*}", GetVKReplacement(VK_PAD_B) ); text = replaceAll(text, L"{*CONTROLLER_VK_X*}", GetVKReplacement(VK_PAD_X) ); text = replaceAll(text, L"{*CONTROLLER_VK_Y*}", GetVKReplacement(VK_PAD_Y) ); text = replaceAll(text, L"{*CONTROLLER_VK_LB*}", GetVKReplacement(VK_PAD_LSHOULDER) ); text = replaceAll(text, L"{*CONTROLLER_VK_RB*}", GetVKReplacement(VK_PAD_RSHOULDER) ); text = replaceAll(text, L"{*CONTROLLER_VK_LS*}", GetVKReplacement(VK_PAD_LTHUMB_UP) ); text = replaceAll(text, L"{*CONTROLLER_VK_RS*}", GetVKReplacement(VK_PAD_RTHUMB_UP) ); text = replaceAll(text, L"{*CONTROLLER_VK_LT*}", GetVKReplacement(VK_PAD_LTRIGGER) ); text = replaceAll(text, L"{*CONTROLLER_VK_RT*}", GetVKReplacement(VK_PAD_RTRIGGER) ); text = replaceAll(text, L"{*ICON_SHANK_01*}", GetIconReplacement(XZP_ICON_SHANK_01) ); text = replaceAll(text, L"{*ICON_SHANK_03*}", GetIconReplacement(XZP_ICON_SHANK_03) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_UP*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_UP ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_DOWN*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_DOWN ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_RIGHT*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_RIGHT ) ); text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_LEFT*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_LEFT ) ); #if defined _XBOX_ONE || defined __PSVITA__ text = replaceAll(text, L"{*CONTROLLER_VK_START*}", GetVKReplacement(VK_PAD_START ) ); text = replaceAll(text, L"{*CONTROLLER_VK_BACK*}", GetVKReplacement(VK_PAD_BACK ) ); #endif #ifdef _XBOX wstring imageRoot = L""; Minecraft *pMinecraft = Minecraft::GetInstance(); imageRoot = pMinecraft->skins->getSelected()->getXuiRootPath(); text = replaceAll(text, L"{*IMAGEROOT*}", imageRoot); #endif // _XBOX // Fix for #8903 - UI: Localization: KOR/JPN/CHT: Button Icons are rendered with padding space, which looks no good DWORD dwLanguage = XGetLanguage( ); switch(dwLanguage) { case XC_LANGUAGE_KOREAN: case XC_LANGUAGE_JAPANESE: case XC_LANGUAGE_TCHINESE: text = replaceAll(text, L" ", L"" ); break; } return text; } wstring CMinecraftApp::GetActionReplacement(int iPad, unsigned char ucAction) { unsigned int input = InputManager.GetGameJoypadMaps(InputManager.GetJoypadMapVal(iPad) ,ucAction); #ifdef _XBOX switch(input) { case _360_JOY_BUTTON_A: return app.GetString( IDS_CONTROLLER_A ); case _360_JOY_BUTTON_B: return app.GetString( IDS_CONTROLLER_B ); case _360_JOY_BUTTON_X: return app.GetString( IDS_CONTROLLER_X ); case _360_JOY_BUTTON_Y: return app.GetString( IDS_CONTROLLER_Y ); case _360_JOY_BUTTON_LSTICK_UP: case _360_JOY_BUTTON_LSTICK_DOWN: case _360_JOY_BUTTON_LSTICK_LEFT: case _360_JOY_BUTTON_LSTICK_RIGHT: return app.GetString( IDS_CONTROLLER_LEFT_STICK ); case _360_JOY_BUTTON_RSTICK_LEFT: case _360_JOY_BUTTON_RSTICK_RIGHT: case _360_JOY_BUTTON_RSTICK_UP: case _360_JOY_BUTTON_RSTICK_DOWN: return app.GetString( IDS_CONTROLLER_RIGHT_STICK ); case _360_JOY_BUTTON_LT: return app.GetString( IDS_CONTROLLER_LEFT_TRIGGER ); case _360_JOY_BUTTON_RT: return app.GetString( IDS_CONTROLLER_RIGHT_TRIGGER ); case _360_JOY_BUTTON_RB: return app.GetString( IDS_CONTROLLER_RIGHT_BUMPER ); case _360_JOY_BUTTON_LB: return app.GetString( IDS_CONTROLLER_LEFT_BUMPER ); case _360_JOY_BUTTON_BACK: return app.GetString( IDS_CONTROLLER_BACK ); case _360_JOY_BUTTON_START: return app.GetString( IDS_CONTROLLER_START ); case _360_JOY_BUTTON_RTHUMB: return app.GetString( IDS_CONTROLLER_RIGHT_THUMBSTICK ); case _360_JOY_BUTTON_LTHUMB: return app.GetString( IDS_CONTROLLER_LEFT_THUMBSTICK ); case _360_JOY_BUTTON_DPAD_LEFT: return app.GetString( IDS_CONTROLLER_DPAD_L ); case _360_JOY_BUTTON_DPAD_RIGHT: return app.GetString( IDS_CONTROLLER_DPAD_R ); case _360_JOY_BUTTON_DPAD_UP: return app.GetString( IDS_CONTROLLER_DPAD_U ); case _360_JOY_BUTTON_DPAD_DOWN: return app.GetString( IDS_CONTROLLER_DPAD_D ); }; return L""; #else wstring replacement = L""; // 4J Stu - Some of our actions can be mapped to multiple physical buttons, so replaces the switch that was here if (input & _360_JOY_BUTTON_A) replacement = L"ButtonA"; else if(input &_360_JOY_BUTTON_B) replacement = L"ButtonB"; else if(input &_360_JOY_BUTTON_X) replacement = L"ButtonX"; else if(input &_360_JOY_BUTTON_Y) replacement = L"ButtonY"; else if( (input &_360_JOY_BUTTON_LSTICK_UP) || (input &_360_JOY_BUTTON_LSTICK_DOWN) || (input &_360_JOY_BUTTON_LSTICK_LEFT) || (input &_360_JOY_BUTTON_LSTICK_RIGHT) ) { replacement = L"ButtonLeftStick"; } else if( (input &_360_JOY_BUTTON_RSTICK_LEFT) || (input &_360_JOY_BUTTON_RSTICK_RIGHT) || (input &_360_JOY_BUTTON_RSTICK_UP) || (input &_360_JOY_BUTTON_RSTICK_DOWN) ) { replacement = L"ButtonRightStick"; } else if(input &_360_JOY_BUTTON_DPAD_LEFT) replacement = L"ButtonDpadL"; else if(input &_360_JOY_BUTTON_DPAD_RIGHT) replacement = L"ButtonDpadR"; else if(input &_360_JOY_BUTTON_DPAD_UP) replacement = L"ButtonDpadU"; else if(input &_360_JOY_BUTTON_DPAD_DOWN) replacement = L"ButtonDpadD"; else if(input &_360_JOY_BUTTON_LT) replacement = L"ButtonLeftTrigger"; else if(input &_360_JOY_BUTTON_RT) replacement = L"ButtonRightTrigger"; else if(input &_360_JOY_BUTTON_RB) replacement = L"ButtonRightBumper"; else if(input &_360_JOY_BUTTON_LB) replacement = L"ButtonLeftBumper"; else if(input &_360_JOY_BUTTON_BACK) replacement = L"ButtonBack"; else if(input &_360_JOY_BUTTON_START) replacement = L"ButtonStart"; else if(input &_360_JOY_BUTTON_RTHUMB) replacement = L"ButtonRS"; else if(input &_360_JOY_BUTTON_LTHUMB) replacement = L"ButtonLS"; wchar_t string[128]; #ifdef __PS3__ int size = 30; #elif defined _WIN64 int size = 45; if(ui.getScreenHeight() < 1080) size = 30; #else int size = 45; #endif swprintf(string,128,L"", replacement.c_str(), size, size); return string; #endif } wstring CMinecraftApp::GetVKReplacement(unsigned int uiVKey) { #ifdef _XBOX switch(uiVKey) { case VK_PAD_A: return app.GetString( IDS_CONTROLLER_A ); case VK_PAD_B: return app.GetString( IDS_CONTROLLER_B ); case VK_PAD_X: return app.GetString( IDS_CONTROLLER_X ); case VK_PAD_Y: return app.GetString( IDS_CONTROLLER_Y ); case VK_PAD_LSHOULDER: return app.GetString( IDS_CONTROLLER_LEFT_BUMPER ); case VK_PAD_RSHOULDER: return app.GetString( IDS_CONTROLLER_RIGHT_BUMPER ); case VK_PAD_LTRIGGER: return app.GetString( IDS_CONTROLLER_LEFT_TRIGGER ); case VK_PAD_RTRIGGER: return app.GetString( IDS_CONTROLLER_RIGHT_TRIGGER ); case VK_PAD_LTHUMB_UP : case VK_PAD_LTHUMB_DOWN : case VK_PAD_LTHUMB_RIGHT : case VK_PAD_LTHUMB_LEFT : case VK_PAD_LTHUMB_UPLEFT : case VK_PAD_LTHUMB_UPRIGHT : case VK_PAD_LTHUMB_DOWNRIGHT: case VK_PAD_LTHUMB_DOWNLEFT : return app.GetString( IDS_CONTROLLER_LEFT_STICK ); case VK_PAD_RTHUMB_UP : case VK_PAD_RTHUMB_DOWN : case VK_PAD_RTHUMB_RIGHT : case VK_PAD_RTHUMB_LEFT : case VK_PAD_RTHUMB_UPLEFT : case VK_PAD_RTHUMB_UPRIGHT : case VK_PAD_RTHUMB_DOWNRIGHT: case VK_PAD_RTHUMB_DOWNLEFT : return app.GetString( IDS_CONTROLLER_RIGHT_STICK ); default: break; } return NULL; #else wstring replacement = L""; switch(uiVKey) { case VK_PAD_A: #if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) if( InputManager.IsCircleCrossSwapped() ) replacement = L"ButtonB"; else replacement = L"ButtonA"; #else replacement = L"ButtonA"; #endif break; case VK_PAD_B: #if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) if( InputManager.IsCircleCrossSwapped() ) replacement = L"ButtonA"; else replacement = L"ButtonB"; #else replacement = L"ButtonB"; #endif break; case VK_PAD_X: replacement = L"ButtonX"; break; case VK_PAD_Y: replacement = L"ButtonY"; break; case VK_PAD_LSHOULDER: replacement = L"ButtonLeftBumper"; break; case VK_PAD_RSHOULDER: replacement = L"ButtonRightBumper"; break; case VK_PAD_LTRIGGER: replacement = L"ButtonLeftTrigger"; break; case VK_PAD_RTRIGGER: replacement = L"ButtonRightTrigger"; break; case VK_PAD_LTHUMB_UP : case VK_PAD_LTHUMB_DOWN : case VK_PAD_LTHUMB_RIGHT : case VK_PAD_LTHUMB_LEFT : case VK_PAD_LTHUMB_UPLEFT : case VK_PAD_LTHUMB_UPRIGHT : case VK_PAD_LTHUMB_DOWNRIGHT: case VK_PAD_LTHUMB_DOWNLEFT : replacement = L"ButtonLeftStick"; break; case VK_PAD_RTHUMB_UP : case VK_PAD_RTHUMB_DOWN : case VK_PAD_RTHUMB_RIGHT : case VK_PAD_RTHUMB_LEFT : case VK_PAD_RTHUMB_UPLEFT : case VK_PAD_RTHUMB_UPRIGHT : case VK_PAD_RTHUMB_DOWNRIGHT: case VK_PAD_RTHUMB_DOWNLEFT : replacement = L"ButtonRightStick"; break; #if defined _XBOX_ONE || defined __PSVITA__ case VK_PAD_START: replacement = L"ButtonStart"; break; case VK_PAD_BACK: replacement = L"ButtonBack"; break; #endif default: break; } wchar_t string[128]; #ifdef __PS3__ int size = 30; #elif defined _WIN64 int size = 45; if(ui.getScreenHeight() < 1080) size = 30; #else int size = 45; #endif swprintf(string,128,L"", replacement.c_str(), size, size); return string; #endif } wstring CMinecraftApp::GetIconReplacement(unsigned int uiIcon) { #ifdef _XBOX switch(uiIcon) { case XZP_ICON_SHANK_01: return app.GetString( IDS_ICON_SHANK_01 ); case XZP_ICON_SHANK_03: return app.GetString( IDS_ICON_SHANK_03 ); default: break; } return NULL; #else wchar_t string[128]; #ifdef __PS3__ int size = 22; #elif defined _WIN64 int size = 33; if(ui.getScreenHeight() < 1080) size = 22; #else int size = 33; #endif swprintf(string,128,L"", size, size); wstring result = L""; switch(uiIcon) { case XZP_ICON_SHANK_01: result = string; break; case XZP_ICON_SHANK_03: result.append(string).append(string).append(string); break; default: break; } return result; #endif } #if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) unordered_map CMinecraftApp::MojangData; unordered_map CMinecraftApp::DLCTextures_PackID; unordered_map CMinecraftApp::DLCInfo; unordered_map CMinecraftApp::DLCInfo_SkinName; #elif defined(_DURANGO) unordered_map CMinecraftApp::MojangData; unordered_map CMinecraftApp::DLCTextures_PackID; // for mash-up packs & texture packs //unordered_map CMinecraftApp::DLCInfo_Trial; // full offerid, dlc_info unordered_map CMinecraftApp::DLCInfo_Full; // full offerid, dlc_info unordered_map CMinecraftApp::DLCInfo_SkinName; // skin name, full offer id #else unordered_map CMinecraftApp::MojangData; unordered_map CMinecraftApp::DLCTextures_PackID; unordered_map CMinecraftApp::DLCInfo_Trial; unordered_map CMinecraftApp::DLCInfo_Full; unordered_map CMinecraftApp::DLCInfo_SkinName; #endif HRESULT CMinecraftApp::RegisterMojangData(WCHAR *pXuidName, PlayerUID xuid, WCHAR *pSkin, WCHAR *pCape) { HRESULT hr=S_OK; eXUID eTempXuid=eXUID_Undefined; MOJANG_DATA *pMojangData=NULL; // ignore the names if we don't recognize them if(pXuidName!=NULL) { if( wcscmp( pXuidName, L"XUID_NOTCH" ) == 0 ) { eTempXuid = eXUID_Notch; // might be needed for the apple at some point } else if( wcscmp( pXuidName, L"XUID_DEADMAU5" ) == 0 ) { eTempXuid = eXUID_Deadmau5; // Needed for the deadmau5 ears } else { eTempXuid=eXUID_NoName; } } if(eTempXuid!=eXUID_Undefined) { pMojangData = new MOJANG_DATA; ZeroMemory(pMojangData,sizeof(MOJANG_DATA)); pMojangData->eXuid=eTempXuid; wcsncpy( pMojangData->wchSkin, pSkin, MAX_CAPENAME_SIZE); wcsncpy( pMojangData->wchCape, pCape, MAX_CAPENAME_SIZE); MojangData[xuid]=pMojangData; } return hr; } MOJANG_DATA *CMinecraftApp::GetMojangDataForXuid(PlayerUID xuid) { return MojangData[xuid]; } HRESULT CMinecraftApp::RegisterConfigValues(WCHAR *pType, int iValue) { HRESULT hr=S_OK; // #ifdef _XBOX // if(pType!=NULL) // { // if(wcscmp(pType,L"XboxOneTransfer")==0) // { // if(iValue>0) // { // app.m_bTransferSavesToXboxOne=true; // } // else // { // app.m_bTransferSavesToXboxOne=false; // } // } // else if(wcscmp(pType,L"TransferSlotCount")==0) // { // app.m_uiTransferSlotC=iValue; // } // // } // #endif return hr; } #if (defined _XBOX || defined _WINDOWS64) HRESULT CMinecraftApp::RegisterDLCData(WCHAR *pType, WCHAR *pBannerName, int iGender, uint64_t ullOfferID_Full, uint64_t ullOfferID_Trial, WCHAR *pFirstSkin, unsigned int uiSortIndex, int iConfig, WCHAR *pDataFile) { HRESULT hr=S_OK; DLC_INFO *pDLCData=new DLC_INFO; ZeroMemory(pDLCData,sizeof(DLC_INFO)); pDLCData->ullOfferID_Full=ullOfferID_Full; pDLCData->ullOfferID_Trial=ullOfferID_Trial; pDLCData->eDLCType=e_DLC_NotDefined; pDLCData->iGender=iGender; pDLCData->uiSortIndex=uiSortIndex; pDLCData->iConfig=iConfig; #ifndef __ORBIS__ // ignore the names if we don't recognize them if(pBannerName!=L"") { wcsncpy_s( pDLCData->wchBanner, pBannerName, MAX_BANNERNAME_SIZE); } if(pDataFile[0]!=0) { wcsncpy_s( pDLCData->wchDataFile, pDataFile, MAX_BANNERNAME_SIZE); } #endif if(pType!=NULL) { if(wcscmp(pType,L"Skin")==0) { pDLCData->eDLCType=e_DLC_SkinPack; } else if(wcscmp(pType,L"Gamerpic")==0) { pDLCData->eDLCType=e_DLC_Gamerpics; } else if(wcscmp(pType,L"Theme")==0) { pDLCData->eDLCType=e_DLC_Themes; } else if(wcscmp(pType,L"Avatar")==0) { pDLCData->eDLCType=e_DLC_AvatarItems; } else if(wcscmp(pType,L"MashUpPack")==0) { pDLCData->eDLCType=e_DLC_MashupPacks; DLCTextures_PackID[pDLCData->iConfig]=ullOfferID_Full; } else if(wcscmp(pType,L"TexturePack")==0) { pDLCData->eDLCType=e_DLC_TexturePacks; DLCTextures_PackID[pDLCData->iConfig]=ullOfferID_Full; } } if(ullOfferID_Trial!=0ll) DLCInfo_Trial[ullOfferID_Trial]=pDLCData; if(ullOfferID_Full!=0ll) DLCInfo_Full[ullOfferID_Full]=pDLCData; if(pFirstSkin[0]!=0) DLCInfo_SkinName[pFirstSkin]=ullOfferID_Full; return hr; } #elif defined _XBOX_ONE unordered_map *CMinecraftApp::GetDLCInfo() { return &DLCInfo_Full; } HRESULT CMinecraftApp::RegisterDLCData(eDLCContentType eType, WCHAR *pwchBannerName,WCHAR *pwchProductId, WCHAR *pwchProductName, WCHAR *pwchFirstSkin, int iConfig, unsigned int uiSortIndex) { HRESULT hr=S_OK; // 4J-PB - need to convert the product id to uppercase because the catalog calls come back with upper case WCHAR wchUppercaseProductID[64]; if(pwchProductId[0]!=0) { for(int i=0;i<64;i++) { wchUppercaseProductID[i]=towupper((wchar_t)pwchProductId[i]); } } // check if we already have this info from the local DLC file wstring wsTemp=wchUppercaseProductID; auto it = DLCInfo_Full.find(wsTemp); if( it == DLCInfo_Full.end() ) { // Not found DLC_INFO *pDLCData=new DLC_INFO; ZeroMemory(pDLCData,sizeof(DLC_INFO)); pDLCData->eDLCType=e_DLC_NotDefined; pDLCData->uiSortIndex=uiSortIndex; pDLCData->iConfig=iConfig; if(pwchProductId[0]!=0) { pDLCData->wsProductId=wchUppercaseProductID; } // ignore the names if we don't recognize them if(pwchBannerName!=L"") { wcsncpy_s( pDLCData->wchBanner, pwchBannerName, MAX_BANNERNAME_SIZE); } if(pwchProductName[0]!=0) { pDLCData->wsDisplayName=pwchProductName; } pDLCData->eDLCType=eType; switch(eType) { case e_DLC_MashupPacks: case e_DLC_TexturePacks: DLCTextures_PackID[iConfig]=pDLCData->wsProductId; break; } if(pwchFirstSkin[0]!=0) DLCInfo_SkinName[pwchFirstSkin]=pDLCData->wsProductId; #ifdef _XBOX_ONE // ignore the names, and use the product id instead DLCInfo_Full[pDLCData->wsProductId]=pDLCData; #else DLCInfo_Full[pDLCData->wsDisplayName]=pDLCData; #endif } app.DebugPrintf("DLCInfo - type - %d, productID - %ls, name - %ls , banner - %ls, iconfig - %d, sort index - %d\n",eType,pwchProductId, pwchProductName,pwchBannerName, iConfig, uiSortIndex); return hr; } #else HRESULT CMinecraftApp::RegisterDLCData(char *pchDLCName, unsigned int uiSortIndex,char *pchImageURL) { // on PS3 we get all the required info from the name char chDLCType[3]; HRESULT hr=S_OK; DLC_INFO *pDLCData=new DLC_INFO; ZeroMemory(pDLCData,sizeof(DLC_INFO)); chDLCType[0]=pchDLCName[0]; chDLCType[1]=pchDLCName[1]; chDLCType[2]=0; pDLCData->iConfig = app.GetiConfigFromName(pchDLCName); pDLCData->uiSortIndex=uiSortIndex; pDLCData->eDLCType = app.GetDLCTypeFromName(pchDLCName); strcpy(pDLCData->chImageURL,pchImageURL); //bool bIsTrialDLC = app.GetTrialFromName(pchDLCName); switch(pDLCData->eDLCType) { case e_DLC_TexturePacks: { char *pchName=(char *)malloc(strlen(pchDLCName)+1); strcpy(pchName,pchDLCName); DLCTextures_PackID[pDLCData->iConfig]=pchName; } break; case e_DLC_MashupPacks: { char *pchName=(char *)malloc(strlen(pchDLCName)+1); strcpy(pchName,pchDLCName); DLCTextures_PackID[pDLCData->iConfig]=pchName; } break; default: break; } app.DebugPrintf(5,"Adding DLC - %s\n",pchDLCName); DLCInfo[pchDLCName]=pDLCData; // if(ullOfferID_Trial!=0ll) DLCInfo_Trial[ullOfferID_Trial]=pDLCData; // if(ullOfferID_Full!=0ll) DLCInfo_Full[ullOfferID_Full]=pDLCData; // if(pFirstSkin[0]!=0) DLCInfo_SkinName[pFirstSkin]=ullOfferID_Full; // DLCInfo[ullOfferID_Trial]=pDLCData; return hr; } #endif #if defined( __PS3__) || defined(__ORBIS__) || defined(__PSVITA__) bool CMinecraftApp::GetDLCFullOfferIDForSkinID(const wstring &FirstSkin,ULONGLONG *pullVal) { auto it = DLCInfo_SkinName.find(FirstSkin); if( it == DLCInfo_SkinName.end() ) { return false; } else { *pullVal=(ULONGLONG)it->second; return true; } } bool CMinecraftApp::GetDLCNameForPackID(const int iPackID,char **ppchKeyID) { auto it = DLCTextures_PackID.find(iPackID); if( it == DLCTextures_PackID.end() ) { *ppchKeyID=NULL; return false; } else { *ppchKeyID=(char *)it->second; return true; } } DLC_INFO *CMinecraftApp::GetDLCInfo(char *pchDLCName) { string tempString=pchDLCName; if(DLCInfo.size()>0) { auto it = DLCInfo.find(tempString); if( it == DLCInfo.end() ) { // nothing for this return NULL; } else { return it->second; } } else return NULL; } DLC_INFO *CMinecraftApp::GetDLCInfoFromTPackID(int iTPID) { unordered_map::iterator it= DLCInfo.begin(); for(int i=0;isecond)->iConfig==iTPID) { return it->second; } ++it; } return NULL; } DLC_INFO *CMinecraftApp::GetDLCInfo(int iIndex) { unordered_map::iterator it= DLCInfo.begin(); for(int i=0;isecond; } char *CMinecraftApp::GetDLCInfoTextures(int iIndex) { unordered_map::iterator it= DLCTextures_PackID.begin(); for(int i=0;isecond; } #elif defined _XBOX_ONE bool CMinecraftApp::GetDLCFullOfferIDForSkinID(const wstring &FirstSkin,wstring &ProductId) { auto it = DLCInfo_SkinName.find(FirstSkin); if( it == DLCInfo_SkinName.end() ) { return false; } else { ProductId=it->second; return true; } } bool CMinecraftApp::GetDLCFullOfferIDForPackID(const int iPackID,wstring &ProductId) { auto it = DLCTextures_PackID.find(iPackID); if( it == DLCTextures_PackID.end() ) { return false; } else { ProductId=it->second; return true; } } // DLC_INFO *CMinecraftApp::GetDLCInfoForTrialOfferID(wstring &ProductId) // { // return NULL; // } DLC_INFO *CMinecraftApp::GetDLCInfoTrialOffer(int iIndex) { return NULL; } DLC_INFO *CMinecraftApp::GetDLCInfoFullOffer(int iIndex) { unordered_map::iterator it= DLCInfo_Full.begin(); for(int i=0;isecond; } wstring CMinecraftApp::GetDLCInfoTexturesFullOffer(int iIndex) { unordered_map::iterator it= DLCTextures_PackID.begin(); for(int i=0;isecond; } #else bool CMinecraftApp::GetDLCFullOfferIDForSkinID(const wstring &FirstSkin,ULONGLONG *pullVal) { auto it = DLCInfo_SkinName.find(FirstSkin); if( it == DLCInfo_SkinName.end() ) { return false; } else { *pullVal=(ULONGLONG)it->second; return true; } } bool CMinecraftApp::GetDLCFullOfferIDForPackID(const int iPackID,ULONGLONG *pullVal) { auto it = DLCTextures_PackID.find(iPackID); if( it == DLCTextures_PackID.end() ) { *pullVal=0ULL; return false; } else { *pullVal=it->second; return true; } } DLC_INFO *CMinecraftApp::GetDLCInfoForTrialOfferID(ULONGLONG ullOfferID_Trial) { //DLC_INFO *pDLCInfo=NULL; if(DLCInfo_Trial.size()>0) { auto it = DLCInfo_Trial.find(ullOfferID_Trial); if( it == DLCInfo_Trial.end() ) { // nothing for this return NULL; } else { return it->second; } } else return NULL; } DLC_INFO *CMinecraftApp::GetDLCInfoTrialOffer(int iIndex) { unordered_map::iterator it= DLCInfo_Trial.begin(); for(int i=0;isecond; } DLC_INFO *CMinecraftApp::GetDLCInfoFullOffer(int iIndex) { unordered_map::iterator it= DLCInfo_Full.begin(); for(int i=0;isecond; } ULONGLONG CMinecraftApp::GetDLCInfoTexturesFullOffer(int iIndex) { unordered_map::iterator it= DLCTextures_PackID.begin(); for(int i=0;isecond; } #endif #ifdef _XBOX_ONE DLC_INFO *CMinecraftApp::GetDLCInfoForFullOfferID(WCHAR *pwchProductID) { wstring wsTemp = pwchProductID; if(DLCInfo_Full.size()>0) { auto it = DLCInfo_Full.find(wsTemp); if( it == DLCInfo_Full.end() ) { // nothing for this return NULL; } else { return it->second; } } else return NULL; } DLC_INFO *CMinecraftApp::GetDLCInfoForProductName(WCHAR *pwchProductName) { unordered_map::iterator it= DLCInfo_Full.begin(); wstring wsProductName=pwchProductName; for(int i=0;isecond; if(wsProductName==pDLCInfo->wsDisplayName) { return pDLCInfo; } ++it; } return NULL; } #elif defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) #else DLC_INFO *CMinecraftApp::GetDLCInfoForFullOfferID(ULONGLONG ullOfferID_Full) { if(DLCInfo_Full.size()>0) { auto it = DLCInfo_Full.find(ullOfferID_Full); if( it == DLCInfo_Full.end() ) { // nothing for this return NULL; } else { return it->second; } } else return NULL; } #endif void CMinecraftApp::EnterSaveNotificationSection() { EnterCriticalSection(&m_saveNotificationCriticalSection); if( m_saveNotificationDepth++ == 0 ) { if(g_NetworkManager.IsInSession()) // this can be triggered from the front end if we're downloading a save { MinecraftServer::getInstance()->broadcastStartSavingPacket(); if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) { app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)TRUE); } } } LeaveCriticalSection(&m_saveNotificationCriticalSection); } void CMinecraftApp::LeaveSaveNotificationSection() { EnterCriticalSection(&m_saveNotificationCriticalSection); if( --m_saveNotificationDepth == 0 ) { if(g_NetworkManager.IsInSession()) // this can be triggered from the front end if we're downloading a save { MinecraftServer::getInstance()->broadcastStopSavingPacket(); if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) { app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE); } } } LeaveCriticalSection(&m_saveNotificationCriticalSection); } int CMinecraftApp::RemoteSaveThreadProc( void* lpParameter ) { // The game should be stopped while we are doing this, but the connections ticks may try to create some AABB's or Vec3's AABB::UseDefaultThreadStorage(); Vec3::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); // 4J-PB - Xbox 360 - 163153 - [CRASH] TU17: Code: Multiplayer: During the Autosave in an online Multiplayer session, the game occasionally crashes for one or more Clients // callstack - > if(tls->tileId != this->id) updateDefaultShape(); // callstack - > default.exe!WaterlilyTile::getAABB(Level * level, int x, int y, int z) line 38 + 8 bytes C++ // ... // default.exe!CMinecraftApp::RemoteSaveThreadProc(void * lpParameter) line 6694 C++ // host autosave, and the clients can crash on receiving handleMoveEntity when it's a tile within this thread, so need to do the tls for tiles Tile::CreateNewThreadStorage(); Minecraft *pMinecraft = Minecraft::GetInstance(); pMinecraft->progressRenderer->progressStartNoAbort( IDS_PROGRESS_HOST_SAVING ); pMinecraft->progressRenderer->progressStage( -1 ); pMinecraft->progressRenderer->progressStagePercentage(0); while( !app.GetGameStarted() && app.GetXuiAction( ProfileManager.GetPrimaryPad() ) == eAppAction_WaitRemoteServerSaveComplete ) { // Tick all the games connections pMinecraft->tickAllConnections(); Sleep( 100 ); } if( app.GetXuiAction( ProfileManager.GetPrimaryPad() ) != eAppAction_WaitRemoteServerSaveComplete ) { // Something cancelled us? return ERROR_CANCELLED; } app.SetAction(ProfileManager.GetPrimaryPad(),eAppAction_Idle); ui.UpdatePlayerBasePositions(); Tile::ReleaseThreadStorage(); return S_OK; } void CMinecraftApp::ExitGameFromRemoteSave( LPVOID lpParameter ) { int primaryPad = ProfileManager.GetPrimaryPad(); UINT uiIDA[3]; uiIDA[0]=IDS_CONFIRM_CANCEL; uiIDA[1]=IDS_CONFIRM_OK; ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 2, primaryPad,&CMinecraftApp::ExitGameFromRemoteSaveDialogReturned,NULL); } int CMinecraftApp::ExitGameFromRemoteSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) { //CScene_Pause* pClass = (CScene_Pause*)pParam; // results switched for this dialog if(result==C4JStorage::EMessage_ResultDecline) { app.SetAction(iPad,eAppAction_ExitWorld); } else { #ifndef _XBOX // Inform fullscreen progress scene that it's not being cancelled after all UIScene_FullscreenProgress *pScene = (UIScene_FullscreenProgress *)ui.FindScene(eUIScene_FullscreenProgress); #ifdef __PS3__ if(pScene!=NULL) #else if (pScene != nullptr) #endif { pScene->SetWasCancelled(false); } #else // Don't have to worry about this on Xbox #endif } return 0; } void CMinecraftApp::SetSpecialTutorialCompletionFlag(int iPad, int index) { if(index >= 0 && index < 32 && GameSettingsA[iPad] != NULL) { GameSettingsA[iPad]->uiSpecialTutorialBitmask |= (1<clear(); if(BannedListA[iPad].pBannedList) { delete [] BannedListA[iPad].pBannedList; BannedListA[iPad].pBannedList=NULL; } } } #ifdef _XBOX_ONE void CMinecraftApp::AddLevelToBannedLevelList(int iPad, PBANNEDLISTDATA pBannedListData, bool bWriteToTMS) { PlayerUID xuid= pBannedListData->wchPlayerUID; AddLevelToBannedLevelList(iPad,xuid,pBannedListData->pszLevelName,bWriteToTMS); } #endif void CMinecraftApp::AddLevelToBannedLevelList(int iPad, PlayerUID xuid, char *pszLevelName, bool bWriteToTMS) { // we will have retrieved the banned level list from TMS, so add this one to it and write it back to TMS BANNEDLISTDATA *pBannedListData = new BANNEDLISTDATA; memset(pBannedListData,0,sizeof(BANNEDLISTDATA)); #ifdef _DURANGO memcpy(&pBannedListData->wchPlayerUID, xuid.toString().c_str(), sizeof(WCHAR)*64); #else memcpy(&pBannedListData->xuid, &xuid, sizeof(PlayerUID)); #endif strcpy(pBannedListData->pszLevelName,pszLevelName); m_vBannedListA[iPad]->push_back(pBannedListData); if(bWriteToTMS) { DWORD dwDataBytes=(DWORD)(sizeof(BANNEDLISTDATA)*m_vBannedListA[iPad]->size()); PBANNEDLISTDATA pBannedList = (BANNEDLISTDATA *)(new CHAR [dwDataBytes]); int iCount=0; for (PBANNEDLISTDATA pData : *m_vBannedListA[iPad] ) { memcpy(&pBannedList[iCount++],pData,sizeof(BANNEDLISTDATA)); } // 4J-PB - write to TMS++ now //bool bRes=StorageManager.WriteTMSFile(iPad,C4JStorage::eGlobalStorage_TitleUser,L"BannedList",(PBYTE)pBannedList, dwDataBytes); #ifdef _XBOX StorageManager.TMSPP_WriteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,C4JStorage::TMS_UGCTYPE_NONE,"BannedList",(PCHAR) pBannedList, dwDataBytes,NULL,NULL, 0); #elif defined _XBOX_ONE StorageManager.TMSPP_WriteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"BannedList",(PBYTE) pBannedList, dwDataBytes,NULL,NULL, 0); #endif } // update telemetry too } bool CMinecraftApp::IsInBannedLevelList(int iPad, PlayerUID xuid, char *pszLevelName) { for( PBANNEDLISTDATA pData : *m_vBannedListA[iPad] ) { #ifdef _XBOX_ONE PlayerUID bannedPlayerUID = pData->wchPlayerUID; if(IsEqualXUID (bannedPlayerUID,xuid) && (strcmp(pData->pszLevelName,pszLevelName)==0)) #else if(IsEqualXUID (pData->xuid,xuid) && (strcmp(pData->pszLevelName,pszLevelName)==0)) #endif { return true; } } return false; } void CMinecraftApp::RemoveLevelFromBannedLevelList(int iPad, PlayerUID xuid, char *pszLevelName) { //bool bFound=false; //bool bRes; // we will have retrieved the banned level list from TMS, so remove this one from it and write it back to TMS for (auto it = m_vBannedListA[iPad]->begin(); it != m_vBannedListA[iPad]->end(); ) { PBANNEDLISTDATA pBannedListData = *it; if(pBannedListData!=NULL) { #ifdef _XBOX_ONE PlayerUID bannedPlayerUID = pBannedListData->wchPlayerUID; if(IsEqualXUID (bannedPlayerUID,xuid) && (strcmp(pBannedListData->pszLevelName,pszLevelName)==0)) #else if(IsEqualXUID (pBannedListData->xuid,xuid) && (strcmp(pBannedListData->pszLevelName,pszLevelName)==0)) #endif { TelemetryManager->RecordUnBanLevel(iPad); // match found, so remove this entry it = m_vBannedListA[iPad]->erase(it); } else { ++it; } } else { ++it; } } DWORD dwDataBytes=(DWORD)(sizeof(BANNEDLISTDATA)*m_vBannedListA[iPad]->size()); if(dwDataBytes==0) { // wipe the file #ifdef _XBOX StorageManager.DeleteTMSFile(iPad,C4JStorage::eGlobalStorage_TitleUser,L"BannedList"); #elif defined _XBOX_ONE StorageManager.TMSPP_DeleteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"BannedList",NULL,NULL, 0); #endif } else { PBANNEDLISTDATA pBannedList = (BANNEDLISTDATA *)(new BYTE [dwDataBytes]); int iSize=(int)m_vBannedListA[iPad]->size(); for(int i=0;iat(i); memcpy(&pBannedList[i],pBannedListData,sizeof(BANNEDLISTDATA)); } #ifdef _XBOX StorageManager.WriteTMSFile(iPad,C4JStorage::eGlobalStorage_TitleUser,L"BannedList",(PBYTE)pBannedList, dwDataBytes); #elif defined _XBOX_ONE StorageManager.TMSPP_WriteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"BannedList",(PBYTE) pBannedList, dwDataBytes,NULL,NULL, 0); #endif delete [] pBannedList; } // update telemetry too } // function to add credits for the DLC packs void CMinecraftApp::AddCreditText(LPCWSTR lpStr) { DebugPrintf("ADDING CREDIT - %ls\n",lpStr); // add a string from the DLC to a credits vector SCreditTextItemDef *pCreditStruct = new SCreditTextItemDef; pCreditStruct->m_eType=eSmallText; pCreditStruct->m_iStringID[0]=NO_TRANSLATED_STRING; pCreditStruct->m_iStringID[1]=NO_TRANSLATED_STRING; pCreditStruct->m_Text=new WCHAR [wcslen(lpStr)+1]; wcscpy((WCHAR *)pCreditStruct->m_Text,lpStr); vDLCCredits.push_back(pCreditStruct); } bool CMinecraftApp::AlreadySeenCreditText(const wstring &wstemp) { for(unsigned int i=0;i>4; break; case eGameHostOption_All: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_ALL); break; case eGameHostOption_Tutorial: // special case - tutorial is offline, but we want the gamertag option, and set Easy mode, structures on, fire on, tnt on, pvp on, trust players on return ((uiHostSettings&GAME_HOST_OPTION_BITMASK_GAMERTAGS)| GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS| GAME_HOST_OPTION_BITMASK_FIRESPREADS| GAME_HOST_OPTION_BITMASK_TNT| GAME_HOST_OPTION_BITMASK_PVP| GAME_HOST_OPTION_BITMASK_STRUCTURES|1); break; case eGameHostOption_LevelType: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_LEVELTYPE); break; case eGameHostOption_Structures: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_STRUCTURES); break; case eGameHostOption_BonusChest: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_BONUSCHEST); break; case eGameHostOption_HasBeenInCreative: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_BEENINCREATIVE); break; case eGameHostOption_PvP: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_PVP); break; case eGameHostOption_TrustPlayers: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS); break; case eGameHostOption_TNT: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_TNT); break; case eGameHostOption_FireSpreads: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_FIRESPREADS); break; case eGameHostOption_CheatsEnabled: return (uiHostSettings&(GAME_HOST_OPTION_BITMASK_HOSTFLY|GAME_HOST_OPTION_BITMASK_HOSTHUNGER|GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE)); break; case eGameHostOption_HostCanFly: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HOSTFLY); break; case eGameHostOption_HostCanChangeHunger: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HOSTHUNGER); break; case eGameHostOption_HostCanBeInvisible: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE); break; case eGameHostOption_BedrockFog: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_BEDROCKFOG); break; case eGameHostOption_DisableSaving: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_DISABLESAVE); break; case eGameHostOption_WasntSaveOwner: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_NOTOWNER); case eGameHostOption_WorldSize: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_WORLDSIZE) >> GAME_HOST_OPTION_BITMASK_WORLDSIZE_BITSHIFT; case eGameHostOption_MobGriefing: return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_MOBGRIEFING); case eGameHostOption_KeepInventory: return (uiHostSettings&GAME_HOST_OPTION_BITMASK_KEEPINVENTORY); case eGameHostOption_DoMobSpawning: return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DOMOBSPAWNING); case eGameHostOption_DoMobLoot: return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DOMOBLOOT); case eGameHostOption_DoTileDrops: return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DOTILEDROPS); case eGameHostOption_NaturalRegeneration: return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_NATURALREGEN); case eGameHostOption_DoDaylightCycle: return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE); break; } return false; } bool CMinecraftApp::CanRecordStatsAndAchievements() { bool isTutorial = Minecraft::GetInstance() != NULL && Minecraft::GetInstance()->isTutorial(); // 4J Stu - All of these options give the host player some advantage, so should not allow achievements return !(app.GetGameHostOption(eGameHostOption_HasBeenInCreative) || app.GetGameHostOption(eGameHostOption_HostCanBeInvisible) || app.GetGameHostOption(eGameHostOption_HostCanChangeHunger) || app.GetGameHostOption(eGameHostOption_HostCanFly) || app.GetGameHostOption(eGameHostOption_WasntSaveOwner) || !app.GetGameHostOption(eGameHostOption_MobGriefing) || app.GetGameHostOption(eGameHostOption_KeepInventory) || !app.GetGameHostOption(eGameHostOption_DoMobSpawning) || (!app.GetGameHostOption(eGameHostOption_DoDaylightCycle) && !isTutorial ) ); } void CMinecraftApp::processSchematics(LevelChunk *levelChunk) { m_gameRules.processSchematics(levelChunk); } void CMinecraftApp::processSchematicsLighting(LevelChunk *levelChunk) { m_gameRules.processSchematicsLighting(levelChunk); } void CMinecraftApp::loadDefaultGameRules() { m_gameRules.loadDefaultGameRules(); } void CMinecraftApp::setLevelGenerationOptions(LevelGenerationOptions *levelGen) { m_gameRules.setLevelGenerationOptions(levelGen); } LPCWSTR CMinecraftApp::GetGameRulesString(const wstring &key) { return m_gameRules.GetGameRulesString(key); } unsigned char CMinecraftApp::m_szPNG[8]= { 137,80,78,71,13,10,26,10 }; #define PNG_TAG_tEXt 0x74455874 unsigned int CMinecraftApp::FromBigEndian(unsigned int uiValue) { #if defined(__PS3__) || defined(_XBOX) // Keep it in big endian return uiValue; #else unsigned int uiReturn = ( ( uiValue >> 24 ) & 0x000000ff ) | ( ( uiValue >> 8 ) & 0x0000ff00 ) | ( ( uiValue << 8 ) & 0x00ff0000 ) | ( ( uiValue << 24 ) & 0xff000000 ); return uiReturn; #endif } void CMinecraftApp::GetImageTextData(PBYTE pbImageData, DWORD dwImageBytes,unsigned char *pszSeed,unsigned int &uiHostOptions,bool &bHostOptionsRead,DWORD &uiTexturePack) { unsigned char *ucPtr=pbImageData; unsigned int uiCount=0; unsigned int uiChunkLen; unsigned int uiChunkType; unsigned int uiCRC; char szKeyword[80]; // check it's a png for(int i=0;i<8;i++) { if(m_szPNG[i]!=ucPtr[i]) return; } uiCount+=8; while(uiCount> std::hex >> uiHostOptions; } else if(strcmp(szKeyword,"4J_TEXTUREPACK")==0) { // read the texture pack value unsigned int uiValueC=0; unsigned char pszTexturePack[9]; // Hex representation of unsigned int ZeroMemory(&pszTexturePack,9); while(*pszKeyword!=0 && (pszKeyword < ucPtr + uiCount + uiChunkLen) && uiValueC < 8) { pszTexturePack[uiValueC++]=*pszKeyword; pszKeyword++; } std::stringstream ss; ss << pszTexturePack; ss >> std::hex >> uiTexturePack; } } } uiCount+=uiChunkLen; uiCRC=*(unsigned int*)&ucPtr[uiCount]; uiCRC=FromBigEndian(uiCRC); uiCount+=sizeof(int); } return; } unsigned int CMinecraftApp::CreateImageTextData(PBYTE bTextMetadata, int64_t seed, bool hasSeed, unsigned int uiHostOptions, unsigned int uiTexturePackId) { int iTextMetadataBytes = 0; if(hasSeed) { strcpy((char *)bTextMetadata,"4J_SEED"); _i64toa_s(seed,(char *)&bTextMetadata[8],42,10); // get the length iTextMetadataBytes+=8; while(bTextMetadata[iTextMetadataBytes]!=0) iTextMetadataBytes++; ++iTextMetadataBytes; // Add a null terminator at the end of the seed value } // Save the host options that this world was last played with strcpy((char *)&bTextMetadata[iTextMetadataBytes],"4J_HOSTOPTIONS"); _itoa_s(uiHostOptions,(char *)&bTextMetadata[iTextMetadataBytes+15],9,16); iTextMetadataBytes += 15; while(bTextMetadata[iTextMetadataBytes]!=0) iTextMetadataBytes++; ++iTextMetadataBytes; // Add a null terminator at the end of the host options value // Save the texture pack id strcpy((char *)&bTextMetadata[iTextMetadataBytes],"4J_TEXTUREPACK"); _itoa_s(uiTexturePackId,(char *)&bTextMetadata[iTextMetadataBytes+15],9,16); iTextMetadataBytes += 15; while(bTextMetadata[iTextMetadataBytes]!=0) iTextMetadataBytes++; return iTextMetadataBytes; } void CMinecraftApp::AddTerrainFeaturePosition(_eTerrainFeatureType eFeatureType,int x,int z) { // check we don't already have this in for( FEATURE_DATA *pFeatureData : m_vTerrainFeatures ) { if((pFeatureData->eTerrainFeature==eFeatureType) &&(pFeatureData->x==x) && (pFeatureData->z==z)) return; } FEATURE_DATA *pFeatureData= new FEATURE_DATA; pFeatureData->eTerrainFeature=eFeatureType; pFeatureData->x=x; pFeatureData->z=z; m_vTerrainFeatures.push_back(pFeatureData); } _eTerrainFeatureType CMinecraftApp::IsTerrainFeature(int x,int z) { for(FEATURE_DATA *pFeatureData : m_vTerrainFeatures ) { if((pFeatureData->x==x) && (pFeatureData->z==z)) return pFeatureData->eTerrainFeature; } return eTerrainFeature_None; } bool CMinecraftApp::GetTerrainFeaturePosition(_eTerrainFeatureType eType,int *pX, int *pZ) { for ( const FEATURE_DATA *pFeatureData : m_vTerrainFeatures ) { if(pFeatureData->eTerrainFeature==eType) { *pX=pFeatureData->x; *pZ=pFeatureData->z; return true; } } return false; } void CMinecraftApp::ClearTerrainFeaturePosition() { FEATURE_DATA *pFeatureData; while(m_vTerrainFeatures.size()>0) { pFeatureData = m_vTerrainFeatures.back(); m_vTerrainFeatures.pop_back(); delete pFeatureData; } } void CMinecraftApp::UpdatePlayerInfo(BYTE networkSmallId, SHORT playerColourIndex, unsigned int playerGamePrivileges) { for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) { if(m_playerColours[i]==networkSmallId) { m_playerColours[i] = 0; m_playerGamePrivileges[i] = 0; } } if(playerColourIndex >=0 && playerColourIndex < MINECRAFT_NET_MAX_PLAYERS) { m_playerColours[playerColourIndex] = networkSmallId; m_playerGamePrivileges[playerColourIndex] = playerGamePrivileges; } } short CMinecraftApp::GetPlayerColour(BYTE networkSmallId) { short index = -1; for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) { if(m_playerColours[i]==networkSmallId) { index = i; break; } } return index; } unsigned int CMinecraftApp::GetPlayerPrivileges(BYTE networkSmallId) { unsigned int privileges = 0; for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) { if(m_playerColours[i]==networkSmallId) { privileges = m_playerGamePrivileges[i]; break; } } return privileges; } wstring CMinecraftApp::getEntityName(eINSTANCEOF type) { switch(type) { case eTYPE_WOLF: return app.GetString(IDS_WOLF); case eTYPE_CREEPER: return app.GetString(IDS_CREEPER); case eTYPE_SKELETON: return app.GetString(IDS_SKELETON); case eTYPE_SPIDER: return app.GetString(IDS_SPIDER); case eTYPE_ZOMBIE: return app.GetString(IDS_ZOMBIE); case eTYPE_PIGZOMBIE: return app.GetString(IDS_PIGZOMBIE); case eTYPE_ENDERMAN: return app.GetString(IDS_ENDERMAN); case eTYPE_SILVERFISH: return app.GetString(IDS_SILVERFISH); case eTYPE_CAVESPIDER: return app.GetString(IDS_CAVE_SPIDER); case eTYPE_GHAST: return app.GetString(IDS_GHAST); case eTYPE_SLIME: return app.GetString(IDS_SLIME); case eTYPE_ARROW: return app.GetString(IDS_ITEM_ARROW); case eTYPE_ENDERDRAGON: return app.GetString(IDS_ENDERDRAGON); case eTYPE_BLAZE: return app.GetString(IDS_BLAZE); case eTYPE_LAVASLIME: return app.GetString(IDS_LAVA_SLIME); // 4J-PB - fix for #107167 - Customer Encountered: TU12: Content: UI: There is no information what killed Player after being slain by Iron Golem. case eTYPE_VILLAGERGOLEM: return app.GetString(IDS_IRONGOLEM); case eTYPE_HORSE: return app.GetString(IDS_HORSE); case eTYPE_WITCH: return app.GetString(IDS_WITCH); case eTYPE_WITHERBOSS: return app.GetString(IDS_WITHER); case eTYPE_BAT: return app.GetString(IDS_BAT); }; return L""; } DWORD CMinecraftApp::m_dwContentTypeA[e_Marketplace_MAX]= { XMARKETPLACE_OFFERING_TYPE_CONTENT, // e_DLC_SkinPack, e_DLC_TexturePacks, e_DLC_MashupPacks #ifndef _XBOX_ONE XMARKETPLACE_OFFERING_TYPE_THEME, // e_DLC_Themes XMARKETPLACE_OFFERING_TYPE_AVATARITEM, // e_DLC_AvatarItems XMARKETPLACE_OFFERING_TYPE_TILE, // e_DLC_Gamerpics #endif }; unsigned int CMinecraftApp::AddDLCRequest(eDLCMarketplaceType eType, bool bPromote) { // lock access EnterCriticalSection(&csDLCDownloadQueue); // If it's already in there, promote it to the top of the list int iPosition=0; for( DLCRequest *pCurrent : m_DLCDownloadQueue ) { if(pCurrent->dwType==m_dwContentTypeA[eType]) { // already got this in the list if(pCurrent->eState == e_DLC_ContentState_Retrieving || pCurrent->eState == e_DLC_ContentState_Retrieved) { // already retrieved this LeaveCriticalSection(&csDLCDownloadQueue); return 0; } else { // promote if(bPromote) { m_DLCDownloadQueue.erase(m_DLCDownloadQueue.begin()+iPosition); m_DLCDownloadQueue.insert(m_DLCDownloadQueue.begin(),pCurrent); } LeaveCriticalSection(&csDLCDownloadQueue); return 0; } } iPosition++; } DLCRequest *pDLCreq = new DLCRequest; pDLCreq->dwType=m_dwContentTypeA[eType]; pDLCreq->eState=e_DLC_ContentState_Idle; m_DLCDownloadQueue.push_back(pDLCreq); m_bAllDLCContentRetrieved=false; LeaveCriticalSection(&csDLCDownloadQueue); app.DebugPrintf("[Consoles_App] Added DLC request.\n"); return 1; } unsigned int CMinecraftApp::AddTMSPPFileTypeRequest(eDLCContentType eType, bool bPromote) { #if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__) // lock access EnterCriticalSection(&csTMSPPDownloadQueue); // If it's already in there, promote it to the top of the list int iPosition=0; //ignore promoting for now /* bool bPromoted=false; for ( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) { TMSPPRequest *pCurrent = *it; if(pCurrent->eType==eType) { if(!(pCurrent->eState == e_TMS_ContentState_Retrieving || pCurrent->eState == e_TMS_ContentState_Retrieved)) { // promote if(bPromote) { m_TMSPPDownloadQueue.erase(m_TMSPPDownloadQueue.begin()+iPosition); m_TMSPPDownloadQueue.insert(m_TMSPPDownloadQueue.begin(),pCurrent); bPromoted=true; } } } iPosition++; } if(bPromoted) { // re-ordered the list, so leave now LeaveCriticalSection(&csTMSPPDownloadQueue); return 0; } */ // special case for data files (not image files) if(eType==e_DLC_TexturePackData) { int iCount=GetDLCInfoFullOffersCount(); for(int i=0;ieDLCType==e_DLC_TexturePacks) || (pDLC->eDLCType==e_DLC_MashupPacks)) { // first check if the image is already in the memory textures, since we might be loading some from the Title Update partition if(pDLC->wchDataFile[0]!=0) { //WCHAR *cString = pDLC->wchDataFile; // 4J-PB - shouldn't check this here - let the TMS files override it, so if they are on TMS, we'll take them first //int iIndex = app.GetLocalTMSFileIndex(pDLC->wchDataFile,true); //if(iIndex!=-1) { bool bPresent = app.IsFileInTPD(pDLC->iConfig); if(!bPresent) { // this may already be present in the vector because of a previous trial/full offer bool bAlreadyInQueue=false; for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) { if(wcscmp(pDLC->wchDataFile,pCurrent->wchFilename)==0) { bAlreadyInQueue=true; break; } } if(!bAlreadyInQueue) { TMSPPRequest *pTMSPPreq = new TMSPPRequest; pTMSPPreq->CallbackFunc=&CMinecraftApp::TMSPPFileReturned; pTMSPPreq->lpCallbackParam=this; pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_Title; pTMSPPreq->eFileTypeVal=C4JStorage::TMS_FILETYPE_BINARY; memcpy(pTMSPPreq->wchFilename,pDLC->wchDataFile,sizeof(WCHAR)*MAX_BANNERNAME_SIZE); pTMSPPreq->eType=e_DLC_TexturePackData; pTMSPPreq->eState=e_TMS_ContentState_Queued; m_bAllTMSContentRetrieved=false; m_TMSPPDownloadQueue.push_back(pTMSPPreq); } } else { app.DebugPrintf("Texture data already present in the TPD\n"); } } } } } } else { // for all the files of type eType, add them to the download list // run through the trial offers first, then the full offers. Any duplicates won't be added to the download queue int iCount; #ifdef _XBOX // Only trial offers on Xbox 360 iCount=GetDLCInfoTrialOffersCount(); for(int i=0;ieDLCType==eType) { WCHAR *cString = pDLC->wchBanner; // 4J-PB - shouldn't check this here - let the TMS files override it, so if they are on TMS, we'll take them first // is the file in the TMS XZP? //int iIndex = app.GetLocalTMSFileIndex(cString,true); //if(iIndex!=-1) { bool bPresent = app.IsFileInMemoryTextures(cString); if(!bPresent) // retrieve it from TMSPP { bool bAlreadyInQueue=false; for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) { if(wcscmp(pDLC->wchBanner,pCurrent->wchFilename)==0) { bAlreadyInQueue=true; break; } } if(!bAlreadyInQueue) { TMSPPRequest *pTMSPPreq = new TMSPPRequest; pTMSPPreq->CallbackFunc=&CMinecraftApp::TMSPPFileReturned; pTMSPPreq->lpCallbackParam=this; pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_Title; pTMSPPreq->eFileTypeVal=C4JStorage::TMS_FILETYPE_BINARY; //wcstombs(pTMSPPreq->szFilename,pDLC->wchBanner,MAX_TMSFILENAME_SIZE); memcpy(pTMSPPreq->wchFilename,pDLC->wchBanner,sizeof(WCHAR)*MAX_BANNERNAME_SIZE); pTMSPPreq->eType=eType; pTMSPPreq->eState=e_TMS_ContentState_Queued; m_bAllTMSContentRetrieved=false; m_TMSPPDownloadQueue.push_back(pTMSPPreq); app.DebugPrintf("===m_TMSPPDownloadQueue Adding %ls, q size is %d\n",pTMSPPreq->wchFilename,m_TMSPPDownloadQueue.size()); } } } } } #endif // and the full offers iCount=GetDLCInfoFullOffersCount(); for(int i=0;iwchType,wchDLCTypeNames[eType])==0) if(pDLC->eDLCType==eType) { // first check if the image is already in the memory textures, since we might be loading some from the Title Update partition WCHAR *cString = pDLC->wchBanner; // 4J-PB - shouldn't check this here - let the TMS files override it, so if they are on TMS, we'll take them first //int iIndex = app.GetLocalTMSFileIndex(cString,true); //if(iIndex!=-1) { bool bPresent = app.IsFileInMemoryTextures(cString); if(!bPresent) { // this may already be present in the vector because of a previous trial/full offer bool bAlreadyInQueue=false; for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) { if(wcscmp(pDLC->wchBanner,pCurrent->wchFilename)==0) { bAlreadyInQueue=true; break; } } if(!bAlreadyInQueue) { //app.DebugPrintf("Adding a request to the TMSPP download queue - %ls\n",pDLC->wchBanner); TMSPPRequest *pTMSPPreq = new TMSPPRequest; ZeroMemory(pTMSPPreq,sizeof(TMSPPRequest)); pTMSPPreq->CallbackFunc=&CMinecraftApp::TMSPPFileReturned; pTMSPPreq->lpCallbackParam=this; // 4J-PB - testing for now //pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_TitleUser; pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_Title; pTMSPPreq->eFileTypeVal=C4JStorage::TMS_FILETYPE_BINARY; //wcstombs(pTMSPPreq->szFilename,pDLC->wchBanner,MAX_TMSFILENAME_SIZE); memcpy(pTMSPPreq->wchFilename,pDLC->wchBanner,sizeof(WCHAR)*MAX_BANNERNAME_SIZE); pTMSPPreq->eType=eType; pTMSPPreq->eState=e_TMS_ContentState_Queued; m_bAllTMSContentRetrieved=false; m_TMSPPDownloadQueue.push_back(pTMSPPreq); app.DebugPrintf("===m_TMSPPDownloadQueue Adding %ls, q size is %d\n",pTMSPPreq->wchFilename,m_TMSPPDownloadQueue.size()); } } } } } } LeaveCriticalSection(&csTMSPPDownloadQueue); #endif return 1; } bool CMinecraftApp::CheckTMSDLCCanStop() { EnterCriticalSection(&csTMSPPDownloadQueue); for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) { if(pCurrent->eState==e_TMS_ContentState_Retrieving) { LeaveCriticalSection(&csTMSPPDownloadQueue); return false; } } LeaveCriticalSection(&csTMSPPDownloadQueue); return true; } bool CMinecraftApp::RetrieveNextDLCContent() { // If there's already a retrieve in progress, quit // we may have re-ordered the list, so need to check every item // is there a primary player and a network connection? int primPad = ProfileManager.GetPrimaryPad(); if ( primPad == -1 || !ProfileManager.IsSignedInLive(primPad) ) { return true; // 4J-JEV: We need to wait until the primary player is online. } EnterCriticalSection(&csDLCDownloadQueue); for( const DLCRequest* pCurrent : m_DLCDownloadQueue ) { if(pCurrent->eState==e_DLC_ContentState_Retrieving) { LeaveCriticalSection(&csDLCDownloadQueue); return true; } } // Now look for the next retrieval for( DLCRequest *pCurrent : m_DLCDownloadQueue ) { if(pCurrent->eState==e_DLC_ContentState_Idle) { #ifdef _DEBUG app.DebugPrintf("RetrieveNextDLCContent - type = %d\n",pCurrent->dwType); #endif C4JStorage::EDLCStatus status = StorageManager.GetDLCOffers(ProfileManager.GetPrimaryPad(), &CMinecraftApp::DLCOffersReturned, this, pCurrent->dwType); if(status==C4JStorage::EDLC_Pending) { pCurrent->eState=e_DLC_ContentState_Retrieving; } else { // no content of this type, or some other problem app.DebugPrintf("RetrieveNextDLCContent - PROBLEM\n"); pCurrent->eState=e_DLC_ContentState_Retrieved; } LeaveCriticalSection(&csDLCDownloadQueue); return true; } } LeaveCriticalSection(&csDLCDownloadQueue); app.DebugPrintf("[Consoles_App] Finished downloading dlc content.\n"); return false; } #if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__) #ifdef _XBOX_ONE int CMinecraftApp::TMSPPFileReturned(LPVOID pParam,int iPad,int iUserData,LPVOID lpvData, WCHAR* wchFilename) { C4JStorage::PTMSPP_FILEDATA pFileData=(C4JStorage::PTMSPP_FILEDATA)lpvData; #else int CMinecraftApp::TMSPPFileReturned(LPVOID pParam,int iPad,int iUserData,C4JStorage::PTMSPP_FILEDATA pFileData, LPCSTR szFilename) { #endif CMinecraftApp* pClass = (CMinecraftApp *) pParam; // find the right one in the vector EnterCriticalSection(&pClass->csTMSPPDownloadQueue); for( TMSPPRequest *pCurrent : pClass->m_TMSPPDownloadQueue ) { #if defined(_XBOX) || defined(_WINDOWS64) char szFile[MAX_TMSFILENAME_SIZE]; wcstombs(szFile,pCurrent->wchFilename,MAX_TMSFILENAME_SIZE); if(strcmp(szFilename,szFile)==0) #elif _XBOX_ONE if(wcscmp(wchFilename,pCurrent->wchFilename)==0) #endif { // set this to retrieved whether it found it or not pCurrent->eState=e_TMS_ContentState_Retrieved; if(pFileData!=NULL) { #ifdef _XBOX_ONE switch(pCurrent->eType) { case e_DLC_TexturePackData: { // 4J-PB - we need to allocate memory for the file data and copy into it, since the current data is a reference into the blob download memory PBYTE pbData = new BYTE [pFileData->dwSize]; memcpy(pbData,pFileData->pbData,pFileData->dwSize); pClass->m_vTMSPPData.push_back(pbData); app.DebugPrintf("Got texturepack data\n"); // get the config value for the texture pack int iConfig=app.GetTPConfigVal(pCurrent->wchFilename); app.AddMemoryTPDFile(iConfig, pbData, pFileData->dwSize); } break; default: // 4J-PB - check the data is an image if(pFileData->pbData[0]==0x89) { // 4J-PB - we need to allocate memory for the file data and copy into it, since the current data is a reference into the blob download memory PBYTE pbData = new BYTE [pFileData->dwSize]; memcpy(pbData,pFileData->pbData,pFileData->dwSize); pClass->m_vTMSPPData.push_back(pbData); app.DebugPrintf("Got image data - %ls\n",pCurrent->wchFilename); app.AddMemoryTextureFile(pCurrent->wchFilename, pbData, pFileData->dwSize); } else { app.DebugPrintf("Got image data, but it's not a png - %ls\n",pCurrent->wchFilename); } break; } #else switch(pCurrent->eType) { case e_DLC_TexturePackData: { app.DebugPrintf("--- Got texturepack data %ls\n",pCurrent->wchFilename); // get the config value for the texture pack int iConfig=app.GetTPConfigVal(pCurrent->wchFilename); app.AddMemoryTPDFile(iConfig, pFileData->pbData, pFileData->dwSize); } break; default: app.DebugPrintf("--- Got image data - %ls\n",pCurrent->wchFilename); app.AddMemoryTextureFile(pCurrent->wchFilename, pFileData->pbData, pFileData->dwSize); break; } #endif } else { #ifdef _XBOX_ONE app.DebugPrintf("TMSImageReturned failed (%ls)...\n",wchFilename); #else app.DebugPrintf("TMSImageReturned failed (%s)...\n",szFilename); #endif } break; } } LeaveCriticalSection(&pClass->csTMSPPDownloadQueue); return 0; } #endif bool CMinecraftApp::RetrieveNextTMSPPContent() { #if defined _XBOX || defined _XBOX_ONE // If there's already a retrieve in progress, quit // we may have re-ordered the list, so need to check every item // is there a primary player and a network connection? if(ProfileManager.GetPrimaryPad()==-1) return false; if(ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad())==false) return false; for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) { TMSPPRequest *pCurrent = *it; if(pCurrent->eState==e_TMS_ContentState_Retrieving) { app.DebugPrintf("."); LeaveCriticalSection(&csTMSPPDownloadQueue); return true; } } // Now look for the next retrieval for( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) { TMSPPRequest *pCurrent = *it; if(pCurrent->eState==e_TMS_ContentState_Queued) { // 4J-PB - the file may be in the local TMS files, but try to retrieve it from the remote TMS in case it's been changed. If it's not in the list of TMS files, this will // return right away with a ETMSStatus_Fail_ReadDetailsNotRetrieved #ifdef _XBOX char szFilename[MAX_TMSFILENAME_SIZE]; wcstombs(szFilename,pCurrent->wchFilename,MAX_TMSFILENAME_SIZE); app.DebugPrintf("\nRetrieveNextTMSPPContent - type = %d, %s\n",pCurrent->eType,szFilename); C4JStorage::ETMSStatus status=StorageManager.TMSPP_ReadFile(ProfileManager.GetPrimaryPad(),pCurrent->eStorageFacility,pCurrent->eFileTypeVal,szFilename,pCurrent->CallbackFunc,this); switch(status) { case C4JStorage::ETMSStatus_Pending: pCurrent->eState=e_TMS_ContentState_Retrieving; break; case C4JStorage::ETMSStatus_Idle: pCurrent->eState=e_TMS_ContentState_Retrieved; break; case C4JStorage::ETMSStatus_Fail_ReadInProgress: case C4JStorage::ETMSStatus_ReadInProgress: pCurrent->eState=e_TMS_ContentState_Retrieving; if(pCurrent->eState==C4JStorage::ETMSStatus_Fail_ReadInProgress) { app.DebugPrintf("TMSPP_ReadFile failed - read in progress\n"); Sleep(50); LeaveCriticalSection(&csTMSPPDownloadQueue); return false; } break; default: pCurrent->eState=e_TMS_ContentState_Retrieved; break; } #else eTitleStorageState status; app.DebugPrintf("RetrieveNextTMSPPContent - type = %d, %ls\n",pCurrent->eType,pCurrent->wchFilename); //eTitleStorageState status=StorageManager.TMSPP_ReadFile(ProfileManager.GetPrimaryPad(),pCurrent->eStorageFacility,pCurrent->eFileTypeVal,pCurrent->wchFilename,pCurrent->CallbackFunc,this,0); if(0)//wcscmp(pCurrent->wchFilename,L"TP01.png")==0) { // TP01 fails because the blob size returned is bigger than the global metadata says it should be status=eTitleStorage_readerror; } else { status=StorageManager.TMSPP_ReadFile(ProfileManager.GetPrimaryPad(),pCurrent->eStorageFacility,pCurrent->eFileTypeVal,pCurrent->wchFilename,pCurrent->CallbackFunc,this,0); } switch(status) { case eTitleStorage_pending: pCurrent->eState=e_TMS_ContentState_Retrieving; break; case eTitleStorage_idle: pCurrent->eState=e_TMS_ContentState_Retrieved; break; case eTitleStorage_busy: // try again next time { app.DebugPrintf("@@@@@@@@@@@@@@@@@ TMSPP_ReadFile failed - busy (probably reading already)\n"); Sleep(50); LeaveCriticalSection(&csTMSPPDownloadQueue); return false; } break; default: pCurrent->eState=e_TMS_ContentState_Retrieved; break; } #endif LeaveCriticalSection(&csTMSPPDownloadQueue); return true; } } LeaveCriticalSection(&csTMSPPDownloadQueue); #endif return false; } void CMinecraftApp::TickDLCOffersRetrieved() { if(!m_bAllDLCContentRetrieved) { if (!app.RetrieveNextDLCContent()) { app.DebugPrintf("[Consoles_App] All content retrieved.\n"); m_bAllDLCContentRetrieved=true; } } } void CMinecraftApp::ClearAndResetDLCDownloadQueue() { app.DebugPrintf("[Consoles_App] Clear and reset download queue.\n"); int iPosition=0; EnterCriticalSection(&csTMSPPDownloadQueue); for( DLCRequest *pCurrent : m_DLCDownloadQueue ) { if ( pCurrent ) delete pCurrent; iPosition++; } m_DLCDownloadQueue.clear(); m_bAllDLCContentRetrieved=true; LeaveCriticalSection(&csTMSPPDownloadQueue); } void CMinecraftApp::TickTMSPPFilesRetrieved() { if(m_bTickTMSDLCFiles && !m_bAllTMSContentRetrieved) { if(app.RetrieveNextTMSPPContent()==false) { m_bAllTMSContentRetrieved=true; } } } void CMinecraftApp::ClearTMSPPFilesRetrieved() { int iPosition=0; EnterCriticalSection(&csTMSPPDownloadQueue); for ( TMSPPRequest *pCurrent : m_TMSPPDownloadQueue ) { if ( pCurrent ) delete pCurrent; iPosition++; } m_TMSPPDownloadQueue.clear(); m_bAllTMSContentRetrieved=true; LeaveCriticalSection(&csTMSPPDownloadQueue); } int CMinecraftApp::DLCOffersReturned(void *pParam, int iOfferC, DWORD dwType, int iPad) { CMinecraftApp* pClass = (CMinecraftApp *) pParam; // find the right one in the vector EnterCriticalSection(&pClass->csTMSPPDownloadQueue); for( DLCRequest *pCurrent : pClass->m_DLCDownloadQueue ) { // avatar items are coming back as type Content, so we can't trust the type setting if(pCurrent->dwType==dwType) { pClass->m_iDLCOfferC = iOfferC; app.DebugPrintf("DLCOffersReturned - type %d, count %d - setting to retrieved\n",dwType,iOfferC); pCurrent->eState=e_DLC_ContentState_Retrieved; break; } } LeaveCriticalSection(&pClass->csTMSPPDownloadQueue); return 0; } eDLCContentType CMinecraftApp::Find_eDLCContentType(DWORD dwType) { for(int i=0;idwType==m_dwContentTypeA[eType]) && (pCurrent->eState==e_DLC_ContentState_Retrieved)) { LeaveCriticalSection(&csDLCDownloadQueue); return true; } } LeaveCriticalSection(&csDLCDownloadQueue); return false; } void CMinecraftApp::SetAdditionalSkinBoxes(DWORD dwSkinID, SKIN_BOX *SkinBoxA, DWORD dwSkinBoxC) { EntityRenderer *renderer = EntityRenderDispatcher::instance->getRenderer(eTYPE_PLAYER); Model *pModel = renderer->getModel(); vector *pvModelPart = new vector; vector *pvSkinBoxes = new vector; EnterCriticalSection( &csAdditionalModelParts ); EnterCriticalSection( &csAdditionalSkinBoxes ); app.DebugPrintf("*** SetAdditionalSkinBoxes - Inserting model parts for skin %d from array of Skin Boxes\n",dwSkinID&0x0FFFFFFF); // convert the skin boxes into model parts, and add to the humanoid model for(unsigned int i=0;iAddOrRetrievePart(&SkinBoxA[i]); pvModelPart->push_back(pModelPart); pvSkinBoxes->push_back(&SkinBoxA[i]); } } m_AdditionalModelParts.insert( std::pair *>(dwSkinID, pvModelPart) ); m_AdditionalSkinBoxes.insert( std::pair *>(dwSkinID, pvSkinBoxes) ); LeaveCriticalSection( &csAdditionalSkinBoxes ); LeaveCriticalSection( &csAdditionalModelParts ); } vector * CMinecraftApp::SetAdditionalSkinBoxes(DWORD dwSkinID, vector *pvSkinBoxA) { EntityRenderer *renderer = EntityRenderDispatcher::instance->getRenderer(eTYPE_PLAYER); Model *pModel = renderer->getModel(); vector *pvModelPart = new vector; EnterCriticalSection( &csAdditionalModelParts ); EnterCriticalSection( &csAdditionalSkinBoxes ); app.DebugPrintf("*** SetAdditionalSkinBoxes - Inserting model parts for skin %d from array of Skin Boxes\n",dwSkinID&0x0FFFFFFF); // convert the skin boxes into model parts, and add to the humanoid model for( auto& it : *pvSkinBoxA ) { if(pModel) { ModelPart *pModelPart=pModel->AddOrRetrievePart(it); pvModelPart->push_back(pModelPart); } } m_AdditionalModelParts.emplace(dwSkinID, pvModelPart); m_AdditionalSkinBoxes.emplace(dwSkinID, pvSkinBoxA); LeaveCriticalSection( &csAdditionalSkinBoxes ); LeaveCriticalSection( &csAdditionalModelParts ); return pvModelPart; } vector *CMinecraftApp::GetAdditionalModelParts(DWORD dwSkinID) { EnterCriticalSection( &csAdditionalModelParts ); vector *pvModelParts=NULL; if(m_AdditionalModelParts.size()>0) { auto it = m_AdditionalModelParts.find(dwSkinID); if(it!=m_AdditionalModelParts.end()) { pvModelParts = (*it).second; } } LeaveCriticalSection( &csAdditionalModelParts ); return pvModelParts; } vector *CMinecraftApp::GetAdditionalSkinBoxes(DWORD dwSkinID) { EnterCriticalSection( &csAdditionalSkinBoxes ); vector *pvSkinBoxes=NULL; if(m_AdditionalSkinBoxes.size()>0) { auto it = m_AdditionalSkinBoxes.find(dwSkinID); if(it!=m_AdditionalSkinBoxes.end()) { pvSkinBoxes = (*it).second; } } LeaveCriticalSection( &csAdditionalSkinBoxes ); return pvSkinBoxes; } unsigned int CMinecraftApp::GetAnimOverrideBitmask(DWORD dwSkinID) { EnterCriticalSection( &csAnimOverrideBitmask ); unsigned int uiAnimOverrideBitmask=0L; if(m_AnimOverrides.size()>0) { auto it = m_AnimOverrides.find(dwSkinID); if(it!=m_AnimOverrides.end()) { uiAnimOverrideBitmask = (*it).second; } } LeaveCriticalSection( &csAnimOverrideBitmask ); return uiAnimOverrideBitmask; } void CMinecraftApp::SetAnimOverrideBitmask(DWORD dwSkinID,unsigned int uiAnimOverrideBitmask) { // Make thread safe EnterCriticalSection( &csAnimOverrideBitmask ); if(m_AnimOverrides.size()>0) { auto it = m_AnimOverrides.find(dwSkinID); if(it!=m_AnimOverrides.end()) { LeaveCriticalSection( &csAnimOverrideBitmask ); return; // already in here } } m_AnimOverrides.insert( std::pair(dwSkinID, uiAnimOverrideBitmask) ); LeaveCriticalSection( &csAnimOverrideBitmask ); } DWORD CMinecraftApp::getSkinIdFromPath(const wstring &skin) { bool dlcSkin = false; unsigned int skinId = 0; if(skin.size() >= 14) { dlcSkin = skin.substr(0,3).compare(L"dlc") == 0; wstring skinValue = skin.substr(7,skin.size()); skinValue = skinValue.substr(0,skinValue.find_first_of(L'.')); std::wstringstream ss; // 4J Stu - dlc skins are numbered using decimal to make it easier for artists/people to number manually // Everything else is numbered using hex if(dlcSkin) ss << std::dec << skinValue.c_str(); else ss << std::hex << skinValue.c_str(); ss >> skinId; skinId = MAKE_SKIN_BITMASK(dlcSkin, skinId); } return skinId; } wstring CMinecraftApp::getSkinPathFromId(DWORD skinId) { // 4J Stu - This function maps the encoded DWORD we store in the player profile // to a filename that is stored as a memory texture and shared between systems in game wchar_t chars[256]; if( GET_IS_DLC_SKIN_FROM_BITMASK(skinId) ) { // 4J Stu - DLC skins are numbered using decimal rather than hex to make it easier to number manually swprintf(chars, 256, L"dlcskin%08d.png", GET_DLC_SKIN_ID_FROM_BITMASK(skinId)); } else { DWORD ugcSkinIndex = GET_UGC_SKIN_ID_FROM_BITMASK(skinId); DWORD defaultSkinIndex = GET_DEFAULT_SKIN_ID_FROM_BITMASK(skinId); if( ugcSkinIndex == 0 ) { swprintf(chars, 256, L"defskin%08X.png",defaultSkinIndex); } else { swprintf(chars, 256, L"ugcskin%08X.png",ugcSkinIndex); } } return chars; } int CMinecraftApp::TexturePackDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) { #if defined __PSVITA__ || defined __PS3__ || defined __ORBIS__ if(result==C4JStorage::EMessage_ResultAccept) { Minecraft *pMinecraft = Minecraft::GetInstance(); if( pMinecraft->skins->selectTexturePackById(app.GetRequiredTexturePackID()) ) { // it's been installed already } else { // we need to enable background downloading for the DLC XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); SONYDLC *pSONYDLCInfo=app.GetSONYDLCInfo(app.GetRequiredTexturePackID()); if(pSONYDLCInfo!=NULL) { char chName[42]; char chKeyName[20]; char chSkuID[SCE_NP_COMMERCE2_SKU_ID_LEN]; memset(chSkuID,0,SCE_NP_COMMERCE2_SKU_ID_LEN); // we have to retrieve the skuid from the store info, it can't be hardcoded since Sony may change it. // So we assume the first sku for the product is the one we want // MGH - keyname in the DLC file is 16 chars long, but there's no space for a NULL terminating char memset(chKeyName, 0, sizeof(chKeyName)); strncpy(chKeyName, pSONYDLCInfo->chDLCKeyname, 16); #ifdef __ORBIS__ strcpy(chName, chKeyName); #else sprintf(chName,"%s-%s",app.GetCommerceCategory(),chKeyName); #endif app.GetDLCSkuIDFromProductList(chName,chSkuID); // 4J-PB - need to check for an empty store if(app.CheckForEmptyStore(iPad)==false) { if(app.DLCAlreadyPurchased(chSkuID)) { app.DownloadAlreadyPurchased(chSkuID); } else { app.Checkout(chSkuID); } } } } } else { app.DebugPrintf("Continuing without installing texture pack\n"); } #endif #ifdef _XBOX if(result!=C4JStorage::EMessage_Cancelled) { if(app.GetRequiredTexturePackID()!=0) { // we need to enable background downloading for the DLC XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); ULONGLONG ullOfferID_Full; ULONGLONG ullIndexA[1]; app.GetDLCFullOfferIDForPackID(app.GetRequiredTexturePackID(),&ullOfferID_Full); if( result==C4JStorage::EMessage_ResultAccept ) // Full version { ullIndexA[0]=ullOfferID_Full; StorageManager.InstallOffer(1,ullIndexA,NULL,NULL); } else // trial version { DLC_INFO *pDLCInfo=app.GetDLCInfoForFullOfferID(ullOfferID_Full); ullIndexA[0]=pDLCInfo->ullOfferID_Trial; StorageManager.InstallOffer(1,ullIndexA,NULL,NULL); } } } #endif return 0; } int CMinecraftApp::getArchiveFileSize(const wstring &filename) { TexturePack *tPack = NULL; Minecraft *pMinecraft = Minecraft::GetInstance(); if(pMinecraft && pMinecraft->skins) tPack = pMinecraft->skins->getSelected(); if(tPack && tPack->hasData() && tPack->getArchiveFile() && tPack->getArchiveFile()->hasFile(filename)) { return tPack->getArchiveFile()->getFileSize(filename); } else return m_mediaArchive->getFileSize(filename); } bool CMinecraftApp::hasArchiveFile(const wstring &filename) { TexturePack *tPack = NULL; Minecraft *pMinecraft = Minecraft::GetInstance(); if(pMinecraft && pMinecraft->skins) tPack = pMinecraft->skins->getSelected(); if(tPack && tPack->hasData() && tPack->getArchiveFile() && tPack->getArchiveFile()->hasFile(filename)) return true; else return m_mediaArchive->hasFile(filename); } byteArray CMinecraftApp::getArchiveFile(const wstring &filename) { TexturePack *tPack = NULL; Minecraft *pMinecraft = Minecraft::GetInstance(); if(pMinecraft && pMinecraft->skins) tPack = pMinecraft->skins->getSelected(); if(tPack && tPack->hasData() && tPack->getArchiveFile() && tPack->getArchiveFile()->hasFile(filename)) { return tPack->getArchiveFile()->getFile(filename); } else return m_mediaArchive->getFile(filename); } // DLC #if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) int CMinecraftApp::GetDLCInfoCount() { return (int)DLCInfo.size(); } #elif defined _XBOX_ONE int CMinecraftApp::GetDLCInfoTrialOffersCount() { return 0; } int CMinecraftApp::GetDLCInfoFullOffersCount() { return (int)DLCInfo_Full.size(); } #else int CMinecraftApp::GetDLCInfoTrialOffersCount() { return (int)DLCInfo_Trial.size(); } int CMinecraftApp::GetDLCInfoFullOffersCount() { return (int)DLCInfo_Full.size(); } #endif int CMinecraftApp::GetDLCInfoTexturesOffersCount() { return (int)DLCTextures_PackID.size(); } // AUTOSAVE void CMinecraftApp::SetAutosaveTimerTime(void) { #if defined(_XBOX_ONE) || defined(__ORBIS__) m_uiAutosaveTimer= GetTickCount()+1000*60; #else m_uiAutosaveTimer= GetTickCount()+GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_Autosave)*1000*60*15; #endif }// value x 15 to get mins, x60 for secs bool CMinecraftApp::AutosaveDue(void) { return (GetTickCount()>m_uiAutosaveTimer); } unsigned int CMinecraftApp::SecondsToAutosave() { return (m_uiAutosaveTimer - GetTickCount() ) / 1000; } void CMinecraftApp::SetTrialTimerStart(void) { m_fTrialTimerStart=m_Time.fAppTime; mfTrialPausedTime=0.0f; } float CMinecraftApp::getTrialTimer(void) { return m_Time.fAppTime-m_fTrialTimerStart-mfTrialPausedTime; } bool CMinecraftApp::IsLocalMultiplayerAvailable() { DWORD connectedControllers = 0; for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) { if( InputManager.IsPadConnected(i) || ProfileManager.IsSignedIn(i) ) ++connectedControllers; } #ifdef _WINDOWS64 bool available = connectedControllers > 1; #else bool available = RenderManager.IsHiDef() && connectedControllers > 1; #endif #ifdef __ORBIS__ // Check for remote play available = available && InputManager.IsLocalMultiplayerAvailable(); #endif return available; // Found this in GameNetworkManager? //#ifdef _DURANGO // iOtherConnectedControllers = InputManager.GetConnectedGamepadCount(); // if((InputManager.IsPadConnected(userIndex) || ProfileManager.IsSignedIn(userIndex))) // { // --iOtherConnectedControllers; // } //#else // for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) // { // if( (i!=userIndex) && (InputManager.IsPadConnected(i) || ProfileManager.IsSignedIn(i)) ) // { // iOtherConnectedControllers++; // } // } //#endif } // 4J-PB - language and locale function void CMinecraftApp::getLocale(vector &vecWstrLocales) { vector locales; DWORD dwSystemLanguage = XGetLanguage( ); // 4J-PB - restrict the 360 language until we're ready to have them in #ifdef _XBOX switch(dwSystemLanguage) { case XC_LANGUAGE_FRENCH : locales.push_back(eMCLang_frFR); break; case XC_LANGUAGE_ITALIAN : locales.push_back(eMCLang_itIT); break; case XC_LANGUAGE_GERMAN : locales.push_back(eMCLang_deDE); break; case XC_LANGUAGE_SPANISH : locales.push_back(eMCLang_esES); break; case XC_LANGUAGE_PORTUGUESE : if(XGetLocale()==XC_LOCALE_BRAZIL) { locales.push_back(eMCLang_ptBR); } locales.push_back(eMCLang_ptPT); break; case XC_LANGUAGE_JAPANESE : locales.push_back(eMCLang_jaJP); break; case XC_LANGUAGE_KOREAN : locales.push_back(eMCLang_koKR); break; case XC_LANGUAGE_TCHINESE : locales.push_back(eMCLang_zhCHT); break; } #else switch(dwSystemLanguage) { case XC_LANGUAGE_ENGLISH: switch(XGetLocale()) { case XC_LOCALE_AUSTRALIA: case XC_LOCALE_CANADA: case XC_LOCALE_CZECH_REPUBLIC: case XC_LOCALE_GREECE: case XC_LOCALE_HONG_KONG: case XC_LOCALE_HUNGARY: case XC_LOCALE_INDIA: case XC_LOCALE_IRELAND: case XC_LOCALE_ISRAEL: case XC_LOCALE_NEW_ZEALAND: case XC_LOCALE_SAUDI_ARABIA: case XC_LOCALE_SINGAPORE: case XC_LOCALE_SLOVAK_REPUBLIC: case XC_LOCALE_SOUTH_AFRICA: case XC_LOCALE_UNITED_ARAB_EMIRATES: case XC_LOCALE_GREAT_BRITAIN: locales.push_back(eMCLang_enGB); break; default: //XC_LOCALE_UNITED_STATES break; } break; case XC_LANGUAGE_JAPANESE : locales.push_back(eMCLang_jaJP); break; case XC_LANGUAGE_GERMAN : switch(XGetLocale()) { case XC_LOCALE_AUSTRIA: locales.push_back(eMCLang_deAT); break; case XC_LOCALE_SWITZERLAND: locales.push_back(eMCLang_deCH); break; default:// XC_LOCALE_GERMANY: break; } locales.push_back(eMCLang_deDE); break; case XC_LANGUAGE_FRENCH : switch(XGetLocale()) { case XC_LOCALE_BELGIUM: locales.push_back(eMCLang_frBE); break; case XC_LOCALE_CANADA: locales.push_back(eMCLang_frCA); break; case XC_LOCALE_SWITZERLAND: locales.push_back(eMCLang_frCH); break; default:// XC_LOCALE_FRANCE: break; } locales.push_back(eMCLang_frFR); break; case XC_LANGUAGE_SPANISH : switch(XGetLocale()) { case XC_LOCALE_MEXICO: case XC_LOCALE_ARGENTINA: case XC_LOCALE_CHILE: case XC_LOCALE_COLOMBIA: case XC_LOCALE_UNITED_STATES: case XC_LOCALE_LATIN_AMERICA: locales.push_back(eMCLang_laLAS); locales.push_back(eMCLang_esMX); break; default://XC_LOCALE_SPAIN break; } locales.push_back(eMCLang_esES); break; case XC_LANGUAGE_ITALIAN : locales.push_back(eMCLang_itIT); break; case XC_LANGUAGE_KOREAN : locales.push_back(eMCLang_koKR); break; case XC_LANGUAGE_TCHINESE : switch(XGetLocale()) { case XC_LOCALE_HONG_KONG: locales.push_back(eMCLang_zhHK); locales.push_back(eMCLang_zhTW); break; case XC_LOCALE_TAIWAN: locales.push_back(eMCLang_zhTW); locales.push_back(eMCLang_zhHK); default: break; } locales.push_back(eMCLang_hant); locales.push_back(eMCLang_zhCHT); break; case XC_LANGUAGE_PORTUGUESE : if(XGetLocale()==XC_LOCALE_BRAZIL) { locales.push_back(eMCLang_ptBR); } locales.push_back(eMCLang_ptPT); break; case XC_LANGUAGE_POLISH : locales.push_back(eMCLang_plPL); break; case XC_LANGUAGE_RUSSIAN : locales.push_back(eMCLang_ruRU); break; case XC_LANGUAGE_SWEDISH : locales.push_back(eMCLang_svSV); locales.push_back(eMCLang_svSE); break; case XC_LANGUAGE_TURKISH : locales.push_back(eMCLang_trTR); break; case XC_LANGUAGE_BNORWEGIAN : locales.push_back(eMCLang_nbNO); locales.push_back(eMCLang_noNO); locales.push_back(eMCLang_nnNO); break; case XC_LANGUAGE_DUTCH : switch(XGetLocale()) { case XC_LOCALE_BELGIUM: locales.push_back(eMCLang_nlBE); break; default: break; } locales.push_back(eMCLang_nlNL); break; case XC_LANGUAGE_SCHINESE : switch(XGetLocale()) { case XC_LOCALE_SINGAPORE: locales.push_back(eMCLang_zhSG); break; default: break; } locales.push_back(eMCLang_hans); locales.push_back(eMCLang_csCS); locales.push_back(eMCLang_zhCN); break; #if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ || defined _DURANGO case XC_LANGUAGE_DANISH: locales.push_back(eMCLang_daDA); locales.push_back(eMCLang_daDK); break; case XC_LANGUAGE_FINISH : locales.push_back(eMCLang_fiFI); break; case XC_LANGUAGE_CZECH : locales.push_back(eMCLang_csCZ); locales.push_back(eMCLang_enCZ); break; case XC_LANGUAGE_SLOVAK : locales.push_back(eMCLang_skSK); locales.push_back(eMCLang_enSK); break; case XC_LANGUAGE_GREEK : locales.push_back(eMCLang_elEL); locales.push_back(eMCLang_elGR); locales.push_back(eMCLang_enGR); locales.push_back(eMCLang_enGB); break; #endif } #endif locales.push_back(eMCLang_enUS); locales.push_back(eMCLang_null); for (int i=0; i