the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 10187 lines 312 kB view raw
1 2#include "stdafx.h" 3#include "..\..\Minecraft.World\net.minecraft.world.entity.item.h" 4#include "..\..\Minecraft.World\net.minecraft.world.entity.player.h" 5#include "..\..\Minecraft.World\net.minecraft.world.level.tile.entity.h" 6#include "..\..\Minecraft.World\net.minecraft.world.phys.h" 7#include "..\..\Minecraft.World\InputOutputStream.h" 8#include "..\..\Minecraft.World\compression.h" 9#include "..\Options.h" 10#include "..\MinecraftServer.h" 11#include "..\MultiPlayerLevel.h" 12#include "..\GameRenderer.h" 13#include "..\ProgressRenderer.h" 14#include "..\LevelRenderer.h" 15#include "..\MobSkinMemTextureProcessor.h" 16#include "..\Minecraft.h" 17#include "..\ClientConnection.h" 18#include "..\MultiPlayerLocalPlayer.h" 19#include "..\LocalPlayer.h" 20#include "..\..\Minecraft.World\Player.h" 21#include "..\..\Minecraft.World\Inventory.h" 22#include "..\..\Minecraft.World\Level.h" 23#include "..\..\Minecraft.World\FurnaceTileEntity.h" 24#include "..\..\Minecraft.World\Container.h" 25#include "..\..\Minecraft.World\DispenserTileEntity.h" 26#include "..\..\Minecraft.World\SignTileEntity.h" 27#include "..\StatsCounter.h" 28#include "..\GameMode.h" 29#include "..\Xbox\Social\SocialManager.h" 30#include "Tutorial\TutorialMode.h" 31#if defined _XBOX || defined _WINDOWS64 32#include "..\Xbox\XML\ATGXmlParser.h" 33#include "..\Xbox\XML\xmlFilesCallback.h" 34#endif 35#include "Minecraft_Macros.h" 36#include "..\PlayerList.h" 37#include "..\ServerPlayer.h" 38#include "GameRules\ConsoleGameRules.h" 39#include "GameRules\ConsoleSchematicFile.h" 40#include "..\User.h" 41#include "..\..\Minecraft.World\LevelData.h" 42#include "..\..\Minecraft.World\net.minecraft.world.entity.player.h" 43#include "..\EntityRenderDispatcher.h" 44#include "..\..\Minecraft.World\compression.h" 45#include "..\TexturePackRepository.h" 46#include "..\DLCTexturePack.h" 47#include "DLC\DLCPack.h" 48#include "..\StringTable.h" 49#ifndef _XBOX 50#include "..\ArchiveFile.h" 51#endif 52#include "..\Minecraft.h" 53#ifdef _XBOX 54#include "..\Xbox\GameConfig\Minecraft.spa.h" 55#include "..\Xbox\Network\NetworkPlayerXbox.h" 56#include "XUI\XUI_TextEntry.h" 57#include "XUI\XUI_XZP_Icons.h" 58#include "XUI\XUI_PauseMenu.h" 59#else 60#include "UI\UI.h" 61#include "UI\UIScene_PauseMenu.h" 62#endif 63#ifdef __PS3__ 64#include <sys/tty.h> 65#endif 66#ifdef __ORBIS__ 67#include <save_data_dialog.h> 68#endif 69 70#include "..\Common\Leaderboards\LeaderboardManager.h" 71 72//CMinecraftApp app; 73unsigned int CMinecraftApp::m_uiLastSignInData = 0; 74 75const float CMinecraftApp::fSafeZoneX = 64.0f; // 5% of 1280 76const float CMinecraftApp::fSafeZoneY = 36.0f; // 5% of 720 77 78int CMinecraftApp::s_iHTMLFontSizesA[eHTMLSize_COUNT] = 79{ 80#ifdef _XBOX 81 14,12,14,24 82#else 83 //20,15,20,24 84 20,13,20,26 85#endif 86}; 87 88 89CMinecraftApp::CMinecraftApp() 90{ 91 if(GAME_SETTINGS_PROFILE_DATA_BYTES != sizeof(GAME_SETTINGS)) 92 { 93 // 4J Stu - See comment for GAME_SETTINGS_PROFILE_DATA_BYTES in Xbox_App.h 94 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); 95#ifndef _CONTENT_PACKAGE 96 __debugbreak(); 97#endif 98 } 99 100 for(int i=0;i<XUSER_MAX_COUNT;i++) 101 { 102 m_eTMSAction[i]=eTMSAction_Idle; 103 m_eXuiAction[i]=eAppAction_Idle; 104 m_eXuiActionParam[i] = NULL; 105 //m_dwAdditionalModelParts[i] = 0; 106 107 if(FAILED(XUserGetSigninInfo(i,XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY ,&m_currentSigninInfo[i]))) 108 { 109 m_currentSigninInfo[i].xuid = INVALID_XUID; 110 m_currentSigninInfo[i].dwGuestNumber = 0; 111 } 112 DebugPrintf("Player at index %d has guest number %d\n", i,m_currentSigninInfo[i].dwGuestNumber ); 113 114 m_bRead_BannedListA[i]=false; 115 SetBanListCheck(i,false); 116 117 m_uiOpacityCountDown[i]=0; 118 119 } 120 m_eGlobalXuiAction=eAppAction_Idle; 121 m_eGlobalXuiServerAction=eXuiServerAction_Idle; 122 123 m_bResourcesLoaded=false; 124 m_bGameStarted=false; 125 m_bIsAppPaused=false; 126 //m_bSplitScreenEnabled = false; 127 128 129 m_bIntroRunning=false; 130 m_eGameMode=eMode_Singleplayer; 131 m_bLoadSavesFromFolderEnabled = false; 132 m_bWriteSavesToFolderEnabled = false; 133 //m_bInterfaceRenderingOff = false; 134 //m_bHandRenderingOff = false; 135 m_bTutorialMode = false; 136 m_disconnectReason = DisconnectPacket::eDisconnect_None; 137 m_bLiveLinkRequired = false; 138 m_bChangingSessionType = false; 139 m_bReallyChangingSessionType = false; 140 141#ifdef _DEBUG_MENUS_ENABLED 142 143#ifdef _CONTENT_PACKAGE 144 m_bDebugOptions=false; // make them off by default in a content package build 145#else 146 m_bDebugOptions=true; 147#endif 148#else 149 m_bDebugOptions=false; 150#endif 151 152 //ZeroMemory(m_PreviewBuffer,sizeof(XSOCIAL_PREVIEWIMAGE)*XUSER_MAX_COUNT); 153 154 m_xuidNotch = INVALID_XUID; 155 156 ZeroMemory(&m_InviteData,sizeof(JoinFromInviteData) ); 157 158 // m_bRead_TMS_XUIDS_XML=false; 159 // m_bRead_TMS_DLCINFO_XML=false; 160 161 m_pDLCFileBuffer=NULL; 162 m_dwDLCFileSize=0; 163 m_pBannedListFileBuffer=NULL; 164 m_dwBannedListFileSize=0; 165 166 m_bDefaultCapeInstallAttempted=false; 167 m_bDLCInstallProcessCompleted=false; 168 m_bDLCInstallPending=false; 169 m_iTotalDLC = 0; 170 m_iTotalDLCInstalled = 0; 171 mfTrialPausedTime=0.0f; 172 m_uiAutosaveTimer=0; 173 ZeroMemory(m_pszUniqueMapName,14); 174 175 176 m_bNewDLCAvailable=false; 177 m_bSeenNewDLCTip=false; 178 179 m_uiGameHostSettings=0; 180 181#ifdef _LARGE_WORLDS 182 m_GameNewWorldSize = 0; 183 m_bGameNewWorldSizeUseMoat = false; 184 m_GameNewHellScale = 0; 185#endif 186 187 ZeroMemory(m_playerColours,MINECRAFT_NET_MAX_PLAYERS); 188 189 m_iDLCOfferC=0; 190 m_bAllDLCContentRetrieved=true; 191 InitializeCriticalSection(&csDLCDownloadQueue); 192 m_bAllTMSContentRetrieved=true; 193 m_bTickTMSDLCFiles=true; 194 InitializeCriticalSection(&csTMSPPDownloadQueue); 195 InitializeCriticalSection(&csAdditionalModelParts); 196 InitializeCriticalSection(&csAdditionalSkinBoxes); 197 InitializeCriticalSection(&csAnimOverrideBitmask); 198 InitializeCriticalSection(&csMemFilesLock); 199 InitializeCriticalSection(&csMemTPDLock); 200 201 InitializeCriticalSection(&m_saveNotificationCriticalSection); 202 m_saveNotificationDepth = 0; 203 204 m_dwRequiredTexturePackID=0; 205 206 m_bResetNether=false; 207 208#ifdef _XBOX 209 // m_bTransferSavesToXboxOne=false; 210 // m_uiTransferSlotC=5; 211#endif 212 213#if (defined _CONTENT_PACAKGE) || (defined _XBOX) 214 m_bUseDPadForDebug = false; 215#else 216 m_bUseDPadForDebug = true; 217#endif 218 219#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) 220 for(int i=0;i<XUSER_MAX_COUNT;i++) 221 { 222 m_eOptionsStatusA[i]=C4JStorage::eOptions_Callback_Idle; 223 } 224#endif 225 226 for(int i=0;i<XUSER_MAX_COUNT;i++) 227 { 228 m_vBannedListA[i] = new vector<PBANNEDLISTDATA>; 229 } 230 231 LocaleAndLanguageInit(); 232 233#ifdef _XBOX_ONE 234 m_hasReachedMainMenu = false; 235#endif 236} 237 238 239 240void CMinecraftApp::DebugPrintf(const char *szFormat, ...) 241{ 242 243#ifndef _FINAL_BUILD 244 char buf[1024]; 245 va_list ap; 246 va_start(ap, szFormat); 247 vsnprintf(buf, sizeof(buf), szFormat, ap); 248 va_end(ap); 249 OutputDebugStringA(buf); 250#endif 251 252} 253 254void CMinecraftApp::DebugPrintf(int user, const char *szFormat, ...) 255{ 256#ifndef _FINAL_BUILD 257 if(user == USER_NONE) 258 return; 259 char buf[1024]; 260 va_list ap; 261 va_start(ap, szFormat); 262 vsnprintf(buf, sizeof(buf), szFormat, ap); 263 va_end(ap); 264#ifdef __PS3__ 265 unsigned int writelen; 266 sys_tty_write(SYS_TTYP_USER1 + ( user - 1 ), buf, strlen(buf), &writelen ); 267#elif defined __PSVITA__ 268 switch(user) 269 { 270 case 0: 271 { 272 SceUID tty2 = sceIoOpen("tty2:", SCE_O_WRONLY, 0); 273 if(tty2>=0) 274 { 275 std::string string1(buf); 276 sceIoWrite(tty2, string1.c_str(), string1.length()); 277 sceIoClose(tty2); 278 } 279 } 280 break; 281 case 1: 282 { 283 SceUID tty3 = sceIoOpen("tty3:", SCE_O_WRONLY, 0); 284 if(tty3>=0) 285 { 286 std::string string1(buf); 287 sceIoWrite(tty3, string1.c_str(), string1.length()); 288 sceIoClose(tty3); 289 } 290 } 291 break; 292 default: 293 OutputDebugStringA(buf); 294 break; 295 } 296#else 297 OutputDebugStringA(buf); 298#endif 299#ifndef _XBOX 300 if(user == USER_UI) 301 { 302 ui.logDebugString(buf); 303 } 304#endif 305#endif 306} 307 308LPCWSTR CMinecraftApp::GetString(int iID) 309{ 310 //return L"Değişiklikler ve Yenilikler"; 311 //return L"ÕÕÕÕÖÖÖÖ"; 312 return app.m_stringTable->getString(iID); 313} 314 315void CMinecraftApp::SetAction(int iPad, eXuiAction action, LPVOID param) 316{ 317 if( ( m_eXuiAction[iPad] == eAppAction_ReloadTexturePack ) && ( action == eAppAction_EthernetDisconnected ) ) 318 { 319 app.DebugPrintf("Invalid change of App action for pad %d from %d to %d, ignoring\n", iPad, m_eXuiAction[iPad], action); 320 } 321 else if( ( m_eXuiAction[iPad] == eAppAction_ReloadTexturePack ) && ( action == eAppAction_ExitWorld ) ) 322 { 323 app.DebugPrintf("Invalid change of App action for pad %d from %d to %d, ignoring\n", iPad, m_eXuiAction[iPad], action); 324 } 325 else if(m_eXuiAction[iPad] == eAppAction_ExitWorldCapturedThumbnail && action != eAppAction_Idle) 326 { 327 app.DebugPrintf("Invalid change of App action for pad %d from %d to %d, ignoring\n", iPad, m_eXuiAction[iPad], action); 328 } 329 else 330 { 331 app.DebugPrintf("Changing App action for pad %d from %d to %d\n", iPad, m_eXuiAction[iPad], action); 332 m_eXuiAction[iPad]=action; 333 m_eXuiActionParam[iPad] = param; 334 } 335} 336 337bool CMinecraftApp::IsAppPaused() 338{ 339#if defined(_XBOX_ONE) || defined(__ORBIS__) 340 bool paused = m_bIsAppPaused; 341 EnterCriticalSection(&m_saveNotificationCriticalSection); 342 if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) 343 { 344 paused |= m_saveNotificationDepth > 0; 345 } 346 LeaveCriticalSection(&m_saveNotificationCriticalSection); 347 return paused; 348#else 349 return m_bIsAppPaused; 350#endif 351} 352 353void CMinecraftApp::SetAppPaused(bool val) 354{ 355 m_bIsAppPaused = val; 356} 357 358void CMinecraftApp::HandleButtonPresses() 359{ 360 for(int i=0;i<4;i++) 361 { 362 HandleButtonPresses(i); 363 } 364} 365 366void CMinecraftApp::HandleButtonPresses(int iPad) 367{ 368 369 // // test an update of the profile data 370 // void *pData=ProfileManager.GetGameDefinedProfileData(iPad); 371 // 372 // unsigned char *pchData= (unsigned char *)pData; 373 // int iCount=0; 374 // for(int i=0;i<GAME_DEFINED_PROFILE_DATA_BYTES;i++) 375 // { 376 // pchData[i]=0xBC; 377 // //if(iCount==255) iCount = 0; 378 // } 379 // ProfileManager.WriteToProfile(iPad,true); 380} 381 382bool CMinecraftApp::LoadInventoryMenu(int iPad,shared_ptr<LocalPlayer> player,bool bNavigateBack) 383{ 384 bool success = true; 385 386 InventoryScreenInput* initData = new InventoryScreenInput(); 387 initData->player = player; 388 initData->bNavigateBack=bNavigateBack; 389 initData->iPad = iPad; 390 391 if(app.GetLocalPlayerCount()>1) 392 { 393 initData->bSplitscreen=true; 394 success = ui.NavigateToScene(iPad,eUIScene_InventoryMenu,initData); 395 } 396 else 397 { 398 initData->bSplitscreen=false; 399 success = ui.NavigateToScene(iPad,eUIScene_InventoryMenu,initData); 400 } 401 402 return success; 403} 404 405bool CMinecraftApp::LoadCreativeMenu(int iPad,shared_ptr<LocalPlayer> player,bool bNavigateBack) 406{ 407 bool success = true; 408 409 InventoryScreenInput* initData = new InventoryScreenInput(); 410 initData->player = player; 411 initData->bNavigateBack=bNavigateBack; 412 initData->iPad = iPad; 413 414 if(app.GetLocalPlayerCount()>1) 415 { 416 initData->bSplitscreen=true; 417 success = ui.NavigateToScene(iPad,eUIScene_CreativeMenu,initData); 418 } 419 else 420 { 421 initData->bSplitscreen=false; 422 success = ui.NavigateToScene(iPad,eUIScene_CreativeMenu,initData); 423 } 424 425 return success; 426} 427 428bool CMinecraftApp::LoadCrafting2x2Menu(int iPad,shared_ptr<LocalPlayer> player) 429{ 430 bool success = true; 431 432 CraftingPanelScreenInput* initData = new CraftingPanelScreenInput(); 433 initData->player = player; 434 initData->iContainerType=RECIPE_TYPE_2x2; 435 initData->iPad = iPad; 436 initData->x = 0; 437 initData->y = 0; 438 initData->z = 0; 439 440 if(app.GetLocalPlayerCount()>1) 441 { 442 initData->bSplitscreen=true; 443 success = ui.NavigateToScene(iPad,eUIScene_Crafting2x2Menu, initData); 444 } 445 else 446 { 447 initData->bSplitscreen=false; 448 success = ui.NavigateToScene(iPad,eUIScene_Crafting2x2Menu, initData); 449 } 450 451 return success; 452} 453 454bool CMinecraftApp::LoadCrafting3x3Menu(int iPad,shared_ptr<LocalPlayer> player, int x, int y, int z) 455{ 456 bool success = true; 457 458 CraftingPanelScreenInput* initData = new CraftingPanelScreenInput(); 459 initData->player = player; 460 initData->iContainerType=RECIPE_TYPE_3x3; 461 initData->iPad = iPad; 462 initData->x = x; 463 initData->y = y; 464 initData->z = z; 465 466 if(app.GetLocalPlayerCount()>1) 467 { 468 initData->bSplitscreen=true; 469 success = ui.NavigateToScene(iPad,eUIScene_Crafting3x3Menu, initData); 470 } 471 else 472 { 473 initData->bSplitscreen=false; 474 success = ui.NavigateToScene(iPad,eUIScene_Crafting3x3Menu, initData); 475 } 476 477 return success; 478} 479 480bool CMinecraftApp::LoadFireworksMenu(int iPad,shared_ptr<LocalPlayer> player, int x, int y, int z) 481{ 482 bool success = true; 483 484 FireworksScreenInput* initData = new FireworksScreenInput(); 485 initData->player = player; 486 initData->iPad = iPad; 487 initData->x = x; 488 initData->y = y; 489 initData->z = z; 490 491 if(app.GetLocalPlayerCount()>1) 492 { 493 initData->bSplitscreen=true; 494 success = ui.NavigateToScene(iPad,eUIScene_FireworksMenu, initData); 495 } 496 else 497 { 498 initData->bSplitscreen=false; 499 success = ui.NavigateToScene(iPad,eUIScene_FireworksMenu, initData); 500 } 501 502 return success; 503} 504 505bool CMinecraftApp::LoadEnchantingMenu(int iPad,shared_ptr<Inventory> inventory, int x, int y, int z, Level *level, const wstring &name) 506{ 507 bool success = true; 508 509 EnchantingScreenInput* initData = new EnchantingScreenInput(); 510 initData->inventory = inventory; 511 initData->level = level; 512 initData->x = x; 513 initData->y = y; 514 initData->z = z; 515 initData->iPad = iPad; 516 initData->name = name; 517 518 if(app.GetLocalPlayerCount()>1) 519 { 520 initData->bSplitscreen=true; 521 success = ui.NavigateToScene(iPad,eUIScene_EnchantingMenu, initData); 522 } 523 else 524 { 525 initData->bSplitscreen=false; 526 success = ui.NavigateToScene(iPad,eUIScene_EnchantingMenu, initData); 527 } 528 529 return success; 530} 531 532bool CMinecraftApp::LoadFurnaceMenu(int iPad,shared_ptr<Inventory> inventory, shared_ptr<FurnaceTileEntity> furnace) 533{ 534 bool success = true; 535 536 FurnaceScreenInput* initData = new FurnaceScreenInput(); 537 538 initData->furnace = furnace; 539 initData->inventory = inventory; 540 initData->iPad = iPad; 541 542 // Load the scene. 543 if(app.GetLocalPlayerCount()>1) 544 { 545 initData->bSplitscreen=true; 546 success = ui.NavigateToScene(iPad,eUIScene_FurnaceMenu, initData); 547 } 548 else 549 { 550 initData->bSplitscreen=false; 551 success = ui.NavigateToScene(iPad,eUIScene_FurnaceMenu, initData); 552 } 553 554 return success; 555} 556 557bool CMinecraftApp::LoadBrewingStandMenu(int iPad,shared_ptr<Inventory> inventory, shared_ptr<BrewingStandTileEntity> brewingStand) 558{ 559 bool success = true; 560 561 BrewingScreenInput* initData = new BrewingScreenInput(); 562 563 initData->brewingStand = brewingStand; 564 initData->inventory = inventory; 565 initData->iPad = iPad; 566 567 // Load the scene. 568 if(app.GetLocalPlayerCount()>1) 569 { 570 initData->bSplitscreen=true; 571 success = ui.NavigateToScene(iPad,eUIScene_BrewingStandMenu, initData); 572 } 573 else 574 { 575 initData->bSplitscreen=false; 576 success = ui.NavigateToScene(iPad,eUIScene_BrewingStandMenu, initData); 577 } 578 579 return success; 580} 581 582 583bool CMinecraftApp::LoadContainerMenu(int iPad,shared_ptr<Container> inventory, shared_ptr<Container> container) 584{ 585 bool success = true; 586 587 ContainerScreenInput* initData = new ContainerScreenInput(); 588 589 initData->inventory = inventory; 590 initData->container = container; 591 initData->iPad = iPad; 592 593 // Load the scene. 594 if(app.GetLocalPlayerCount()>1) 595 { 596 initData->bSplitscreen=true; 597 598 bool bLargeChest = (initData->container->getContainerSize() > 3*9)?true:false; 599 if(bLargeChest) 600 { 601 success = ui.NavigateToScene(iPad,eUIScene_LargeContainerMenu,initData); 602 } 603 else 604 { 605 success = ui.NavigateToScene(iPad,eUIScene_ContainerMenu,initData); 606 } 607 } 608 else 609 { 610 initData->bSplitscreen=false; 611 success = ui.NavigateToScene(iPad,eUIScene_ContainerMenu,initData); 612 } 613 614 return success; 615} 616 617bool CMinecraftApp::LoadTrapMenu(int iPad,shared_ptr<Container> inventory, shared_ptr<DispenserTileEntity> trap) 618{ 619 bool success = true; 620 621 TrapScreenInput* initData = new TrapScreenInput(); 622 623 initData->inventory = inventory; 624 initData->trap = trap; 625 initData->iPad = iPad; 626 627 // Load the scene. 628 if(app.GetLocalPlayerCount()>1) 629 { 630 initData->bSplitscreen=true; 631 success = ui.NavigateToScene(iPad,eUIScene_DispenserMenu, initData); 632 } 633 else 634 { 635 initData->bSplitscreen=false; 636 success = ui.NavigateToScene(iPad,eUIScene_DispenserMenu, initData); 637 } 638 639 return success; 640} 641 642bool CMinecraftApp::LoadSignEntryMenu(int iPad,shared_ptr<SignTileEntity> sign) 643{ 644 bool success = true; 645 646 SignEntryScreenInput* initData = new SignEntryScreenInput(); 647 648 initData->sign = sign; 649 initData->iPad = iPad; 650 651 success = ui.NavigateToScene(iPad,eUIScene_SignEntryMenu, initData); 652 653 delete initData; 654 655 return success; 656} 657 658bool CMinecraftApp::LoadRepairingMenu(int iPad,shared_ptr<Inventory> inventory, Level *level, int x, int y, int z) 659{ 660 bool success = true; 661 662 AnvilScreenInput *initData = new AnvilScreenInput(); 663 initData->inventory = inventory; 664 initData->level = level; 665 initData->x = x; 666 initData->y = y; 667 initData->z = z; 668 initData->iPad = iPad; 669 if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; 670 else initData->bSplitscreen=false; 671 672 success = ui.NavigateToScene(iPad,eUIScene_AnvilMenu, initData); 673 674 return success; 675} 676 677bool CMinecraftApp::LoadTradingMenu(int iPad, shared_ptr<Inventory> inventory, shared_ptr<Merchant> trader, Level *level, const wstring &name) 678{ 679 bool success = true; 680 681 TradingScreenInput *initData = new TradingScreenInput(); 682 initData->inventory = inventory; 683 initData->trader = trader; 684 initData->level = level; 685 initData->iPad = iPad; 686 if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; 687 else initData->bSplitscreen=false; 688 689 success = ui.NavigateToScene(iPad,eUIScene_TradingMenu, initData); 690 691 return success; 692} 693 694bool CMinecraftApp::LoadHopperMenu(int iPad ,shared_ptr<Inventory> inventory, shared_ptr<HopperTileEntity> hopper) 695{ 696 bool success = true; 697 698 HopperScreenInput *initData = new HopperScreenInput(); 699 initData->inventory = inventory; 700 initData->hopper = hopper; 701 initData->iPad = iPad; 702 if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; 703 else initData->bSplitscreen=false; 704 705 success = ui.NavigateToScene(iPad,eUIScene_HopperMenu, initData); 706 707 return success; 708} 709 710bool CMinecraftApp::LoadHopperMenu(int iPad ,shared_ptr<Inventory> inventory, shared_ptr<MinecartHopper> hopper) 711{ 712 bool success = true; 713 714 HopperScreenInput *initData = new HopperScreenInput(); 715 initData->inventory = inventory; 716 initData->hopper = dynamic_pointer_cast<Container>(hopper); 717 initData->iPad = iPad; 718 if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; 719 else initData->bSplitscreen=false; 720 721 success = ui.NavigateToScene(iPad,eUIScene_HopperMenu, initData); 722 723 return success; 724} 725 726 727bool CMinecraftApp::LoadHorseMenu(int iPad ,shared_ptr<Inventory> inventory, shared_ptr<Container> container, shared_ptr<EntityHorse> horse) 728{ 729 bool success = true; 730 731 HorseScreenInput *initData = new HorseScreenInput(); 732 initData->inventory = inventory; 733 initData->container = container; 734 initData->horse = horse; 735 initData->iPad = iPad; 736 if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; 737 else initData->bSplitscreen=false; 738 739 success = ui.NavigateToScene(iPad,eUIScene_HorseMenu, initData); 740 741 return success; 742} 743 744bool CMinecraftApp::LoadBeaconMenu(int iPad ,shared_ptr<Inventory> inventory, shared_ptr<BeaconTileEntity> beacon) 745{ 746 bool success = true; 747 748 BeaconScreenInput *initData = new BeaconScreenInput(); 749 initData->inventory = inventory; 750 initData->beacon = beacon; 751 initData->iPad = iPad; 752 if(app.GetLocalPlayerCount()>1) initData->bSplitscreen=true; 753 else initData->bSplitscreen=false; 754 755 success = ui.NavigateToScene(iPad,eUIScene_BeaconMenu, initData); 756 757 return success; 758} 759 760////////////////////////////////////////////// 761// GAME SETTINGS 762////////////////////////////////////////////// 763 764#ifdef _WINDOWS64 765static void Win64_GetSettingsPath(char *outPath, DWORD size) 766{ 767 GetModuleFileNameA(NULL, outPath, size); 768 char *lastSlash = strrchr(outPath, '\\'); 769 if (lastSlash) *(lastSlash + 1) = '\0'; 770 strncat_s(outPath, size, "settings.dat", _TRUNCATE); 771} 772static void Win64_SaveSettings(GAME_SETTINGS *gs) 773{ 774 if (!gs) return; 775 char filePath[MAX_PATH] = {}; 776 Win64_GetSettingsPath(filePath, MAX_PATH); 777 FILE *f = NULL; 778 if (fopen_s(&f, filePath, "wb") == 0 && f) 779 { 780 fwrite(gs, sizeof(GAME_SETTINGS), 1, f); 781 fclose(f); 782 } 783} 784static void Win64_LoadSettings(GAME_SETTINGS *gs) 785{ 786 if (!gs) return; 787 char filePath[MAX_PATH] = {}; 788 Win64_GetSettingsPath(filePath, MAX_PATH); 789 FILE *f = NULL; 790 if (fopen_s(&f, filePath, "rb") == 0 && f) 791 { 792 GAME_SETTINGS temp = {}; 793 if (fread(&temp, sizeof(GAME_SETTINGS), 1, f) == 1) 794 memcpy(gs, &temp, sizeof(GAME_SETTINGS)); 795 fclose(f); 796 } 797} 798#endif 799 800void CMinecraftApp::InitGameSettings() 801{ 802 for(int i=0;i<XUSER_MAX_COUNT;i++) 803 { 804#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) 805 GameSettingsA[i]=(GAME_SETTINGS *)StorageManager.GetGameDefinedProfileData(i); 806#else 807 GameSettingsA[i]=(GAME_SETTINGS *)ProfileManager.GetGameDefinedProfileData(i); 808#endif 809 // clear the flag to say the settings have changed 810 GameSettingsA[i]->bSettingsChanged=false; 811 812 //SetDefaultGameSettings(i); - done on a callback from the profile manager 813 814 // 4J-PB - adding in for Windows & PS3 to set the defaults for the joypad 815#if defined _WINDOWS64// || defined __PSVITA__ 816 C_4JProfile::PROFILESETTINGS *pProfileSettings=ProfileManager.GetDashboardProfileSettings(i); 817 // clear this for now - it will come from reading the system values 818 memset(pProfileSettings,0,sizeof(C_4JProfile::PROFILESETTINGS)); 819 SetDefaultOptions(pProfileSettings,i); 820 Win64_LoadSettings(GameSettingsA[i]); 821 ApplyGameSettingsChanged(i); 822#elif defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ 823 C4JStorage::PROFILESETTINGS *pProfileSettings=StorageManager.GetDashboardProfileSettings(i); 824 // 4J-PB - don't cause an options write to happen here 825 SetDefaultOptions(pProfileSettings,i,false); 826 827#endif 828 } 829} 830 831#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) 832int CMinecraftApp::SetDefaultOptions(C4JStorage::PROFILESETTINGS *pSettings,const int iPad,bool bWriteProfile) 833#else 834int CMinecraftApp::SetDefaultOptions(C_4JProfile::PROFILESETTINGS *pSettings,const int iPad) 835#endif 836{ 837 SetGameSettings(iPad,eGameSetting_MusicVolume,DEFAULT_VOLUME_LEVEL); 838 SetGameSettings(iPad,eGameSetting_SoundFXVolume,DEFAULT_VOLUME_LEVEL); 839 SetGameSettings(iPad,eGameSetting_Gamma,50); 840 841 // 4J-PB - Don't reset the difficult level if we're in-game 842 if(Minecraft::GetInstance()->level==NULL) 843 { 844 app.DebugPrintf("SetDefaultOptions - Difficulty = 1\n"); 845 SetGameSettings(iPad,eGameSetting_Difficulty,1); 846 } 847 SetGameSettings(iPad,eGameSetting_Sensitivity_InGame,100); 848 SetGameSettings(iPad,eGameSetting_ViewBob,1); 849 SetGameSettings(iPad,eGameSetting_ControlScheme,0); 850 SetGameSettings(iPad,eGameSetting_ControlInvertLook,(pSettings->iYAxisInversion!=0)?1:0); 851 SetGameSettings(iPad,eGameSetting_ControlSouthPaw,pSettings->bSwapSticks?1:0); 852 SetGameSettings(iPad,eGameSetting_SplitScreenVertical,0); 853 SetGameSettings(iPad,eGameSetting_GamertagsVisible,1); 854 855 // Interim TU 1.6.6 856 SetGameSettings(iPad,eGameSetting_Sensitivity_InMenu,100); 857 SetGameSettings(iPad,eGameSetting_DisplaySplitscreenGamertags,1); 858 SetGameSettings(iPad,eGameSetting_Hints,1); 859 SetGameSettings(iPad,eGameSetting_Autosave,2); 860 SetGameSettings(iPad,eGameSetting_Tooltips,1); 861 SetGameSettings(iPad,eGameSetting_InterfaceOpacity,80); 862 863 // TU 5 864 SetGameSettings(iPad,eGameSetting_Clouds,1); 865 SetGameSettings(iPad,eGameSetting_Online,1); 866 SetGameSettings(iPad,eGameSetting_InviteOnly,0); 867 SetGameSettings(iPad,eGameSetting_FriendsOfFriends,1); 868 869 // default the update changes message to zero 870 // 4J-PB - We'll only display the message if the profile is pre-TU5 871 //SetGameSettings(iPad,eGameSetting_DisplayUpdateMessage,0); 872 873 // TU 6 874 SetGameSettings(iPad,eGameSetting_BedrockFog,0); 875 SetGameSettings(iPad,eGameSetting_DisplayHUD,1); 876 SetGameSettings(iPad,eGameSetting_DisplayHand,1); 877 878 // TU 7 879 SetGameSettings(iPad,eGameSetting_CustomSkinAnim,1); 880 881 // TU 9 882 SetGameSettings(iPad,eGameSetting_DeathMessages,1); 883 SetGameSettings(iPad,eGameSetting_UISize,1); 884 SetGameSettings(iPad,eGameSetting_UISizeSplitscreen,2); 885 SetGameSettings(iPad,eGameSetting_AnimatedCharacter,1); 886 887 // TU 12 888 GameSettingsA[iPad]->ucCurrentFavoriteSkinPos=0; 889 for(int i=0;i<MAX_FAVORITE_SKINS;i++) 890 { 891 GameSettingsA[iPad]->uiFavoriteSkinA[i]=0xFFFFFFFF; 892 } 893 894 // TU 13 895 GameSettingsA[iPad]->uiMashUpPackWorldsDisplay=0xFFFFFFFF; 896 897 // 1.6.4 898 app.SetGameHostOption(eGameHostOption_MobGriefing, 1); 899 app.SetGameHostOption(eGameHostOption_KeepInventory, 0); 900 app.SetGameHostOption(eGameHostOption_DoMobSpawning, 1 ); 901 app.SetGameHostOption(eGameHostOption_DoMobLoot, 1 ); 902 app.SetGameHostOption(eGameHostOption_DoTileDrops, 1 ); 903 app.SetGameHostOption(eGameHostOption_NaturalRegeneration, 1 ); 904 app.SetGameHostOption(eGameHostOption_DoDaylightCycle, 1 ); 905 906 // 4J-PB - leave these in, or remove from everywhere they are referenced! 907 // 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 908 //#ifdef __PS3__ 909 // PS3DEC13 910 SetGameSettings(iPad,eGameSetting_PS3_EULA_Read,0); // EULA not read 911 912 // PS3 1.05 - added Greek 913 914 // 4J-JEV: We cannot change these in-game, as they could affect localised strings and font. 915 // 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 916 if (!app.GetGameStarted()) 917 { 918 GameSettingsA[iPad]->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language 919 GameSettingsA[iPad]->ucLocale = MINECRAFT_LANGUAGE_DEFAULT; // use the system locale 920 } 921 922 //#endif 923 924#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) 925 GameSettingsA[iPad]->bSettingsChanged=bWriteProfile; 926#endif 927 928 return 0; 929} 930 931#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) 932int CMinecraftApp::DefaultOptionsCallback(LPVOID pParam,C4JStorage::PROFILESETTINGS *pSettings, const int iPad) 933#else 934int CMinecraftApp::DefaultOptionsCallback(LPVOID pParam,C_4JProfile::PROFILESETTINGS *pSettings, const int iPad) 935#endif 936{ 937 CMinecraftApp *pApp=(CMinecraftApp *)pParam; 938 939 // flag the default options to be set 940 941 pApp->DebugPrintf("Setting default options for player %d", iPad); 942 pApp->SetAction(iPad,eAppAction_SetDefaultOptions, (LPVOID)pSettings); 943 //pApp->SetDefaultOptions(pSettings,iPad); 944 945 // if the profile data has been changed, then force a profile write 946 // It seems we're allowed to break the 5 minute rule if it's the result of a user action 947 //pApp->CheckGameSettingsChanged(); 948 949 return 0; 950} 951 952#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) 953 954wstring CMinecraftApp::toStringOptionsStatus(const C4JStorage::eOptionsCallback &eStatus) 955{ 956#ifndef _CONTENT_PACKAGE 957 switch(eStatus) 958 { 959 case C4JStorage::eOptions_Callback_Idle: return L"Idle"; 960 case C4JStorage::eOptions_Callback_Write: return L"Write"; 961 case C4JStorage::eOptions_Callback_Write_Fail_NoSpace: return L"Write_Fail_NoSpace"; 962 case C4JStorage::eOptions_Callback_Write_Fail: return L"Write_Fail"; 963 case C4JStorage::eOptions_Callback_Read: return L"Read"; 964 case C4JStorage::eOptions_Callback_Read_Fail: return L"Read_Fail"; 965 case C4JStorage::eOptions_Callback_Read_FileNotFound: return L"Read_FileNotFound"; 966 case C4JStorage::eOptions_Callback_Read_Corrupt: return L"Read_Corrupt"; 967 case C4JStorage::eOptions_Callback_Read_CorruptDeletePending: return L"Read_CorruptDeletePending"; 968 case C4JStorage::eOptions_Callback_Read_CorruptDeleted: return L"Read_CorruptDeleted"; 969 default: return L"[UNRECOGNISED_OPTIONS_STATUS]"; 970 } 971#else 972 return L""; 973#endif 974} 975 976#ifdef __ORBIS__ 977int CMinecraftApp::OptionsDataCallback(LPVOID pParam,int iPad,unsigned short usVersion,C4JStorage::eOptionsCallback eStatus,int iBlocksRequired) 978{ 979 CMinecraftApp *pApp=(CMinecraftApp *)pParam; 980 pApp->m_eOptionsStatusA[iPad]=eStatus; 981 pApp->m_eOptionsBlocksRequiredA[iPad]=iBlocksRequired; 982 return 0; 983} 984 985int CMinecraftApp::GetOptionsBlocksRequired(int iPad) 986{ 987 return m_eOptionsBlocksRequiredA[iPad]; 988} 989 990#else 991int CMinecraftApp::OptionsDataCallback(LPVOID pParam,int iPad,unsigned short usVersion,C4JStorage::eOptionsCallback eStatus) 992{ 993 CMinecraftApp *pApp=(CMinecraftApp *)pParam; 994 995#ifndef _CONTENT_PACKAGE 996 pApp->DebugPrintf("[OptionsDataCallback] Pad_%i: new status == %ls(%i).\n", iPad, pApp->toStringOptionsStatus(eStatus).c_str(), (int) eStatus); 997#endif 998 999 pApp->m_eOptionsStatusA[iPad] = eStatus; 1000 1001 return 0; 1002} 1003#endif 1004 1005C4JStorage::eOptionsCallback CMinecraftApp::GetOptionsCallbackStatus(int iPad) 1006{ 1007 return m_eOptionsStatusA[iPad]; 1008} 1009 1010void CMinecraftApp::SetOptionsCallbackStatus(int iPad, C4JStorage::eOptionsCallback eStatus) 1011{ 1012 m_eOptionsStatusA[iPad]=eStatus; 1013} 1014#endif 1015 1016int CMinecraftApp::OldProfileVersionCallback(LPVOID pParam,unsigned char *pucData, const unsigned short usVersion, const int iPad) 1017{ 1018 // check what needs to be done with this version to update to the current one 1019 1020 switch(usVersion) 1021 { 1022#ifdef _XBOX 1023 case PROFILE_VERSION_1: 1024 case PROFILE_VERSION_2: 1025 // 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 1026 { 1027 GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; 1028 pGameSettings->ucMenuSensitivity=100; //eGameSetting_Sensitivity_InMenu 1029 pGameSettings->ucInterfaceOpacity=80; //eGameSetting_Sensitivity_InMenu 1030 pGameSettings->usBitmaskValues|=0x0200; //eGameSetting_DisplaySplitscreenGamertags - on 1031 pGameSettings->usBitmaskValues|=0x0400; //eGameSetting_Hints - on 1032 pGameSettings->usBitmaskValues|=0x1000; //eGameSetting_Autosave - 2 1033 pGameSettings->usBitmaskValues|=0x8000; //eGameSetting_Tooltips - on 1034 1035 // 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 1036 // 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 1037 //ProfileManager.ReAwardAchievements(iPad); 1038 1039 pGameSettings->uiBitmaskValues=0L; // reset 1040 pGameSettings->uiBitmaskValues|=GAMESETTING_CLOUDS; //eGameSetting_Clouds - on 1041 pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on 1042 //eGameSetting_GameSetting_Invite - off 1043 pGameSettings->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on 1044 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) 1045 // TU6 1046 pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off 1047 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on 1048 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on 1049 // TU7 1050 pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on 1051 // TU9 1052 pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on 1053 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 1054 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 1055 pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on 1056 // TU12 1057 // favorite skins added, but only set in TU12 - set to FFs 1058 for(int i=0;i<MAX_FAVORITE_SKINS;i++) 1059 { 1060 pGameSettings->uiFavoriteSkinA[i]=0xFFFFFFFF; 1061 } 1062 pGameSettings->ucCurrentFavoriteSkinPos=0; 1063 // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list 1064 pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; 1065 1066 // PS3 1.05 - added Greek 1067 pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language 1068 } 1069 break; 1070 case PROFILE_VERSION_3: 1071 1072 { 1073 GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; 1074 pGameSettings->uiBitmaskValues=0L; // reset 1075 pGameSettings->uiBitmaskValues|=GAMESETTING_CLOUDS; //eGameSetting_Clouds - on 1076 pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on 1077 //eGameSetting_GameSetting_Invite - off 1078 pGameSettings->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on 1079 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) 1080 // TU6 1081 pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off 1082 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on 1083 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on 1084 // TU7 1085 pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on 1086 // TU9 1087 pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on 1088 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 1089 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 1090 pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on 1091 // TU12 1092 // favorite skins added, but only set in TU12 - set to FFs 1093 for(int i=0;i<MAX_FAVORITE_SKINS;i++) 1094 { 1095 pGameSettings->uiFavoriteSkinA[i]=0xFFFFFFFF; 1096 } 1097 pGameSettings->ucCurrentFavoriteSkinPos=0; 1098 // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list 1099 pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; 1100 1101 // PS3 1.05 - added Greek 1102 pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language 1103 1104 } 1105 break; 1106 case PROFILE_VERSION_4: 1107 { 1108 GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; 1109 1110 pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off 1111 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on 1112 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on 1113 // TU7 1114 pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on 1115 // TU9 1116 pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on 1117 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 1118 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 1119 pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on 1120 1121 // 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) 1122 pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on 1123 // TU12 1124 // favorite skins added, but only set in TU12 - set to FFs 1125 for(int i=0;i<MAX_FAVORITE_SKINS;i++) 1126 { 1127 pGameSettings->uiFavoriteSkinA[i]=0xFFFFFFFF; 1128 } 1129 pGameSettings->ucCurrentFavoriteSkinPos=0; 1130 // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list 1131 pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; 1132 1133 // PS3 1.05 - added Greek 1134 pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language 1135 1136 } 1137 1138 break; 1139 case PROFILE_VERSION_5: 1140 { 1141 GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; 1142 1143 // reset the display new message counter 1144 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) 1145 // TU7 1146 pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on 1147 // TU9 1148 pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on 1149 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 1150 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 1151 pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on 1152 // 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) 1153 pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on 1154 // TU12 1155 // favorite skins added, but only set in TU12 - set to FFs 1156 for(int i=0;i<MAX_FAVORITE_SKINS;i++) 1157 { 1158 pGameSettings->uiFavoriteSkinA[i]=0xFFFFFFFF; 1159 } 1160 pGameSettings->ucCurrentFavoriteSkinPos=0; 1161 // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list 1162 pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; 1163 1164 // PS3 1.05 - added Greek 1165 pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language 1166 1167 1168 } 1169 1170 break; 1171 case PROFILE_VERSION_6: 1172 { 1173 GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; 1174 1175 // Added gui size for splitscreen and fullscreen 1176 // Added death messages toggle 1177 1178 // reset the display new message counter 1179 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) 1180 // TU9 1181 pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on 1182 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 1183 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 1184 pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on 1185 // 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) 1186 pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on 1187 // TU12 1188 // favorite skins added, but only set in TU12 - set to FFs 1189 for(int i=0;i<MAX_FAVORITE_SKINS;i++) 1190 { 1191 pGameSettings->uiFavoriteSkinA[i]=0xFFFFFFFF; 1192 } 1193 pGameSettings->ucCurrentFavoriteSkinPos=0; 1194 // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list 1195 pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; 1196 1197 // PS3 1.05 - added Greek 1198 pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language 1199 1200 1201 } 1202 1203 break; 1204 1205 case PROFILE_VERSION_7: 1206 { 1207 GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; 1208 // reset the display new message counter 1209 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) 1210 1211 // TU12 1212 // favorite skins added, but only set in TU12 - set to FFs 1213 for(int i=0;i<MAX_FAVORITE_SKINS;i++) 1214 { 1215 pGameSettings->uiFavoriteSkinA[i]=0xFFFFFFFF; 1216 } 1217 pGameSettings->ucCurrentFavoriteSkinPos=0; 1218 // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list 1219 pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; 1220 1221 // PS3 1.05 - added Greek 1222 pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language 1223 1224 1225 } 1226 break; 1227#endif 1228 case PROFILE_VERSION_8: 1229 { 1230 GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; 1231 // reset the display new message counter 1232 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) 1233 1234 // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list 1235 pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; 1236 1237 // PS3DEC13 1238 pGameSettings->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off 1239 1240 // PS3 1.05 - added Greek 1241 pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language 1242 1243 } 1244 break; 1245 case PROFILE_VERSION_9: 1246 // PS3DEC13 1247 { 1248 GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; 1249 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) 1250 pGameSettings->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off 1251 1252 // PS3 1.05 - added Greek 1253 pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language 1254 1255 } 1256 break; 1257 case PROFILE_VERSION_10: 1258 { 1259 GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; 1260 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) 1261 pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language 1262 } 1263 break; 1264 case PROFILE_VERSION_11: 1265 { 1266 GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; 1267 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) 1268 } 1269 break; 1270 case PROFILE_VERSION_12: 1271 { 1272 GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; 1273 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) 1274 } 1275 break; 1276 default: 1277 { 1278 // This might be from a version during testing of new profile updates 1279 app.DebugPrintf("Don't know what to do with this profile version!\n"); 1280#ifndef _CONTENT_PACKAGE 1281 // __debugbreak(); 1282#endif 1283 1284 GAME_SETTINGS *pGameSettings=(GAME_SETTINGS *)pucData; 1285 pGameSettings->ucMenuSensitivity=100; //eGameSetting_Sensitivity_InMenu 1286 pGameSettings->ucInterfaceOpacity=80; //eGameSetting_Sensitivity_InMenu 1287 pGameSettings->usBitmaskValues|=0x0200; //eGameSetting_DisplaySplitscreenGamertags - on 1288 pGameSettings->usBitmaskValues|=0x0400; //eGameSetting_Hints - on 1289 pGameSettings->usBitmaskValues|=0x1000; //eGameSetting_Autosave - 2 1290 pGameSettings->usBitmaskValues|=0x8000; //eGameSetting_Tooltips - on 1291 1292 pGameSettings->uiBitmaskValues=0L; // reset 1293 pGameSettings->uiBitmaskValues|=GAMESETTING_CLOUDS; //eGameSetting_Clouds - on 1294 pGameSettings->uiBitmaskValues|=GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on 1295 //eGameSetting_GameSetting_Invite - off 1296 pGameSettings->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on 1297 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter) 1298 pGameSettings->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off 1299 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on 1300 pGameSettings->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on 1301 pGameSettings->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on 1302 pGameSettings->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on 1303 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE&0x00000800); // uisize 2 1304 pGameSettings->uiBitmaskValues|=(GAMESETTING_UISIZE_SPLITSCREEN&0x00004000); // splitscreen ui size 3 1305 pGameSettings->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on 1306 // TU12 1307 // favorite skins added, but only set in TU12 - set to FFs 1308 for(int i=0;i<MAX_FAVORITE_SKINS;i++) 1309 { 1310 pGameSettings->uiFavoriteSkinA[i]=0xFFFFFFFF; 1311 } 1312 pGameSettings->ucCurrentFavoriteSkinPos=0; 1313 // Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list 1314 pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF; 1315 1316 // PS3DEC13 1317 pGameSettings->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off 1318 1319 // PS3 1.05 - added Greek 1320 pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language 1321 1322 } 1323 break; 1324 } 1325 1326 return 0; 1327} 1328 1329void CMinecraftApp::ApplyGameSettingsChanged(int iPad) 1330{ 1331 ActionGameSettings(iPad,eGameSetting_MusicVolume ); 1332 ActionGameSettings(iPad,eGameSetting_SoundFXVolume ); 1333 ActionGameSettings(iPad,eGameSetting_Gamma ); 1334 ActionGameSettings(iPad,eGameSetting_Difficulty ); 1335 ActionGameSettings(iPad,eGameSetting_Sensitivity_InGame ); 1336 ActionGameSettings(iPad,eGameSetting_ViewBob ); 1337 ActionGameSettings(iPad,eGameSetting_ControlScheme ); 1338 ActionGameSettings(iPad,eGameSetting_ControlInvertLook); 1339 ActionGameSettings(iPad,eGameSetting_ControlSouthPaw); 1340 ActionGameSettings(iPad,eGameSetting_SplitScreenVertical); 1341 ActionGameSettings(iPad,eGameSetting_GamertagsVisible); 1342 1343 // Interim TU 1.6.6 1344 ActionGameSettings(iPad,eGameSetting_Sensitivity_InMenu ); 1345 ActionGameSettings(iPad,eGameSetting_DisplaySplitscreenGamertags); 1346 ActionGameSettings(iPad,eGameSetting_Hints); 1347 ActionGameSettings(iPad,eGameSetting_InterfaceOpacity); 1348 ActionGameSettings(iPad,eGameSetting_Tooltips); 1349 1350 ActionGameSettings(iPad,eGameSetting_Clouds); 1351 ActionGameSettings(iPad,eGameSetting_BedrockFog); 1352 ActionGameSettings(iPad,eGameSetting_DisplayHUD); 1353 ActionGameSettings(iPad,eGameSetting_DisplayHand); 1354 ActionGameSettings(iPad,eGameSetting_CustomSkinAnim); 1355 ActionGameSettings(iPad,eGameSetting_DeathMessages); 1356 ActionGameSettings(iPad,eGameSetting_UISize); 1357 ActionGameSettings(iPad,eGameSetting_UISizeSplitscreen); 1358 ActionGameSettings(iPad,eGameSetting_AnimatedCharacter); 1359 1360 ActionGameSettings(iPad,eGameSetting_PS3_EULA_Read); 1361 1362} 1363 1364void CMinecraftApp::ActionGameSettings(int iPad,eGameSetting eVal) 1365{ 1366 Minecraft *pMinecraft=Minecraft::GetInstance(); 1367 switch(eVal) 1368 { 1369 case eGameSetting_MusicVolume: 1370 if(iPad==ProfileManager.GetPrimaryPad()) 1371 { 1372 pMinecraft->options->set(Options::Option::MUSIC,((float)GameSettingsA[iPad]->ucMusicVolume)/100.0f); 1373 } 1374 break; 1375 case eGameSetting_SoundFXVolume: 1376 if(iPad==ProfileManager.GetPrimaryPad()) 1377 { 1378 pMinecraft->options->set(Options::Option::SOUND,((float)GameSettingsA[iPad]->ucSoundFXVolume)/100.0f); 1379 } 1380 break; 1381 case eGameSetting_Gamma: 1382 if(iPad==ProfileManager.GetPrimaryPad()) 1383 { 1384#if defined(_WIN64) || defined(_WINDOWS64) 1385 pMinecraft->options->set(Options::Option::GAMMA, ((float)GameSettingsA[iPad]->ucGamma) / 100.0f); 1386#else 1387 // ucGamma range is 0-100, UpdateGamma is 0 - 32768 1388 float fVal=((float)GameSettingsA[iPad]->ucGamma)*327.68f; 1389 RenderManager.UpdateGamma((unsigned short)fVal); 1390#endif 1391 } 1392 1393 break; 1394 case eGameSetting_Difficulty: 1395 if(iPad==ProfileManager.GetPrimaryPad()) 1396 { 1397 pMinecraft->options->toggle(Options::Option::DIFFICULTY,GameSettingsA[iPad]->usBitmaskValues&0x03); 1398 app.DebugPrintf("Difficulty toggle to %d\n",GameSettingsA[iPad]->usBitmaskValues&0x03); 1399 1400 // Update the Game Host setting 1401 app.SetGameHostOption(eGameHostOption_Difficulty,pMinecraft->options->difficulty); 1402 1403 // send this to the other players if we are in-game 1404 bool bInGame=pMinecraft->level!=NULL; 1405 1406 // Game Host only (and for now we can't change the diff while in game, so this shouldn't happen) 1407 if(bInGame && g_NetworkManager.IsHost() && (iPad==ProfileManager.GetPrimaryPad())) 1408 { 1409 app.SetXuiServerAction(iPad,eXuiServerAction_ServerSettingChanged_Difficulty); 1410 } 1411 } 1412 else 1413 { 1414 app.DebugPrintf("NOT ACTIONING DIFFICULTY - Primary pad is %d, This pad is %d\n",ProfileManager.GetPrimaryPad(),iPad); 1415 } 1416 1417 break; 1418 case eGameSetting_Sensitivity_InGame: 1419 // 4J-PB - we don't use the options value 1420 // tell the input that we've changed the sensitivity - range of the slider is 0 to 200, default is 100 1421 pMinecraft->options->set(Options::Option::SENSITIVITY,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); 1422 //InputManager.SetJoypadSensitivity(iPad,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); 1423 1424 break; 1425 case eGameSetting_ViewBob: 1426 // 4J-PB - not handled here any more - it's read from the gamesettings per player 1427 //pMinecraft->options->toggle(Options::Option::VIEW_BOBBING,GameSettingsA[iPad]->usBitmaskValues&0x04); 1428 break; 1429 case eGameSetting_ControlScheme: 1430 InputManager.SetJoypadMapVal(iPad,(GameSettingsA[iPad]->usBitmaskValues&0x30)>>4); 1431 break; 1432 1433 case eGameSetting_ControlInvertLook: 1434 // Nothing specific to do for this setting. 1435 break; 1436 1437 case eGameSetting_ControlSouthPaw: 1438 // What is the setting? 1439 if ( GameSettingsA[iPad]->usBitmaskValues & 0x80 ) 1440 { 1441 // Southpaw. 1442 InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LX, AXIS_MAP_RX ); 1443 InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LY, AXIS_MAP_RY ); 1444 InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RX, AXIS_MAP_LX ); 1445 InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RY, AXIS_MAP_LY ); 1446 InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_0, TRIGGER_MAP_1 ); 1447 InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_1, TRIGGER_MAP_0 ); 1448 } 1449 else 1450 { 1451 // Right handed. 1452 InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LX, AXIS_MAP_LX ); 1453 InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_LY, AXIS_MAP_LY ); 1454 InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RX, AXIS_MAP_RX ); 1455 InputManager.SetJoypadStickAxisMap( iPad, AXIS_MAP_RY, AXIS_MAP_RY ); 1456 InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_0, TRIGGER_MAP_0 ); 1457 InputManager.SetJoypadStickTriggerMap( iPad, TRIGGER_MAP_1, TRIGGER_MAP_1 ); 1458 } 1459 break; 1460 case eGameSetting_SplitScreenVertical: 1461 if(iPad==ProfileManager.GetPrimaryPad()) 1462 { 1463 pMinecraft->updatePlayerViewportAssignments(); 1464 } 1465 break; 1466 case eGameSetting_GamertagsVisible: 1467 { 1468 bool bInGame=pMinecraft->level!=NULL; 1469 1470 // Game Host only 1471 if(bInGame && g_NetworkManager.IsHost() && (iPad==ProfileManager.GetPrimaryPad())) 1472 { 1473 // Update the Game Host setting if you are the host and you are in-game 1474 app.SetGameHostOption(eGameHostOption_Gamertags,((GameSettingsA[iPad]->usBitmaskValues&0x0008)!=0)?1:0); 1475 app.SetXuiServerAction(iPad,eXuiServerAction_ServerSettingChanged_Gamertags); 1476 1477 PlayerList *players = MinecraftServer::getInstance()->getPlayerList(); 1478 for(AUTO_VAR(it3, players->players.begin()); it3 != players->players.end(); ++it3) 1479 { 1480 shared_ptr<ServerPlayer> decorationPlayer = *it3; 1481 decorationPlayer->setShowOnMaps((app.GetGameHostOption(eGameHostOption_Gamertags)!=0)?true:false); 1482 } 1483 } 1484 } 1485 break; 1486 // Interim TU 1.6.6 1487 case eGameSetting_Sensitivity_InMenu: 1488 // 4J-PB - we don't use the options value 1489 // tell the input that we've changed the sensitivity - range of the slider is 0 to 200, default is 100 1490 //pMinecraft->options->set(Options::Option::SENSITIVITY,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); 1491 //InputManager.SetJoypadSensitivity(iPad,((float)GameSettingsA[iPad]->ucSensitivity)/100.0f); 1492 1493 break; 1494 1495 case eGameSetting_DisplaySplitscreenGamertags: 1496 for( BYTE idx = 0; idx < XUSER_MAX_COUNT; ++idx) 1497 { 1498 if(pMinecraft->localplayers[idx] != NULL) 1499 { 1500 if(pMinecraft->localplayers[idx]->m_iScreenSection==C4JRender::VIEWPORT_TYPE_FULLSCREEN) 1501 { 1502 ui.DisplayGamertag(idx,false); 1503 } 1504 else 1505 { 1506 ui.DisplayGamertag(idx,true); 1507 } 1508 } 1509 } 1510 1511 break; 1512 case eGameSetting_InterfaceOpacity: 1513 // update the tooltips display 1514 ui.RefreshTooltips( iPad); 1515 1516 break; 1517 case eGameSetting_Hints: 1518 //nothing to do here 1519 break; 1520 case eGameSetting_Tooltips: 1521 if((GameSettingsA[iPad]->usBitmaskValues&0x8000)!=0) 1522 { 1523 ui.SetEnableTooltips(iPad,TRUE); 1524 } 1525 else 1526 { 1527 ui.SetEnableTooltips(iPad,FALSE); 1528 } 1529 break; 1530 case eGameSetting_Clouds: 1531 //nothing to do here 1532 break; 1533 case eGameSetting_Online: 1534 //nothing to do here 1535 break; 1536 case eGameSetting_InviteOnly: 1537 //nothing to do here 1538 break; 1539 case eGameSetting_FriendsOfFriends: 1540 //nothing to do here 1541 break; 1542 case eGameSetting_BedrockFog: 1543 { 1544 bool bInGame=pMinecraft->level!=NULL; 1545 1546 // Game Host only 1547 if(bInGame && g_NetworkManager.IsHost() && (iPad==ProfileManager.GetPrimaryPad())) 1548 { 1549 // Update the Game Host setting if you are the host and you are in-game 1550 app.SetGameHostOption(eGameHostOption_BedrockFog,GetGameSettings(iPad,eGameSetting_BedrockFog)?1:0); 1551 app.SetXuiServerAction(iPad,eXuiServerAction_ServerSettingChanged_BedrockFog); 1552 } 1553 } 1554 break; 1555 case eGameSetting_DisplayHUD: 1556 //nothing to do here 1557 break; 1558 case eGameSetting_DisplayHand: 1559 //nothing to do here 1560 break; 1561 case eGameSetting_CustomSkinAnim: 1562 //nothing to do here 1563 break; 1564 case eGameSetting_DeathMessages: 1565 //nothing to do here 1566 break; 1567 case eGameSetting_UISize: 1568 //nothing to do here 1569 break; 1570 case eGameSetting_UISizeSplitscreen: 1571 //nothing to do here 1572 break; 1573 case eGameSetting_AnimatedCharacter: 1574 //nothing to do here 1575 break; 1576 case eGameSetting_PS3_EULA_Read: 1577 //nothing to do here 1578 break; 1579 case eGameSetting_PSVita_NetworkModeAdhoc: 1580 //nothing to do here 1581 break; 1582 } 1583} 1584 1585void CMinecraftApp::SetPlayerSkin(int iPad,const wstring &name) 1586{ 1587 DWORD skinId = app.getSkinIdFromPath(name); 1588 1589 SetPlayerSkin(iPad,skinId); 1590} 1591 1592void CMinecraftApp::SetPlayerSkin(int iPad,DWORD dwSkinId) 1593{ 1594 DebugPrintf("Setting skin for %d to %08X\n", iPad, dwSkinId); 1595 1596 GameSettingsA[iPad]->dwSelectedSkin = dwSkinId; 1597 GameSettingsA[iPad]->bSettingsChanged = true; 1598 1599 TelemetryManager->RecordSkinChanged(iPad, GameSettingsA[iPad]->dwSelectedSkin); 1600 1601 if(Minecraft::GetInstance()->localplayers[iPad]!=NULL) Minecraft::GetInstance()->localplayers[iPad]->setAndBroadcastCustomSkin(dwSkinId); 1602} 1603 1604 1605wstring CMinecraftApp::GetPlayerSkinName(int iPad) 1606{ 1607 return app.getSkinPathFromId(GameSettingsA[iPad]->dwSelectedSkin); 1608} 1609 1610DWORD CMinecraftApp::GetPlayerSkinId(int iPad) 1611{ 1612 // 4J-PB -check the user has rights to use this skin - they may have had at some point but the entitlement has been removed. 1613 DLCPack *Pack=NULL; 1614 DLCSkinFile *skinFile=NULL; 1615 DWORD dwSkin=GameSettingsA[iPad]->dwSelectedSkin; 1616 wchar_t chars[256]; 1617 1618 if( GET_IS_DLC_SKIN_FROM_BITMASK(dwSkin) ) 1619 { 1620 // 4J Stu - DLC skins are numbered using decimal rather than hex to make it easier to number manually 1621 swprintf(chars, 256, L"dlcskin%08d.png", GET_DLC_SKIN_ID_FROM_BITMASK(dwSkin)); 1622 1623 Pack=app.m_dlcManager.getPackContainingSkin(chars); 1624 1625 if(Pack) 1626 { 1627 skinFile = Pack->getSkinFile(chars); 1628 1629 bool bSkinIsFree = skinFile->getParameterAsBool( DLCManager::e_DLCParamType_Free ); 1630 bool bLicensed = Pack->hasPurchasedFile( DLCManager::e_DLCType_Skin, skinFile->getPath() ); 1631 1632 if(bSkinIsFree || bLicensed) 1633 { 1634 return dwSkin; 1635 } 1636 else 1637 { 1638 return 0; 1639 } 1640 } 1641 } 1642 1643 1644 return dwSkin; 1645} 1646 1647DWORD CMinecraftApp::GetAdditionalModelParts(int iPad) 1648{ 1649 return m_dwAdditionalModelParts[iPad]; 1650} 1651 1652 1653void CMinecraftApp::SetPlayerCape(int iPad,const wstring &name) 1654{ 1655 DWORD capeId = Player::getCapeIdFromPath(name); 1656 1657 SetPlayerCape(iPad,capeId); 1658} 1659 1660void CMinecraftApp::SetPlayerCape(int iPad,DWORD dwCapeId) 1661{ 1662 DebugPrintf("Setting cape for %d to %08X\n", iPad, dwCapeId); 1663 1664 GameSettingsA[iPad]->dwSelectedCape = dwCapeId; 1665 GameSettingsA[iPad]->bSettingsChanged = true; 1666 1667 //SentientManager.RecordSkinChanged(iPad, GameSettingsA[iPad]->dwSelectedSkin); 1668 1669 if(Minecraft::GetInstance()->localplayers[iPad]!=NULL) Minecraft::GetInstance()->localplayers[iPad]->setAndBroadcastCustomCape(dwCapeId); 1670} 1671 1672wstring CMinecraftApp::GetPlayerCapeName(int iPad) 1673{ 1674 return Player::getCapePathFromId(GameSettingsA[iPad]->dwSelectedCape); 1675} 1676 1677DWORD CMinecraftApp::GetPlayerCapeId(int iPad) 1678{ 1679 return GameSettingsA[iPad]->dwSelectedCape; 1680} 1681 1682void CMinecraftApp::SetPlayerFavoriteSkin(int iPad, int iIndex,unsigned int uiSkinID) 1683{ 1684 DebugPrintf("Setting favorite skin for %d to %08X\n", iPad, uiSkinID); 1685 1686 GameSettingsA[iPad]->uiFavoriteSkinA[iIndex] = uiSkinID; 1687 GameSettingsA[iPad]->bSettingsChanged = true; 1688} 1689 1690unsigned int CMinecraftApp::GetPlayerFavoriteSkin(int iPad,int iIndex) 1691{ 1692 return GameSettingsA[iPad]->uiFavoriteSkinA[iIndex]; 1693} 1694 1695unsigned char CMinecraftApp::GetPlayerFavoriteSkinsPos(int iPad) 1696{ 1697 return GameSettingsA[iPad]->ucCurrentFavoriteSkinPos; 1698} 1699 1700void CMinecraftApp::SetPlayerFavoriteSkinsPos(int iPad, int iPos) 1701{ 1702 GameSettingsA[iPad]->ucCurrentFavoriteSkinPos=(unsigned char)iPos; 1703 GameSettingsA[iPad]->bSettingsChanged = true; 1704} 1705 1706unsigned int CMinecraftApp::GetPlayerFavoriteSkinsCount(int iPad) 1707{ 1708 unsigned int uiCount=0; 1709 for(int i=0;i<MAX_FAVORITE_SKINS;i++) 1710 { 1711 if(GameSettingsA[iPad]->uiFavoriteSkinA[i]!=0xFFFFFFFF) 1712 { 1713 uiCount++; 1714 } 1715 else 1716 { 1717 break; 1718 } 1719 } 1720 return uiCount; 1721} 1722 1723void CMinecraftApp::ValidateFavoriteSkins(int iPad) 1724{ 1725 unsigned int uiCount=GetPlayerFavoriteSkinsCount(iPad); 1726 1727 // remove invalid skins 1728 unsigned int uiValidSkin=0; 1729 wchar_t chars[256]; 1730 1731 for(unsigned int i=0;i<uiCount;i++) 1732 { 1733 // get the pack number from the skin id 1734 swprintf(chars, 256, L"dlcskin%08d.png", app.GetPlayerFavoriteSkin(iPad,i)); 1735 1736 // Also check they haven't reverted to a trial pack 1737 DLCPack *pDLCPack=app.m_dlcManager.getPackContainingSkin(chars); 1738 1739 if(pDLCPack!=NULL) 1740 { 1741 // 4J-PB - We should let players add the free skins to their favourites as well! 1742 //DLCFile *pDLCFile=pDLCPack->getFile(DLCManager::e_DLCType_Skin,chars); 1743 DLCSkinFile *pSkinFile = pDLCPack->getSkinFile(chars); 1744 1745 if( pDLCPack->hasPurchasedFile(DLCManager::e_DLCType_Skin, L"") || (pSkinFile && pSkinFile->isFree())) 1746 { 1747 GameSettingsA[iPad]->uiFavoriteSkinA[uiValidSkin++]=GameSettingsA[iPad]->uiFavoriteSkinA[i]; 1748 } 1749 } 1750 } 1751 1752 for(unsigned int i=uiValidSkin;i<MAX_FAVORITE_SKINS;i++) 1753 { 1754 GameSettingsA[iPad]->uiFavoriteSkinA[i]=0xFFFFFFFF; 1755 } 1756} 1757 1758// Mash-up pack worlds 1759void CMinecraftApp::HideMashupPackWorld(int iPad, unsigned int iMashupPackID) 1760{ 1761 unsigned int uiPackID=iMashupPackID - 1024; // mash-up ids start at 1024 1762 GameSettingsA[iPad]->uiMashUpPackWorldsDisplay&=~(1<<uiPackID); 1763 GameSettingsA[iPad]->bSettingsChanged = true; 1764} 1765 1766void CMinecraftApp::EnableMashupPackWorlds(int iPad) 1767{ 1768 GameSettingsA[iPad]->uiMashUpPackWorldsDisplay=0xFFFFFFFF; 1769 GameSettingsA[iPad]->bSettingsChanged = true; 1770} 1771 1772unsigned int CMinecraftApp::GetMashupPackWorlds(int iPad) 1773{ 1774 return GameSettingsA[iPad]->uiMashUpPackWorldsDisplay; 1775} 1776 1777void CMinecraftApp::SetMinecraftLanguage(int iPad, unsigned char ucLanguage) 1778{ 1779 GameSettingsA[iPad]->ucLanguage = ucLanguage; 1780 GameSettingsA[iPad]->bSettingsChanged = true; 1781} 1782 1783unsigned char CMinecraftApp::GetMinecraftLanguage(int iPad) 1784{ 1785 // if there are no game settings read yet, return the default language 1786 if(GameSettingsA[iPad]==NULL) 1787 { 1788 return 0; 1789 } 1790 else 1791 { 1792 return GameSettingsA[iPad]->ucLanguage; 1793 } 1794} 1795 1796void CMinecraftApp::SetMinecraftLocale(int iPad, unsigned char ucLocale) 1797{ 1798 GameSettingsA[iPad]->ucLocale = ucLocale; 1799 GameSettingsA[iPad]->bSettingsChanged = true; 1800} 1801 1802unsigned char CMinecraftApp::GetMinecraftLocale(int iPad) 1803{ 1804 // if there are no game settings read yet, return the default language 1805 if(GameSettingsA[iPad]==NULL) 1806 { 1807 return 0; 1808 } 1809 else 1810 { 1811 return GameSettingsA[iPad]->ucLocale; 1812 } 1813} 1814 1815void CMinecraftApp::SetGameSettings(int iPad,eGameSetting eVal,unsigned char ucVal) 1816{ 1817 //Minecraft *pMinecraft=Minecraft::GetInstance(); 1818 1819 switch(eVal) 1820 { 1821 case eGameSetting_MusicVolume: 1822 if(GameSettingsA[iPad]->ucMusicVolume!=ucVal) 1823 { 1824 GameSettingsA[iPad]->ucMusicVolume=ucVal; 1825 if(iPad==ProfileManager.GetPrimaryPad()) 1826 { 1827 ActionGameSettings(iPad,eVal); 1828 } 1829 GameSettingsA[iPad]->bSettingsChanged=true; 1830 } 1831 break; 1832 case eGameSetting_SoundFXVolume: 1833 if(GameSettingsA[iPad]->ucSoundFXVolume!=ucVal) 1834 { 1835 GameSettingsA[iPad]->ucSoundFXVolume=ucVal; 1836 if(iPad==ProfileManager.GetPrimaryPad()) 1837 { 1838 ActionGameSettings(iPad,eVal); 1839 } 1840 GameSettingsA[iPad]->bSettingsChanged=true; 1841 } 1842 break; 1843 case eGameSetting_Gamma: 1844 if(GameSettingsA[iPad]->ucGamma!=ucVal) 1845 { 1846 GameSettingsA[iPad]->ucGamma=ucVal; 1847 if(iPad==ProfileManager.GetPrimaryPad()) 1848 { 1849 ActionGameSettings(iPad,eVal); 1850 } 1851 GameSettingsA[iPad]->bSettingsChanged=true; 1852 } 1853 break; 1854 case eGameSetting_Difficulty: 1855 if((GameSettingsA[iPad]->usBitmaskValues&0x03)!=(ucVal&0x03)) 1856 { 1857 GameSettingsA[iPad]->usBitmaskValues&=~0x03; 1858 GameSettingsA[iPad]->usBitmaskValues|=ucVal&0x03; 1859 if(iPad==ProfileManager.GetPrimaryPad()) 1860 { 1861 ActionGameSettings(iPad,eVal); 1862 } 1863 GameSettingsA[iPad]->bSettingsChanged=true; 1864 } 1865 break; 1866 case eGameSetting_Sensitivity_InGame: 1867 if(GameSettingsA[iPad]->ucSensitivity!=ucVal) 1868 { 1869 GameSettingsA[iPad]->ucSensitivity=ucVal; 1870 ActionGameSettings(iPad,eVal); 1871 GameSettingsA[iPad]->bSettingsChanged=true; 1872 } 1873 break; 1874 case eGameSetting_ViewBob: 1875 if((GameSettingsA[iPad]->usBitmaskValues&0x0004)!=((ucVal&0x01)<<2)) 1876 { 1877 if(ucVal!=0) 1878 { 1879 GameSettingsA[iPad]->usBitmaskValues|=0x0004; 1880 } 1881 else 1882 { 1883 GameSettingsA[iPad]->usBitmaskValues&=~0x0004; 1884 } 1885 ActionGameSettings(iPad,eVal); 1886 GameSettingsA[iPad]->bSettingsChanged=true; 1887 } 1888 break; 1889 case eGameSetting_ControlScheme: // bits 5 and 6 1890 if((GameSettingsA[iPad]->usBitmaskValues&0x30)!=((ucVal&0x03)<<4)) 1891 { 1892 GameSettingsA[iPad]->usBitmaskValues&=~0x0030; 1893 if(ucVal!=0) 1894 { 1895 GameSettingsA[iPad]->usBitmaskValues|=(ucVal&0x03)<<4; 1896 } 1897 ActionGameSettings(iPad,eVal); 1898 GameSettingsA[iPad]->bSettingsChanged=true; 1899 } 1900 break; 1901 1902 case eGameSetting_ControlInvertLook: 1903 if((GameSettingsA[iPad]->usBitmaskValues&0x0040)!=((ucVal&0x01)<<6)) 1904 { 1905 if(ucVal!=0) 1906 { 1907 GameSettingsA[iPad]->usBitmaskValues|=0x0040; 1908 } 1909 else 1910 { 1911 GameSettingsA[iPad]->usBitmaskValues&=~0x0040; 1912 } 1913 ActionGameSettings(iPad,eVal); 1914 GameSettingsA[iPad]->bSettingsChanged=true; 1915 } 1916 break; 1917 1918 case eGameSetting_ControlSouthPaw: 1919 if((GameSettingsA[iPad]->usBitmaskValues&0x0080)!=((ucVal&0x01)<<7)) 1920 { 1921 if(ucVal!=0) 1922 { 1923 GameSettingsA[iPad]->usBitmaskValues|=0x0080; 1924 } 1925 else 1926 { 1927 GameSettingsA[iPad]->usBitmaskValues&=~0x0080; 1928 } 1929 ActionGameSettings(iPad,eVal); 1930 GameSettingsA[iPad]->bSettingsChanged=true; 1931 } 1932 break; 1933 case eGameSetting_SplitScreenVertical: 1934 if((GameSettingsA[iPad]->usBitmaskValues&0x0100)!=((ucVal&0x01)<<8)) 1935 { 1936 if(ucVal!=0) 1937 { 1938 GameSettingsA[iPad]->usBitmaskValues|=0x0100; 1939 } 1940 else 1941 { 1942 GameSettingsA[iPad]->usBitmaskValues&=~0x0100; 1943 } 1944 ActionGameSettings(iPad,eVal); 1945 GameSettingsA[iPad]->bSettingsChanged=true; 1946 } 1947 break; 1948 case eGameSetting_GamertagsVisible: 1949 if((GameSettingsA[iPad]->usBitmaskValues&0x0008)!=((ucVal&0x01)<<3)) 1950 { 1951 if(ucVal!=0) 1952 { 1953 GameSettingsA[iPad]->usBitmaskValues|=0x0008; 1954 } 1955 else 1956 { 1957 GameSettingsA[iPad]->usBitmaskValues&=~0x0008; 1958 } 1959 ActionGameSettings(iPad,eVal); 1960 GameSettingsA[iPad]->bSettingsChanged=true; 1961 } 1962 break; 1963 1964 // 4J-PB - Added for Interim TU for 1.6.6 1965 case eGameSetting_Sensitivity_InMenu: 1966 if(GameSettingsA[iPad]->ucMenuSensitivity!=ucVal) 1967 { 1968 GameSettingsA[iPad]->ucMenuSensitivity=ucVal; 1969 ActionGameSettings(iPad,eVal); 1970 GameSettingsA[iPad]->bSettingsChanged=true; 1971 } 1972 break; 1973 case eGameSetting_DisplaySplitscreenGamertags: 1974 if((GameSettingsA[iPad]->usBitmaskValues&0x0200)!=((ucVal&0x01)<<9)) 1975 { 1976 if(ucVal!=0) 1977 { 1978 GameSettingsA[iPad]->usBitmaskValues|=0x0200; 1979 } 1980 else 1981 { 1982 GameSettingsA[iPad]->usBitmaskValues&=~0x0200; 1983 } 1984 ActionGameSettings(iPad,eVal); 1985 GameSettingsA[iPad]->bSettingsChanged=true; 1986 } 1987 break; 1988 case eGameSetting_Hints: 1989 if((GameSettingsA[iPad]->usBitmaskValues&0x0400)!=((ucVal&0x01)<<10)) 1990 { 1991 if(ucVal!=0) 1992 { 1993 GameSettingsA[iPad]->usBitmaskValues|=0x0400; 1994 } 1995 else 1996 { 1997 GameSettingsA[iPad]->usBitmaskValues&=~0x0400; 1998 } 1999 ActionGameSettings(iPad,eVal); 2000 GameSettingsA[iPad]->bSettingsChanged=true; 2001 } 2002 break; 2003 case eGameSetting_Autosave: 2004 if((GameSettingsA[iPad]->usBitmaskValues&0x7800)!=((ucVal&0x0F)<<11)) 2005 { 2006 GameSettingsA[iPad]->usBitmaskValues&=~0x7800; 2007 if(ucVal!=0) 2008 { 2009 GameSettingsA[iPad]->usBitmaskValues|=(ucVal&0x0F)<<11; 2010 } 2011 ActionGameSettings(iPad,eVal); 2012 GameSettingsA[iPad]->bSettingsChanged=true; 2013 } 2014 break; 2015 2016 case eGameSetting_Tooltips: 2017 if((GameSettingsA[iPad]->usBitmaskValues&0x8000)!=((ucVal&0x01)<<15)) 2018 { 2019 if(ucVal!=0) 2020 { 2021 GameSettingsA[iPad]->usBitmaskValues|=0x8000; 2022 } 2023 else 2024 { 2025 GameSettingsA[iPad]->usBitmaskValues&=~0x8000; 2026 } 2027 ActionGameSettings(iPad,eVal); 2028 GameSettingsA[iPad]->bSettingsChanged=true; 2029 } 2030 break; 2031 case eGameSetting_InterfaceOpacity: 2032 if(GameSettingsA[iPad]->ucInterfaceOpacity!=ucVal) 2033 { 2034 GameSettingsA[iPad]->ucInterfaceOpacity=ucVal; 2035 ActionGameSettings(iPad,eVal); 2036 GameSettingsA[iPad]->bSettingsChanged=true; 2037 } 2038 2039 break; 2040 case eGameSetting_Clouds: 2041 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CLOUDS)!=(ucVal&0x01)) 2042 { 2043 if(ucVal==1) 2044 { 2045 GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_CLOUDS; 2046 } 2047 else 2048 { 2049 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_CLOUDS; 2050 } 2051 ActionGameSettings(iPad,eVal); 2052 GameSettingsA[iPad]->bSettingsChanged=true; 2053 } 2054 2055 break; 2056 2057 case eGameSetting_Online: 2058 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ONLINE)!=(ucVal&0x01)<<1) 2059 { 2060 if(ucVal==1) 2061 { 2062 GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_ONLINE; 2063 } 2064 else 2065 { 2066 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_ONLINE; 2067 } 2068 ActionGameSettings(iPad,eVal); 2069 GameSettingsA[iPad]->bSettingsChanged=true; 2070 } 2071 2072 break; 2073 case eGameSetting_InviteOnly: 2074 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_INVITEONLY)!=(ucVal&0x01)<<2) 2075 { 2076 if(ucVal==1) 2077 { 2078 GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_INVITEONLY; 2079 } 2080 else 2081 { 2082 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_INVITEONLY; 2083 } 2084 ActionGameSettings(iPad,eVal); 2085 GameSettingsA[iPad]->bSettingsChanged=true; 2086 } 2087 2088 break; 2089 case eGameSetting_FriendsOfFriends: 2090 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_FRIENDSOFFRIENDS)!=(ucVal&0x01)<<3) 2091 { 2092 if(ucVal==1) 2093 { 2094 GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_FRIENDSOFFRIENDS; 2095 } 2096 else 2097 { 2098 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_FRIENDSOFFRIENDS; 2099 } 2100 ActionGameSettings(iPad,eVal); 2101 GameSettingsA[iPad]->bSettingsChanged=true; 2102 } 2103 2104 break; 2105 case eGameSetting_DisplayUpdateMessage: 2106 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYUPDATEMSG)!=(ucVal&0x03)<<4) 2107 { 2108 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DISPLAYUPDATEMSG; 2109 if(ucVal>0) 2110 { 2111 GameSettingsA[iPad]->uiBitmaskValues|=(ucVal&0x03)<<4; 2112 } 2113 2114 ActionGameSettings(iPad,eVal); 2115 GameSettingsA[iPad]->bSettingsChanged=true; 2116 } 2117 2118 break; 2119 2120 case eGameSetting_BedrockFog: 2121 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_BEDROCKFOG)!=(ucVal&0x01)<<6) 2122 { 2123 if(ucVal==1) 2124 { 2125 GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_BEDROCKFOG; 2126 } 2127 else 2128 { 2129 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_BEDROCKFOG; 2130 } 2131 ActionGameSettings(iPad,eVal); 2132 GameSettingsA[iPad]->bSettingsChanged=true; 2133 } 2134 2135 break; 2136 case eGameSetting_DisplayHUD: 2137 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHUD)!=(ucVal&0x01)<<7) 2138 { 2139 if(ucVal==1) 2140 { 2141 GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_DISPLAYHUD; 2142 } 2143 else 2144 { 2145 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DISPLAYHUD; 2146 } 2147 ActionGameSettings(iPad,eVal); 2148 GameSettingsA[iPad]->bSettingsChanged=true; 2149 } 2150 2151 break; 2152 case eGameSetting_DisplayHand: 2153 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHAND)!=(ucVal&0x01)<<8) 2154 { 2155 if(ucVal==1) 2156 { 2157 GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_DISPLAYHAND; 2158 } 2159 else 2160 { 2161 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DISPLAYHAND; 2162 } 2163 ActionGameSettings(iPad,eVal); 2164 GameSettingsA[iPad]->bSettingsChanged=true; 2165 } 2166 2167 break; 2168 2169 case eGameSetting_CustomSkinAnim: 2170 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CUSTOMSKINANIM)!=(ucVal&0x01)<<9) 2171 { 2172 if(ucVal==1) 2173 { 2174 GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_CUSTOMSKINANIM; 2175 } 2176 else 2177 { 2178 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_CUSTOMSKINANIM; 2179 } 2180 ActionGameSettings(iPad,eVal); 2181 GameSettingsA[iPad]->bSettingsChanged=true; 2182 } 2183 2184 break; 2185 // TU9 2186 case eGameSetting_DeathMessages: 2187 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DEATHMESSAGES)!=(ucVal&0x01)<<10) 2188 { 2189 if(ucVal==1) 2190 { 2191 GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_DEATHMESSAGES; 2192 } 2193 else 2194 { 2195 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_DEATHMESSAGES; 2196 } 2197 ActionGameSettings(iPad,eVal); 2198 GameSettingsA[iPad]->bSettingsChanged=true; 2199 } 2200 break; 2201 case eGameSetting_UISize: 2202 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE)!=((ucVal&0x03)<<11)) 2203 { 2204 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_UISIZE; 2205 if(ucVal!=0) 2206 { 2207 GameSettingsA[iPad]->uiBitmaskValues|=(ucVal&0x03)<<11; 2208 } 2209 ActionGameSettings(iPad,eVal); 2210 GameSettingsA[iPad]->bSettingsChanged=true; 2211 } 2212 break; 2213 case eGameSetting_UISizeSplitscreen: 2214 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE_SPLITSCREEN)!=((ucVal&0x03)<<13)) 2215 { 2216 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_UISIZE_SPLITSCREEN; 2217 if(ucVal!=0) 2218 { 2219 GameSettingsA[iPad]->uiBitmaskValues|=(ucVal&0x03)<<13; 2220 } 2221 ActionGameSettings(iPad,eVal); 2222 GameSettingsA[iPad]->bSettingsChanged=true; 2223 } 2224 break; 2225 case eGameSetting_AnimatedCharacter: 2226 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ANIMATEDCHARACTER)!=(ucVal&0x01)<<15) 2227 { 2228 if(ucVal==1) 2229 { 2230 GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_ANIMATEDCHARACTER; 2231 } 2232 else 2233 { 2234 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_ANIMATEDCHARACTER; 2235 } 2236 ActionGameSettings(iPad,eVal); 2237 GameSettingsA[iPad]->bSettingsChanged=true; 2238 } 2239 break; 2240 case eGameSetting_PS3_EULA_Read: 2241 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PS3EULAREAD)!=(ucVal&0x01)<<16) 2242 { 2243 if(ucVal==1) 2244 { 2245 GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_PS3EULAREAD; 2246 } 2247 else 2248 { 2249 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_PS3EULAREAD; 2250 } 2251 ActionGameSettings(iPad,eVal); 2252 GameSettingsA[iPad]->bSettingsChanged=true; 2253 } 2254 break; 2255 case eGameSetting_PSVita_NetworkModeAdhoc: 2256 if((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PSVITANETWORKMODEADHOC)!=(ucVal&0x01)<<17) 2257 { 2258 if(ucVal==1) 2259 { 2260 GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_PSVITANETWORKMODEADHOC; 2261 } 2262 else 2263 { 2264 GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_PSVITANETWORKMODEADHOC; 2265 } 2266 ActionGameSettings(iPad,eVal); 2267 GameSettingsA[iPad]->bSettingsChanged=true; 2268 } 2269 break; 2270 2271 } 2272} 2273 2274unsigned char CMinecraftApp::GetGameSettings(eGameSetting eVal) 2275{ 2276 int iPad=ProfileManager.GetPrimaryPad(); 2277 2278 return GetGameSettings(iPad,eVal); 2279} 2280 2281unsigned char CMinecraftApp::GetGameSettings(int iPad,eGameSetting eVal) 2282{ 2283 switch(eVal) 2284 { 2285 case eGameSetting_MusicVolume: 2286 return GameSettingsA[iPad]->ucMusicVolume; 2287 break; 2288 case eGameSetting_SoundFXVolume: 2289 return GameSettingsA[iPad]->ucSoundFXVolume; 2290 break; 2291 case eGameSetting_Gamma: 2292 return GameSettingsA[iPad]->ucGamma; 2293 break; 2294 case eGameSetting_Difficulty: 2295 return GameSettingsA[iPad]->usBitmaskValues&0x0003; 2296 break; 2297 case eGameSetting_Sensitivity_InGame: 2298 return GameSettingsA[iPad]->ucSensitivity; 2299 break; 2300 case eGameSetting_ViewBob: 2301 return ((GameSettingsA[iPad]->usBitmaskValues&0x0004)>>2); 2302 break; 2303 case eGameSetting_GamertagsVisible: 2304 return ((GameSettingsA[iPad]->usBitmaskValues&0x0008)>>3); 2305 break; 2306 case eGameSetting_ControlScheme: 2307 return ((GameSettingsA[iPad]->usBitmaskValues&0x0030)>>4); // 2 bits 2308 break; 2309 case eGameSetting_ControlInvertLook: 2310 return ((GameSettingsA[iPad]->usBitmaskValues&0x0040)>>6); 2311 break; 2312 case eGameSetting_ControlSouthPaw: 2313 return ((GameSettingsA[iPad]->usBitmaskValues&0x0080)>>7); 2314 break; 2315 case eGameSetting_SplitScreenVertical: 2316 return ((GameSettingsA[iPad]->usBitmaskValues&0x0100)>>8); 2317 break; 2318 // 4J-PB - Added for Interim TU for 1.6.6 2319 case eGameSetting_Sensitivity_InMenu: 2320 return GameSettingsA[iPad]->ucMenuSensitivity; 2321 break; 2322 2323 case eGameSetting_DisplaySplitscreenGamertags: 2324 return ((GameSettingsA[iPad]->usBitmaskValues&0x0200)>>9); 2325 break; 2326 2327 case eGameSetting_Hints: 2328 return ((GameSettingsA[iPad]->usBitmaskValues&0x0400)>>10); 2329 break; 2330 case eGameSetting_Autosave: 2331 { 2332 unsigned char ucVal=(GameSettingsA[iPad]->usBitmaskValues&0x7800)>>11; 2333 return ucVal; 2334 } 2335 break; 2336 case eGameSetting_Tooltips: 2337 return ((GameSettingsA[iPad]->usBitmaskValues&0x8000)>>15); 2338 break; 2339 2340 case eGameSetting_InterfaceOpacity: 2341 return GameSettingsA[iPad]->ucInterfaceOpacity; 2342 break; 2343 2344 case eGameSetting_Clouds: 2345 return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CLOUDS); 2346 break; 2347 case eGameSetting_Online: 2348 return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ONLINE)>>1; 2349 break; 2350 case eGameSetting_InviteOnly: 2351 return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_INVITEONLY)>>2; 2352 break; 2353 case eGameSetting_FriendsOfFriends: 2354 return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_FRIENDSOFFRIENDS)>>3; 2355 break; 2356 case eGameSetting_DisplayUpdateMessage: 2357 return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYUPDATEMSG)>>4; 2358 break; 2359 case eGameSetting_BedrockFog: 2360 return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_BEDROCKFOG)>>6; 2361 break; 2362 case eGameSetting_DisplayHUD: 2363 return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHUD)>>7; 2364 break; 2365 case eGameSetting_DisplayHand: 2366 return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DISPLAYHAND)>>8; 2367 break; 2368 case eGameSetting_CustomSkinAnim: 2369 return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_CUSTOMSKINANIM)>>9; 2370 break; 2371 // TU9 2372 case eGameSetting_DeathMessages: 2373 return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_DEATHMESSAGES)>>10; 2374 break; 2375 case eGameSetting_UISize: 2376 { 2377 unsigned char ucVal=(GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE)>>11; 2378 return ucVal; 2379 } 2380 break; 2381 case eGameSetting_UISizeSplitscreen: 2382 { 2383 unsigned char ucVal=(GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_UISIZE_SPLITSCREEN)>>13; 2384 return ucVal; 2385 } 2386 break; 2387 case eGameSetting_AnimatedCharacter: 2388 return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_ANIMATEDCHARACTER)>>15; 2389 2390 case eGameSetting_PS3_EULA_Read: 2391 return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PS3EULAREAD)>>16; 2392 2393 case eGameSetting_PSVita_NetworkModeAdhoc: 2394 return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PSVITANETWORKMODEADHOC)>>17; 2395 2396 } 2397 return 0; 2398} 2399 2400void CMinecraftApp::CheckGameSettingsChanged(bool bOverride5MinuteTimer, int iPad) 2401{ 2402 // If the settings have changed, write them to the profile 2403 2404 if(iPad==XUSER_INDEX_ANY) 2405 { 2406 for(int i=0;i<XUSER_MAX_COUNT;i++) 2407 { 2408 if(GameSettingsA[i]->bSettingsChanged) 2409 { 2410#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ ) 2411 StorageManager.WriteToProfile(i,true, bOverride5MinuteTimer); 2412#else 2413 ProfileManager.WriteToProfile(i,true, bOverride5MinuteTimer); 2414#ifdef _WINDOWS64 2415 Win64_SaveSettings(GameSettingsA[i]); 2416#endif 2417#endif 2418 GameSettingsA[i]->bSettingsChanged=false; 2419 } 2420 } 2421 } 2422 else 2423 { 2424 if(GameSettingsA[iPad]->bSettingsChanged) 2425 { 2426#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) 2427 StorageManager.WriteToProfile(iPad,true, bOverride5MinuteTimer); 2428#else 2429 ProfileManager.WriteToProfile(iPad,true, bOverride5MinuteTimer); 2430#ifdef _WINDOWS64 2431 Win64_SaveSettings(GameSettingsA[iPad]); 2432#endif 2433#endif 2434 GameSettingsA[iPad]->bSettingsChanged=false; 2435 } 2436 } 2437} 2438 2439void CMinecraftApp::ClearGameSettingsChangedFlag(int iPad) 2440{ 2441 GameSettingsA[iPad]->bSettingsChanged=false; 2442} 2443 2444/////////////////////////// 2445// 2446// Remove the debug settings in the content package build 2447// 2448//////////////////////////// 2449#ifndef _DEBUG_MENUS_ENABLED 2450unsigned int CMinecraftApp::GetGameSettingsDebugMask(int iPad,bool bOverridePlayer) //bOverridePlayer is to force the send for the server to get the read options 2451{ 2452 return 0; 2453} 2454 2455void CMinecraftApp::SetGameSettingsDebugMask(int iPad, unsigned int uiVal) 2456{ 2457} 2458 2459void CMinecraftApp::ActionDebugMask(int iPad,bool bSetAllClear) 2460{ 2461} 2462 2463#else 2464 2465unsigned int CMinecraftApp::GetGameSettingsDebugMask(int iPad,bool bOverridePlayer) //bOverridePlayer is to force the send for the server to get the read options 2466{ 2467 if(iPad==-1) 2468 { 2469 iPad=ProfileManager.GetPrimaryPad(); 2470 } 2471 if(iPad < 0) iPad = 0; 2472 2473 shared_ptr<Player> player = Minecraft::GetInstance()->localplayers[iPad]; 2474 2475 if(bOverridePlayer || player==NULL) 2476 { 2477 return GameSettingsA[iPad]->uiDebugBitmask; 2478 } 2479 else 2480 { 2481 return player->GetDebugOptions(); 2482 } 2483} 2484 2485 2486void CMinecraftApp::SetGameSettingsDebugMask(int iPad, unsigned int uiVal) 2487{ 2488#ifndef _CONTENT_PACKAGE 2489 GameSettingsA[iPad]->bSettingsChanged=true; 2490 GameSettingsA[iPad]->uiDebugBitmask=uiVal; 2491 2492 // update the value so the network server can use it 2493 shared_ptr<Player> player = Minecraft::GetInstance()->localplayers[iPad]; 2494 2495 if(player) 2496 { 2497 Minecraft::GetInstance()->localgameModes[iPad]->handleDebugOptions(uiVal,player); 2498 } 2499#endif 2500} 2501 2502void CMinecraftApp::ActionDebugMask(int iPad,bool bSetAllClear) 2503{ 2504 unsigned int ulBitmask=app.GetGameSettingsDebugMask(iPad); 2505 2506 if(bSetAllClear) ulBitmask=0L; 2507 2508 2509 2510 // these settings should only be actioned for the primary player 2511 if(ProfileManager.GetPrimaryPad()!=iPad) return; 2512 2513 for(int i=0;i<eDebugSetting_Max;i++) 2514 { 2515 switch(i) 2516 { 2517 case eDebugSetting_LoadSavesFromDisk: 2518 if(ulBitmask&(1<<i)) 2519 { 2520 app.SetLoadSavesFromFolderEnabled(true); 2521 } 2522 else 2523 { 2524 app.SetLoadSavesFromFolderEnabled(false); 2525 } 2526 break; 2527 2528 case eDebugSetting_WriteSavesToDisk: 2529 if(ulBitmask&(1<<i)) 2530 { 2531 app.SetWriteSavesToFolderEnabled(true); 2532 } 2533 else 2534 { 2535 app.SetWriteSavesToFolderEnabled(false); 2536 } 2537 break; 2538 2539 case eDebugSetting_FreezePlayers: //eDebugSetting_InterfaceOff: 2540 if(ulBitmask&(1<<i)) 2541 { 2542 app.SetFreezePlayers(true); 2543 2544 // Turn off interface rendering. 2545 //app.SetInterfaceRenderingOff( true ); 2546 } 2547 else 2548 { 2549 app.SetFreezePlayers(false); 2550 2551 // Turn on interface rendering. 2552 //app.SetInterfaceRenderingOff( false ); 2553 } 2554 break; 2555 case eDebugSetting_Safearea: 2556 if(ulBitmask&(1<<i)) 2557 { 2558 app.ShowSafeArea( TRUE ); 2559 } 2560 else 2561 { 2562 app.ShowSafeArea( FALSE ); 2563 } 2564 break; 2565 2566 //case eDebugSetting_HandRenderingOff: 2567 // if(ulBitmask&(1<<i)) 2568 // { 2569 // // Turn off hand rendering. 2570 // //app.SetHandRenderingOff( true ); 2571 // } 2572 // else 2573 // { 2574 // // Turn on hand rendering. 2575 // //app.SetHandRenderingOff( false ); 2576 // } 2577 // break; 2578 2579 case eDebugSetting_ShowUIConsole: 2580 if(ulBitmask&(1<<i)) 2581 { 2582 ui.ShowUIDebugConsole(true); 2583 } 2584 else 2585 { 2586 ui.ShowUIDebugConsole(false); 2587 } 2588 break; 2589 2590 case eDebugSetting_ShowUIMarketingGuide: 2591 if(ulBitmask&(1<<i)) 2592 { 2593 ui.ShowUIDebugMarketingGuide(true); 2594 } 2595 else 2596 { 2597 ui.ShowUIDebugMarketingGuide(false); 2598 } 2599 break; 2600 2601 case eDebugSetting_MobsDontAttack: 2602 if(ulBitmask&(1<<i)) 2603 { 2604 app.SetMobsDontAttackEnabled(true); 2605 } 2606 else 2607 { 2608 app.SetMobsDontAttackEnabled(false); 2609 } 2610 break; 2611 2612 case eDebugSetting_UseDpadForDebug: 2613 if(ulBitmask&(1<<i)) 2614 { 2615 app.SetUseDPadForDebug(true); 2616 } 2617 else 2618 { 2619 app.SetUseDPadForDebug(false); 2620 } 2621 break; 2622 case eDebugSetting_MobsDontTick: 2623 if(ulBitmask&(1<<i)) 2624 { 2625 app.SetMobsDontTickEnabled(true); 2626 } 2627 else 2628 { 2629 app.SetMobsDontTickEnabled(false); 2630 } 2631 break; 2632 2633 } 2634 } 2635} 2636#endif 2637 2638int CMinecraftApp::DisplaySavingMessage(void *pParam, C4JStorage::ESavingMessage eVal, int iPad) 2639{ 2640 //CMinecraftApp* pClass = (CMinecraftApp*)pParam; 2641 2642 ui.ShowSavingMessage(iPad, eVal); 2643 2644 return 0; 2645} 2646 2647void CMinecraftApp::SetActionConfirmed(LPVOID param) 2648{ 2649 XuiActionParam *actionInfo = (XuiActionParam *)param; 2650 app.SetAction(actionInfo->iPad, actionInfo->action); 2651} 2652 2653 2654void CMinecraftApp::HandleXuiActions(void) 2655{ 2656 eXuiAction eAction; 2657 eTMSAction eTMS; 2658 LPVOID param; 2659 Minecraft *pMinecraft=Minecraft::GetInstance(); 2660 shared_ptr<MultiplayerLocalPlayer> player; 2661 2662 // are there any global actions to deal with? 2663 eAction = app.GetGlobalXuiAction(); 2664 if(eAction!=eAppAction_Idle) 2665 { 2666 switch(eAction) 2667 { 2668 case eAppAction_DisplayLavaMessage: 2669 // Display a warning about placing lava in the spawn area 2670 { 2671 UINT uiIDA[1]; 2672 uiIDA[0]=IDS_CONFIRM_OK; 2673 C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_CANT_PLACE_NEAR_SPAWN_TITLE, IDS_CANT_PLACE_NEAR_SPAWN_TEXT, uiIDA,1,XUSER_INDEX_ANY); 2674 if(result != C4JStorage::EMessage_Busy) SetGlobalXuiAction(eAppAction_Idle); 2675 2676 } 2677 break; 2678 default: 2679 break; 2680 } 2681 } 2682 2683 // are there any app actions to deal with? 2684 for(int i=0;i<XUSER_MAX_COUNT;i++) 2685 { 2686 eAction = app.GetXuiAction(i); 2687 param = m_eXuiActionParam[i]; 2688 2689 if(eAction!=eAppAction_Idle) 2690 { 2691 switch(eAction) 2692 { 2693 // the renderer will capture a screenshot 2694 case eAppAction_SocialPost: 2695 if(ProfileManager.IsFullVersion()) 2696 { 2697 // Facebook Share 2698 if( CSocialManager::Instance()->IsTitleAllowedToPostImages() && CSocialManager::Instance()->AreAllUsersAllowedToPostImages() ) 2699 { 2700 // disable character name tags for the shot 2701 //m_bwasHidingGui = pMinecraft->options->hideGui; // 4J Stu - Removed 1.8.2 bug fix (TU6) as don't need this 2702 pMinecraft->options->hideGui = true; 2703 2704 SetAction(i,eAppAction_SocialPostScreenshot); 2705 } 2706 else 2707 { 2708 SetAction(i,eAppAction_Idle); 2709 } 2710 } 2711 else 2712 { 2713 SetAction(i,eAppAction_Idle); 2714 } 2715 break; 2716 case eAppAction_SocialPostScreenshot: 2717 { 2718 SetAction(i,eAppAction_Idle); 2719 bool bKeepHiding = false; 2720 for(int j=0; j < XUSER_MAX_COUNT;++j) 2721 { 2722 if(app.GetXuiAction(j) == eAppAction_SocialPostScreenshot) 2723 { 2724 bKeepHiding = true; 2725 break; 2726 } 2727 } 2728 pMinecraft->options->hideGui=bKeepHiding; 2729 2730 // Facebook Share 2731 2732 if(app.GetLocalPlayerCount()>1) 2733 { 2734 ui.NavigateToScene(i,eUIScene_SocialPost); 2735 } 2736 else 2737 { 2738 ui.NavigateToScene(i,eUIScene_SocialPost); 2739 } 2740 } 2741 break; 2742 case eAppAction_SaveGame: 2743 SetAction(i,eAppAction_Idle); 2744 if(!GetChangingSessionType()) 2745 { 2746 // If this is the trial game, do an upsell 2747 if(ProfileManager.IsFullVersion()) 2748 { 2749 2750 // flag the render to capture the screenshot for the save 2751 SetAction(i,eAppAction_SaveGameCapturedThumbnail); 2752 } 2753 else 2754 { 2755 // ask the player if they would like to upgrade, or they'll lose the level 2756 2757 UINT uiIDA[2]; 2758 uiIDA[0]=IDS_CONFIRM_OK; 2759 uiIDA[1]=IDS_CONFIRM_CANCEL; 2760 ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_TOSAVE_TEXT, uiIDA, 2,i,&CMinecraftApp::UnlockFullSaveReturned,this); 2761 } 2762 } 2763 2764 break; 2765 case eAppAction_AutosaveSaveGame: 2766 { 2767 // 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 2768 bool bSaveExists; 2769 StorageManager.DoesSaveExist(&bSaveExists); 2770 2771 SetAction(i,eAppAction_Idle); 2772 if(!GetChangingSessionType()) 2773 { 2774 2775 // flag the render to capture the screenshot for the save 2776 SetAction(i,eAppAction_AutosaveSaveGameCapturedThumbnail); 2777 } 2778 } 2779 2780 break; 2781 2782 case eAppAction_SaveGameCapturedThumbnail: 2783 // reset the autosave timer 2784 app.SetAutosaveTimerTime(); 2785 SetAction(i,eAppAction_Idle); 2786 // 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 2787 /*if(StorageManager.GetSaveName()==NULL) 2788 { 2789 app.NavigateToScene(i,eUIScene_SaveWorld); 2790 } 2791 else*/ 2792 { 2793 // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen 2794 ui.HideAllGameUIElements(); 2795 2796 // Hide the other players scenes 2797 ui.ShowOtherPlayersBaseScene(ProfileManager.GetPrimaryPad(), false); 2798 2799 //INT saveOrCheckpointId = 0; 2800 //bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId); 2801 //SentientManager.RecordLevelSaveOrCheckpoint(ProfileManager.GetPrimaryPad(), saveOrCheckpointId); 2802 2803 LoadingInputParams *loadingParams = new LoadingInputParams(); 2804 loadingParams->func = &UIScene_PauseMenu::SaveWorldThreadProc; 2805 loadingParams->lpParam = (LPVOID)false; 2806 2807 // 4J-JEV - PS4: Fix for #5708 - [ONLINE] - If the user pulls their network cable out while saving the title will hang. 2808 loadingParams->waitForThreadToDelete = true; 2809 2810 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); 2811 completionData->bShowBackground=TRUE; 2812 completionData->bShowLogo=TRUE; 2813 completionData->type = e_ProgressCompletion_NavigateBackToScene; 2814 completionData->iPad = ProfileManager.GetPrimaryPad(); 2815 2816 if( ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) 2817 { 2818 completionData->scene = eUIScene_EndPoem; 2819 } 2820 else 2821 { 2822 completionData->scene = eUIScene_PauseMenu; 2823 } 2824 2825 loadingParams->completionData = completionData; 2826 2827 // 4J Stu - Xbox only 2828#ifdef _XBOX 2829 // Temporarily make this scene fullscreen 2830 CXuiSceneBase::SetPlayerBaseScenePosition( ProfileManager.GetPrimaryPad(), CXuiSceneBase::e_BaseScene_Fullscreen ); 2831#endif 2832 2833 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams , eUILayer_Fullscreen, eUIGroup_Fullscreen); 2834 2835 } 2836 break; 2837 case eAppAction_AutosaveSaveGameCapturedThumbnail: 2838 2839 { 2840 app.SetAutosaveTimerTime(); 2841 SetAction(i,eAppAction_Idle); 2842 2843#if defined(_XBOX_ONE) || defined(__ORBIS__) 2844 app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_AutoSaveGame); 2845 2846 if(app.GetGameHostOption(eGameHostOption_DisableSaving)) StorageManager.SetSaveDisabled(true); 2847#else 2848 // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen 2849 ui.HideAllGameUIElements(); 2850 2851 //app.CloseAllPlayersXuiScenes(); 2852 // Hide the other players scenes 2853 ui.ShowOtherPlayersBaseScene(ProfileManager.GetPrimaryPad(), false); 2854 2855 // This just allows it to be shown 2856 if(pMinecraft->localgameModes[ProfileManager.GetPrimaryPad()] != NULL) pMinecraft->localgameModes[ProfileManager.GetPrimaryPad()]->getTutorial()->showTutorialPopup(false); 2857 2858 //INT saveOrCheckpointId = 0; 2859 //bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId); 2860 //SentientManager.RecordLevelSaveOrCheckpoint(ProfileManager.GetPrimaryPad(), saveOrCheckpointId); 2861 2862 2863 LoadingInputParams *loadingParams = new LoadingInputParams(); 2864 loadingParams->func = &UIScene_PauseMenu::SaveWorldThreadProc; 2865 2866 loadingParams->lpParam = (LPVOID)true; 2867 2868 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); 2869 completionData->bShowBackground=TRUE; 2870 completionData->bShowLogo=TRUE; 2871 completionData->type = e_ProgressCompletion_AutosaveNavigateBack; 2872 completionData->iPad = ProfileManager.GetPrimaryPad(); 2873 //completionData->bAutosaveWasMenuDisplayed=ui.GetMenuDisplayed(ProfileManager.GetPrimaryPad()); 2874 loadingParams->completionData = completionData; 2875 2876 // 4J Stu - Xbox only 2877#ifdef _XBOX 2878 // Temporarily make this scene fullscreen 2879 CXuiSceneBase::SetPlayerBaseScenePosition( ProfileManager.GetPrimaryPad(), CXuiSceneBase::e_BaseScene_Fullscreen ); 2880#endif 2881 2882 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams , eUILayer_Fullscreen, eUIGroup_Fullscreen); 2883#endif 2884 } 2885 break; 2886 case eAppAction_ExitPlayer: 2887 // a secondary player has chosen to quit 2888 { 2889 int iPlayerC=g_NetworkManager.GetPlayerCount(); 2890 2891 // Since the player is exiting, let's flush any profile writes for them, and hope we're not breaking TCR 136... 2892#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) 2893 StorageManager.ForceQueuedProfileWrites(i); 2894 LeaderboardManager::Instance()->OpenSession(); 2895 for (int j = 0; j < XUSER_MAX_COUNT; j++) 2896 { 2897 if( ProfileManager.IsSignedIn(j) ) 2898 { 2899 app.DebugPrintf("Stats save for an offline game for the player at index %d\n", 0); 2900 Minecraft::GetInstance()->forceStatsSave(j); 2901 } 2902 } 2903 LeaderboardManager::Instance()->CloseSession(); 2904#else 2905 ProfileManager.ForceQueuedProfileWrites(i); 2906#endif 2907 2908 // not required - it's done within the removeLocalPlayerIdx 2909 // if(pMinecraft->level->isClientSide) 2910 // { 2911 // // 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 2912 // g_NetworkManager.NotifyPlayerLeaving(g_NetworkManager.GetLocalPlayerByUserIndex(i)); 2913 // } 2914 2915 // if there are any tips showing, we need to close them 2916 2917 pMinecraft->gui->clearMessages(i); 2918 2919 // Make sure we've not got this player selected as current - this shouldn't be the case anyway 2920 pMinecraft->setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); 2921 pMinecraft->removeLocalPlayerIdx(i); 2922 2923#ifdef _XBOX 2924 // tell the xui scenes a splitscreen player left - has to come after removeLocalPlayerIdx which calls updatePlayerViewportAssignments 2925 XUIMessage xuiMsg; 2926 CustomMessage_Splitscreenplayer_Struct myMsgData; 2927 CustomMessage_Splitscreenplayer( &xuiMsg, &myMsgData, false); 2928 2929 // send the message 2930 for(int idx=0;idx<XUSER_MAX_COUNT;idx++) 2931 { 2932 if((i!=idx) && (pMinecraft->localplayers[idx]!=NULL)) 2933 { 2934 XuiBroadcastMessage( CXuiSceneBase::GetPlayerBaseScene(idx), &xuiMsg ); 2935 } 2936 } 2937#endif 2938 2939#ifndef _XBOX 2940 // Wipe out the tooltips 2941 ui.SetTooltips(i, -1); 2942#endif 2943 2944 // Change the presence info 2945 // Are we offline or online, and how many players are there 2946 if(iPlayerC>2) // one player is about to leave here - they'll be set to idle in the qnet manager player leave 2947 { 2948 for(int iPlayer=0;iPlayer<XUSER_MAX_COUNT;iPlayer++) 2949 { 2950 if((iPlayer!=i) && pMinecraft->localplayers[iPlayer]) 2951 { 2952 if(g_NetworkManager.IsLocalGame()) 2953 { 2954 ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); 2955 } 2956 else 2957 { 2958 ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER,false); 2959 } 2960 } 2961 } 2962 } 2963 else 2964 { 2965 for(int iPlayer=0;iPlayer<XUSER_MAX_COUNT;iPlayer++) 2966 { 2967 if((iPlayer!=i) && pMinecraft->localplayers[iPlayer]) 2968 { 2969 if(g_NetworkManager.IsLocalGame()) 2970 { 2971 ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); 2972 } 2973 else 2974 { 2975 ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); 2976 } 2977 } 2978 } 2979 } 2980 2981#ifdef _DURANGO 2982 ProfileManager.RemoveGamepadFromGame(i); 2983#endif 2984 2985 SetAction(i,eAppAction_Idle); 2986 } 2987 break; 2988 case eAppAction_ExitPlayerPreLogin: 2989 { 2990 int iPlayerC=g_NetworkManager.GetPlayerCount(); 2991 // Since the player is exiting, let's flush any profile writes for them, and hope we're not breaking TCR 136... 2992#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) 2993 StorageManager.ForceQueuedProfileWrites(i); 2994#else 2995 ProfileManager.ForceQueuedProfileWrites(i); 2996#endif 2997 // if there are any tips showing, we need to close them 2998 2999 pMinecraft->gui->clearMessages(i); 3000 3001 // Make sure we've not got this player selected as current - this shouldn't be the case anyway 3002 pMinecraft->setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); 3003 pMinecraft->removeLocalPlayerIdx(i); 3004 3005#ifdef _XBOX 3006 // tell the xui scenes a splitscreen player left - has to come after removeLocalPlayerIdx which calls updatePlayerViewportAssignments 3007 XUIMessage xuiMsg; 3008 CustomMessage_Splitscreenplayer_Struct myMsgData; 3009 CustomMessage_Splitscreenplayer( &xuiMsg, &myMsgData, false); 3010 3011 // send the message 3012 for(int idx=0;idx<XUSER_MAX_COUNT;idx++) 3013 { 3014 if((i!=idx) && (pMinecraft->localplayers[idx]!=NULL)) 3015 { 3016 XuiBroadcastMessage( CXuiSceneBase::GetPlayerBaseScene(idx), &xuiMsg ); 3017 } 3018 } 3019#endif 3020 3021#ifndef _XBOX 3022 // Wipe out the tooltips 3023 ui.SetTooltips(i, -1); 3024#endif 3025 3026 // Change the presence info 3027 // Are we offline or online, and how many players are there 3028 if(iPlayerC>2) // one player is about to leave here - they'll be set to idle in the qnet manager player leave 3029 { 3030 for(int iPlayer=0;iPlayer<XUSER_MAX_COUNT;iPlayer++) 3031 { 3032 if((iPlayer!=i) && pMinecraft->localplayers[iPlayer]) 3033 { 3034 if(g_NetworkManager.IsLocalGame()) 3035 { 3036 ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); 3037 } 3038 else 3039 { 3040 ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER,false); 3041 } 3042 } 3043 } 3044 } 3045 else 3046 { 3047 for(int iPlayer=0;iPlayer<XUSER_MAX_COUNT;iPlayer++) 3048 { 3049 if((iPlayer!=i) && pMinecraft->localplayers[iPlayer]) 3050 { 3051 if(g_NetworkManager.IsLocalGame()) 3052 { 3053 ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); 3054 } 3055 else 3056 { 3057 ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); 3058 } 3059 } 3060 } 3061 } 3062 SetAction(i,eAppAction_Idle); 3063 } 3064 break; 3065 3066#ifdef __ORBIS__ 3067 case eAppAction_OptionsSaveNoSpace: 3068 { 3069 SetAction(i,eAppAction_Idle); 3070 3071 SceSaveDataDialogParam param; 3072 SceSaveDataDialogSystemMessageParam sysParam; 3073 SceSaveDataDialogItems items; 3074 SceSaveDataDirName dirName; 3075 3076 sceSaveDataDialogParamInitialize(&param); 3077 param.mode = SCE_SAVE_DATA_DIALOG_MODE_SYSTEM_MSG; 3078 param.dispType = SCE_SAVE_DATA_DIALOG_TYPE_SAVE; 3079 memset(&sysParam,0,sizeof(sysParam)); 3080 param.sysMsgParam = &sysParam; 3081 param.sysMsgParam->sysMsgType = SCE_SAVE_DATA_DIALOG_SYSMSG_TYPE_NOSPACE_CONTINUABLE; 3082 param.sysMsgParam->value = app.GetOptionsBlocksRequired(i); 3083 memset(&items, 0, sizeof(items)); 3084 param.items = &items; 3085 param.items->userId = ProfileManager.getUserID(i); 3086 3087 int ret = sceSaveDataDialogInitialize(); 3088 ret = sceSaveDataDialogOpen(&param); 3089 3090 app.SetOptionsSaveDataDialogRunning(true);//m_bOptionsSaveDataDialogRunning = true; 3091 //pClass->m_eSaveIncompleteType = saveIncompleteType; 3092 3093 //StorageManager.SetSaveDisabled(true); 3094 //pClass->EnterSaveNotificationSection(); 3095 3096 } 3097 break; 3098#endif 3099 3100 case eAppAction_ExitWorld: 3101 3102 SetAction(i,eAppAction_Idle); 3103 3104 // If we're already leaving don't exit 3105 if (g_NetworkManager.IsLeavingGame()) 3106 { 3107 break; 3108 } 3109 3110 pMinecraft->gui->clearMessages(); 3111 3112 // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen 3113 ui.HideAllGameUIElements(); 3114 3115 // reset the flag stopping new dlc message being shown if you've seen the message before 3116 DisplayNewDLCTipAgain(); 3117 3118 // clear the autosave timer that might be on screen 3119 ui.ShowAutosaveCountdownTimer(false); 3120 3121 // Hide the selected item text 3122 ui.HideAllGameUIElements(); 3123 3124 // Since the player forced the exit, let's flush any profile writes, and hope we're not breaking TCR 136... 3125#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) 3126 StorageManager.ForceQueuedProfileWrites(); 3127 LeaderboardManager::Instance()->OpenSession(); 3128 for (int j = 0; j < XUSER_MAX_COUNT; j++) 3129 { 3130 if( ProfileManager.IsSignedIn(j) ) 3131 { 3132 app.DebugPrintf("Stats save for an offline game for the player at index %d\n", 0); 3133 Minecraft::GetInstance()->forceStatsSave(j); 3134 } 3135 } 3136 LeaderboardManager::Instance()->CloseSession(); 3137#elif (defined _XBOX) 3138 ProfileManager.ForceQueuedProfileWrites(); 3139#endif 3140 3141 // 4J-PB - cancel any possible string verifications queued with LIVE 3142 //InputManager.CancelAllVerifyInProgress(); 3143 3144 if(ProfileManager.IsFullVersion()) 3145 { 3146 3147 // In a split screen, only the primary player actually quits the game, others just remove their players 3148 if( i != ProfileManager.GetPrimaryPad() ) 3149 { 3150 // Make sure we've not got this player selected as current - this shouldn't be the case anyway 3151 pMinecraft->setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); 3152 pMinecraft->removeLocalPlayerIdx(i); 3153 3154#ifdef _DURANGO 3155 ProfileManager.RemoveGamepadFromGame(i); 3156#endif 3157 SetAction(i,eAppAction_Idle); 3158 return; 3159 } 3160 // flag to capture the save thumbnail 3161 SetAction(i,eAppAction_ExitWorldCapturedThumbnail, param); 3162 } 3163 else 3164 { 3165 // ask the player if they would like to upgrade, or they'll lose the level 3166 UINT uiIDA[2]; 3167 uiIDA[0]=IDS_CONFIRM_OK; 3168 uiIDA[1]=IDS_CONFIRM_CANCEL; 3169 ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_TOSAVE_TEXT, uiIDA, 2, i,&CMinecraftApp::UnlockFullExitReturned,this); 3170 } 3171 3172 // Change the presence info 3173 // Are we offline or online, and how many players are there 3174 3175 if(g_NetworkManager.GetPlayerCount()>1) 3176 { 3177 for(int j=0;j<XUSER_MAX_COUNT;j++) 3178 { 3179 if(pMinecraft->localplayers[j]) 3180 { 3181 if(g_NetworkManager.IsLocalGame()) 3182 { 3183 app.SetRichPresenceContext(j,CONTEXT_GAME_STATE_BLANK); 3184 ProfileManager.SetCurrentGameActivity(j,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); 3185 } 3186 else 3187 { 3188 app.SetRichPresenceContext(j,CONTEXT_GAME_STATE_BLANK); 3189 ProfileManager.SetCurrentGameActivity(j,CONTEXT_PRESENCE_MULTIPLAYER,false); 3190 } 3191 TelemetryManager->RecordLevelExit(j, eSen_LevelExitStatus_Exited); 3192 } 3193 } 3194 } 3195 else 3196 { 3197 app.SetRichPresenceContext(i,CONTEXT_GAME_STATE_BLANK); 3198 if(g_NetworkManager.IsLocalGame()) 3199 { 3200 ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); 3201 } 3202 else 3203 { 3204 ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); 3205 } 3206 TelemetryManager->RecordLevelExit(i, eSen_LevelExitStatus_Exited); 3207 } 3208 break; 3209 case eAppAction_ExitWorldCapturedThumbnail: 3210 { 3211 SetAction(i,eAppAction_Idle); 3212 // Stop app running 3213 SetGameStarted(false); 3214 SetChangingSessionType(true); // Added to stop handling ethernet disconnects 3215 3216 ui.CloseAllPlayersScenes(); 3217 3218 // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen 3219 ui.HideAllGameUIElements(); 3220 3221 // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save 3222 for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) 3223 { 3224#ifdef _XBOX 3225 app.TutorialSceneNavigateBack(idx,true); 3226#endif 3227 3228 // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial 3229 // It doesn't matter if they were in the tutorial already 3230 pMinecraft->playerLeftTutorial( idx ); 3231 } 3232 3233 LoadingInputParams *loadingParams = new LoadingInputParams(); 3234 loadingParams->func = &UIScene_PauseMenu::ExitWorldThreadProc; 3235 loadingParams->lpParam = param; 3236 3237 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); 3238 // If param is non-null then this is a forced exit by the server, so make sure the player knows why 3239 // 4J Stu - Changed - Don't use the FullScreenProgressScreen for action, use a dialog instead 3240 completionData->bRequiresUserAction = FALSE;//(param != NULL) ? TRUE : FALSE; 3241 completionData->bShowTips = (param != NULL) ? FALSE : TRUE; 3242 completionData->bShowBackground=TRUE; 3243 completionData->bShowLogo=TRUE; 3244 completionData->type = e_ProgressCompletion_NavigateToHomeMenu; 3245 completionData->iPad = DEFAULT_XUI_MENU_USER; 3246 loadingParams->completionData = completionData; 3247 3248 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); 3249 } 3250 break; 3251 case eAppAction_ExitWorldTrial: 3252 { 3253 SetAction(i,eAppAction_Idle); 3254 3255 pMinecraft->gui->clearMessages(); 3256 3257 // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen 3258 ui.HideAllGameUIElements(); 3259 3260 // Stop app running 3261 SetGameStarted(false); 3262 3263 ui.CloseAllPlayersScenes(); 3264 3265 // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save 3266 for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) 3267 { 3268#ifdef _XBOX 3269 app.TutorialSceneNavigateBack(idx,true); 3270#endif 3271 3272 // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial 3273 // It doesn't matter if they were in the tutorial already 3274 pMinecraft->playerLeftTutorial( idx ); 3275 } 3276 3277 LoadingInputParams *loadingParams = new LoadingInputParams(); 3278 loadingParams->func = &UIScene_PauseMenu::ExitWorldThreadProc; 3279 loadingParams->lpParam = param; 3280 3281 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); 3282 completionData->bShowBackground=TRUE; 3283 completionData->bShowLogo=TRUE; 3284 completionData->type = e_ProgressCompletion_NavigateToHomeMenu; 3285 completionData->iPad = DEFAULT_XUI_MENU_USER; 3286 loadingParams->completionData = completionData; 3287 3288 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); 3289 } 3290 3291 break; 3292 case eAppAction_ExitTrial: 3293 //XLaunchNewImage(XLAUNCH_KEYWORD_DASH_ARCADE, 0); 3294 ExitGame(); 3295 break; 3296 3297 case eAppAction_Respawn: 3298 { 3299 ConnectionProgressParams *param = new ConnectionProgressParams(); 3300 param->iPad = i; 3301 param->stringId = IDS_PROGRESS_RESPAWNING; 3302 param->showTooltips = false; 3303 param->setFailTimer = false; 3304 ui.NavigateToScene(i,eUIScene_ConnectingProgress, param); 3305 3306 // Need to reset this incase the player has already died and respawned 3307 pMinecraft->localplayers[i]->SetPlayerRespawned(false); 3308 3309 SetAction(i,eAppAction_WaitForRespawnComplete); 3310 if( app.GetLocalPlayerCount()>1 ) 3311 { 3312 // In split screen mode, we don't want to do any async loading or flushing of the cache, just a simple respawn 3313 pMinecraft->localplayers[i]->respawn(); 3314 3315 // If the respawn requires a dimension change then the action will have changed 3316 //if(app.GetXuiAction(i) == eAppAction_Respawn) 3317 //{ 3318 // SetAction(i,eAppAction_Idle); 3319 // CloseXuiScenes(i); 3320 //} 3321 } 3322 else 3323 { 3324 //SetAction(i,eAppAction_WaitForRespawnComplete); 3325 3326 //LoadingInputParams *loadingParams = new LoadingInputParams(); 3327 //loadingParams->func = &CScene_Death::RespawnThreadProc; 3328 //loadingParams->lpParam = (LPVOID)i; 3329 3330 // Disable game & update thread whilst we do any of this 3331 //app.SetGameStarted(false); 3332 pMinecraft->gameRenderer->DisableUpdateThread(); 3333 3334 // 4J Stu - We don't need this on a thread in multiplayer as respawning is asynchronous. 3335 pMinecraft->localplayers[i]->respawn(); 3336 3337 //app.SetGameStarted(true); 3338 pMinecraft->gameRenderer->EnableUpdateThread(); 3339 3340 //UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); 3341 //completionData->bShowBackground=TRUE; 3342 //completionData->bShowLogo=TRUE; 3343 //completionData->type = e_ProgressCompletion_CloseUIScenes; 3344 //completionData->iPad = i; 3345 //loadingParams->completionData = completionData; 3346 3347 //app.NavigateToScene(i,eUIScene_FullscreenProgress, loadingParams, true); 3348 } 3349 } 3350 break; 3351 case eAppAction_WaitForRespawnComplete: 3352 player = pMinecraft->localplayers[i]; 3353 if(player != NULL && player->GetPlayerRespawned()) 3354 { 3355 SetAction(i,eAppAction_Idle); 3356 3357 if(ui.IsSceneInStack(i, eUIScene_EndPoem)) 3358 { 3359 ui.NavigateBack(i,false,eUIScene_EndPoem); 3360 } 3361 else 3362 { 3363 ui.CloseUIScenes(i); 3364 } 3365 3366 // clear the progress messages 3367 3368 // pMinecraft->progressRenderer->progressStart(-1); 3369 // pMinecraft->progressRenderer->progressStage(-1); 3370 } 3371 else if(!g_NetworkManager.IsInGameplay()) 3372 { 3373 SetAction(i,eAppAction_Idle); 3374 } 3375 break; 3376 case eAppAction_WaitForDimensionChangeComplete: 3377 player = pMinecraft->localplayers[i]; 3378 if(player != NULL && player->connection && player->connection->isStarted()) 3379 { 3380 SetAction(i,eAppAction_Idle); 3381 ui.CloseUIScenes(i); 3382 } 3383 else if(!g_NetworkManager.IsInGameplay()) 3384 { 3385 SetAction(i,eAppAction_Idle); 3386 } 3387 break; 3388 case eAppAction_PrimaryPlayerSignedOut: 3389 { 3390 //SetAction(i,eAppAction_Idle); 3391 3392 // clear the autosavetimer that might be displayed 3393 ui.ShowAutosaveCountdownTimer(false); 3394 3395 // If the player signs out before the game started the server can be killed a bit earlier to stop 3396 // the loading or saving of a new game continuing running while the UI/Guide is up 3397 if(!app.GetGameStarted()) MinecraftServer::HaltServer(true); 3398 3399 // inform the player they are being returned to the menus because they signed out 3400 StorageManager.SetSaveDeviceSelected(i,false); 3401 // need to clear the player stats - can't assume it'll be done in setlevel - we may not be in the game 3402 StatsCounter* pStats = Minecraft::GetInstance()->stats[ i ]; 3403 pStats->clear(); 3404 3405 // 4J-PB - the libs will display the Returned to Title screen 3406 // UINT uiIDA[1]; 3407 // uiIDA[0]=IDS_CONFIRM_OK; 3408 // 3409 // ui.RequestMessageBox(IDS_RETURNEDTOMENU_TITLE, IDS_RETURNEDTOTITLESCREEN_TEXT, uiIDA, 1, i,&CMinecraftApp::PrimaryPlayerSignedOutReturned,this,app.GetStringTable()); 3410 if( g_NetworkManager.IsInSession() ) 3411 { 3412 app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned); 3413 } 3414 else 3415 { 3416 app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned_Menus); 3417 MinecraftServer::resetFlags(); 3418 } 3419 } 3420 break; 3421 case eAppAction_EthernetDisconnected: 3422 { 3423 app.DebugPrintf("Handling eAppAction_EthernetDisconnected\n"); 3424 SetAction(i,eAppAction_Idle); 3425 3426 // 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. 3427 if(!g_NetworkManager.IsLeavingGame()) 3428 { 3429 app.DebugPrintf("Handling eAppAction_EthernetDisconnected - Not leaving game\n"); 3430 // 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. 3431 if( g_NetworkManager.IsHost() ) 3432 { 3433 app.DebugPrintf("Handling eAppAction_EthernetDisconnected - Is Host\n"); 3434 // If it's already a local game, then an ethernet disconnect should have no effect 3435 if( !g_NetworkManager.IsLocalGame() && g_NetworkManager.IsInGameplay() ) 3436 { 3437 // Change the session to an offline session 3438 SetAction(i,eAppAction_ChangeSessionType); 3439 } 3440 else if(!g_NetworkManager.IsLocalGame() && !g_NetworkManager.IsInGameplay() ) 3441 { 3442 // There are two cases here, either: 3443 // 1. We're early enough in the create/load game that we can do a really minimal shutdown or 3444 // 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 3445 3446 // If there's a non-null level then, for our purposes, the game has started 3447 bool gameStarted = false; 3448 for(int j = 0; j < pMinecraft->levels.length; j++) 3449 { 3450 if (pMinecraft->levels.data[i] != nullptr) 3451 { 3452 gameStarted = true; 3453 break; 3454 } 3455 } 3456 3457 if (!gameStarted) 3458 { 3459 // 1. Exit 3460 MinecraftServer::HaltServer(); 3461 3462 // 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. 3463 // 4J Stu - Leave the session 3464 g_NetworkManager.LeaveGame(FALSE); 3465 3466 // need to clear the player stats - can't assume it'll be done in setlevel - we may not be in the game 3467 StatsCounter* pStats = Minecraft::GetInstance()->stats[ i ]; 3468 pStats->clear(); 3469 UINT uiIDA[1]; 3470 uiIDA[0]=IDS_CONFIRM_OK; 3471 3472 ui.RequestErrorMessage(g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST), g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST_LIVE), uiIDA, 1, i,&CMinecraftApp::EthernetDisconnectReturned,this); 3473 } 3474 else 3475 { 3476 // 2. Switch to offline 3477 SetAction(i,eAppAction_ChangeSessionType); 3478 } 3479 } 3480 } 3481 else 3482 { 3483#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ 3484 if(UIScene_LoadOrJoinMenu::isSaveTransferRunning()) 3485 { 3486 // the save transfer is still in progress, delay jumping back to the main menu until we've cleaned up 3487 SetAction(i,eAppAction_EthernetDisconnected); 3488 } 3489 else 3490#endif 3491 { 3492 app.DebugPrintf("Handling eAppAction_EthernetDisconnected - Not host\n"); 3493 // need to clear the player stats - can't assume it'll be done in setlevel - we may not be in the game 3494 StatsCounter* pStats = Minecraft::GetInstance()->stats[ i ]; 3495 pStats->clear(); 3496 UINT uiIDA[1]; 3497 uiIDA[0]=IDS_CONFIRM_OK; 3498 3499 ui.RequestErrorMessage(g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST), g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST_LIVE), uiIDA, 1, i,&CMinecraftApp::EthernetDisconnectReturned,this); 3500 3501 } 3502 } 3503 } 3504 } 3505 break; 3506 // We currently handle both these returns the same way. 3507 case eAppAction_EthernetDisconnectedReturned: 3508 case eAppAction_PrimaryPlayerSignedOutReturned: 3509 { 3510 SetAction(i,eAppAction_Idle); 3511 3512 pMinecraft->gui->clearMessages(); 3513 3514 // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen 3515 ui.HideAllGameUIElements(); 3516 3517 // set the state back to pre-game 3518 ProfileManager.ResetProfileProcessState(); 3519 3520 3521 if( g_NetworkManager.IsLeavingGame() ) 3522 { 3523 // 4J Stu - If we are already leaving the game, then we just need to signal that the player signed out to stop saves 3524 pMinecraft->progressRenderer->progressStartNoAbort( IDS_EXITING_GAME ); 3525 pMinecraft->progressRenderer->progressStage(-1); 3526 // This has no effect on client machines 3527 MinecraftServer::HaltServer(true); 3528 } 3529 else 3530 { 3531 // Stop app running 3532 SetGameStarted(false); 3533 3534 // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen 3535 ui.HideAllGameUIElements(); 3536 3537 ui.CloseAllPlayersScenes(); 3538 3539 // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save 3540 for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) 3541 { 3542#ifdef _XBOX 3543 app.TutorialSceneNavigateBack(idx,true); 3544#endif 3545 3546 // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial 3547 // It doesn't matter if they were in the tutorial already 3548 pMinecraft->playerLeftTutorial( idx ); 3549 } 3550 3551 LoadingInputParams *loadingParams = new LoadingInputParams(); 3552 loadingParams->func = &CMinecraftApp::SignoutExitWorldThreadProc; 3553 3554 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); 3555 completionData->bShowBackground=TRUE; 3556 completionData->bShowLogo=TRUE; 3557 completionData->iPad=DEFAULT_XUI_MENU_USER; 3558 completionData->type = e_ProgressCompletion_NavigateToHomeMenu; 3559 loadingParams->completionData = completionData; 3560 3561 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); 3562 } 3563 } 3564 break; 3565 case eAppAction_PrimaryPlayerSignedOutReturned_Menus: 3566 SetAction(i,eAppAction_Idle); 3567 // set the state back to pre-game 3568 ProfileManager.ResetProfileProcessState(); 3569 // clear the save device 3570 StorageManager.SetSaveDeviceSelected(i,false); 3571 3572 ui.UpdatePlayerBasePositions(); 3573 // there are multiple layers in the help menu, so a navigate back isn't enough 3574 ui.NavigateToHomeMenu(); 3575 3576 break; 3577 case eAppAction_EthernetDisconnectedReturned_Menus: 3578 SetAction(i,eAppAction_Idle); 3579 // set the state back to pre-game 3580 ProfileManager.ResetProfileProcessState(); 3581 3582 ui.UpdatePlayerBasePositions(); 3583 3584 // there are multiple layers in the help menu, so a navigate back isn't enough 3585 ui.NavigateToHomeMenu(); 3586 3587 break; 3588 3589 case eAppAction_TrialOver: 3590 { 3591 SetAction(i,eAppAction_Idle); 3592 UINT uiIDA[2]; 3593 uiIDA[0]=IDS_UNLOCK_TITLE; 3594 uiIDA[1]=IDS_EXIT_GAME; 3595 3596 ui.RequestErrorMessage(IDS_TRIALOVER_TITLE, IDS_TRIALOVER_TEXT, uiIDA, 2, i,&CMinecraftApp::TrialOverReturned,this); 3597 } 3598 break; 3599 3600 // INVITES 3601 case eAppAction_DashboardTrialJoinFromInvite: 3602 { 3603 TelemetryManager->RecordUpsellPresented(i, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID); 3604 3605 SetAction(i,eAppAction_Idle); 3606 UINT uiIDA[2]; 3607 uiIDA[0]=IDS_CONFIRM_OK; 3608 uiIDA[1]=IDS_CONFIRM_CANCEL; 3609 3610 ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_ACCEPT_INVITE, uiIDA, 2, i,&CMinecraftApp::UnlockFullInviteReturned,this); 3611 } 3612 break; 3613 case eAppAction_ExitAndJoinFromInvite: 3614 { 3615 UINT uiIDA[3]; 3616 3617 SetAction(i,eAppAction_Idle); 3618 // Check the player really wants to do this 3619 3620#if defined(_XBOX_ONE) || defined(__ORBIS__) 3621 // Show save option is saves ARE disabled 3622 if(ProfileManager.IsFullVersion() && StorageManager.GetSaveDisabled() && i==ProfileManager.GetPrimaryPad() && g_NetworkManager.IsHost() && GetGameStarted() ) 3623 { 3624 uiIDA[0]=IDS_CONFIRM_CANCEL; 3625 uiIDA[1]=IDS_EXIT_GAME_SAVE; 3626 uiIDA[2]=IDS_EXIT_GAME_NO_SAVE; 3627 3628 ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_LEAVE_VIA_INVITE, uiIDA, 3, i,&CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned,this); 3629 } 3630 else 3631#else 3632 if(ProfileManager.IsFullVersion() && !StorageManager.GetSaveDisabled() && i==ProfileManager.GetPrimaryPad() && g_NetworkManager.IsHost() && GetGameStarted() ) 3633 { 3634 uiIDA[0]=IDS_CONFIRM_CANCEL; 3635 uiIDA[1]=IDS_EXIT_GAME_SAVE; 3636 uiIDA[2]=IDS_EXIT_GAME_NO_SAVE; 3637 3638 ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_LEAVE_VIA_INVITE, uiIDA, 3, i,&CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned,this); 3639 } 3640 else 3641#endif 3642 { 3643 if(!ProfileManager.IsFullVersion()) 3644 { 3645 TelemetryManager->RecordUpsellPresented(i, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID); 3646 3647 // upsell 3648 uiIDA[0]=IDS_CONFIRM_OK; 3649 uiIDA[1]=IDS_CONFIRM_CANCEL; 3650 ui.RequestErrorMessage(IDS_UNLOCK_TITLE, IDS_UNLOCK_ACCEPT_INVITE, uiIDA, 2, i,&CMinecraftApp::UnlockFullInviteReturned,this); 3651 } 3652 else 3653 { 3654 uiIDA[0]=IDS_CONFIRM_CANCEL; 3655 uiIDA[1]=IDS_CONFIRM_OK; 3656 ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_LEAVE_VIA_INVITE, uiIDA, 2,i,&CMinecraftApp::ExitAndJoinFromInvite,this); 3657 } 3658 } 3659 } 3660 break; 3661 case eAppAction_ExitAndJoinFromInviteConfirmed: 3662 { 3663 SetAction(i,eAppAction_Idle); 3664 3665 pMinecraft->gui->clearMessages(); 3666 3667 // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen 3668 ui.HideAllGameUIElements(); 3669 3670 // Stop app running 3671 SetGameStarted(false); 3672 3673 ui.CloseAllPlayersScenes(); 3674 3675 // 4J Stu - Fix for #12368 - Crash: Game crashes when saving then exiting and selecting to save 3676 for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) 3677 { 3678#ifdef _XBOX 3679 app.TutorialSceneNavigateBack(idx,true); 3680#endif 3681 3682 // 4J Stu - Fix for #13257 - CRASH: Gameplay: Title crashed after exiting the tutorial 3683 // It doesn't matter if they were in the tutorial already 3684 pMinecraft->playerLeftTutorial( idx ); 3685 } 3686 3687 // 4J-PB - may have been using a texture pack with audio , so clean up anything texture pack related here 3688 3689 // unload any texture pack audio 3690 // if there is audio in use, clear out the audio, and unmount the pack 3691 TexturePack *pTexPack=Minecraft::GetInstance()->skins->getSelected(); 3692 DLCTexturePack *pDLCTexPack=NULL; 3693 3694 if(pTexPack->hasAudio()) 3695 { 3696 // get the dlc texture pack, and store it 3697 pDLCTexPack=(DLCTexturePack *)pTexPack; 3698 } 3699 3700 // change to the default texture pack 3701 pMinecraft->skins->selectTexturePackById(TexturePackRepository::DEFAULT_TEXTURE_PACK_ID); 3702 3703 if(pTexPack->hasAudio()) 3704 { 3705 // need to stop the streaming audio - by playing streaming audio from the default texture pack now 3706 // reset the streaming sounds back to the normal ones 3707#ifndef _XBOX 3708 pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, 3709 eStream_Nether1,eStream_Nether4, 3710 eStream_end_dragon,eStream_end_end, 3711 eStream_CD_1); 3712#endif 3713 pMinecraft->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1); 3714 3715#ifdef _XBOX 3716 if(pDLCTexPack->m_pStreamedWaveBank!=NULL) 3717 { 3718 pDLCTexPack->m_pStreamedWaveBank->Destroy(); 3719 } 3720 if(pDLCTexPack->m_pSoundBank!=NULL) 3721 { 3722 pDLCTexPack->m_pSoundBank->Destroy(); 3723 } 3724#endif 3725#ifdef _DURANGO 3726 DWORD result = StorageManager.UnmountInstalledDLC(L"TPACK"); 3727#else 3728 DWORD result = StorageManager.UnmountInstalledDLC("TPACK"); 3729#endif 3730 app.DebugPrintf("Unmount result is %d\n",result); 3731 } 3732 3733#ifdef _XBOX_ONE 3734 // 4J Stu - It's possible that we can sign in/remove players between the mask initially being set and this point 3735 m_InviteData.dwLocalUsersMask = 0; 3736 for(unsigned int index = 0; index < XUSER_MAX_COUNT; ++index) 3737 { 3738 if(ProfileManager.IsSignedIn(index) ) 3739 { 3740 if(index==i || pMinecraft->localplayers[index]!=NULL ) 3741 { 3742 m_InviteData.dwLocalUsersMask |= g_NetworkManager.GetLocalPlayerMask( index ); 3743 } 3744 } 3745 } 3746#endif 3747 3748 LoadingInputParams *loadingParams = new LoadingInputParams(); 3749 loadingParams->func = &CGameNetworkManager::ExitAndJoinFromInviteThreadProc; 3750 loadingParams->lpParam = (LPVOID)&m_InviteData; 3751 3752 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); 3753 completionData->bShowBackground=TRUE; 3754 completionData->bShowLogo=TRUE; 3755 completionData->iPad=DEFAULT_XUI_MENU_USER; 3756 completionData->type = e_ProgressCompletion_NoAction; 3757 loadingParams->completionData = completionData; 3758 3759 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); 3760 } 3761 3762 break; 3763 case eAppAction_JoinFromInvite: 3764 { 3765 SetAction(i,eAppAction_Idle); 3766 3767 // 4J Stu - Move this state block from CPlatformNetworkManager::ExitAndJoinFromInviteThreadProc, as g_NetworkManager.JoinGameFromInviteInfo ultimately can call NavigateToScene, 3768 /// and we should only be calling that from the main thread 3769 app.SetTutorialMode( false ); 3770 3771 g_NetworkManager.SetLocalGame(false); 3772 3773 JoinFromInviteData *inviteData = (JoinFromInviteData *)param; 3774 // 4J-PB - clear any previous connection errors 3775 Minecraft::GetInstance()->clearConnectionFailed(); 3776 3777 app.DebugPrintf( "Changing Primary Pad on an invite accept - pad was %d, and is now %d\n", ProfileManager.GetPrimaryPad(), inviteData->dwUserIndex ); 3778 ProfileManager.SetLockedProfile(inviteData->dwUserIndex); 3779 ProfileManager.SetPrimaryPad(inviteData->dwUserIndex); 3780 3781#ifdef _XBOX_ONE 3782 // 4J Stu - If a player is signed in (i.e. locked) but not in the mask, unlock them 3783 for(unsigned int index = 0; index < XUSER_MAX_COUNT; ++index) 3784 { 3785 if( index != inviteData->dwUserIndex && ProfileManager.IsSignedIn(index) ) 3786 { 3787 if( (m_InviteData.dwLocalUsersMask & g_NetworkManager.GetLocalPlayerMask( index ) ) == 0 ) 3788 { 3789 ProfileManager.RemoveGamepadFromGame(index); 3790 } 3791 } 3792 } 3793#endif 3794 3795 // change the minecraft player name 3796 Minecraft::GetInstance()->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); 3797 3798 bool success = g_NetworkManager.JoinGameFromInviteInfo( 3799 inviteData->dwUserIndex, // dwUserIndex 3800 inviteData->dwLocalUsersMask, // dwUserMask 3801 inviteData->pInviteInfo ); // pInviteInfo 3802 3803 if( !success ) 3804 { 3805 app.DebugPrintf( "Failed joining game from invite\n" ); 3806 //return hr; 3807 3808 // 4J Stu - Copied this from XUI_FullScreenProgress to properly handle the fail case, as the thread will no longer be failing 3809 UINT uiIDA[1]; 3810 uiIDA[0]=IDS_CONFIRM_OK; 3811 ui.RequestErrorMessage( IDS_CONNECTION_FAILED, IDS_CONNECTION_LOST_SERVER, uiIDA,1,ProfileManager.GetPrimaryPad()); 3812 3813 ui.NavigateToHomeMenu(); 3814 ui.UpdatePlayerBasePositions(); 3815 } 3816 } 3817 break; 3818 case eAppAction_ChangeSessionType: 3819 { 3820 // If we are not in gameplay yet, then wait until the server is setup before changing the session type 3821 if( g_NetworkManager.IsInGameplay() ) 3822 { 3823 // 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 3824 3825 SetAction(i,eAppAction_Idle); 3826 3827 if( !GetChangingSessionType() && !g_NetworkManager.IsLocalGame() ) 3828 { 3829 SetGameStarted(false); 3830 SetChangingSessionType(true); 3831 SetReallyChangingSessionType(true); 3832 3833 // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen 3834 ui.HideAllGameUIElements(); 3835 3836 if( !ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) 3837 { 3838 ui.CloseAllPlayersScenes(); 3839 } 3840 ui.ShowOtherPlayersBaseScene(ProfileManager.GetPrimaryPad(), true); 3841 3842 // Remove this line to fix: 3843 // #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. 3844 //app.NavigateToScene(0,eUIScene_Main); 3845 3846 LoadingInputParams *loadingParams = new LoadingInputParams(); 3847 loadingParams->func = &CGameNetworkManager::ChangeSessionTypeThreadProc; 3848 loadingParams->lpParam = NULL; 3849 3850 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); 3851#ifdef __PS3__ 3852 completionData->bRequiresUserAction=FALSE; 3853#else 3854 completionData->bRequiresUserAction=TRUE; 3855#endif 3856 completionData->bShowBackground=TRUE; 3857 completionData->bShowLogo=TRUE; 3858 completionData->iPad=DEFAULT_XUI_MENU_USER; 3859 if( ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) 3860 { 3861 completionData->type = e_ProgressCompletion_NavigateBackToScene; 3862 completionData->scene = eUIScene_EndPoem; 3863 } 3864 else 3865 { 3866 completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; 3867 } 3868 loadingParams->completionData = completionData; 3869 3870 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); 3871 } 3872 } 3873 else if( g_NetworkManager.IsLeavingGame() ) 3874 { 3875 // If we are leaving the game, then ignore the state change 3876 SetAction(i,eAppAction_Idle); 3877 } 3878#if 0 3879 // 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 3880 // this if statements original purpose (to allow us to wait for IsInGameplay before actioning switching to offline 3881 3882 // 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, 3883 // 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 3884 else 3885 { 3886 if( g_NetworkManager.IsInSession() ) 3887 { 3888 g_NetworkManager._LeaveGame(); 3889 } 3890 } 3891#endif 3892 } 3893 break; 3894 case eAppAction_SetDefaultOptions: 3895 SetAction(i,eAppAction_Idle); 3896#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__) 3897 SetDefaultOptions((C4JStorage::PROFILESETTINGS *)param,i); 3898#else 3899 SetDefaultOptions((C_4JProfile::PROFILESETTINGS *)param,i); 3900#endif 3901 3902 // if the profile data has been changed, then force a profile write 3903 // It seems we're allowed to break the 5 minute rule if it's the result of a user action 3904 CheckGameSettingsChanged(true,i); 3905 3906 break; 3907 3908 case eAppAction_RemoteServerSave: 3909 { 3910 // If the remote server save has already finished, don't complete the action 3911 if (GetGameStarted()) 3912 { 3913 SetAction(ProfileManager.GetPrimaryPad(), eAppAction_Idle); 3914 break; 3915 } 3916 3917 SetAction(i,eAppAction_WaitRemoteServerSaveComplete); 3918 3919 for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) 3920 { 3921 ui.CloseUIScenes(i, true); 3922 } 3923 3924 // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen 3925 ui.HideAllGameUIElements(); 3926 3927 LoadingInputParams *loadingParams = new LoadingInputParams(); 3928 loadingParams->func = &CMinecraftApp::RemoteSaveThreadProc; 3929 loadingParams->lpParam = NULL; 3930 3931 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); 3932 completionData->bRequiresUserAction=FALSE; 3933 completionData->bShowBackground=TRUE; 3934 completionData->bShowLogo=TRUE; 3935 completionData->iPad=DEFAULT_XUI_MENU_USER; 3936 if( ui.IsSceneInStack( ProfileManager.GetPrimaryPad(), eUIScene_EndPoem ) ) 3937 { 3938 completionData->type = e_ProgressCompletion_NavigateBackToScene; 3939 completionData->scene = eUIScene_EndPoem; 3940 } 3941 else 3942 { 3943 completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; 3944 } 3945 loadingParams->completionData = completionData; 3946 3947 loadingParams->cancelFunc = &CMinecraftApp::ExitGameFromRemoteSave; 3948 loadingParams->cancelText = IDS_TOOLTIPS_EXIT; 3949 3950 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); 3951 } 3952 break; 3953 case eAppAction_WaitRemoteServerSaveComplete: 3954 // Do nothing 3955 break; 3956 case eAppAction_FailedToJoinNoPrivileges: 3957 { 3958 UINT uiIDA[1]; 3959 uiIDA[0]=IDS_CONFIRM_OK; 3960 C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_NO_MULTIPLAYER_PRIVILEGE_TITLE, IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT, uiIDA,1,ProfileManager.GetPrimaryPad()); 3961 if(result != C4JStorage::EMessage_Busy) SetAction(i,eAppAction_Idle); 3962 } 3963 break; 3964 case eAppAction_ProfileReadError: 3965 // Return player to the main menu - code largely copied from that for handling 3966 // eAppAction_PrimaryPlayerSignedOut, although I don't think we should have got as 3967 // far as needing to halt the server, or running the game, before returning to the menu 3968 if(!app.GetGameStarted()) MinecraftServer::HaltServer(true); 3969 3970 if( g_NetworkManager.IsInSession() ) 3971 { 3972 app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned); 3973 } 3974 else 3975 { 3976 app.SetAction(i,eAppAction_PrimaryPlayerSignedOutReturned_Menus); 3977 MinecraftServer::resetFlags(); 3978 } 3979 break; 3980 3981 case eAppAction_BanLevel: 3982 { 3983 // 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 3984 if(g_NetworkManager.IsInGameplay() && !g_NetworkManager.IsLeavingGame()) 3985 { 3986 TelemetryManager->RecordBanLevel(i); 3987 3988#if defined _XBOX 3989 INetworkPlayer *pHost=g_NetworkManager.GetHostPlayer(); 3990 // write the level to the banned level list, and exit the world 3991 AddLevelToBannedLevelList(i,((NetworkPlayerXbox *)pHost)->GetUID(),GetUniqueMapName(),true); 3992#elif defined _XBOX_ONE 3993 INetworkPlayer *pHost=g_NetworkManager.GetHostPlayer(); 3994 AddLevelToBannedLevelList(i,pHost->GetUID(),GetUniqueMapName(),true); 3995#endif 3996 // primary player would exit the world, secondary would exit the player 3997 if(ProfileManager.GetPrimaryPad()==i) 3998 { 3999 SetAction(i,eAppAction_ExitWorld); 4000 } 4001 else 4002 { 4003 SetAction(i,eAppAction_ExitPlayer); 4004 } 4005 } 4006 } 4007 break; 4008 case eAppAction_LevelInBanLevelList: 4009 { 4010 UINT uiIDA[2]; 4011 uiIDA[0]=IDS_BUTTON_REMOVE_FROM_BAN_LIST; 4012 uiIDA[1]=IDS_EXIT_GAME; 4013 4014 // pass in the gamertag format string 4015 WCHAR wchFormat[40]; 4016 INetworkPlayer *player = g_NetworkManager.GetLocalPlayerByUserIndex(i); 4017 4018 // If not the primary player, but the primary player has banned this level and decided not to unban 4019 // then we may have left the game by now 4020 if(player) 4021 { 4022 swprintf(wchFormat, 40, L"%ls\n\n%%ls",player->GetOnlineName()); 4023 4024 C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_BANNED_LEVEL_TITLE, IDS_PLAYER_BANNED_LEVEL, uiIDA,2,i,&CMinecraftApp::BannedLevelDialogReturned,this, wchFormat); 4025 if(result != C4JStorage::EMessage_Busy) SetAction(i,eAppAction_Idle); 4026 } 4027 else 4028 { 4029 SetAction(i,eAppAction_Idle); 4030 } 4031 } 4032 break; 4033 case eAppAction_DebugText: 4034 // launch the xui for text entry 4035 { 4036#ifdef _XBOX 4037 CScene_TextEntry::XuiTextInputParams *pDebugTextParams= new CScene_TextEntry::XuiTextInputParams; 4038 pDebugTextParams->iPad=i; 4039 pDebugTextParams->wch=(WCHAR)param; 4040 4041 app.NavigateToScene(i,eUIScene_TextEntry,pDebugTextParams); 4042#endif 4043 SetAction(i,eAppAction_Idle); 4044 } 4045 break; 4046 4047 case eAppAction_ReloadTexturePack: 4048 { 4049 SetAction(i,eAppAction_Idle); 4050 Minecraft *pMinecraft = Minecraft::GetInstance(); 4051 pMinecraft->textures->reloadAll(); 4052 pMinecraft->skins->updateUI(); 4053 4054 if(!pMinecraft->skins->isUsingDefaultSkin()) 4055 { 4056 TexturePack *pTexturePack = pMinecraft->skins->getSelected(); 4057 4058 DLCPack *pDLCPack=pTexturePack->getDLCPack(); 4059 4060 bool purchased = false; 4061 // do we have a license? 4062 if(pDLCPack && pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) 4063 { 4064 purchased = true; 4065 } 4066#ifdef _XBOX 4067 TelemetryManager->RecordTexturePackLoaded(i, pTexturePack->getId(), purchased?1:0); 4068#endif 4069 } 4070 4071 // 4J-PB - If the texture pack has audio, we need to switch to this 4072 if(pMinecraft->skins->getSelected()->hasAudio()) 4073 { 4074 Minecraft::GetInstance()->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1); 4075 } 4076 } 4077 break; 4078 4079 case eAppAction_ReloadFont: 4080 { 4081#ifndef _XBOX 4082 app.DebugPrintf( 4083 "[Consoles_App] eAppAction_ReloadFont, ingame='%s'.\n", 4084 app.GetGameStarted() ? "Yes" : "No" ); 4085 4086 SetAction(i,eAppAction_Idle); 4087 4088 ui.SetTooltips(i, -1); 4089 4090 ui.ReloadSkin(); 4091 ui.StartReloadSkinThread(); 4092 4093 ui.setCleanupOnReload(); 4094#endif 4095 } 4096 break; 4097 4098 case eAppAction_TexturePackRequired: 4099 { 4100#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ 4101 UINT uiIDA[2]; 4102 uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION; 4103 uiIDA[1]=IDS_CONFIRM_CANCEL; // let them continue without the texture pack here (as this is only really for r 4104 // Give the player a warning about the texture pack missing 4105 ui.RequestErrorMessage(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::TexturePackDialogReturned,this); 4106 SetAction(i,eAppAction_Idle); 4107#else 4108#ifdef _XBOX 4109 ULONGLONG ullOfferID_Full; 4110 app.GetDLCFullOfferIDForPackID(app.GetRequiredTexturePackID(),&ullOfferID_Full); 4111 4112 TelemetryManager->RecordUpsellPresented(ProfileManager.GetPrimaryPad(), eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF); 4113#endif 4114 UINT uiIDA[2]; 4115 4116 uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION; 4117 uiIDA[1]=IDS_TEXTURE_PACK_TRIALVERSION; 4118 4119 // Give the player a warning about the texture pack missing 4120 ui.RequestErrorMessage(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::TexturePackDialogReturned,this); 4121 SetAction(i,eAppAction_Idle); 4122#endif 4123 } 4124 4125 break; 4126 } 4127 } 4128 4129 // Any TMS actions? 4130 4131 eTMS = app.GetTMSAction(i); 4132 4133 if(eTMS!=eTMSAction_Idle) 4134 { 4135 switch(eTMS) 4136 { 4137 // TMS++ actions 4138 case eTMSAction_TMSPP_RetrieveFiles_CreateLoad_SignInReturned: 4139 case eTMSAction_TMSPP_RetrieveFiles_RunPlayGame: 4140#ifdef _XBOX 4141 app.TMSPP_SetTitleGroupID(GROUP_ID); 4142 SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList); 4143#elif defined _XBOX_ONE 4144 SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList_Waiting); 4145 app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,eTMSAction_TMSPP_UserFileList); 4146#else 4147 SetTMSAction(i,eTMSAction_TMSPP_UserFileList); 4148#endif 4149 break; 4150 4151#ifdef _XBOX 4152 case eTMSAction_TMSPP_GlobalFileList: 4153 SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList_Waiting); 4154 app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,"\\",eTMSAction_TMSPP_UserFileList); 4155 break; 4156#endif 4157 case eTMSAction_TMSPP_UserFileList: 4158 // retrieve the file list first 4159#if defined _XBOX 4160 SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); 4161 app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,"\\",eTMSAction_TMSPP_XUIDSFile); 4162#elif defined _XBOX_ONE 4163 SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); 4164 app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,eTMSAction_TMSPP_DLCFile); 4165#else 4166 SetTMSAction(i,eTMSAction_TMSPP_XUIDSFile); 4167#endif 4168 break; 4169 case eTMSAction_TMSPP_XUIDSFile: 4170#ifdef _XBOX 4171 SetTMSAction(i,eTMSAction_TMSPP_XUIDSFile_Waiting); 4172 // pass in the next app action on the call or callback completing 4173 app.TMSPP_ReadXuidsFile(i,eTMSAction_TMSPP_DLCFile); 4174#else 4175 SetTMSAction(i,eTMSAction_TMSPP_DLCFile); 4176#endif 4177 4178 break; 4179 case eTMSAction_TMSPP_DLCFile: 4180#if defined _XBOX || defined _XBOX_ONE 4181 SetTMSAction(i,eTMSAction_TMSPP_DLCFile_Waiting); 4182 // pass in the next app action on the call or callback completing 4183 app.TMSPP_ReadDLCFile(i,eTMSAction_TMSPP_BannedListFile); 4184#else 4185 SetTMSAction(i,eTMSAction_TMSPP_BannedListFile); 4186#endif 4187 break; 4188 case eTMSAction_TMSPP_BannedListFile: 4189 // If we have one in TMSPP, then we can assume we can ignore TMS 4190#if defined _XBOX 4191 SetTMSAction(i,eTMSAction_TMSPP_BannedListFile_Waiting); 4192 // pass in the next app action on the call or callback completing 4193 if(app.TMSPP_ReadBannedList(i,eTMSAction_TMS_RetrieveFiles_Complete)==false) 4194 { 4195 // we don't have a banned list in TMSPP, so we should check TMS 4196 app.ReadBannedList(i, eTMSAction_TMS_RetrieveFiles_Complete,true); 4197 } 4198#elif defined _XBOX_ONE 4199 SetTMSAction(i,eTMSAction_TMSPP_BannedListFile_Waiting); 4200 // pass in the next app action on the call or callback completing 4201 app.TMSPP_ReadBannedList(i,eTMSAction_TMS_RetrieveFiles_Complete); 4202 4203#else 4204 SetTMSAction(i,eTMSAction_TMS_RetrieveFiles_Complete); 4205#endif 4206 break; 4207 4208 // SPECIAL CASE - where the user goes directly in to Help & Options from the main menu 4209 case eTMSAction_TMSPP_RetrieveFiles_HelpAndOptions: 4210 case eTMSAction_TMSPP_RetrieveFiles_DLCMain: 4211 // retrieve the file list first 4212#if defined _XBOX 4213 // pass in the next app action on the call or callback completing 4214 SetTMSAction(i,eTMSAction_TMSPP_XUIDSFile_Waiting); 4215 app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,"\\",eTMSAction_TMSPP_DLCFileOnly); 4216#elif defined _XBOX_ONE 4217 SetTMSAction(i,eTMSAction_TMSPP_GlobalFileList_Waiting); 4218 app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_Title,eTMSAction_TMSPP_RetrieveUserFilelist_DLCFileOnly); 4219#else 4220 SetTMSAction(i,eTMSAction_TMSPP_DLCFileOnly); 4221#endif 4222 break; 4223 case eTMSAction_TMSPP_RetrieveUserFilelist_DLCFileOnly: 4224#if defined _XBOX 4225 SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); 4226 app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,"\\",eTMSAction_TMSPP_XUIDSFile); 4227#elif defined _XBOX_ONE 4228 //StorageManager.TMSPP_DeleteFile(i,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"TP06.png",NULL,NULL, 0); 4229 SetTMSAction(i,eTMSAction_TMSPP_UserFileList_Waiting); 4230 app.TMSPP_RetrieveFileList(i,C4JStorage::eGlobalStorage_TitleUser,eTMSAction_TMSPP_DLCFileOnly); 4231#else 4232 SetTMSAction(i,eTMSAction_TMSPP_DLCFileOnly); 4233#endif 4234 4235 break; 4236 4237 case eTMSAction_TMSPP_DLCFileOnly: 4238#if defined _XBOX || defined _XBOX_ONE 4239 SetTMSAction(i,eTMSAction_TMSPP_DLCFile_Waiting); 4240 // pass in the next app action on the call or callback completing 4241 app.TMSPP_ReadDLCFile(i,eTMSAction_TMSPP_RetrieveFiles_Complete); 4242#else 4243 SetTMSAction(i,eTMSAction_TMSPP_RetrieveFiles_Complete); 4244#endif 4245 break; 4246 4247 4248 case eTMSAction_TMSPP_RetrieveFiles_Complete: 4249 SetTMSAction(i,eTMSAction_Idle); 4250 break; 4251 4252 4253 // TMS files 4254 /* case eTMSAction_TMS_RetrieveFiles_CreateLoad_SignInReturned: 4255 case eTMSAction_TMS_RetrieveFiles_RunPlayGame: 4256 #ifdef _XBOX 4257 SetTMSAction(i,eTMSAction_TMS_XUIDSFile_Waiting); 4258 // pass in the next app action on the call or callback completing 4259 app.ReadXuidsFileFromTMS(i,eTMSAction_TMS_DLCFile,true); 4260 #else 4261 SetTMSAction(i,eTMSAction_TMS_DLCFile); 4262 #endif 4263 break; 4264 4265 case eTMSAction_TMS_DLCFile: 4266 #ifdef _XBOX 4267 SetTMSAction(i,eTMSAction_TMS_DLCFile_Waiting); 4268 // pass in the next app action on the call or callback completing 4269 app.ReadDLCFileFromTMS(i,eTMSAction_TMS_BannedListFile,true); 4270 #else 4271 SetTMSAction(i,eTMSAction_TMS_BannedListFile); 4272 #endif 4273 4274 break; 4275 4276 case eTMSAction_TMS_RetrieveFiles_HelpAndOptions: 4277 case eTMSAction_TMS_RetrieveFiles_DLCMain: 4278 #ifdef _XBOX 4279 SetTMSAction(i,eTMSAction_TMS_DLCFile_Waiting); 4280 // pass in the next app action on the call or callback completing 4281 app.ReadDLCFileFromTMS(i,eTMSAction_Idle,true); 4282 #else 4283 SetTMSAction(i,eTMSAction_Idle); 4284 #endif 4285 4286 break; 4287 case eTMSAction_TMS_BannedListFile: 4288 #ifdef _XBOX 4289 SetTMSAction(i,eTMSAction_TMS_BannedListFile_Waiting); 4290 // pass in the next app action on the call or callback completing 4291 app.ReadBannedList(i, eTMSAction_TMS_RetrieveFiles_Complete,true); 4292 #else 4293 SetTMSAction(i,eTMSAction_TMS_RetrieveFiles_Complete); 4294 #endif 4295 4296 break; 4297 4298 */ 4299 case eTMSAction_TMS_RetrieveFiles_Complete: 4300 SetTMSAction(i,eTMSAction_Idle); 4301 // if(StorageManager.SetSaveDevice(&CScene_Main::DeviceSelectReturned,pClass)) 4302 // { 4303 // // save device already selected 4304 // // ensure we've applied this player's settings 4305 // app.ApplyGameSettingsChanged(ProfileManager.GetPrimaryPad()); 4306 // app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_MultiGameJoinLoad); 4307 // } 4308 break; 4309 } 4310 } 4311 4312 } 4313} 4314 4315int CMinecraftApp::BannedLevelDialogReturned(void *pParam,int iPad,const C4JStorage::EMessageResult result) 4316{ 4317 CMinecraftApp* pApp = (CMinecraftApp*)pParam; 4318 //Minecraft *pMinecraft=Minecraft::GetInstance(); 4319 4320 if(result==C4JStorage::EMessage_ResultAccept) 4321 { 4322#if defined _XBOX || defined _XBOX_ONE 4323 INetworkPlayer *pHost = g_NetworkManager.GetHostPlayer(); 4324 // unban the level 4325 if (pHost != NULL) 4326 { 4327#if defined _XBOX 4328 pApp->RemoveLevelFromBannedLevelList(iPad,((NetworkPlayerXbox *)pHost)->GetUID(),pApp->GetUniqueMapName()); 4329#else 4330 pApp->RemoveLevelFromBannedLevelList(iPad,pHost->GetUID(),pApp->GetUniqueMapName()); 4331#endif 4332 } 4333#endif 4334 } 4335 else 4336 { 4337 if( iPad == ProfileManager.GetPrimaryPad() ) 4338 { 4339 pApp->SetAction(iPad,eAppAction_ExitWorld); 4340 } 4341 else 4342 { 4343 pApp->SetAction(iPad,eAppAction_ExitPlayer); 4344 } 4345 } 4346 4347 return 0; 4348} 4349 4350void CMinecraftApp::loadMediaArchive() 4351{ 4352 wstring mediapath = L""; 4353 4354#ifdef __PS3__ 4355 mediapath = L"Common\\Media\\MediaPS3.arc"; 4356#elif _WINDOWS64 4357 mediapath = L"Common\\Media\\MediaWindows64.arc"; 4358#elif __ORBIS__ 4359 mediapath = L"Common\\Media\\MediaOrbis.arc"; 4360#elif _DURANGO 4361 mediapath = L"Common\\Media\\MediaDurango.arc"; 4362#elif __PSVITA__ 4363 mediapath = L"Common\\Media\\MediaPSVita.arc"; 4364#endif 4365 4366 if (!mediapath.empty()) 4367 { 4368 m_mediaArchive = new ArchiveFile( File(mediapath) ); 4369 } 4370#if 0 4371 string path = "Common\\media.arc"; 4372 HANDLE hFile = CreateFile( path.c_str(), 4373 GENERIC_READ, 4374 FILE_SHARE_READ, 4375 NULL, 4376 OPEN_EXISTING, 4377 FILE_FLAG_SEQUENTIAL_SCAN, 4378 NULL ); 4379 4380 if( hFile != INVALID_HANDLE_VALUE ) 4381 { 4382 File fileHelper(convStringToWstring(path)); 4383 DWORD dwFileSize = fileHelper.length(); 4384 4385 // Initialize memory. 4386 PBYTE m_fBody = new BYTE[ dwFileSize ]; 4387 ZeroMemory(m_fBody, dwFileSize); 4388 4389 DWORD m_fSize = 0; 4390 BOOL hr = ReadFile( hFile, 4391 m_fBody, 4392 dwFileSize, 4393 &m_fSize, 4394 NULL ); 4395 4396 assert( m_fSize == dwFileSize ); 4397 4398 CloseHandle( hFile ); 4399 4400 m_mediaArchive = new ArchiveFile(m_fBody, m_fSize); 4401 } 4402 else 4403 { 4404 assert( false ); 4405 // AHHHHHHHHHHHH 4406 m_mediaArchive = NULL; 4407 } 4408#endif 4409} 4410 4411void CMinecraftApp::loadStringTable() 4412{ 4413#ifndef _XBOX 4414 4415 if(m_stringTable!=NULL) 4416 { 4417 // we need to unload the current string table, this is a reload 4418 delete m_stringTable; 4419 } 4420 wstring localisationFile = L"languages.loc"; 4421 if (m_mediaArchive->hasFile(localisationFile)) 4422 { 4423 byteArray locFile = m_mediaArchive->getFile(localisationFile); 4424 m_stringTable = new StringTable(locFile.data, locFile.length); 4425 delete locFile.data; 4426 } 4427 else 4428 { 4429 m_stringTable = NULL; 4430 assert(false); 4431 // AHHHHHHHHH. 4432 } 4433#endif 4434} 4435 4436int CMinecraftApp::PrimaryPlayerSignedOutReturned(void *pParam,int iPad,const C4JStorage::EMessageResult) 4437{ 4438 //CMinecraftApp* pApp = (CMinecraftApp*)pParam; 4439 //Minecraft *pMinecraft=Minecraft::GetInstance(); 4440 4441 // if the player is null, we're in the menus 4442 //if(Minecraft::GetInstance()->player!=NULL) 4443 4444 // We always create a session before kicking of any of the game code, so even though we may still be joining/creating a game 4445 // at this point we want to handle it differently from just being in a menu 4446 if( g_NetworkManager.IsInSession() ) 4447 { 4448 app.SetAction(iPad,eAppAction_PrimaryPlayerSignedOutReturned); 4449 } 4450 else 4451 { 4452 app.SetAction(iPad,eAppAction_PrimaryPlayerSignedOutReturned_Menus); 4453 } 4454 return 0; 4455} 4456 4457int CMinecraftApp::EthernetDisconnectReturned(void *pParam,int iPad,const C4JStorage::EMessageResult) 4458{ 4459 //CMinecraftApp* pApp = (CMinecraftApp*)pParam; 4460 Minecraft *pMinecraft=Minecraft::GetInstance(); 4461 4462 // if the player is null, we're in the menus 4463 if(Minecraft::GetInstance()->player!=NULL) 4464 { 4465 app.SetAction(pMinecraft->player->GetXboxPad(),eAppAction_EthernetDisconnectedReturned); 4466 } 4467 else 4468 { 4469 // 4J-PB - turn off the PSN store icon just in case this happened when we were in one of the DLC menus 4470#if defined __ORBIS__ || defined __PSVITA__ 4471 app.GetCommerce()->HidePsStoreIcon(); 4472#endif 4473 app.SetAction(iPad,eAppAction_EthernetDisconnectedReturned_Menus); 4474 } 4475 return 0; 4476} 4477 4478int CMinecraftApp::SignoutExitWorldThreadProc( void* lpParameter ) 4479{ 4480 4481 // 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 4482 AABB::UseDefaultThreadStorage(); 4483 Vec3::UseDefaultThreadStorage(); 4484 Compression::UseDefaultThreadStorage(); 4485 4486 //app.SetGameStarted(false); 4487 4488 Minecraft *pMinecraft=Minecraft::GetInstance(); 4489 4490 int exitReasonStringId = -1; 4491 4492 bool saveStats = false; 4493 if (pMinecraft->isClientSide() || g_NetworkManager.IsInSession() ) 4494 { 4495 if(lpParameter != NULL ) 4496 { 4497 switch( app.GetDisconnectReason() ) 4498 { 4499 case DisconnectPacket::eDisconnect_Kicked: 4500 exitReasonStringId = IDS_DISCONNECTED_KICKED; 4501 break; 4502 case DisconnectPacket::eDisconnect_NoUGC_AllLocal: 4503 exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL; 4504 break; 4505 case DisconnectPacket::eDisconnect_NoUGC_Single_Local: 4506 exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL; 4507 break; 4508#ifdef _XBOX 4509 case DisconnectPacket::eDisconnect_NoUGC_Remote: 4510 exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE; 4511 break; 4512#endif 4513 case DisconnectPacket::eDisconnect_NoFlying: 4514 exitReasonStringId = IDS_DISCONNECTED_FLYING; 4515 break; 4516 case DisconnectPacket::eDisconnect_OutdatedServer: 4517 exitReasonStringId = IDS_DISCONNECTED_SERVER_OLD; 4518 break; 4519 case DisconnectPacket::eDisconnect_OutdatedClient: 4520 exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD; 4521 break; 4522 default: 4523 exitReasonStringId = IDS_DISCONNECTED; 4524 } 4525 pMinecraft->progressRenderer->progressStartNoAbort( exitReasonStringId ); 4526 // 4J - Force a disconnection, this handles the situation that the server has already disconnected 4527 if( pMinecraft->levels[0] != NULL ) pMinecraft->levels[0]->disconnect(false); 4528 if( pMinecraft->levels[1] != NULL ) pMinecraft->levels[1]->disconnect(false); 4529 } 4530 else 4531 { 4532 exitReasonStringId = IDS_EXITING_GAME; 4533 pMinecraft->progressRenderer->progressStartNoAbort( IDS_EXITING_GAME ); 4534 4535 if( pMinecraft->levels[0] != NULL ) pMinecraft->levels[0]->disconnect(); 4536 if( pMinecraft->levels[1] != NULL ) pMinecraft->levels[1]->disconnect(); 4537 } 4538 4539 // 4J Stu - This only does something if we actually have a server, so don't need to do any other checks 4540 MinecraftServer::HaltServer(true); 4541 4542 // We need to call the stats & leaderboards save before we exit the session 4543 //pMinecraft->forceStatsSave(); 4544 saveStats = false; 4545 4546 // 4J Stu - Leave the session once the disconnect packet has been sent 4547 g_NetworkManager.LeaveGame(FALSE); 4548 } 4549 else 4550 { 4551 if(lpParameter != NULL ) 4552 { 4553 switch( app.GetDisconnectReason() ) 4554 { 4555 case DisconnectPacket::eDisconnect_Kicked: 4556 exitReasonStringId = IDS_DISCONNECTED_KICKED; 4557 break; 4558 case DisconnectPacket::eDisconnect_NoUGC_AllLocal: 4559 exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL; 4560 break; 4561 case DisconnectPacket::eDisconnect_NoUGC_Single_Local: 4562 exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL; 4563 break; 4564#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) 4565 case DisconnectPacket::eDisconnect_ContentRestricted_AllLocal: 4566 exitReasonStringId = IDS_CONTENT_RESTRICTION_MULTIPLAYER; 4567 break; 4568 case DisconnectPacket::eDisconnect_ContentRestricted_Single_Local: 4569 exitReasonStringId = IDS_CONTENT_RESTRICTION; 4570 break; 4571#endif 4572#ifdef _XBOX 4573 case DisconnectPacket::eDisconnect_NoUGC_Remote: 4574 exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE; 4575 break; 4576#endif 4577 case DisconnectPacket::eDisconnect_OutdatedServer: 4578 exitReasonStringId = IDS_DISCONNECTED_SERVER_OLD; 4579 break; 4580 case DisconnectPacket::eDisconnect_OutdatedClient: 4581 exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD; 4582 default: 4583 exitReasonStringId = IDS_DISCONNECTED; 4584 } 4585 pMinecraft->progressRenderer->progressStartNoAbort( exitReasonStringId ); 4586 } 4587 } 4588 pMinecraft->setLevel(NULL,exitReasonStringId,nullptr,saveStats,true); 4589 4590 // 4J-JEV: Fix for #106402 - TCR #014 BAS Debug Output: 4591 // 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 4592 app.m_gameRules.unloadCurrentGameRules(); // 4593 4594 MinecraftServer::resetFlags(); 4595 4596 // We can't start/join a new game until the session is destroyed, so wait for it to be idle again 4597 while( g_NetworkManager.IsInSession() ) 4598 { 4599 Sleep(1); 4600 } 4601 4602 return S_OK; 4603} 4604 4605int CMinecraftApp::UnlockFullInviteReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 4606{ 4607 //CMinecraftApp* pApp = (CMinecraftApp*)pParam; 4608 Minecraft *pMinecraft=Minecraft::GetInstance(); 4609 bool bNoPlayer; 4610 4611 // bug 11285 - TCR 001: BAS Game Stability: CRASH - When trying to join a full version game with a trial version, the trial crashes 4612 // 4J-PB - we may be in the main menus here, and we don't have a pMinecraft->player 4613 4614 if(pMinecraft->player==NULL) 4615 { 4616 bNoPlayer=true; 4617 } 4618 4619 if(result==C4JStorage::EMessage_ResultAccept) 4620 { 4621 if(ProfileManager.IsSignedInLive(iPad)) 4622 { 4623 // 4J-PB - need to check this user can access the store 4624#if defined(__PS3__) || defined(__PSVITA__) 4625 bool bContentRestricted; 4626 ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,NULL,&bContentRestricted,NULL); 4627 if(bContentRestricted) 4628 { 4629 UINT uiIDA[1]; 4630 uiIDA[0]=IDS_CONFIRM_OK; 4631 ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); 4632 } 4633 else 4634#endif 4635 { 4636 ProfileManager.DisplayFullVersionPurchase(false,iPad,eSen_UpsellID_Full_Version_Of_Game); 4637 } 4638 } 4639#if defined(__PS3__) 4640 else 4641 { 4642 // you're not signed in to PSN! 4643 UINT uiIDA[2]; 4644 uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; 4645 uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; 4646 ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); 4647 4648 } 4649#endif 4650 } 4651 else 4652 { 4653 TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); 4654 } 4655 4656 return 0; 4657} 4658 4659int CMinecraftApp::UnlockFullSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 4660{ 4661 //CMinecraftApp* pApp = (CMinecraftApp*)pParam; 4662 Minecraft *pMinecraft=Minecraft::GetInstance(); 4663 4664 if(result==C4JStorage::EMessage_ResultAccept) 4665 { 4666 if(ProfileManager.IsSignedInLive(pMinecraft->player->GetXboxPad())) 4667 { 4668 // 4J-PB - need to check this user can access the store 4669#if defined(__PS3__) || defined(__PSVITA__) 4670 bool bContentRestricted; 4671 ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,NULL,&bContentRestricted,NULL); 4672 if(bContentRestricted) 4673 { 4674 UINT uiIDA[1]; 4675 uiIDA[0]=IDS_CONFIRM_OK; 4676 ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); 4677 } 4678 else 4679#endif 4680 { 4681 ProfileManager.DisplayFullVersionPurchase(false,pMinecraft->player->GetXboxPad(),eSen_UpsellID_Full_Version_Of_Game); 4682 } 4683 } 4684#if defined(__PS3__) 4685 else 4686 { 4687 // you're not signed in to PSN! 4688 UINT uiIDA[2]; 4689 uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; 4690 uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; 4691 ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); 4692 } 4693#elif defined(__ORBIS__) 4694 else 4695 { 4696 // Determine why they're not "signed in live" 4697 if (ProfileManager.isSignedInPSN(iPad)) 4698 { 4699 // Signed in to PSN but not connected (no internet access) 4700 assert(!ProfileManager.isConnectedToPSN(iPad)); 4701 4702 UINT uiIDA[1]; 4703 uiIDA[0] = IDS_OK; 4704 ui.RequestErrorMessage( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad); 4705 } 4706 else 4707 { 4708 // Not signed in to PSN 4709 UINT uiIDA[1]; 4710 uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; 4711 ui.RequestAlertMessage( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, iPad, &CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); 4712 } 4713 } 4714#endif 4715 } 4716 else 4717 { 4718 TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); 4719 } 4720 4721 return 0; 4722} 4723 4724int CMinecraftApp::UnlockFullExitReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 4725{ 4726 CMinecraftApp* pApp = (CMinecraftApp*)pParam; 4727 Minecraft *pMinecraft=Minecraft::GetInstance(); 4728 4729 if(result==C4JStorage::EMessage_ResultAccept) 4730 { 4731 if(ProfileManager.IsSignedInLive(pMinecraft->player->GetXboxPad())) 4732 { 4733 // 4J-PB - need to check this user can access the store 4734#if defined(__PS3__) || defined(__PSVITA__) 4735 bool bContentRestricted; 4736 ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,NULL,&bContentRestricted,NULL); 4737 if(bContentRestricted) 4738 { 4739 UINT uiIDA[1]; 4740 uiIDA[0]=IDS_CONFIRM_OK; 4741 ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); 4742 } 4743 else 4744#endif 4745 { 4746 ProfileManager.DisplayFullVersionPurchase(false,pMinecraft->player->GetXboxPad(),eSen_UpsellID_Full_Version_Of_Game); 4747#if defined __ORBIS__ || defined __PS3__ || defined __PSVITA__ 4748 // still need to exit the trial or we'll be in the Pause menu with input ignored 4749 pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); 4750#endif 4751 } 4752 } 4753#if defined(__PS3__) || defined __PSVITA__ 4754 else 4755 { 4756 // you're not signed in to PSN! 4757 UINT uiIDA[2]; 4758 uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; 4759 uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; 4760 ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturnedExitTrial,&app); 4761 } 4762#elif defined(__ORBIS__) 4763 else 4764 { 4765 // Determine why they're not "signed in live" 4766 if (ProfileManager.isSignedInPSN(iPad)) 4767 { 4768 // Signed in to PSN but not connected (no internet access) 4769 assert(!ProfileManager.isConnectedToPSN(iPad)); 4770 4771 UINT uiIDA[1]; 4772 uiIDA[0] = IDS_OK; 4773 ui.RequestErrorMessage( IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, iPad); 4774 // still need to exit the trial or we'll be in the Pause menu with input ignored 4775 pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); 4776 } 4777 else 4778 { 4779 // Not signed in to PSN 4780 UINT uiIDA[1]; 4781 uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; 4782 ui.RequestAlertMessage( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, iPad, &CMinecraftApp::MustSignInFullVersionPurchaseReturnedExitTrial,&app); 4783 } 4784 } 4785#endif 4786 } 4787 else 4788 { 4789 TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); 4790 pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); 4791 } 4792 4793 return 0; 4794} 4795 4796int CMinecraftApp::TrialOverReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 4797{ 4798 CMinecraftApp* pApp = (CMinecraftApp*)pParam; 4799 Minecraft *pMinecraft=Minecraft::GetInstance(); 4800 4801 if(result==C4JStorage::EMessage_ResultAccept) 4802 { 4803 // we need a signed in user for the unlock 4804 if(ProfileManager.IsSignedInLive(pMinecraft->player->GetXboxPad())) 4805 { 4806 // 4J-PB - need to check this user can access the store 4807#if defined(__PS3__) || defined(__PSVITA__) 4808 bool bContentRestricted; 4809 ProfileManager.GetChatAndContentRestrictions(ProfileManager.GetPrimaryPad(),true,NULL,&bContentRestricted,NULL); 4810 if(bContentRestricted) 4811 { 4812 UINT uiIDA[1]; 4813 uiIDA[0]=IDS_CONFIRM_OK; 4814 ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); 4815 } 4816 else 4817#endif 4818 { 4819 ProfileManager.DisplayFullVersionPurchase(false,pMinecraft->player->GetXboxPad(),eSen_UpsellID_Full_Version_Of_Game); 4820 } 4821 } 4822 else 4823 { 4824#if defined(__PS3__) 4825 4826 // you're not signed in to PSN! 4827 UINT uiIDA[2]; 4828 uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; 4829 uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; 4830 ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); 4831 4832 // 4J Stu - We can't actually exit the game, so just exit back to the main menu 4833 //pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); 4834#else 4835 pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitTrial); 4836#endif 4837 } 4838 } 4839 else 4840 { 4841 TelemetryManager->RecordUpsellResponded(iPad, eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, eSen_UpsellOutcome_Declined); 4842 4843#if defined(__PS3__) || defined(__ORBIS__) 4844 // 4J Stu - We can't actually exit the game, so just exit back to the main menu 4845 pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitWorldTrial); 4846#else 4847 pApp->SetAction(pMinecraft->player->GetXboxPad(),eAppAction_ExitTrial); 4848#endif 4849 } 4850 4851 return 0; 4852} 4853 4854void CMinecraftApp::ProfileReadErrorCallback(void *pParam) 4855{ 4856 CMinecraftApp *pApp=(CMinecraftApp *)pParam; 4857 int iPrimaryPlayer=ProfileManager.GetPrimaryPad(); 4858 pApp->SetAction(iPrimaryPlayer, eAppAction_ProfileReadError); 4859} 4860 4861void CMinecraftApp::ClearSignInChangeUsersMask() 4862{ 4863 // 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 4864 // 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 4865 // This is because m_uiLastSignInData remembers they were in previously, and doesn't read the profile data for them again 4866 // 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 4867 int iPrimaryPlayer=ProfileManager.GetPrimaryPad(); 4868 4869 if(m_uiLastSignInData!=0) 4870 { 4871 if(iPrimaryPlayer>=0) 4872 { 4873 m_uiLastSignInData=1<<iPrimaryPlayer; 4874 } 4875 else 4876 { 4877 m_uiLastSignInData=0; 4878 } 4879 } 4880} 4881void CMinecraftApp::SignInChangeCallback(LPVOID pParam,bool bPrimaryPlayerChanged,unsigned int uiSignInData) 4882{ 4883#ifdef __PS3__ 4884 // this is normally set in the main menu, but we can go online in the create world screens, and the primary player name isn't updated 4885 Minecraft::GetInstance()->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad())); 4886#endif 4887 4888 CMinecraftApp *pApp=(CMinecraftApp *)pParam; 4889 // check if the primary player signed out 4890 int iPrimaryPlayer=ProfileManager.GetPrimaryPad(); 4891 4892 if((ProfileManager.GetLockedProfile()!=-1) && iPrimaryPlayer!=-1) 4893 { 4894 if ( ((uiSignInData & (1<<iPrimaryPlayer)) == 0) || bPrimaryPlayerChanged ) 4895 { 4896 // Primary Player gone or there's been a sign out and sign in of the primary player, so kick them out 4897 pApp->SetAction(iPrimaryPlayer,eAppAction_PrimaryPlayerSignedOut); 4898 4899 // 4J-PB - invalidate their banned level list 4900 pApp->InvalidateBannedList(iPrimaryPlayer); 4901 4902 // need to ditch any DLCOffers info 4903 StorageManager.ClearDLCOffers(); 4904 pApp->ClearAndResetDLCDownloadQueue(); 4905 pApp->ClearDLCInstalled(); 4906 } 4907 else 4908 { 4909 unsigned int uiChangedPlayers = uiSignInData ^ m_uiLastSignInData; 4910 4911 if( g_NetworkManager.IsInSession() ) 4912 { 4913 bool hasGuestIdChanged = false; 4914 for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) 4915 { 4916 DWORD guestNumber = 0; 4917 if(ProfileManager.IsSignedIn(i)) 4918 { 4919 XUSER_SIGNIN_INFO info; 4920 XUserGetSigninInfo(i,XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY ,&info); 4921 pApp->DebugPrintf("Player at index %d has guest number %d\n", i,info.dwGuestNumber ); 4922 guestNumber = info.dwGuestNumber; 4923 } 4924 if( pApp->m_currentSigninInfo[i].dwGuestNumber != 0 && guestNumber != 0 && pApp->m_currentSigninInfo[i].dwGuestNumber != guestNumber ) 4925 { 4926 hasGuestIdChanged = true; 4927 } 4928 } 4929 4930 if( hasGuestIdChanged ) 4931 { 4932 UINT uiIDA[1]; 4933 uiIDA[0]=IDS_CONFIRM_OK; 4934 ui.RequestErrorMessage(IDS_GUEST_ORDER_CHANGED_TITLE, IDS_GUEST_ORDER_CHANGED_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad()); 4935 } 4936 4937 // 4J Stu - On PS4 we can also cause to exit players if they are signed out here, but we shouldn't do that if 4938 // we are going to switch to an offline game as it will likely crash due to incompatible parallel processes 4939 bool switchToOffline = false; 4940 // If it's an online game, and the primary profile is no longer signed into LIVE then we act as if disconnected 4941 if( !ProfileManager.IsSignedInLive( ProfileManager.GetLockedProfile() ) && !g_NetworkManager.IsLocalGame() ) 4942 { 4943 switchToOffline = true; 4944 } 4945 4946 //printf("Old: %x, New: %x, Changed: %x\n", m_ulLastSignInData, ulSignInData, changedPlayers); 4947 for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) 4948 { 4949 // Primary player shouldn't be subjected to these checks, and shouldn't call ExitPlayer 4950 if(i == iPrimaryPlayer) continue; 4951 4952 // A guest a signed in or out, out of order which invalidates all the guest players we have in the game 4953 if(hasGuestIdChanged && pApp->m_currentSigninInfo[i].dwGuestNumber != 0 && g_NetworkManager.GetLocalPlayerByUserIndex(i)!=NULL) 4954 { 4955 pApp->DebugPrintf("Recommending removal of player at index %d because their guest id changed\n",i); 4956 pApp->SetAction(i, eAppAction_ExitPlayer); 4957 } 4958 else 4959 { 4960 XUSER_SIGNIN_INFO info; 4961 XUserGetSigninInfo(i,XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY ,&info); 4962 // 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) 4963 // Fix for #48451 - TU5: Code: UI: Splitscreen: Title crashes when switching to a profile previously signed out via splitscreen profile selection 4964 4965 // 4J-PB - compiler complained about if below ('&&' within '||') - making it easier to read 4966 bool bPlayerChanged=(uiChangedPlayers&(1<<i))==(1<<i); 4967 bool bPlayerSignedIn=((uiSignInData&(1<<i))!=0); 4968 4969 if( bPlayerChanged && (!bPlayerSignedIn || (bPlayerSignedIn && !ProfileManager.AreXUIDSEqual(pApp->m_currentSigninInfo[i].xuid, info.xuid) ) )) 4970 { 4971 // 4J-PB - invalidate their banned level list 4972 pApp->DebugPrintf("Player at index %d Left - invalidating their banned list\n",i); 4973 pApp->InvalidateBannedList(i); 4974 4975 // 4J-HG: If either the player is in the network manager or in the game, need to exit player 4976 // TODO: Do we need to check the network manager? 4977 if (g_NetworkManager.GetLocalPlayerByUserIndex(i) != NULL || Minecraft::GetInstance()->localplayers[i] != NULL) 4978 { 4979 pApp->DebugPrintf("Player %d signed out\n", i); 4980 pApp->SetAction(i, eAppAction_ExitPlayer); 4981 } 4982 } 4983 } 4984#ifdef __ORBIS__ 4985 // check if any of the addition players have signed out of PSN (primary player is handled below) 4986 if(!switchToOffline && i != ProfileManager.GetLockedProfile() && !g_NetworkManager.IsLocalGame()) 4987 { 4988 if(g_NetworkManager.GetLocalPlayerByUserIndex(i)!=NULL) 4989 { 4990 if(ProfileManager.IsSignedInLive(i) == false) 4991 { 4992 pApp->DebugPrintf("Recommending removal of player at index %d because they're no longer signed into PSNd\n",i); 4993 pApp->SetAction(i,eAppAction_ExitPlayer); 4994 } 4995 } 4996 } 4997#endif 4998 } 4999 5000 // If it's an online game, and the primary profile is no longer signed into LIVE then we act as if disconnected 5001 if( switchToOffline ) 5002 { 5003 pApp->SetAction(iPrimaryPlayer,eAppAction_EthernetDisconnected); 5004 } 5005 5006 5007 g_NetworkManager.HandleSignInChange(); 5008 } 5009 // Some menus require the player to be signed in to live, so if this callback happens and the primary player is 5010 // no longer signed in then nav back 5011 else if ( pApp->GetLiveLinkRequired() && !ProfileManager.IsSignedInLive( ProfileManager.GetLockedProfile() ) ) 5012 { 5013#ifdef __PSVITA__ 5014 if(!CGameNetworkManager::usingAdhocMode()) // if we're in adhoc mode, we can ignore this 5015#endif 5016 { 5017 pApp->SetAction(iPrimaryPlayer,eAppAction_EthernetDisconnected); 5018 } 5019 } 5020 5021#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ ) 5022 // 4J-JEV: Need to kick of loading of profile data for sub-sign in players. 5023 for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) 5024 { 5025 if( i != iPrimaryPlayer 5026 && ( uiChangedPlayers & (1<<i) ) 5027 && ( uiSignInData & (1<<i) ) 5028 ) 5029 { 5030 StorageManager.ReadFromProfile(i); 5031 } 5032 } 5033#endif 5034 } 5035 m_uiLastSignInData = uiSignInData; 5036 } 5037 else if(iPrimaryPlayer!=-1) 5038 { 5039 // make sure the TMS banned list data is ditched - the player may have gone in to help & options, backed out, and signed out 5040 pApp->InvalidateBannedList(iPrimaryPlayer); 5041 5042 // need to ditch any DLCOffers info 5043 StorageManager.ClearDLCOffers(); 5044 pApp->ClearAndResetDLCDownloadQueue(); 5045 pApp->ClearDLCInstalled(); 5046 5047 } 5048 5049 // Update the guest numbers to the current state 5050 for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) 5051 { 5052 if(FAILED(XUserGetSigninInfo(i,XUSER_GET_SIGNIN_INFO_OFFLINE_XUID_ONLY,&pApp->m_currentSigninInfo[i]))) 5053 { 5054 pApp->m_currentSigninInfo[i].xuid = INVALID_XUID; 5055 pApp->m_currentSigninInfo[i].dwGuestNumber = 0; 5056 } 5057 app.DebugPrintf("Player at index %d has guest number %d\n", i,pApp->m_currentSigninInfo[i].dwGuestNumber ); 5058 } 5059} 5060 5061void CMinecraftApp::NotificationsCallback(LPVOID pParam,DWORD dwNotification, unsigned int uiParam) 5062{ 5063 CMinecraftApp* pClass = (CMinecraftApp*)pParam; 5064 5065 // push these on to the notifications to be handled in qnet's dowork 5066 5067 PNOTIFICATION pNotification = new NOTIFICATION; 5068 5069 pNotification->dwNotification=dwNotification; 5070 pNotification->uiParam=uiParam; 5071 5072 switch( dwNotification ) 5073 { 5074 case XN_SYS_SIGNINCHANGED: 5075 { 5076 pClass->DebugPrintf("Signing changed - %d\n", uiParam ); 5077 } 5078 break; 5079 case XN_SYS_INPUTDEVICESCHANGED: 5080 if(app.GetGameStarted() && g_NetworkManager.IsInSession()) 5081 { 5082 for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) 5083 { 5084 if(!InputManager.IsPadConnected(i) && 5085 Minecraft::GetInstance()->localplayers[i] != NULL && 5086 !ui.IsPauseMenuDisplayed(i) && !ui.IsSceneInStack(i, eUIScene_EndPoem) ) 5087 { 5088 ui.CloseUIScenes(i); 5089 ui.NavigateToScene(i,eUIScene_PauseMenu); 5090 } 5091 } 5092 } 5093 break; 5094 case XN_LIVE_CONTENT_INSTALLED: 5095 // Need to inform xuis that we've possibly had DLC installed 5096 { 5097 //app.m_dlcManager.SetNeedsUpdated(true); 5098 // Clear the DLC installed flag to cause a GetDLC to run if it's called 5099 app.ClearDLCInstalled(); 5100 5101 ui.HandleDLCInstalled(ProfileManager.GetPrimaryPad()); 5102 } 5103 break; 5104 case XN_SYS_STORAGEDEVICESCHANGED: 5105 { 5106#ifdef _XBOX 5107 // 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 5108 // audio streaming, as if we leave this until later xact gets locked up attempting to destroy the streamed wave bank. 5109 TexturePack *pTexPack=Minecraft::GetInstance()->skins->getSelected(); 5110 if(pTexPack->hasAudio()) 5111 { 5112 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)pTexPack; 5113 XCONTENTDEVICEID deviceID = pDLCTexPack->GetDLCDeviceID(); 5114 if( XContentGetDeviceState( deviceID, NULL ) != ERROR_SUCCESS ) 5115 { 5116 // 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, 5117 // and also so that we don't try and unmount this again, or play any sounds from it in the future 5118 pTexPack->setHasAudio(false); 5119 // need to stop the streaming audio - by playing streaming audio from the default texture pack now 5120 Minecraft::GetInstance()->soundEngine->playStreaming(L"", 0, 0, 0, 0, 0); 5121 5122 if(pDLCTexPack->m_pStreamedWaveBank!=NULL) 5123 { 5124 pDLCTexPack->m_pStreamedWaveBank->Destroy(); 5125 } 5126 if(pDLCTexPack->m_pSoundBank!=NULL) 5127 { 5128 pDLCTexPack->m_pSoundBank->Destroy(); 5129 } 5130 DWORD result = StorageManager.UnmountInstalledDLC("TPACK"); 5131 app.DebugPrintf("Unmount result is %d\n",result); 5132 } 5133 } 5134#endif 5135 } 5136 break; 5137 } 5138 5139 pClass->m_vNotifications.push_back(pNotification); 5140} 5141 5142#if defined __PS3__ || defined __PSVITA__ || defined __ORBIS__ 5143int CMinecraftApp::MustSignInFullVersionPurchaseReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 5144{ 5145 if(result==C4JStorage::EMessage_ResultAccept) 5146 { 5147#ifdef __PS3__ 5148 SQRNetworkManager_PS3::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); 5149#elif defined __PSVITA__ 5150 SQRNetworkManager_Vita::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); 5151#else // __PS4__ 5152 SQRNetworkManager_Orbis::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); 5153#endif 5154 } 5155 5156 return 0; 5157} 5158 5159#if defined __PS3__ || defined __PSVITA__ || defined __ORBIS__ 5160int CMinecraftApp::MustSignInFullVersionPurchaseReturnedExitTrial(void *pParam,int iPad,C4JStorage::EMessageResult result) 5161{ 5162 if(result==C4JStorage::EMessage_ResultAccept) 5163 { 5164#ifdef __PS3__ 5165 SQRNetworkManager_PS3::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); 5166#elif defined __PSVITA__ 5167 SQRNetworkManager_Vita::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); 5168#else // __PS4__ 5169 SQRNetworkManager_Orbis::AttemptPSNSignIn(&CMinecraftApp::NowDisplayFullVersionPurchase, &app,true); 5170#endif 5171 } 5172 5173 //4J-PB - we need to exit the trial, or we'll be in the pause menu with ignore input true 5174 app.SetAction(iPad,eAppAction_ExitWorldTrial); 5175 5176 return 0; 5177} 5178#endif 5179 5180int CMinecraftApp::NowDisplayFullVersionPurchase(void *pParam, bool bContinue, int iPad) 5181{ 5182 app.m_bDisplayFullVersionPurchase=true; 5183 return 0; 5184} 5185#endif 5186void CMinecraftApp::UpsellReturnedCallback(LPVOID pParam, eUpsellType type, eUpsellResponse result, int iUserData) 5187{ 5188 ESen_UpsellID senType; 5189 ESen_UpsellOutcome senResponse; 5190#ifdef __PS3__ 5191 UINT uiIDA[2]; 5192#endif 5193 5194 // Map the eUpsellResponse to the enum we use for sentient 5195 switch(result) 5196 { 5197 case eUpsellResponse_Accepted_NoPurchase: 5198 senResponse = eSen_UpsellOutcome_Went_To_Guide; 5199 break; 5200 case eUpsellResponse_Accepted_Purchase: 5201 senResponse = eSen_UpsellOutcome_Accepted; 5202 break; 5203#ifdef __PS3__ 5204 // special case for people who are not signed in to the PSN while playing the trial game 5205 case eUpsellResponse_UserNotSignedInPSN: 5206 5207 uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT; 5208 uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE; 5209 ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::MustSignInFullVersionPurchaseReturned,&app); 5210 5211 return; 5212 5213 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 5214 uiIDA[0]=IDS_CONFIRM_OK; 5215 ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, ProfileManager.GetPrimaryPad()); 5216 break; 5217#endif 5218 case eUpsellResponse_Declined: 5219 default: 5220 senResponse = eSen_UpsellOutcome_Declined; 5221 break; 5222 }; 5223 5224 // Map the eUpsellType to the enum we use for sentient 5225 switch(type) 5226 { 5227 case eUpsellType_Custom: 5228 senType = eSen_UpsellID_Full_Version_Of_Game; 5229 break; 5230 default: 5231 senType = eSen_UpsellID_Undefined; 5232 break; 5233 }; 5234 5235 // Always the primary pad that gets an upsell 5236 TelemetryManager->RecordUpsellResponded(ProfileManager.GetPrimaryPad(), eSen_UpsellID_Full_Version_Of_Game, app.m_dwOfferID, senResponse); 5237} 5238 5239#ifdef _DEBUG_MENUS_ENABLED 5240bool CMinecraftApp::DebugArtToolsOn() 5241{ 5242 return DebugSettingsOn() && (GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_ArtTools)) != 0; 5243} 5244#endif 5245 5246void CMinecraftApp::SetDebugSequence(const char *pchSeq) 5247{ 5248 InputManager.SetDebugSequence(pchSeq,&CMinecraftApp::DebugInputCallback,this); 5249} 5250int CMinecraftApp::DebugInputCallback(LPVOID pParam) 5251{ 5252 CMinecraftApp* pClass = (CMinecraftApp*)pParam; 5253 //printf("sequence matched\n"); 5254 pClass->m_bDebugOptions=!pClass->m_bDebugOptions; 5255 5256 for(int i=0;i<XUSER_MAX_COUNT;i++) 5257 { 5258 if(app.DebugSettingsOn()) 5259 { 5260 app.ActionDebugMask(i); 5261 } 5262 else 5263 { 5264 // force debug mask off 5265 app.ActionDebugMask(i,true); 5266 } 5267 } 5268 5269 return 0; 5270} 5271 5272int CMinecraftApp::GetLocalPlayerCount(void) 5273{ 5274 int iPlayerC=0; 5275 Minecraft *pMinecraft = Minecraft::GetInstance(); 5276 for(int i=0;i<XUSER_MAX_COUNT;i++) 5277 { 5278 if(pMinecraft != NULL && pMinecraft->localplayers[i] != NULL) 5279 { 5280 iPlayerC++; 5281 } 5282 } 5283 5284 return iPlayerC; 5285} 5286 5287int CMinecraftApp::MarketplaceCountsCallback(LPVOID pParam,C4JStorage::DLC_TMS_DETAILS *pTMSDetails, int iPad) 5288{ 5289 app.DebugPrintf("Marketplace Counts= New - %d Total - %d\n",pTMSDetails->dwNewOffers,pTMSDetails->dwTotalOffers); 5290 5291 if(pTMSDetails->dwNewOffers>0) 5292 { 5293 app.m_bNewDLCAvailable=true; 5294 app.m_bSeenNewDLCTip=false; 5295 } 5296 else 5297 { 5298 app.m_bNewDLCAvailable=false; 5299 app.m_bSeenNewDLCTip=true; 5300 } 5301 5302 return 0; 5303} 5304 5305bool CMinecraftApp::StartInstallDLCProcess(int iPad) 5306{ 5307 app.DebugPrintf("--- CMinecraftApp::StartInstallDLCProcess: pad=%i.\n", iPad); 5308 5309 // If there is already a call to this in progress, then do nothing 5310 // 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 5311 if((app.DLCInstallProcessCompleted()==false) && (m_bDLCInstallPending==false)) 5312 { 5313 app.m_dlcManager.resetUnnamedCorruptCount(); 5314 m_bDLCInstallPending = true; 5315 m_iTotalDLC = 0; 5316 m_iTotalDLCInstalled = 0; 5317 app.DebugPrintf("--- CMinecraftApp::StartInstallDLCProcess - StorageManager.GetInstalledDLC\n"); 5318 5319 StorageManager.GetInstalledDLC(iPad,&CMinecraftApp::DLCInstalledCallback,this); 5320 return true; 5321 } 5322 else 5323 { 5324 app.DebugPrintf("--- CMinecraftApp::StartInstallDLCProcess - nothing to do\n"); 5325 5326 return false; 5327 } 5328 5329} 5330 5331// Installed DLC callback 5332int CMinecraftApp::DLCInstalledCallback(LPVOID pParam,int iInstalledC,int iPad) 5333{ 5334 app.DebugPrintf("--- CMinecraftApp::DLCInstalledCallback: totalDLC=%i, pad=%i.\n", iInstalledC, iPad); 5335 app.m_iTotalDLC = iInstalledC; 5336 app.MountNextDLC(iPad); 5337 return 0; 5338} 5339 5340void CMinecraftApp::MountNextDLC(int iPad) 5341{ 5342 app.DebugPrintf("--- CMinecraftApp::MountNextDLC: pad=%i.\n", iPad); 5343 if(m_iTotalDLCInstalled < m_iTotalDLC) 5344 { 5345 // Mount it 5346 // We also need to match the ones the user wants to mount with the installed DLC 5347 // We're supposed to use a generic save game as a cache of these to do this, with XUSER_ANY 5348 5349 if(StorageManager.MountInstalledDLC(iPad,m_iTotalDLCInstalled,&CMinecraftApp::DLCMountedCallback,this)!=ERROR_IO_PENDING ) 5350 { 5351 // corrupt DLC 5352 app.DebugPrintf("Failed to mount DLC %d for pad %d\n",m_iTotalDLCInstalled,iPad); 5353 ++m_iTotalDLCInstalled; 5354 app.MountNextDLC(iPad); 5355 } 5356 else 5357 { 5358 app.DebugPrintf("StorageManager.MountInstalledDLC ok\n"); 5359 } 5360 } 5361 else 5362 { 5363 /* Removed - now loading these on demand instead of as each pack is mounted 5364 if(m_iTotalDLCInstalled > 0) 5365 { 5366 Minecraft *pMinecraft=Minecraft::GetInstance(); 5367 pMinecraft->levelRenderer->AddDLCSkinsToMemTextures(); 5368 } 5369 */ 5370 5371 m_bDLCInstallPending = false; 5372 m_bDLCInstallProcessCompleted=true; 5373 5374 ui.HandleDLCMountingComplete(); 5375 5376#if defined(_XBOX_ONE) || defined(__ORBIS__) 5377 // Check if the current texture pack is now installed 5378 if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin()) 5379 { 5380 TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); 5381 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; 5382 5383 DLCPack *pParentPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack(); 5384 5385 if(pParentPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) 5386 { 5387 StorageManager.SetSaveDisabled(false); 5388 } 5389 } 5390#endif 5391#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ 5392 { 5393 TexturePack* currentTPack = Minecraft::GetInstance()->skins->getSelected(); 5394 TexturePack* requiredTPack = Minecraft::GetInstance()->skins->getTexturePackById(app.GetRequiredTexturePackID()); 5395 if(currentTPack != requiredTPack) 5396 { 5397 Minecraft::GetInstance()->skins->selectTexturePackById(app.GetRequiredTexturePackID()); 5398 } 5399 } 5400#endif 5401 } 5402} 5403 5404// 4J-JEV: For the sake of clarity in DLCMountedCallback. 5405#if defined(_XBOX) || defined(__PS3__) || defined(_WINDOWS64) 5406#define CONTENT_DATA_DISPLAY_NAME(a) (a.szDisplayName) 5407#else 5408#define CONTENT_DATA_DISPLAY_NAME(a) (a.wszDisplayName) 5409#endif 5410 5411int CMinecraftApp::DLCMountedCallback(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicenceMask) 5412{ 5413#if defined(_XBOX) || defined(_DURANGO) || defined(__PS3__) || defined(__ORBIS__) || defined(_WINDOWS64) || defined (__PSVITA__) //Chris TODO 5414 app.DebugPrintf("--- CMinecraftApp::DLCMountedCallback\n"); 5415 5416 if(dwErr!=ERROR_SUCCESS) 5417 { 5418 // corrupt DLC 5419 app.DebugPrintf("Failed to mount DLC for pad %d: %d\n",iPad,dwErr); 5420 app.m_dlcManager.incrementUnnamedCorruptCount(); 5421 } 5422 else 5423 { 5424 XCONTENT_DATA ContentData = StorageManager.GetDLC(app.m_iTotalDLCInstalled); 5425 5426 DLCPack *pack = app.m_dlcManager.getPack( CONTENT_DATA_DISPLAY_NAME(ContentData) ); 5427 5428 if( pack != NULL && pack->IsCorrupt() ) 5429 { 5430 app.DebugPrintf("Pack '%ls' is corrupt, removing it from the DLC Manager.\n", CONTENT_DATA_DISPLAY_NAME(ContentData)); 5431 5432 app.m_dlcManager.removePack(pack); 5433 pack = NULL; 5434 } 5435 5436 if(pack == NULL) 5437 { 5438 app.DebugPrintf("Pack \"%ls\" is not installed, so adding it\n", CONTENT_DATA_DISPLAY_NAME(ContentData)); 5439 5440#if defined(_XBOX) || defined(__PS3__) || defined(_WINDOWS64) 5441 pack = new DLCPack(ContentData.szDisplayName,dwLicenceMask); 5442#elif defined _XBOX_ONE 5443 pack = new DLCPack(ContentData.wszDisplayName,ContentData.wszProductID,dwLicenceMask); 5444#else 5445 pack = new DLCPack(ContentData.wszDisplayName,dwLicenceMask); 5446#endif 5447 pack->SetDLCMountIndex(app.m_iTotalDLCInstalled); 5448 pack->SetDLCDeviceID(ContentData.DeviceID); 5449 app.m_dlcManager.addPack(pack); 5450 5451 app.HandleDLC(pack); 5452 5453 if(pack->getDLCItemsCount(DLCManager::e_DLCType_Texture) > 0) 5454 { 5455 Minecraft::GetInstance()->skins->addTexturePackFromDLC(pack, pack->GetPackId() ); 5456 } 5457 } 5458 else 5459 { 5460 app.DebugPrintf("Pack \"%ls\" is already installed. Updating license to %d\n", CONTENT_DATA_DISPLAY_NAME(ContentData), dwLicenceMask); 5461 5462 pack->SetDLCMountIndex(app.m_iTotalDLCInstalled); 5463 pack->SetDLCDeviceID(ContentData.DeviceID); 5464 pack->updateLicenseMask(dwLicenceMask); 5465 } 5466 5467 StorageManager.UnmountInstalledDLC(); 5468 } 5469 ++app.m_iTotalDLCInstalled; 5470 app.MountNextDLC(iPad); 5471 5472#endif // __PSVITA__ 5473 return 0; 5474} 5475#undef CONTENT_DATA_DISPLAY_NAME 5476 5477// void CMinecraftApp::InstallDefaultCape() 5478// { 5479// if(!m_bDefaultCapeInstallAttempted) 5480// { 5481// // we only attempt to install the cape once per launch of the game 5482// m_bDefaultCapeInstallAttempted=true; 5483// 5484// wstring wTemp=L"Default_Cape.png"; 5485// bool bRes=app.IsFileInMemoryTextures(wTemp); 5486// // if the file is not already in the memory textures, then read it from TMS 5487// if(!bRes) 5488// { 5489// BYTE *pBuffer=NULL; 5490// DWORD dwSize=0; 5491// // 4J-PB - out for now for DaveK so he doesn't get the birthday cape 5492// #ifdef _CONTENT_PACKAGE 5493// C4JStorage::ETMSStatus eTMSStatus; 5494// eTMSStatus=StorageManager.ReadTMSFile(ProfileManager.GetPrimaryPad(),C4JStorage::eGlobalStorage_Title,C4JStorage::eTMS_FileType_Graphic, L"Default_Cape.png",&pBuffer, &dwSize); 5495// if(eTMSStatus==C4JStorage::ETMSStatus_Idle) 5496// { 5497// app.AddMemoryTextureFile(wTemp,pBuffer,dwSize); 5498// } 5499// #endif 5500// } 5501// } 5502// } 5503 5504void CMinecraftApp::HandleDLC(DLCPack *pack) 5505{ 5506 DWORD dwFilesProcessed = 0; 5507#ifndef _XBOX 5508#if defined(__PS3__) || defined(__ORBIS__) || defined(_WINDOWS64) || defined (__PSVITA__) 5509 std::vector<std::string> dlcFilenames; 5510#elif defined _DURANGO 5511 std::vector<std::wstring> dlcFilenames; 5512#endif 5513 StorageManager.GetMountedDLCFileList("DLCDrive", dlcFilenames); 5514#ifdef __ORBIS__ 5515 // 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 5516 if(dlcFilenames.size() > 0) m_dlcManager.readDLCDataFile(dwFilesProcessed, dlcFilenames[0], pack); 5517#else 5518 for(int i=0; i<dlcFilenames.size();i++) 5519 { 5520 m_dlcManager.readDLCDataFile(dwFilesProcessed, dlcFilenames[i], pack); 5521 } 5522#endif 5523#else 5524 WIN32_FIND_DATA wfd; 5525 HANDLE hFind; 5526 5527 char szPath[] = "DLCDrive:\\"; 5528 char szFullFilename[256]; 5529 strcpy(szFullFilename,szPath); 5530 strcat(szFullFilename,"*"); 5531 5532 // Start the find and check for failure. 5533 hFind = FindFirstFile( szFullFilename, &wfd ); 5534 5535 if( INVALID_HANDLE_VALUE == hFind ) 5536 { 5537 app.DebugPrintf( "FindFirstFile failed." ); 5538 } 5539 else 5540 { 5541 // Display each file and ask for the next. 5542 do 5543 { 5544 strcpy(szFullFilename,szPath); 5545 strcat(szFullFilename,wfd.cFileName); 5546 5547 if(( GetFileAttributes( szFullFilename ) & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) 5548 { 5549#ifdef _XBOX 5550 DWORD dwPackID=m_dlcManager.retrievePackIDFromDLCDataFile(szFullFilename,pack); 5551 5552 // Do we need to override the TexturePack.pck with an updated version in a TU? 5553 wstring wsTemp=getFilePath(dwPackID, wstring(L"TexturePack.pck"),false ); 5554 File texturePCKPath(wsTemp ); 5555 if(texturePCKPath.exists()) 5556 { 5557 app.DebugPrintf("Found a replacement .pck\n"); 5558 m_dlcManager.readDLCDataFile(dwFilesProcessed, wsTemp,pack); 5559 } 5560 else 5561 { 5562 m_dlcManager.readDLCDataFile(dwFilesProcessed, szFullFilename,pack); 5563 } 5564#else 5565 m_dlcManager.readDLCDataFile(dwFilesProcessed, szFullFilename,pack); 5566 5567#endif 5568 } 5569 } 5570 while( FindNextFile( hFind, &wfd ) ); 5571 5572 // Close the find handle. 5573 FindClose( hFind ); 5574 } 5575#endif // __PS3__ || __ORBIS__ 5576 5577 if( dwFilesProcessed == 0 ) m_dlcManager.removePack(pack); 5578} 5579 5580// int CMinecraftApp::DLCReadCallback(LPVOID pParam,C4JStorage::DLC_FILE_DETAILS *pDLCData) 5581// { 5582// 5583// 5584// return 0; 5585// } 5586 5587//------------------------------------------------------------------------------------- 5588// Name: InitTime() 5589// Desc: Initializes the timer variables 5590//------------------------------------------------------------------------------------- 5591void CMinecraftApp::InitTime() 5592{ 5593 5594 // Get the frequency of the timer 5595 LARGE_INTEGER qwTicksPerSec; 5596 QueryPerformanceFrequency( &qwTicksPerSec ); 5597 m_Time.fSecsPerTick = 1.0f / (float)qwTicksPerSec.QuadPart; 5598 5599 // Save the start time 5600 QueryPerformanceCounter( &m_Time.qwTime ); 5601 5602 // Zero out the elapsed and total time 5603 m_Time.qwAppTime.QuadPart = 0; 5604 m_Time.fAppTime = 0.0f; 5605 m_Time.fElapsedTime = 0.0f; 5606} 5607 5608//------------------------------------------------------------------------------------- 5609// Name: UpdateTime() 5610// Desc: Updates the elapsed time since our last frame. 5611//------------------------------------------------------------------------------------- 5612void CMinecraftApp::UpdateTime() 5613{ 5614 LARGE_INTEGER qwNewTime; 5615 LARGE_INTEGER qwDeltaTime; 5616 5617 QueryPerformanceCounter( &qwNewTime ); 5618 qwDeltaTime.QuadPart = qwNewTime.QuadPart - m_Time.qwTime.QuadPart; 5619 5620 m_Time.qwAppTime.QuadPart += qwDeltaTime.QuadPart; 5621 m_Time.qwTime.QuadPart = qwNewTime.QuadPart; 5622 5623 m_Time.fElapsedTime = m_Time.fSecsPerTick * ((FLOAT)(qwDeltaTime.QuadPart)); 5624 m_Time.fAppTime = m_Time.fSecsPerTick * ((FLOAT)(m_Time.qwAppTime.QuadPart)); 5625} 5626 5627 5628 5629 5630 5631 5632 5633bool CMinecraftApp::isXuidNotch(PlayerUID xuid) 5634{ 5635 if(m_xuidNotch != INVALID_XUID && xuid != INVALID_XUID) 5636 { 5637 return ProfileManager.AreXUIDSEqual(xuid, m_xuidNotch) == TRUE; 5638 } 5639 return false; 5640} 5641 5642bool CMinecraftApp::isXuidDeadmau5(PlayerUID xuid) 5643{ 5644 AUTO_VAR(it, MojangData.find( xuid )); // 4J Stu - The .at and [] accessors insert elements if they don't exist 5645 if (it != MojangData.end() ) 5646 { 5647 MOJANG_DATA *pMojangData=MojangData[xuid]; 5648 if(pMojangData && pMojangData->eXuid==eXUID_Deadmau5) 5649 { 5650 return true; 5651 } 5652 } 5653 5654 return false; 5655} 5656 5657void CMinecraftApp::AddMemoryTextureFile(const wstring &wName,PBYTE pbData,DWORD dwBytes) 5658{ 5659 EnterCriticalSection(&csMemFilesLock); 5660 // check it's not already in 5661 PMEMDATA pData=NULL; 5662 AUTO_VAR(it, m_MEM_Files.find(wName)); 5663 if(it != m_MEM_Files.end()) 5664 { 5665#ifndef _CONTENT_PACKAGE 5666 wprintf(L"Incrementing the memory texture file count for %ls\n", wName.c_str()); 5667#endif 5668 pData = (*it).second; 5669 5670 if(pData->dwBytes == 0 && dwBytes != 0) 5671 { 5672 // This should never be NULL if dwBytes is 0 5673 if(pData->pbData!=NULL) delete [] pData->pbData; 5674 5675 pData->pbData=pbData; 5676 pData->dwBytes=dwBytes; 5677 } 5678 5679 ++pData->ucRefCount; 5680 LeaveCriticalSection(&csMemFilesLock); 5681 return; 5682 } 5683 5684#ifndef _CONTENT_PACKAGE 5685 //wprintf(L"Adding the memory texture file data for %ls\n", wName.c_str()); 5686#endif 5687 // this is a texture (png) file 5688 5689 // add this texture to the list of memory texture files - it will then be picked up by the level renderer's AddEntity 5690 5691 pData = (PMEMDATA)new BYTE[sizeof(MEMDATA)]; 5692 ZeroMemory( pData, sizeof(MEMDATA) ); 5693 pData->pbData=pbData; 5694 pData->dwBytes=dwBytes; 5695 pData->ucRefCount = 1; 5696 5697 // use the xuid to access the skin data 5698 m_MEM_Files[wName]=pData; 5699 5700 LeaveCriticalSection(&csMemFilesLock); 5701} 5702 5703void CMinecraftApp::RemoveMemoryTextureFile(const wstring &wName) 5704{ 5705 EnterCriticalSection(&csMemFilesLock); 5706 5707 AUTO_VAR(it, m_MEM_Files.find(wName)); 5708 if(it != m_MEM_Files.end()) 5709 { 5710#ifndef _CONTENT_PACKAGE 5711 wprintf(L"Decrementing the memory texture file count for %ls\n", wName.c_str()); 5712#endif 5713 PMEMDATA pData = (*it).second; 5714 --pData->ucRefCount; 5715 if(pData->ucRefCount <= 0) 5716 { 5717#ifndef _CONTENT_PACKAGE 5718 wprintf(L"Erasing the memory texture file data for %ls\n", wName.c_str()); 5719#endif 5720 delete [] pData; 5721 m_MEM_Files.erase(wName); 5722 } 5723 } 5724 LeaveCriticalSection(&csMemFilesLock); 5725} 5726 5727bool CMinecraftApp::DefaultCapeExists() 5728{ 5729 wstring wTex=L"Special_Cape.png"; 5730 bool val = false; 5731 5732 EnterCriticalSection(&csMemFilesLock); 5733 AUTO_VAR(it, m_MEM_Files.find(wTex)); 5734 if(it != m_MEM_Files.end()) val = true; 5735 LeaveCriticalSection(&csMemFilesLock); 5736 5737 return val; 5738} 5739 5740bool CMinecraftApp::IsFileInMemoryTextures(const wstring &wName) 5741{ 5742 bool val = false; 5743 5744 EnterCriticalSection(&csMemFilesLock); 5745 AUTO_VAR(it, m_MEM_Files.find(wName)); 5746 if(it != m_MEM_Files.end()) val = true; 5747 LeaveCriticalSection(&csMemFilesLock); 5748 5749 return val; 5750} 5751 5752void CMinecraftApp::GetMemFileDetails(const wstring &wName,PBYTE *ppbData,DWORD *pdwBytes) 5753{ 5754 EnterCriticalSection(&csMemFilesLock); 5755 AUTO_VAR(it, m_MEM_Files.find(wName)); 5756 if(it != m_MEM_Files.end()) 5757 { 5758 PMEMDATA pData = (*it).second; 5759 *ppbData=pData->pbData; 5760 *pdwBytes=pData->dwBytes; 5761 } 5762 LeaveCriticalSection(&csMemFilesLock); 5763} 5764 5765void CMinecraftApp::AddMemoryTPDFile(int iConfig,PBYTE pbData,DWORD dwBytes) 5766{ 5767 EnterCriticalSection(&csMemTPDLock); 5768 // check it's not already in 5769 PMEMDATA pData=NULL; 5770 AUTO_VAR(it, m_MEM_TPD.find(iConfig)); 5771 if(it == m_MEM_TPD.end()) 5772 { 5773 pData = (PMEMDATA)new BYTE[sizeof(MEMDATA)]; 5774 ZeroMemory( pData, sizeof(MEMDATA) ); 5775 pData->pbData=pbData; 5776 pData->dwBytes=dwBytes; 5777 pData->ucRefCount = 1; 5778 5779 m_MEM_TPD[iConfig]=pData; 5780 } 5781 5782 LeaveCriticalSection(&csMemTPDLock); 5783} 5784 5785void CMinecraftApp::RemoveMemoryTPDFile(int iConfig) 5786{ 5787 EnterCriticalSection(&csMemTPDLock); 5788 // check it's not already in 5789 PMEMDATA pData=NULL; 5790 AUTO_VAR(it, m_MEM_TPD.find(iConfig)); 5791 if(it != m_MEM_TPD.end()) 5792 { 5793 pData=m_MEM_TPD[iConfig]; 5794 delete [] pData; 5795 m_MEM_TPD.erase(iConfig); 5796 } 5797 5798 LeaveCriticalSection(&csMemTPDLock); 5799} 5800 5801#ifdef _XBOX 5802int CMinecraftApp::GetTPConfigVal(WCHAR *pwchDataFile) 5803{ 5804 DLC_INFO *pDLCInfo=NULL; 5805 // run through the DLC info to find the right texture pack/mash-up pack 5806 for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i) 5807 { 5808 ULONGLONG ull=app.GetDLCInfoTexturesFullOffer(i); 5809 pDLCInfo=app.GetDLCInfoForFullOfferID(ull); 5810 5811 if(wcscmp(pwchDataFile,pDLCInfo->wchDataFile)==0) 5812 { 5813 return pDLCInfo->iConfig; 5814 } 5815 } 5816 5817 return -1; 5818} 5819#elif defined _XBOX_ONE 5820int CMinecraftApp::GetTPConfigVal(WCHAR *pwchDataFile) 5821{ 5822 DLC_INFO *pDLCInfo=NULL; 5823 // run through the DLC info to find the right texture pack/mash-up pack 5824 for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i) 5825 { 5826 pDLCInfo=app.GetDLCInfoForFullOfferID((WCHAR *)app.GetDLCInfoTexturesFullOffer(i).c_str()); 5827 5828 if(wcscmp(pwchDataFile,pDLCInfo->wchDataFile)==0) 5829 { 5830 return pDLCInfo->iConfig; 5831 } 5832 } 5833 5834 return -1; 5835} 5836#elif defined _WINDOWS64 5837int CMinecraftApp::GetTPConfigVal(WCHAR *pwchDataFile) 5838{ 5839 return -1; 5840} 5841#endif 5842bool CMinecraftApp::IsFileInTPD(int iConfig) 5843{ 5844 bool val = false; 5845 5846 EnterCriticalSection(&csMemTPDLock); 5847 AUTO_VAR(it, m_MEM_TPD.find(iConfig)); 5848 if(it != m_MEM_TPD.end()) val = true; 5849 LeaveCriticalSection(&csMemTPDLock); 5850 5851 return val; 5852} 5853 5854void CMinecraftApp::GetTPD(int iConfig,PBYTE *ppbData,DWORD *pdwBytes) 5855{ 5856 EnterCriticalSection(&csMemTPDLock); 5857 AUTO_VAR(it, m_MEM_TPD.find(iConfig)); 5858 if(it != m_MEM_TPD.end()) 5859 { 5860 PMEMDATA pData = (*it).second; 5861 *ppbData=pData->pbData; 5862 *pdwBytes=pData->dwBytes; 5863 } 5864 LeaveCriticalSection(&csMemTPDLock); 5865} 5866 5867 5868// bool CMinecraftApp::UploadFileToGlobalStorage(int iQuadrant, C4JStorage::eGlobalStorage eStorageFacility, wstring *wsFile ) 5869// { 5870// bool bRes=false; 5871// #ifndef _CONTENT_PACKAGE 5872// // read the local file 5873// File gtsFile( wsFile->c_str() ); 5874// 5875// __int64 fileSize = gtsFile.length(); 5876// 5877// if(fileSize!=0) 5878// { 5879// FileInputStream fis(gtsFile); 5880// byteArray ba((int)fileSize); 5881// fis.read(ba); 5882// fis.close(); 5883// 5884// bRes=StorageManager.WriteTMSFile(iQuadrant,eStorageFacility,(WCHAR *)wsFile->c_str(),ba.data, ba.length); 5885// 5886// } 5887// #endif 5888// return bRes; 5889// } 5890 5891 5892 5893 5894 5895 5896void CMinecraftApp::StoreLaunchData() 5897{ 5898 5899} 5900 5901void CMinecraftApp::ExitGame() 5902{ 5903} 5904 5905// Invites 5906 5907void CMinecraftApp::ProcessInvite(DWORD dwUserIndex, DWORD dwLocalUsersMask, const INVITE_INFO * pInviteInfo) 5908{ 5909 m_InviteData.dwUserIndex=dwUserIndex; 5910 m_InviteData.dwLocalUsersMask=dwLocalUsersMask; 5911 m_InviteData.pInviteInfo=pInviteInfo; 5912 //memcpy(&m_InviteData,pJoinData,sizeof(JoinFromInviteData)); 5913 SetAction(dwUserIndex,eAppAction_ExitAndJoinFromInvite); 5914} 5915 5916int CMinecraftApp::ExitAndJoinFromInvite(void *pParam,int iPad,C4JStorage::EMessageResult result) 5917{ 5918 CMinecraftApp* pApp = (CMinecraftApp*)pParam; 5919 //Minecraft *pMinecraft=Minecraft::GetInstance(); 5920 5921 // buttons are swapped on this menu 5922 if(result==C4JStorage::EMessage_ResultDecline) 5923 { 5924 pApp->SetAction(iPad,eAppAction_ExitAndJoinFromInviteConfirmed); 5925 } 5926 5927 return 0; 5928} 5929 5930int CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 5931{ 5932 CMinecraftApp *pClass = (CMinecraftApp *)pParam; 5933 // Exit with or without saving 5934 // Decline means save in this dialog 5935 if(result==C4JStorage::EMessage_ResultDecline || result==C4JStorage::EMessage_ResultThirdOption) 5936 { 5937 if( result==C4JStorage::EMessage_ResultDecline ) // Save 5938 { 5939 // Check they have the full texture pack if they are using one 5940 // 4J-PB - Is the player trying to save but they are using a trial texturepack ? 5941 if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin()) 5942 { 5943 TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); 5944 5945 DLCPack * pDLCPack=tPack->getDLCPack(); 5946 if(!pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) 5947 { 5948 // upsell 5949 // get the dlc texture pack 5950 5951#ifdef _XBOX 5952 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; 5953 ULONGLONG ullOfferID_Full; 5954 app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullOfferID_Full); 5955 5956 // tell sentient about the upsell of the full version of the skin pack 5957 TelemetryManager->RecordUpsellPresented(iPad, eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF); 5958#endif 5959 5960 UINT uiIDA[2]; 5961 uiIDA[0]=IDS_CONFIRM_OK; 5962 uiIDA[1]=IDS_CONFIRM_CANCEL; 5963 5964 // Give the player a warning about the trial version of the texture pack 5965 ui.RequestErrorMessage(IDS_WARNING_DLC_TRIALTEXTUREPACK_TITLE, IDS_WARNING_DLC_TRIALTEXTUREPACK_TEXT, uiIDA, 2, iPad,&CMinecraftApp::WarningTrialTexturePackReturned,pClass); 5966 5967 return S_OK; 5968 } 5969 } 5970#ifndef _XBOX_ONE 5971 // does the save exist? 5972 bool bSaveExists; 5973 StorageManager.DoesSaveExist(&bSaveExists); 5974 // 4J-PB - we check if the save exists inside the libs 5975 // we need to ask if they are sure they want to overwrite the existing game 5976 if(bSaveExists) 5977 { 5978 UINT uiIDA[2]; 5979 uiIDA[0]=IDS_CONFIRM_CANCEL; 5980 uiIDA[1]=IDS_CONFIRM_OK; 5981 ui.RequestErrorMessage(IDS_TITLE_SAVE_GAME, IDS_CONFIRM_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::ExitAndJoinFromInviteAndSaveReturned,pClass); 5982 return 0; 5983 } 5984 else 5985#endif 5986 { 5987#if defined(_XBOX_ONE) || defined(__ORBIS__) 5988 StorageManager.SetSaveDisabled(false); 5989#endif 5990 MinecraftServer::getInstance()->setSaveOnExit( true ); 5991 } 5992 } 5993 else 5994 { 5995 // been a few requests for a confirm on exit without saving 5996 UINT uiIDA[2]; 5997 uiIDA[0]=IDS_CONFIRM_CANCEL; 5998 uiIDA[1]=IDS_CONFIRM_OK; 5999 ui.RequestErrorMessage(IDS_TITLE_DECLINE_SAVE_GAME, IDS_CONFIRM_DECLINE_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::ExitAndJoinFromInviteDeclineSaveReturned,pClass); 6000 return 0; 6001 } 6002 6003 app.SetAction(ProfileManager.GetPrimaryPad(),eAppAction_ExitAndJoinFromInviteConfirmed); 6004 } 6005 return 0; 6006} 6007 6008int CMinecraftApp::WarningTrialTexturePackReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 6009{ 6010 // 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 6011#if 0 //defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) 6012 if(result==C4JStorage::EMessage_ResultAccept) 6013 { 6014 if(!ProfileManager.IsSignedInLive(iPad)) 6015 { 6016 // you're not signed in to PSN! 6017 6018 } 6019 else 6020 { 6021 // 4J-PB - need to check this user can access the store 6022 bool bContentRestricted; 6023 ProfileManager.GetChatAndContentRestrictions(iPad,true,NULL,&bContentRestricted,NULL); 6024 if(bContentRestricted) 6025 { 6026 UINT uiIDA[1]; 6027 uiIDA[0]=IDS_CONFIRM_OK; 6028 ui.RequestAlertMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, iPad); 6029 } 6030 else 6031 { 6032 // need to get info on the pack to see if the user has already downloaded it 6033 TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); 6034 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; 6035 6036 // retrieve the store name for the skin pack 6037 DLCPack *pDLCPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack(); 6038 const char *pchPackName=wstringtofilename(pDLCPack->getName()); 6039 app.DebugPrintf("Texture Pack - %s\n",pchPackName); 6040 SONYDLC *pSONYDLCInfo=app.GetSONYDLCInfo((char *)pchPackName); 6041 6042 if(pSONYDLCInfo!=NULL) 6043 { 6044 char chName[42]; 6045 char chSkuID[SCE_NP_COMMERCE2_SKU_ID_LEN]; 6046 6047 memset(chSkuID,0,SCE_NP_COMMERCE2_SKU_ID_LEN); 6048 // find the info on the skin pack 6049 // we have to retrieve the skuid from the store info, it can't be hardcoded since Sony may change it. 6050 // So we assume the first sku for the product is the one we want 6051#ifdef __ORBIS__ 6052 sprintf(chName,"%s",pSONYDLCInfo->chDLCKeyname); 6053#else 6054 sprintf(chName,"%s-%s",app.GetCommerceCategory(),pSONYDLCInfo->chDLCKeyname); 6055#endif 6056 app.GetDLCSkuIDFromProductList(chName,chSkuID); 6057 // 4J-PB - need to check for an empty store 6058#if defined __ORBIS__ || defined __PSVITA__ || defined __PS3__ 6059 if(app.CheckForEmptyStore(iPad)==false) 6060#endif 6061 { 6062 if(app.DLCAlreadyPurchased(chSkuID)) 6063 { 6064 app.DownloadAlreadyPurchased(chSkuID); 6065 } 6066 else 6067 { 6068 app.Checkout(chSkuID); 6069 } 6070 } 6071 } 6072 } 6073 } 6074 } 6075#endif // 6076 6077#ifdef _XBOX_ONE 6078 if(result==C4JStorage::EMessage_ResultAccept) 6079 { 6080 if(ProfileManager.IsSignedIn(iPad)) 6081 { 6082 if (ProfileManager.IsSignedInLive(iPad)) 6083 { 6084 TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); 6085 // get the dlc texture pack 6086 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; 6087 6088 DLCPack *pDLCPack=pDLCTexPack->getDLCInfoParentPack(); 6089 6090 DLC_INFO *pDLCInfo=app.GetDLCInfoForProductName((WCHAR *)pDLCPack->getName().c_str()); 6091 6092 StorageManager.InstallOffer(1,(WCHAR *)pDLCInfo->wsProductId.c_str(),NULL,NULL); 6093 6094 // the license change coming in when the offer has been installed will cause this scene to refresh 6095 } 6096 else 6097 { 6098 // 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. 6099 UINT uiIDA[1] = { IDS_CONFIRM_OK }; 6100 ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_XBOXLIVE_NOTIFICATION, uiIDA, 1, iPad); 6101 } 6102 } 6103 } 6104 6105#endif 6106#ifdef _XBOX 6107 6108 CMinecraftApp* pClass = (CMinecraftApp*)pParam; 6109 6110 TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); 6111 // get the dlc texture pack 6112 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; 6113 ULONGLONG ullIndexA[1]; 6114 6115 // Need to get the parent packs id, since this may be one of many child packs with their own ids 6116 app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullIndexA[0]); 6117 6118 if(result==C4JStorage::EMessage_ResultAccept) 6119 { 6120 if(ProfileManager.IsSignedIn(iPad)) 6121 { 6122 // 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... 6123 XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); 6124 6125 StorageManager.InstallOffer(1,ullIndexA,NULL,NULL); 6126 } 6127 } 6128 else 6129 { 6130 TelemetryManager->RecordUpsellResponded(iPad, eSet_UpsellID_Texture_DLC, ( ullIndexA[0] & 0xFFFFFFFF ), eSen_UpsellOutcome_Declined); 6131 } 6132#endif 6133 return 0; 6134} 6135 6136int CMinecraftApp::ExitAndJoinFromInviteAndSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 6137{ 6138 //CMinecraftApp* pClass = (CMinecraftApp*)pParam; 6139 6140 // results switched for this dialog 6141 if(result==C4JStorage::EMessage_ResultDecline) 6142 { 6143 INT saveOrCheckpointId = 0; 6144 6145 // Check they have the full texture pack if they are using one 6146 // 4J-PB - Is the player trying to save but they are using a trial texturepack ? 6147 if(!Minecraft::GetInstance()->skins->isUsingDefaultSkin()) 6148 { 6149 TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); 6150 6151 DLCPack * pDLCPack=tPack->getDLCPack(); 6152 if(!pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" )) 6153 { 6154 // upsell 6155 // get the dlc texture pack 6156 6157#ifdef _XBOX 6158 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tPack; 6159 ULONGLONG ullOfferID_Full; 6160 app.GetDLCFullOfferIDForPackID(pDLCTexPack->getDLCParentPackId(),&ullOfferID_Full); 6161 6162 // tell sentient about the upsell of the full version of the skin pack 6163 TelemetryManager->RecordUpsellPresented(iPad, eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF); 6164#endif 6165 6166 UINT uiIDA[2]; 6167 uiIDA[0]=IDS_CONFIRM_OK; 6168 uiIDA[1]=IDS_CONFIRM_CANCEL; 6169 6170 // Give the player a warning about the trial version of the texture pack 6171 ui.RequestErrorMessage(IDS_WARNING_DLC_TRIALTEXTUREPACK_TITLE, IDS_WARNING_DLC_TRIALTEXTUREPACK_TEXT, uiIDA, 2, iPad,&CMinecraftApp::WarningTrialTexturePackReturned,NULL); 6172 6173 return S_OK; 6174 } 6175 } 6176 //bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId); 6177 //SentientManager.RecordLevelSaveOrCheckpoint(ProfileManager.GetPrimaryPad(), saveOrCheckpointId); 6178 MinecraftServer::getInstance()->setSaveOnExit( true ); 6179 // flag a app action of exit and join game from invite 6180 app.SetAction(iPad,eAppAction_ExitAndJoinFromInviteConfirmed); 6181 } 6182 return 0; 6183} 6184 6185int CMinecraftApp::ExitAndJoinFromInviteDeclineSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 6186{ 6187 // results switched for this dialog 6188 if(result==C4JStorage::EMessage_ResultDecline) 6189 { 6190#if defined(_XBOX_ONE) || defined(__ORBIS__) 6191 StorageManager.SetSaveDisabled(false); 6192#endif 6193 MinecraftServer::getInstance()->setSaveOnExit( false ); 6194 // flag a app action of exit and join game from invite 6195 app.SetAction(iPad,eAppAction_ExitAndJoinFromInviteConfirmed); 6196 } 6197 return 0; 6198} 6199 6200////////////////////////////////////////////////////////////////////////// 6201// 6202// FatalLoadError 6203// 6204// This is called when we can't load one of the required files at startup 6205// It tends to mean the files have been corrupted. 6206// We have to assume that we've not been able to load the text for the game. 6207// 6208////////////////////////////////////////////////////////////////////////// 6209void CMinecraftApp::FatalLoadError() 6210{ 6211 6212} 6213 6214TIPSTRUCT CMinecraftApp::m_GameTipA[MAX_TIPS_GAMETIP]= 6215{ 6216 { 0, IDS_TIPS_GAMETIP_1}, 6217 { 0, IDS_TIPS_GAMETIP_2}, 6218 { 0, IDS_TIPS_GAMETIP_3}, 6219 { 0, IDS_TIPS_GAMETIP_4}, 6220 { 0, IDS_TIPS_GAMETIP_5}, 6221 { 0, IDS_TIPS_GAMETIP_6}, 6222 { 0, IDS_TIPS_GAMETIP_7}, 6223 { 0, IDS_TIPS_GAMETIP_8}, 6224 { 0, IDS_TIPS_GAMETIP_9}, 6225 { 0, IDS_TIPS_GAMETIP_10}, 6226 { 0, IDS_TIPS_GAMETIP_11}, 6227 { 0, IDS_TIPS_GAMETIP_12}, 6228 { 0, IDS_TIPS_GAMETIP_13}, 6229 { 0, IDS_TIPS_GAMETIP_14}, 6230 { 0, IDS_TIPS_GAMETIP_15}, 6231 { 0, IDS_TIPS_GAMETIP_16}, 6232 { 0, IDS_TIPS_GAMETIP_17}, 6233 { 0, IDS_TIPS_GAMETIP_18}, 6234 { 0, IDS_TIPS_GAMETIP_19}, 6235 { 0, IDS_TIPS_GAMETIP_20}, 6236 { 0, IDS_TIPS_GAMETIP_21}, 6237 { 0, IDS_TIPS_GAMETIP_22}, 6238 { 0, IDS_TIPS_GAMETIP_23}, 6239 { 0, IDS_TIPS_GAMETIP_24}, 6240 { 0, IDS_TIPS_GAMETIP_25}, 6241 { 0, IDS_TIPS_GAMETIP_26}, 6242 { 0, IDS_TIPS_GAMETIP_27}, 6243 { 0, IDS_TIPS_GAMETIP_28}, 6244 { 0, IDS_TIPS_GAMETIP_29}, 6245 { 0, IDS_TIPS_GAMETIP_30}, 6246 { 0, IDS_TIPS_GAMETIP_31}, 6247 { 0, IDS_TIPS_GAMETIP_32}, 6248 { 0, IDS_TIPS_GAMETIP_33}, 6249 { 0, IDS_TIPS_GAMETIP_34}, 6250 { 0, IDS_TIPS_GAMETIP_35}, 6251 { 0, IDS_TIPS_GAMETIP_36}, 6252 { 0, IDS_TIPS_GAMETIP_37}, 6253 { 0, IDS_TIPS_GAMETIP_38}, 6254 { 0, IDS_TIPS_GAMETIP_39}, 6255 { 0, IDS_TIPS_GAMETIP_40}, 6256 { 0, IDS_TIPS_GAMETIP_41}, 6257 { 0, IDS_TIPS_GAMETIP_42}, 6258 { 0, IDS_TIPS_GAMETIP_43}, 6259 { 0, IDS_TIPS_GAMETIP_44}, 6260 { 0, IDS_TIPS_GAMETIP_45}, 6261 { 0, IDS_TIPS_GAMETIP_46}, 6262 { 0, IDS_TIPS_GAMETIP_47}, 6263 { 0, IDS_TIPS_GAMETIP_48}, 6264 { 0, IDS_TIPS_GAMETIP_49}, 6265 { 0, IDS_TIPS_GAMETIP_50}, 6266}; 6267 6268TIPSTRUCT CMinecraftApp::m_TriviaTipA[MAX_TIPS_TRIVIATIP]= 6269{ 6270 { 0, IDS_TIPS_TRIVIA_1}, 6271 { 0, IDS_TIPS_TRIVIA_2}, 6272 { 0, IDS_TIPS_TRIVIA_3}, 6273 { 0, IDS_TIPS_TRIVIA_4}, 6274 { 0, IDS_TIPS_TRIVIA_5}, 6275 { 0, IDS_TIPS_TRIVIA_6}, 6276 { 0, IDS_TIPS_TRIVIA_7}, 6277 { 0, IDS_TIPS_TRIVIA_8}, 6278 { 0, IDS_TIPS_TRIVIA_9}, 6279 { 0, IDS_TIPS_TRIVIA_10}, 6280 { 0, IDS_TIPS_TRIVIA_11}, 6281 { 0, IDS_TIPS_TRIVIA_12}, 6282 { 0, IDS_TIPS_TRIVIA_13}, 6283 { 0, IDS_TIPS_TRIVIA_14}, 6284 { 0, IDS_TIPS_TRIVIA_15}, 6285 { 0, IDS_TIPS_TRIVIA_16}, 6286 { 0, IDS_TIPS_TRIVIA_17}, 6287 { 0, IDS_TIPS_TRIVIA_18}, 6288 { 0, IDS_TIPS_TRIVIA_19}, 6289 { 0, IDS_TIPS_TRIVIA_20}, 6290}; 6291 6292Random *CMinecraftApp::TipRandom = new Random(); 6293 6294int CMinecraftApp::TipsSortFunction(const void* a, const void* b) 6295{ 6296 return ((TIPSTRUCT*)a)->iSortValue - ((TIPSTRUCT*)b)->iSortValue; 6297} 6298 6299void CMinecraftApp::InitialiseTips() 6300{ 6301 // We'll randomise the tips at start up based on their priority 6302 6303 ZeroMemory(m_TipIDA,sizeof(UINT)*MAX_TIPS_GAMETIP+MAX_TIPS_TRIVIATIP); 6304 6305 // Make the first tip tell you that you can play splitscreen in HD modes if you are in SD 6306 if(!RenderManager.IsHiDef()) 6307 { 6308 m_GameTipA[0].uiStringID=IDS_TIPS_GAMETIP_0; 6309 } 6310 // randomise then quicksort 6311 // going to leave the multiplayer tip so it is always first 6312 6313 // Only randomise the content package build 6314#ifdef _CONTENT_PACKAGE 6315 6316 for(int i=1;i<MAX_TIPS_GAMETIP;i++) 6317 { 6318 m_GameTipA[i].iSortValue=TipRandom->nextInt(); 6319 } 6320 qsort( &m_GameTipA[1], MAX_TIPS_GAMETIP-1, sizeof(TIPSTRUCT), TipsSortFunction ); 6321#endif 6322 6323 for(int i=0;i<MAX_TIPS_TRIVIATIP;i++) 6324 { 6325 m_TriviaTipA[i].iSortValue=TipRandom->nextInt(); 6326 } 6327 qsort( m_TriviaTipA, MAX_TIPS_TRIVIATIP, sizeof(TIPSTRUCT), TipsSortFunction ); 6328 6329 6330 int iCurrentGameTip=0; 6331 int iCurrentTriviaTip=0; 6332 6333 for(int i=0;i<MAX_TIPS_GAMETIP+MAX_TIPS_TRIVIATIP;i++) 6334 { 6335 // Add a trivia one every third tip (if there are any left) 6336 if((i%3==2) && (iCurrentTriviaTip<MAX_TIPS_TRIVIATIP)) 6337 { 6338 // Add a trivia one 6339 m_TipIDA[i]=m_TriviaTipA[iCurrentTriviaTip++].uiStringID; 6340 } 6341 else 6342 { 6343 if(iCurrentGameTip<MAX_TIPS_GAMETIP) 6344 { 6345 // Add a gametip 6346 m_TipIDA[i]=m_GameTipA[iCurrentGameTip++].uiStringID; 6347 } 6348 else 6349 { 6350 // Add a trivia one 6351 m_TipIDA[i]=m_TriviaTipA[iCurrentTriviaTip++].uiStringID; 6352 } 6353 } 6354 6355 if(m_TipIDA[i]==0) 6356 { 6357 // the m_TriviaTipA or the m_GameTipA are out of sync 6358#ifndef _CONTENT_PACKAGE 6359 __debugbreak(); 6360#endif 6361 } 6362 } 6363 6364 m_uiCurrentTip=0; 6365} 6366 6367UINT CMinecraftApp::GetNextTip() 6368{ 6369 static bool bShowSkinDLCTip=true; 6370 // don't display the DLC tip in the trial game 6371 if(ProfileManager.IsFullVersion() && app.GetNewDLCAvailable() && app.DisplayNewDLCTip()) 6372 { 6373 return IDS_TIPS_GAMETIP_NEWDLC; 6374 } 6375 else 6376 { 6377 if(bShowSkinDLCTip && ProfileManager.IsFullVersion()) 6378 { 6379 bShowSkinDLCTip=false; 6380 if( app.DLCInstallProcessCompleted() ) 6381 { 6382 if(app.m_dlcManager.getPackCount(DLCManager::e_DLCType_Skin)==0) 6383 { 6384 return IDS_TIPS_GAMETIP_SKINPACKS; 6385 } 6386 } 6387 else 6388 { 6389 return IDS_TIPS_GAMETIP_SKINPACKS; 6390 } 6391 } 6392 } 6393 6394 if(m_uiCurrentTip==MAX_TIPS_GAMETIP+MAX_TIPS_TRIVIATIP) m_uiCurrentTip=0; 6395 6396 return m_TipIDA[m_uiCurrentTip++]; 6397} 6398 6399int CMinecraftApp::GetHTMLColour(eMinecraftColour colour) 6400{ 6401 Minecraft *pMinecraft = Minecraft::GetInstance(); 6402 return pMinecraft->skins->getSelected()->getColourTable()->getColour(colour); 6403} 6404 6405int CMinecraftApp::GetHTMLFontSize(EHTMLFontSize size) 6406{ 6407 return s_iHTMLFontSizesA[size]; 6408} 6409 6410wstring CMinecraftApp::FormatHTMLString(int iPad, const wstring &desc, int shadowColour /*= 0xFFFFFFFF*/) 6411{ 6412 wstring text(desc); 6413 6414 wchar_t replacements[64]; 6415 // We will also insert line breaks here as couldn't figure out how to get them to come through from strings.resx ! 6416 text = replaceAll(text, L"{*B*}", L"<br />" ); 6417 swprintf(replacements,64,L"<font color=\"#%08x\">", GetHTMLColour(eHTMLColor_T1)); 6418 text = replaceAll(text, L"{*T1*}", replacements ); 6419 swprintf(replacements,64,L"<font color=\"#%08x\">", GetHTMLColour(eHTMLColor_T2)); 6420 text = replaceAll(text, L"{*T2*}", replacements ); 6421 swprintf(replacements,64,L"<font color=\"#%08x\">", GetHTMLColour(eHTMLColor_T3)); 6422 text = replaceAll(text, L"{*T3*}", replacements ); // for How To Play 6423 swprintf(replacements,64,L"</font><font color=\"#%08x\">", GetHTMLColour(eHTMLColor_Black)); 6424 text = replaceAll(text, L"{*ETB*}", replacements ); 6425 swprintf(replacements,64,L"</font><font color=\"#%08x\">", GetHTMLColour(eHTMLColor_White)); 6426 text = replaceAll(text, L"{*ETW*}", replacements ); 6427 text = replaceAll(text, L"{*EF*}", L"</font>" ); 6428 6429 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_0), shadowColour); 6430 text = replaceAll(text, L"{*C0*}", replacements ); 6431 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_1), shadowColour); 6432 text = replaceAll(text, L"{*C1*}", replacements ); 6433 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_2), shadowColour); 6434 text = replaceAll(text, L"{*C2*}", replacements ); 6435 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_3), shadowColour); 6436 text = replaceAll(text, L"{*C3*}", replacements ); 6437 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_4), shadowColour); 6438 text = replaceAll(text, L"{*C4*}", replacements ); 6439 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_5), shadowColour); 6440 text = replaceAll(text, L"{*C5*}", replacements ); 6441 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_6), shadowColour); 6442 text = replaceAll(text, L"{*C6*}", replacements ); 6443 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_7), shadowColour); 6444 text = replaceAll(text, L"{*C7*}", replacements ); 6445 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_8), shadowColour); 6446 text = replaceAll(text, L"{*C8*}", replacements ); 6447 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_9), shadowColour); 6448 text = replaceAll(text, L"{*C9*}", replacements ); 6449 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_a), shadowColour); 6450 text = replaceAll(text, L"{*CA*}", replacements ); 6451 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_b), shadowColour); 6452 text = replaceAll(text, L"{*CB*}", replacements ); 6453 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_c), shadowColour); 6454 text = replaceAll(text, L"{*CC*}", replacements ); 6455 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_d), shadowColour); 6456 text = replaceAll(text, L"{*CD*}", replacements ); 6457 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_e), shadowColour); 6458 text = replaceAll(text, L"{*CE*}", replacements ); 6459 swprintf(replacements,64,L"<font color=\"#%08x\" shadowcolor=\"#%08x\">", GetHTMLColour(eHTMLColor_f), shadowColour); 6460 text = replaceAll(text, L"{*CF*}", replacements ); 6461 6462 // Swap for southpaw. 6463 if ( app.GetGameSettings(iPad,eGameSetting_ControlSouthPaw) ) 6464 { 6465 text = replaceAll(text, L"{*CONTROLLER_ACTION_MOVE*}", GetActionReplacement(iPad,MINECRAFT_ACTION_LOOK_RIGHT ) ); 6466 text = replaceAll(text, L"{*CONTROLLER_ACTION_LOOK*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RIGHT ) ); 6467 6468 text = replaceAll(text, L"{*CONTROLLER_MENU_NAVIGATE*}", GetVKReplacement(VK_PAD_RTHUMB_LEFT) ); 6469 } 6470 else // Normal right handed. 6471 { 6472 text = replaceAll(text, L"{*CONTROLLER_ACTION_MOVE*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RIGHT ) ); 6473 text = replaceAll(text, L"{*CONTROLLER_ACTION_LOOK*}", GetActionReplacement(iPad,MINECRAFT_ACTION_LOOK_RIGHT ) ); 6474 6475 text = replaceAll(text, L"{*CONTROLLER_MENU_NAVIGATE*}", GetVKReplacement(VK_PAD_LTHUMB_LEFT) ); 6476 } 6477 6478 text = replaceAll(text, L"{*CONTROLLER_ACTION_JUMP*}", GetActionReplacement(iPad,MINECRAFT_ACTION_JUMP ) ); 6479 text = replaceAll(text, L"{*CONTROLLER_ACTION_SNEAK*}", GetActionReplacement(iPad,MINECRAFT_ACTION_SNEAK_TOGGLE ) ); 6480 text = replaceAll(text, L"{*CONTROLLER_ACTION_USE*}", GetActionReplacement(iPad,MINECRAFT_ACTION_USE ) ); 6481 text = replaceAll(text, L"{*CONTROLLER_ACTION_ACTION*}", GetActionReplacement(iPad,MINECRAFT_ACTION_ACTION ) ); 6482 text = replaceAll(text, L"{*CONTROLLER_ACTION_LEFT_SCROLL*}", GetActionReplacement(iPad,MINECRAFT_ACTION_LEFT_SCROLL ) ); 6483 text = replaceAll(text, L"{*CONTROLLER_ACTION_RIGHT_SCROLL*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RIGHT_SCROLL ) ); 6484 text = replaceAll(text, L"{*CONTROLLER_ACTION_INVENTORY*}", GetActionReplacement(iPad,MINECRAFT_ACTION_INVENTORY ) ); 6485 text = replaceAll(text, L"{*CONTROLLER_ACTION_CRAFTING*}", GetActionReplacement(iPad,MINECRAFT_ACTION_CRAFTING ) ); 6486 text = replaceAll(text, L"{*CONTROLLER_ACTION_DROP*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DROP ) ); 6487 text = replaceAll(text, L"{*CONTROLLER_ACTION_CAMERA*}", GetActionReplacement(iPad,MINECRAFT_ACTION_RENDER_THIRD_PERSON ) ); 6488 text = replaceAll(text, L"{*CONTROLLER_ACTION_MENU_PAGEDOWN*}", GetActionReplacement(iPad,ACTION_MENU_PAGEDOWN ) ); 6489 text = replaceAll(text, L"{*CONTROLLER_ACTION_DISMOUNT*}", GetActionReplacement(iPad,MINECRAFT_ACTION_SNEAK_TOGGLE ) ); 6490 text = replaceAll(text, L"{*CONTROLLER_VK_A*}", GetVKReplacement(VK_PAD_A) ); 6491 text = replaceAll(text, L"{*CONTROLLER_VK_B*}", GetVKReplacement(VK_PAD_B) ); 6492 text = replaceAll(text, L"{*CONTROLLER_VK_X*}", GetVKReplacement(VK_PAD_X) ); 6493 text = replaceAll(text, L"{*CONTROLLER_VK_Y*}", GetVKReplacement(VK_PAD_Y) ); 6494 text = replaceAll(text, L"{*CONTROLLER_VK_LB*}", GetVKReplacement(VK_PAD_LSHOULDER) ); 6495 text = replaceAll(text, L"{*CONTROLLER_VK_RB*}", GetVKReplacement(VK_PAD_RSHOULDER) ); 6496 text = replaceAll(text, L"{*CONTROLLER_VK_LS*}", GetVKReplacement(VK_PAD_LTHUMB_UP) ); 6497 text = replaceAll(text, L"{*CONTROLLER_VK_RS*}", GetVKReplacement(VK_PAD_RTHUMB_UP) ); 6498 text = replaceAll(text, L"{*CONTROLLER_VK_LT*}", GetVKReplacement(VK_PAD_LTRIGGER) ); 6499 text = replaceAll(text, L"{*CONTROLLER_VK_RT*}", GetVKReplacement(VK_PAD_RTRIGGER) ); 6500 text = replaceAll(text, L"{*ICON_SHANK_01*}", GetIconReplacement(XZP_ICON_SHANK_01) ); 6501 text = replaceAll(text, L"{*ICON_SHANK_03*}", GetIconReplacement(XZP_ICON_SHANK_03) ); 6502 text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_UP*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_UP ) ); 6503 text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_DOWN*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_DOWN ) ); 6504 text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_RIGHT*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_RIGHT ) ); 6505 text = replaceAll(text, L"{*CONTROLLER_ACTION_DPAD_LEFT*}", GetActionReplacement(iPad,MINECRAFT_ACTION_DPAD_LEFT ) ); 6506#if defined _XBOX_ONE || defined __PSVITA__ 6507 text = replaceAll(text, L"{*CONTROLLER_VK_START*}", GetVKReplacement(VK_PAD_START ) ); 6508 text = replaceAll(text, L"{*CONTROLLER_VK_BACK*}", GetVKReplacement(VK_PAD_BACK ) ); 6509#endif 6510 6511#ifdef _XBOX 6512 wstring imageRoot = L""; 6513 6514 Minecraft *pMinecraft = Minecraft::GetInstance(); 6515 imageRoot = pMinecraft->skins->getSelected()->getXuiRootPath(); 6516 6517 text = replaceAll(text, L"{*IMAGEROOT*}", imageRoot); 6518#endif // _XBOX 6519 6520 // Fix for #8903 - UI: Localization: KOR/JPN/CHT: Button Icons are rendered with padding space, which looks no good 6521 DWORD dwLanguage = XGetLanguage( ); 6522 switch(dwLanguage) 6523 { 6524 case XC_LANGUAGE_KOREAN: 6525 case XC_LANGUAGE_JAPANESE: 6526 case XC_LANGUAGE_TCHINESE: 6527 text = replaceAll(text, L"&nbsp;", L"" ); 6528 break; 6529 } 6530 6531 return text; 6532} 6533 6534wstring CMinecraftApp::GetActionReplacement(int iPad, unsigned char ucAction) 6535{ 6536 unsigned int input = InputManager.GetGameJoypadMaps(InputManager.GetJoypadMapVal(iPad) ,ucAction); 6537 6538#ifdef _XBOX 6539 switch(input) 6540 { 6541 case _360_JOY_BUTTON_A: 6542 return app.GetString( IDS_CONTROLLER_A ); 6543 case _360_JOY_BUTTON_B: 6544 return app.GetString( IDS_CONTROLLER_B ); 6545 case _360_JOY_BUTTON_X: 6546 return app.GetString( IDS_CONTROLLER_X ); 6547 case _360_JOY_BUTTON_Y: 6548 return app.GetString( IDS_CONTROLLER_Y ); 6549 case _360_JOY_BUTTON_LSTICK_UP: 6550 case _360_JOY_BUTTON_LSTICK_DOWN: 6551 case _360_JOY_BUTTON_LSTICK_LEFT: 6552 case _360_JOY_BUTTON_LSTICK_RIGHT: 6553 return app.GetString( IDS_CONTROLLER_LEFT_STICK ); 6554 case _360_JOY_BUTTON_RSTICK_LEFT: 6555 case _360_JOY_BUTTON_RSTICK_RIGHT: 6556 case _360_JOY_BUTTON_RSTICK_UP: 6557 case _360_JOY_BUTTON_RSTICK_DOWN: 6558 return app.GetString( IDS_CONTROLLER_RIGHT_STICK ); 6559 case _360_JOY_BUTTON_LT: 6560 return app.GetString( IDS_CONTROLLER_LEFT_TRIGGER ); 6561 case _360_JOY_BUTTON_RT: 6562 return app.GetString( IDS_CONTROLLER_RIGHT_TRIGGER ); 6563 case _360_JOY_BUTTON_RB: 6564 return app.GetString( IDS_CONTROLLER_RIGHT_BUMPER ); 6565 case _360_JOY_BUTTON_LB: 6566 return app.GetString( IDS_CONTROLLER_LEFT_BUMPER ); 6567 case _360_JOY_BUTTON_BACK: 6568 return app.GetString( IDS_CONTROLLER_BACK ); 6569 case _360_JOY_BUTTON_START: 6570 return app.GetString( IDS_CONTROLLER_START ); 6571 case _360_JOY_BUTTON_RTHUMB: 6572 return app.GetString( IDS_CONTROLLER_RIGHT_THUMBSTICK ); 6573 case _360_JOY_BUTTON_LTHUMB: 6574 return app.GetString( IDS_CONTROLLER_LEFT_THUMBSTICK ); 6575 case _360_JOY_BUTTON_DPAD_LEFT: 6576 return app.GetString( IDS_CONTROLLER_DPAD_L ); 6577 case _360_JOY_BUTTON_DPAD_RIGHT: 6578 return app.GetString( IDS_CONTROLLER_DPAD_R ); 6579 case _360_JOY_BUTTON_DPAD_UP: 6580 return app.GetString( IDS_CONTROLLER_DPAD_U ); 6581 case _360_JOY_BUTTON_DPAD_DOWN: 6582 return app.GetString( IDS_CONTROLLER_DPAD_D ); 6583 }; 6584 return L""; 6585#else 6586 wstring replacement = L""; 6587 6588 // 4J Stu - Some of our actions can be mapped to multiple physical buttons, so replaces the switch that was here 6589 if (input & _360_JOY_BUTTON_A) replacement = L"ButtonA"; 6590 else if(input &_360_JOY_BUTTON_B) replacement = L"ButtonB"; 6591 else if(input &_360_JOY_BUTTON_X) replacement = L"ButtonX"; 6592 else if(input &_360_JOY_BUTTON_Y) replacement = L"ButtonY"; 6593 else if( 6594 (input &_360_JOY_BUTTON_LSTICK_UP) || 6595 (input &_360_JOY_BUTTON_LSTICK_DOWN) || 6596 (input &_360_JOY_BUTTON_LSTICK_LEFT) || 6597 (input &_360_JOY_BUTTON_LSTICK_RIGHT) 6598 ) 6599 { 6600 replacement = L"ButtonLeftStick"; 6601 } 6602 else if( 6603 (input &_360_JOY_BUTTON_RSTICK_LEFT) || 6604 (input &_360_JOY_BUTTON_RSTICK_RIGHT) || 6605 (input &_360_JOY_BUTTON_RSTICK_UP) || 6606 (input &_360_JOY_BUTTON_RSTICK_DOWN) 6607 ) 6608 { 6609 replacement = L"ButtonRightStick"; 6610 } 6611 else if(input &_360_JOY_BUTTON_DPAD_LEFT) replacement = L"ButtonDpadL"; 6612 else if(input &_360_JOY_BUTTON_DPAD_RIGHT) replacement = L"ButtonDpadR"; 6613 else if(input &_360_JOY_BUTTON_DPAD_UP) replacement = L"ButtonDpadU"; 6614 else if(input &_360_JOY_BUTTON_DPAD_DOWN) replacement = L"ButtonDpadD"; 6615 else if(input &_360_JOY_BUTTON_LT) replacement = L"ButtonLeftTrigger"; 6616 else if(input &_360_JOY_BUTTON_RT) replacement = L"ButtonRightTrigger"; 6617 else if(input &_360_JOY_BUTTON_RB) replacement = L"ButtonRightBumper"; 6618 else if(input &_360_JOY_BUTTON_LB) replacement = L"ButtonLeftBumper"; 6619 else if(input &_360_JOY_BUTTON_BACK) replacement = L"ButtonBack"; 6620 else if(input &_360_JOY_BUTTON_START) replacement = L"ButtonStart"; 6621 else if(input &_360_JOY_BUTTON_RTHUMB) replacement = L"ButtonRS"; 6622 else if(input &_360_JOY_BUTTON_LTHUMB) replacement = L"ButtonLS"; 6623 6624 wchar_t string[128]; 6625 6626#ifdef __PS3__ 6627 int size = 30; 6628#elif defined _WIN64 6629 int size = 45; 6630 if(ui.getScreenHeight() < 1080) size = 30; 6631#else 6632 int size = 45; 6633#endif 6634 6635 swprintf(string,128,L"<img src=\"%ls\" align=\"middle\" height=\"%d\" width=\"%d\"/>", replacement.c_str(), size, size); 6636 6637 return string; 6638#endif 6639} 6640 6641wstring CMinecraftApp::GetVKReplacement(unsigned int uiVKey) 6642{ 6643#ifdef _XBOX 6644 switch(uiVKey) 6645 { 6646 case VK_PAD_A: 6647 return app.GetString( IDS_CONTROLLER_A ); 6648 case VK_PAD_B: 6649 return app.GetString( IDS_CONTROLLER_B ); 6650 case VK_PAD_X: 6651 return app.GetString( IDS_CONTROLLER_X ); 6652 case VK_PAD_Y: 6653 return app.GetString( IDS_CONTROLLER_Y ); 6654 case VK_PAD_LSHOULDER: 6655 return app.GetString( IDS_CONTROLLER_LEFT_BUMPER ); 6656 case VK_PAD_RSHOULDER: 6657 return app.GetString( IDS_CONTROLLER_RIGHT_BUMPER ); 6658 case VK_PAD_LTRIGGER: 6659 return app.GetString( IDS_CONTROLLER_LEFT_TRIGGER ); 6660 case VK_PAD_RTRIGGER: 6661 return app.GetString( IDS_CONTROLLER_RIGHT_TRIGGER ); 6662 case VK_PAD_LTHUMB_UP : 6663 case VK_PAD_LTHUMB_DOWN : 6664 case VK_PAD_LTHUMB_RIGHT : 6665 case VK_PAD_LTHUMB_LEFT : 6666 case VK_PAD_LTHUMB_UPLEFT : 6667 case VK_PAD_LTHUMB_UPRIGHT : 6668 case VK_PAD_LTHUMB_DOWNRIGHT: 6669 case VK_PAD_LTHUMB_DOWNLEFT : 6670 return app.GetString( IDS_CONTROLLER_LEFT_STICK ); 6671 case VK_PAD_RTHUMB_UP : 6672 case VK_PAD_RTHUMB_DOWN : 6673 case VK_PAD_RTHUMB_RIGHT : 6674 case VK_PAD_RTHUMB_LEFT : 6675 case VK_PAD_RTHUMB_UPLEFT : 6676 case VK_PAD_RTHUMB_UPRIGHT : 6677 case VK_PAD_RTHUMB_DOWNRIGHT: 6678 case VK_PAD_RTHUMB_DOWNLEFT : 6679 return app.GetString( IDS_CONTROLLER_RIGHT_STICK ); 6680 default: 6681 break; 6682 } 6683 return NULL; 6684#else 6685 wstring replacement = L""; 6686 switch(uiVKey) 6687 { 6688 case VK_PAD_A: 6689#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) 6690 if( InputManager.IsCircleCrossSwapped() ) replacement = L"ButtonB"; 6691 else replacement = L"ButtonA"; 6692#else 6693 replacement = L"ButtonA"; 6694#endif 6695 break; 6696 case VK_PAD_B: 6697#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) 6698 if( InputManager.IsCircleCrossSwapped() ) replacement = L"ButtonA"; 6699 else replacement = L"ButtonB"; 6700#else 6701 replacement = L"ButtonB"; 6702#endif 6703 break; 6704 case VK_PAD_X: 6705 replacement = L"ButtonX"; 6706 break; 6707 case VK_PAD_Y: 6708 replacement = L"ButtonY"; 6709 break; 6710 case VK_PAD_LSHOULDER: 6711 replacement = L"ButtonLeftBumper"; 6712 break; 6713 case VK_PAD_RSHOULDER: 6714 replacement = L"ButtonRightBumper"; 6715 break; 6716 case VK_PAD_LTRIGGER: 6717 replacement = L"ButtonLeftTrigger"; 6718 break; 6719 case VK_PAD_RTRIGGER: 6720 replacement = L"ButtonRightTrigger"; 6721 break; 6722 case VK_PAD_LTHUMB_UP : 6723 case VK_PAD_LTHUMB_DOWN : 6724 case VK_PAD_LTHUMB_RIGHT : 6725 case VK_PAD_LTHUMB_LEFT : 6726 case VK_PAD_LTHUMB_UPLEFT : 6727 case VK_PAD_LTHUMB_UPRIGHT : 6728 case VK_PAD_LTHUMB_DOWNRIGHT: 6729 case VK_PAD_LTHUMB_DOWNLEFT : 6730 replacement = L"ButtonLeftStick"; 6731 break; 6732 case VK_PAD_RTHUMB_UP : 6733 case VK_PAD_RTHUMB_DOWN : 6734 case VK_PAD_RTHUMB_RIGHT : 6735 case VK_PAD_RTHUMB_LEFT : 6736 case VK_PAD_RTHUMB_UPLEFT : 6737 case VK_PAD_RTHUMB_UPRIGHT : 6738 case VK_PAD_RTHUMB_DOWNRIGHT: 6739 case VK_PAD_RTHUMB_DOWNLEFT : 6740 replacement = L"ButtonRightStick"; 6741 break; 6742#if defined _XBOX_ONE || defined __PSVITA__ 6743 case VK_PAD_START: 6744 replacement = L"ButtonStart"; 6745 break; 6746 case VK_PAD_BACK: 6747 replacement = L"ButtonBack"; 6748 break; 6749#endif 6750 default: 6751 break; 6752 } 6753 wchar_t string[128]; 6754 6755#ifdef __PS3__ 6756 int size = 30; 6757#elif defined _WIN64 6758 int size = 45; 6759 if(ui.getScreenHeight() < 1080) size = 30; 6760#else 6761 int size = 45; 6762#endif 6763 6764 swprintf(string,128,L"<img src=\"%ls\" align=\"middle\" height=\"%d\" width=\"%d\"/>", replacement.c_str(), size, size); 6765 6766 return string; 6767#endif 6768} 6769 6770wstring CMinecraftApp::GetIconReplacement(unsigned int uiIcon) 6771{ 6772#ifdef _XBOX 6773 switch(uiIcon) 6774 { 6775 case XZP_ICON_SHANK_01: 6776 return app.GetString( IDS_ICON_SHANK_01 ); 6777 case XZP_ICON_SHANK_03: 6778 return app.GetString( IDS_ICON_SHANK_03 ); 6779 default: 6780 break; 6781 } 6782 return NULL; 6783#else 6784 wchar_t string[128]; 6785 6786#ifdef __PS3__ 6787 int size = 22; 6788#elif defined _WIN64 6789 int size = 33; 6790 if(ui.getScreenHeight() < 1080) size = 22; 6791#else 6792 int size = 33; 6793#endif 6794 6795 swprintf(string,128,L"<img src=\"Icon_Shank\" align=\"middle\" height=\"%d\" width=\"%d\"/>", size, size); 6796 wstring result = L""; 6797 switch(uiIcon) 6798 { 6799 case XZP_ICON_SHANK_01: 6800 result = string; 6801 break; 6802 case XZP_ICON_SHANK_03: 6803 result.append(string).append(string).append(string); 6804 break; 6805 default: 6806 break; 6807 } 6808 return result; 6809#endif 6810} 6811 6812#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) 6813unordered_map<PlayerUID, MOJANG_DATA *, PlayerUID::Hash> CMinecraftApp::MojangData; 6814unordered_map<int, char * > CMinecraftApp::DLCTextures_PackID; 6815unordered_map<string, DLC_INFO * > CMinecraftApp::DLCInfo; 6816unordered_map<wstring, ULONGLONG > CMinecraftApp::DLCInfo_SkinName; 6817#elif defined(_DURANGO) 6818unordered_map<PlayerUID,MOJANG_DATA *, PlayerUID::Hash > CMinecraftApp::MojangData; 6819unordered_map<int, wstring > CMinecraftApp::DLCTextures_PackID; // for mash-up packs & texture packs 6820//unordered_map<ULONGLONG,DLC_INFO * > CMinecraftApp::DLCInfo_Trial; // full offerid, dlc_info 6821unordered_map<wstring,DLC_INFO * > CMinecraftApp::DLCInfo_Full; // full offerid, dlc_info 6822unordered_map<wstring, wstring > CMinecraftApp::DLCInfo_SkinName; // skin name, full offer id 6823#else 6824unordered_map<PlayerUID, MOJANG_DATA *> CMinecraftApp::MojangData; 6825unordered_map<int, ULONGLONG > CMinecraftApp::DLCTextures_PackID; 6826unordered_map<ULONGLONG, DLC_INFO * > CMinecraftApp::DLCInfo_Trial; 6827unordered_map<ULONGLONG, DLC_INFO * > CMinecraftApp::DLCInfo_Full; 6828unordered_map<wstring, ULONGLONG > CMinecraftApp::DLCInfo_SkinName; 6829#endif 6830 6831 6832 6833HRESULT CMinecraftApp::RegisterMojangData(WCHAR *pXuidName, PlayerUID xuid, WCHAR *pSkin, WCHAR *pCape) 6834{ 6835 HRESULT hr=S_OK; 6836 eXUID eTempXuid=eXUID_Undefined; 6837 MOJANG_DATA *pMojangData=NULL; 6838 6839 // ignore the names if we don't recognize them 6840 if(pXuidName!=NULL) 6841 { 6842 if( wcscmp( pXuidName, L"XUID_NOTCH" ) == 0 ) 6843 { 6844 eTempXuid = eXUID_Notch; // might be needed for the apple at some point 6845 } 6846 else if( wcscmp( pXuidName, L"XUID_DEADMAU5" ) == 0 ) 6847 { 6848 eTempXuid = eXUID_Deadmau5; // Needed for the deadmau5 ears 6849 } 6850 else 6851 { 6852 eTempXuid=eXUID_NoName; 6853 } 6854 } 6855 6856 if(eTempXuid!=eXUID_Undefined) 6857 { 6858 pMojangData = new MOJANG_DATA; 6859 ZeroMemory(pMojangData,sizeof(MOJANG_DATA)); 6860 pMojangData->eXuid=eTempXuid; 6861 6862 wcsncpy( pMojangData->wchSkin, pSkin, MAX_CAPENAME_SIZE); 6863 wcsncpy( pMojangData->wchCape, pCape, MAX_CAPENAME_SIZE); 6864 MojangData[xuid]=pMojangData; 6865 } 6866 6867 return hr; 6868} 6869 6870MOJANG_DATA *CMinecraftApp::GetMojangDataForXuid(PlayerUID xuid) 6871{ 6872 return MojangData[xuid]; 6873} 6874 6875HRESULT CMinecraftApp::RegisterConfigValues(WCHAR *pType, int iValue) 6876{ 6877 HRESULT hr=S_OK; 6878 6879 // #ifdef _XBOX 6880 // if(pType!=NULL) 6881 // { 6882 // if(wcscmp(pType,L"XboxOneTransfer")==0) 6883 // { 6884 // if(iValue>0) 6885 // { 6886 // app.m_bTransferSavesToXboxOne=true; 6887 // } 6888 // else 6889 // { 6890 // app.m_bTransferSavesToXboxOne=false; 6891 // } 6892 // } 6893 // else if(wcscmp(pType,L"TransferSlotCount")==0) 6894 // { 6895 // app.m_uiTransferSlotC=iValue; 6896 // } 6897 // 6898 // } 6899 // #endif 6900 6901 6902 return hr; 6903} 6904 6905#if (defined _XBOX || defined _WINDOWS64) 6906HRESULT CMinecraftApp::RegisterDLCData(WCHAR *pType, WCHAR *pBannerName, int iGender, __uint64 ullOfferID_Full, __uint64 ullOfferID_Trial, WCHAR *pFirstSkin, unsigned int uiSortIndex, int iConfig, WCHAR *pDataFile) 6907{ 6908 HRESULT hr=S_OK; 6909 DLC_INFO *pDLCData=new DLC_INFO; 6910 ZeroMemory(pDLCData,sizeof(DLC_INFO)); 6911 pDLCData->ullOfferID_Full=ullOfferID_Full; 6912 pDLCData->ullOfferID_Trial=ullOfferID_Trial; 6913 pDLCData->eDLCType=e_DLC_NotDefined; 6914 pDLCData->iGender=iGender; 6915 pDLCData->uiSortIndex=uiSortIndex; 6916 pDLCData->iConfig=iConfig; 6917 6918#ifndef __ORBIS__ 6919 // ignore the names if we don't recognize them 6920 if(pBannerName!=L"") 6921 { 6922 wcsncpy_s( pDLCData->wchBanner, pBannerName, MAX_BANNERNAME_SIZE); 6923 } 6924 6925 if(pDataFile[0]!=0) 6926 { 6927 wcsncpy_s( pDLCData->wchDataFile, pDataFile, MAX_BANNERNAME_SIZE); 6928 } 6929#endif 6930 6931 if(pType!=NULL) 6932 { 6933 if(wcscmp(pType,L"Skin")==0) 6934 { 6935 pDLCData->eDLCType=e_DLC_SkinPack; 6936 } 6937 else if(wcscmp(pType,L"Gamerpic")==0) 6938 { 6939 pDLCData->eDLCType=e_DLC_Gamerpics; 6940 } 6941 else if(wcscmp(pType,L"Theme")==0) 6942 { 6943 pDLCData->eDLCType=e_DLC_Themes; 6944 } 6945 else if(wcscmp(pType,L"Avatar")==0) 6946 { 6947 pDLCData->eDLCType=e_DLC_AvatarItems; 6948 } 6949 else if(wcscmp(pType,L"MashUpPack")==0) 6950 { 6951 pDLCData->eDLCType=e_DLC_MashupPacks; 6952 DLCTextures_PackID[pDLCData->iConfig]=ullOfferID_Full; 6953 } 6954 else if(wcscmp(pType,L"TexturePack")==0) 6955 { 6956 pDLCData->eDLCType=e_DLC_TexturePacks; 6957 DLCTextures_PackID[pDLCData->iConfig]=ullOfferID_Full; 6958 } 6959 6960 6961 } 6962 6963 if(ullOfferID_Trial!=0ll) DLCInfo_Trial[ullOfferID_Trial]=pDLCData; 6964 if(ullOfferID_Full!=0ll) DLCInfo_Full[ullOfferID_Full]=pDLCData; 6965 if(pFirstSkin[0]!=0) DLCInfo_SkinName[pFirstSkin]=ullOfferID_Full; 6966 6967 return hr; 6968} 6969#elif defined _XBOX_ONE 6970 6971unordered_map<wstring,DLC_INFO * > *CMinecraftApp::GetDLCInfo() 6972{ 6973 return &DLCInfo_Full; 6974} 6975 6976HRESULT CMinecraftApp::RegisterDLCData(eDLCContentType eType, WCHAR *pwchBannerName,WCHAR *pwchProductId, WCHAR *pwchProductName, WCHAR *pwchFirstSkin, int iConfig, unsigned int uiSortIndex) 6977{ 6978 HRESULT hr=S_OK; 6979 // 4J-PB - need to convert the product id to uppercase because the catalog calls come back with upper case 6980 WCHAR wchUppercaseProductID[64]; 6981 if(pwchProductId[0]!=0) 6982 { 6983 for(int i=0;i<64;i++) 6984 { 6985 wchUppercaseProductID[i]=towupper((wchar_t)pwchProductId[i]); 6986 } 6987 } 6988 6989 // check if we already have this info from the local DLC file 6990 wstring wsTemp=wchUppercaseProductID; 6991 6992 AUTO_VAR(it, DLCInfo_Full.find(wsTemp)); 6993 if( it == DLCInfo_Full.end() ) 6994 { 6995 // Not found 6996 6997 DLC_INFO *pDLCData=new DLC_INFO; 6998 ZeroMemory(pDLCData,sizeof(DLC_INFO)); 6999 7000 pDLCData->eDLCType=e_DLC_NotDefined; 7001 pDLCData->uiSortIndex=uiSortIndex; 7002 pDLCData->iConfig=iConfig; 7003 7004 if(pwchProductId[0]!=0) 7005 { 7006 pDLCData->wsProductId=wchUppercaseProductID; 7007 } 7008 7009 // ignore the names if we don't recognize them 7010 if(pwchBannerName!=L"") 7011 { 7012 wcsncpy_s( pDLCData->wchBanner, pwchBannerName, MAX_BANNERNAME_SIZE); 7013 } 7014 7015 if(pwchProductName[0]!=0) 7016 { 7017 pDLCData->wsDisplayName=pwchProductName; 7018 } 7019 7020 pDLCData->eDLCType=eType; 7021 7022 switch(eType) 7023 { 7024 case e_DLC_MashupPacks: 7025 case e_DLC_TexturePacks: 7026 DLCTextures_PackID[iConfig]=pDLCData->wsProductId; 7027 break; 7028 } 7029 7030 if(pwchFirstSkin[0]!=0) DLCInfo_SkinName[pwchFirstSkin]=pDLCData->wsProductId; 7031 7032#ifdef _XBOX_ONE 7033 // ignore the names, and use the product id instead 7034 DLCInfo_Full[pDLCData->wsProductId]=pDLCData; 7035#else 7036 DLCInfo_Full[pDLCData->wsDisplayName]=pDLCData; 7037#endif 7038 } 7039 app.DebugPrintf("DLCInfo - type - %d, productID - %ls, name - %ls , banner - %ls, iconfig - %d, sort index - %d\n",eType,pwchProductId, pwchProductName,pwchBannerName, iConfig, uiSortIndex); 7040 return hr; 7041} 7042#else 7043 7044HRESULT CMinecraftApp::RegisterDLCData(char *pchDLCName, unsigned int uiSortIndex,char *pchImageURL) 7045{ 7046 // on PS3 we get all the required info from the name 7047 char chDLCType[3]; 7048 HRESULT hr=S_OK; 7049 DLC_INFO *pDLCData=new DLC_INFO; 7050 ZeroMemory(pDLCData,sizeof(DLC_INFO)); 7051 7052 chDLCType[0]=pchDLCName[0]; 7053 chDLCType[1]=pchDLCName[1]; 7054 chDLCType[2]=0; 7055 7056 pDLCData->iConfig = app.GetiConfigFromName(pchDLCName); 7057 pDLCData->uiSortIndex=uiSortIndex; 7058 pDLCData->eDLCType = app.GetDLCTypeFromName(pchDLCName); 7059 strcpy(pDLCData->chImageURL,pchImageURL); 7060 //bool bIsTrialDLC = app.GetTrialFromName(pchDLCName); 7061 7062 switch(pDLCData->eDLCType) 7063 { 7064 case e_DLC_TexturePacks: 7065 { 7066 char *pchName=(char *)malloc(strlen(pchDLCName)+1); 7067 strcpy(pchName,pchDLCName); 7068 DLCTextures_PackID[pDLCData->iConfig]=pchName; 7069 } 7070 break; 7071 case e_DLC_MashupPacks: 7072 { 7073 char *pchName=(char *)malloc(strlen(pchDLCName)+1); 7074 strcpy(pchName,pchDLCName); 7075 DLCTextures_PackID[pDLCData->iConfig]=pchName; 7076 } 7077 break; 7078 default: 7079 break; 7080 } 7081 7082 app.DebugPrintf(5,"Adding DLC - %s\n",pchDLCName); 7083 DLCInfo[pchDLCName]=pDLCData; 7084 7085 // if(ullOfferID_Trial!=0ll) DLCInfo_Trial[ullOfferID_Trial]=pDLCData; 7086 // if(ullOfferID_Full!=0ll) DLCInfo_Full[ullOfferID_Full]=pDLCData; 7087 // if(pFirstSkin[0]!=0) DLCInfo_SkinName[pFirstSkin]=ullOfferID_Full; 7088 7089 // DLCInfo[ullOfferID_Trial]=pDLCData; 7090 7091 return hr; 7092} 7093#endif 7094 7095 7096 7097#if defined( __PS3__) || defined(__ORBIS__) || defined(__PSVITA__) 7098bool CMinecraftApp::GetDLCFullOfferIDForSkinID(const wstring &FirstSkin,ULONGLONG *pullVal) 7099{ 7100 AUTO_VAR(it, DLCInfo_SkinName.find(FirstSkin)); 7101 if( it == DLCInfo_SkinName.end() ) 7102 { 7103 return false; 7104 } 7105 else 7106 { 7107 *pullVal=(ULONGLONG)it->second; 7108 return true; 7109 } 7110} 7111bool CMinecraftApp::GetDLCNameForPackID(const int iPackID,char **ppchKeyID) 7112{ 7113 AUTO_VAR(it, DLCTextures_PackID.find(iPackID)); 7114 if( it == DLCTextures_PackID.end() ) 7115 { 7116 *ppchKeyID=NULL; 7117 return false; 7118 } 7119 else 7120 { 7121 *ppchKeyID=(char *)it->second; 7122 return true; 7123 } 7124} 7125DLC_INFO *CMinecraftApp::GetDLCInfo(char *pchDLCName) 7126{ 7127 string tempString=pchDLCName; 7128 7129 if(DLCInfo.size()>0) 7130 { 7131 AUTO_VAR(it, DLCInfo.find(tempString)); 7132 7133 if( it == DLCInfo.end() ) 7134 { 7135 // nothing for this 7136 return NULL; 7137 } 7138 else 7139 { 7140 return it->second; 7141 } 7142 } 7143 else return NULL; 7144} 7145 7146DLC_INFO *CMinecraftApp::GetDLCInfoFromTPackID(int iTPID) 7147{ 7148 unordered_map<string, DLC_INFO *>::iterator it= DLCInfo.begin(); 7149 7150 for(int i=0;i<DLCInfo.size();i++) 7151 { 7152 if(((DLC_INFO *)it->second)->iConfig==iTPID) 7153 { 7154 return it->second; 7155 } 7156 ++it; 7157 } 7158 return NULL; 7159} 7160 7161DLC_INFO *CMinecraftApp::GetDLCInfo(int iIndex) 7162{ 7163 unordered_map<string, DLC_INFO *>::iterator it= DLCInfo.begin(); 7164 7165 for(int i=0;i<iIndex;i++) 7166 { 7167 ++it; 7168 } 7169 7170 return it->second; 7171} 7172 7173char *CMinecraftApp::GetDLCInfoTextures(int iIndex) 7174{ 7175 unordered_map<int, char * >::iterator it= DLCTextures_PackID.begin(); 7176 7177 for(int i=0;i<iIndex;i++) 7178 { 7179 ++it; 7180 } 7181 7182 return it->second; 7183} 7184 7185#elif defined _XBOX_ONE 7186bool CMinecraftApp::GetDLCFullOfferIDForSkinID(const wstring &FirstSkin,wstring &ProductId) 7187{ 7188 AUTO_VAR(it, DLCInfo_SkinName.find(FirstSkin)); 7189 if( it == DLCInfo_SkinName.end() ) 7190 { 7191 return false; 7192 } 7193 else 7194 { 7195 ProductId=it->second; 7196 return true; 7197 } 7198} 7199bool CMinecraftApp::GetDLCFullOfferIDForPackID(const int iPackID,wstring &ProductId) 7200{ 7201 AUTO_VAR(it, DLCTextures_PackID.find(iPackID)); 7202 if( it == DLCTextures_PackID.end() ) 7203 { 7204 return false; 7205 } 7206 else 7207 { 7208 ProductId=it->second; 7209 return true; 7210 } 7211} 7212// DLC_INFO *CMinecraftApp::GetDLCInfoForTrialOfferID(wstring &ProductId) 7213// { 7214// return NULL; 7215// } 7216 7217DLC_INFO *CMinecraftApp::GetDLCInfoTrialOffer(int iIndex) 7218{ 7219 return NULL; 7220} 7221DLC_INFO *CMinecraftApp::GetDLCInfoFullOffer(int iIndex) 7222{ 7223 unordered_map<wstring, DLC_INFO *>::iterator it= DLCInfo_Full.begin(); 7224 7225 for(int i=0;i<iIndex;i++) 7226 { 7227 ++it; 7228 } 7229 7230 return it->second; 7231} 7232wstring CMinecraftApp::GetDLCInfoTexturesFullOffer(int iIndex) 7233{ 7234 unordered_map<int, wstring >::iterator it= DLCTextures_PackID.begin(); 7235 7236 for(int i=0;i<iIndex;i++) 7237 { 7238 ++it; 7239 } 7240 7241 return it->second; 7242} 7243#else 7244bool CMinecraftApp::GetDLCFullOfferIDForSkinID(const wstring &FirstSkin,ULONGLONG *pullVal) 7245{ 7246 AUTO_VAR(it, DLCInfo_SkinName.find(FirstSkin)); 7247 if( it == DLCInfo_SkinName.end() ) 7248 { 7249 return false; 7250 } 7251 else 7252 { 7253 *pullVal=(ULONGLONG)it->second; 7254 return true; 7255 } 7256} 7257bool CMinecraftApp::GetDLCFullOfferIDForPackID(const int iPackID,ULONGLONG *pullVal) 7258{ 7259 AUTO_VAR(it, DLCTextures_PackID.find(iPackID)); 7260 if( it == DLCTextures_PackID.end() ) 7261 { 7262 *pullVal=(ULONGLONG)0; 7263 return false; 7264 } 7265 else 7266 { 7267 *pullVal=(ULONGLONG)it->second; 7268 return true; 7269 } 7270} 7271DLC_INFO *CMinecraftApp::GetDLCInfoForTrialOfferID(ULONGLONG ullOfferID_Trial) 7272{ 7273 //DLC_INFO *pDLCInfo=NULL; 7274 if(DLCInfo_Trial.size()>0) 7275 { 7276 AUTO_VAR(it, DLCInfo_Trial.find(ullOfferID_Trial)); 7277 7278 if( it == DLCInfo_Trial.end() ) 7279 { 7280 // nothing for this 7281 return NULL; 7282 } 7283 else 7284 { 7285 return it->second; 7286 } 7287 } 7288 else return NULL; 7289} 7290 7291DLC_INFO *CMinecraftApp::GetDLCInfoTrialOffer(int iIndex) 7292{ 7293 unordered_map<ULONGLONG, DLC_INFO *>::iterator it= DLCInfo_Trial.begin(); 7294 7295 for(int i=0;i<iIndex;i++) 7296 { 7297 ++it; 7298 } 7299 7300 return it->second; 7301} 7302DLC_INFO *CMinecraftApp::GetDLCInfoFullOffer(int iIndex) 7303{ 7304 unordered_map<ULONGLONG, DLC_INFO *>::iterator it= DLCInfo_Full.begin(); 7305 7306 for(int i=0;i<iIndex;i++) 7307 { 7308 ++it; 7309 } 7310 7311 return it->second; 7312} 7313ULONGLONG CMinecraftApp::GetDLCInfoTexturesFullOffer(int iIndex) 7314{ 7315 unordered_map<int, ULONGLONG >::iterator it= DLCTextures_PackID.begin(); 7316 7317 for(int i=0;i<iIndex;i++) 7318 { 7319 ++it; 7320 } 7321 7322 return it->second; 7323} 7324#endif 7325 7326#ifdef _XBOX_ONE 7327 7328DLC_INFO *CMinecraftApp::GetDLCInfoForFullOfferID(WCHAR *pwchProductID) 7329{ 7330 wstring wsTemp = pwchProductID; 7331 if(DLCInfo_Full.size()>0) 7332 { 7333 AUTO_VAR(it, DLCInfo_Full.find(wsTemp)); 7334 7335 if( it == DLCInfo_Full.end() ) 7336 { 7337 // nothing for this 7338 return NULL; 7339 } 7340 else 7341 { 7342 return it->second; 7343 } 7344 } 7345 else return NULL; 7346} 7347DLC_INFO *CMinecraftApp::GetDLCInfoForProductName(WCHAR *pwchProductName) 7348{ 7349 unordered_map<wstring, DLC_INFO *>::iterator it= DLCInfo_Full.begin(); 7350 wstring wsProductName=pwchProductName; 7351 7352 for(int i=0;i<DLCInfo_Full.size();i++) 7353 { 7354 DLC_INFO *pDLCInfo=(DLC_INFO *)it->second; 7355 if(wsProductName==pDLCInfo->wsDisplayName) 7356 { 7357 return pDLCInfo; 7358 } 7359 ++it; 7360 } 7361 7362 return NULL; 7363} 7364 7365#elif defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) 7366#else 7367 7368DLC_INFO *CMinecraftApp::GetDLCInfoForFullOfferID(ULONGLONG ullOfferID_Full) 7369{ 7370 7371 if(DLCInfo_Full.size()>0) 7372 { 7373 AUTO_VAR(it, DLCInfo_Full.find(ullOfferID_Full)); 7374 7375 if( it == DLCInfo_Full.end() ) 7376 { 7377 // nothing for this 7378 return NULL; 7379 } 7380 else 7381 { 7382 return it->second; 7383 } 7384 } 7385 else return NULL; 7386} 7387#endif 7388 7389void CMinecraftApp::EnterSaveNotificationSection() 7390{ 7391 EnterCriticalSection(&m_saveNotificationCriticalSection); 7392 if( m_saveNotificationDepth++ == 0 ) 7393 { 7394 if(g_NetworkManager.IsInSession()) // this can be triggered from the front end if we're downloading a save 7395 { 7396 MinecraftServer::getInstance()->broadcastStartSavingPacket(); 7397 7398 if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) 7399 { 7400 app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)TRUE); 7401 } 7402 } 7403 } 7404 LeaveCriticalSection(&m_saveNotificationCriticalSection); 7405} 7406 7407void CMinecraftApp::LeaveSaveNotificationSection() 7408{ 7409 EnterCriticalSection(&m_saveNotificationCriticalSection); 7410 if( --m_saveNotificationDepth == 0 ) 7411 { 7412 if(g_NetworkManager.IsInSession()) // this can be triggered from the front end if we're downloading a save 7413 { 7414 MinecraftServer::getInstance()->broadcastStopSavingPacket(); 7415 7416 if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) 7417 { 7418 app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE); 7419 } 7420 } 7421 } 7422 LeaveCriticalSection(&m_saveNotificationCriticalSection); 7423} 7424 7425 7426int CMinecraftApp::RemoteSaveThreadProc( void* lpParameter ) 7427{ 7428 // The game should be stopped while we are doing this, but the connections ticks may try to create some AABB's or Vec3's 7429 AABB::UseDefaultThreadStorage(); 7430 Vec3::UseDefaultThreadStorage(); 7431 Compression::UseDefaultThreadStorage(); 7432 7433 // 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 7434 // callstack - > if(tls->tileId != this->id) updateDefaultShape(); 7435 // callstack - > default.exe!WaterlilyTile::getAABB(Level * level, int x, int y, int z) line 38 + 8 bytes C++ 7436 // ... 7437 // default.exe!CMinecraftApp::RemoteSaveThreadProc(void * lpParameter) line 6694 C++ 7438 // 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 7439 Tile::CreateNewThreadStorage(); 7440 7441 Minecraft *pMinecraft = Minecraft::GetInstance(); 7442 7443 pMinecraft->progressRenderer->progressStartNoAbort( IDS_PROGRESS_HOST_SAVING ); 7444 pMinecraft->progressRenderer->progressStage( -1 ); 7445 pMinecraft->progressRenderer->progressStagePercentage(0); 7446 7447 while( !app.GetGameStarted() && app.GetXuiAction( ProfileManager.GetPrimaryPad() ) == eAppAction_WaitRemoteServerSaveComplete ) 7448 { 7449 // Tick all the games connections 7450 pMinecraft->tickAllConnections(); 7451 Sleep( 100 ); 7452 } 7453 7454 if( app.GetXuiAction( ProfileManager.GetPrimaryPad() ) != eAppAction_WaitRemoteServerSaveComplete ) 7455 { 7456 // Something cancelled us? 7457 return ERROR_CANCELLED; 7458 } 7459 app.SetAction(ProfileManager.GetPrimaryPad(),eAppAction_Idle); 7460 7461 ui.UpdatePlayerBasePositions(); 7462 7463 Tile::ReleaseThreadStorage(); 7464 7465 return S_OK; 7466} 7467 7468void CMinecraftApp::ExitGameFromRemoteSave( LPVOID lpParameter ) 7469{ 7470 int primaryPad = ProfileManager.GetPrimaryPad(); 7471 7472 UINT uiIDA[3]; 7473 uiIDA[0]=IDS_CONFIRM_CANCEL; 7474 uiIDA[1]=IDS_CONFIRM_OK; 7475 7476 ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 2, primaryPad,&CMinecraftApp::ExitGameFromRemoteSaveDialogReturned,NULL); 7477} 7478 7479int CMinecraftApp::ExitGameFromRemoteSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 7480{ 7481 //CScene_Pause* pClass = (CScene_Pause*)pParam; 7482 7483 // results switched for this dialog 7484 if(result==C4JStorage::EMessage_ResultDecline) 7485 { 7486 app.SetAction(iPad,eAppAction_ExitWorld); 7487 } 7488 else 7489 { 7490#ifndef _XBOX 7491 // Inform fullscreen progress scene that it's not being cancelled after all 7492 UIScene_FullscreenProgress *pScene = (UIScene_FullscreenProgress *)ui.FindScene(eUIScene_FullscreenProgress); 7493#ifdef __PS3__ 7494 if(pScene!=NULL) 7495#else 7496 if (pScene != nullptr) 7497#endif 7498 { 7499 pScene->SetWasCancelled(false); 7500 } 7501#else 7502 // Don't have to worry about this on Xbox 7503#endif 7504 } 7505 return 0; 7506} 7507 7508void CMinecraftApp::SetSpecialTutorialCompletionFlag(int iPad, int index) 7509{ 7510 if(index >= 0 && index < 32 && GameSettingsA[iPad] != NULL) 7511 { 7512 GameSettingsA[iPad]->uiSpecialTutorialBitmask |= (1<<index); 7513 } 7514} 7515 7516// BANNED LIST FUNCTIONS 7517 7518void CMinecraftApp::SetUniqueMapName(char *pszUniqueMapName) 7519{ 7520 memcpy(m_pszUniqueMapName,pszUniqueMapName,14); 7521} 7522 7523char *CMinecraftApp::GetUniqueMapName(void) 7524{ 7525 return m_pszUniqueMapName; 7526} 7527 7528void CMinecraftApp::InvalidateBannedList(int iPad) 7529{ 7530 if(m_bRead_BannedListA[iPad]==true) 7531 { 7532 m_bRead_BannedListA[iPad]=false; 7533 SetBanListCheck(iPad,false); 7534 m_vBannedListA[iPad]->clear(); 7535 7536 if(BannedListA[iPad].pBannedList) 7537 { 7538 delete [] BannedListA[iPad].pBannedList; 7539 BannedListA[iPad].pBannedList=NULL; 7540 } 7541 } 7542} 7543 7544#ifdef _XBOX_ONE 7545void CMinecraftApp::AddLevelToBannedLevelList(int iPad, PBANNEDLISTDATA pBannedListData, bool bWriteToTMS) 7546{ 7547 PlayerUID xuid= pBannedListData->wchPlayerUID; 7548 7549 AddLevelToBannedLevelList(iPad,xuid,pBannedListData->pszLevelName,bWriteToTMS); 7550} 7551#endif 7552 7553void CMinecraftApp::AddLevelToBannedLevelList(int iPad, PlayerUID xuid, char *pszLevelName, bool bWriteToTMS) 7554{ 7555 // we will have retrieved the banned level list from TMS, so add this one to it and write it back to TMS 7556 7557 BANNEDLISTDATA *pBannedListData = new BANNEDLISTDATA; 7558 memset(pBannedListData,0,sizeof(BANNEDLISTDATA)); 7559 7560#ifdef _DURANGO 7561 memcpy(&pBannedListData->wchPlayerUID, xuid.toString().c_str(), sizeof(WCHAR)*64); 7562#else 7563 memcpy(&pBannedListData->xuid, &xuid, sizeof(PlayerUID)); 7564#endif 7565 strcpy(pBannedListData->pszLevelName,pszLevelName); 7566 m_vBannedListA[iPad]->push_back(pBannedListData); 7567 7568 if(bWriteToTMS) 7569 { 7570 DWORD dwDataBytes=(DWORD)(sizeof(BANNEDLISTDATA)*m_vBannedListA[iPad]->size()); 7571 PBANNEDLISTDATA pBannedList = (BANNEDLISTDATA *)(new CHAR [dwDataBytes]); 7572 int iCount=0; 7573 for(AUTO_VAR(it, m_vBannedListA[iPad]->begin()); it != m_vBannedListA[iPad]->end(); ++it) 7574 { 7575 PBANNEDLISTDATA pData=*it; 7576 memcpy(&pBannedList[iCount++],pData,sizeof(BANNEDLISTDATA)); 7577 } 7578 7579 // 4J-PB - write to TMS++ now 7580 7581 //bool bRes=StorageManager.WriteTMSFile(iPad,C4JStorage::eGlobalStorage_TitleUser,L"BannedList",(PBYTE)pBannedList, dwDataBytes); 7582#ifdef _XBOX 7583 StorageManager.TMSPP_WriteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,C4JStorage::TMS_UGCTYPE_NONE,"BannedList",(PCHAR) pBannedList, dwDataBytes,NULL,NULL, 0); 7584#elif defined _XBOX_ONE 7585 StorageManager.TMSPP_WriteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"BannedList",(PBYTE) pBannedList, dwDataBytes,NULL,NULL, 0); 7586#endif 7587 } 7588 // update telemetry too 7589} 7590 7591bool CMinecraftApp::IsInBannedLevelList(int iPad, PlayerUID xuid, char *pszLevelName) 7592{ 7593 for(AUTO_VAR(it, m_vBannedListA[iPad]->begin()); it != m_vBannedListA[iPad]->end(); ++it) 7594 { 7595 PBANNEDLISTDATA pData=*it; 7596#ifdef _XBOX_ONE 7597 PlayerUID bannedPlayerUID = pData->wchPlayerUID; 7598 if(IsEqualXUID (bannedPlayerUID,xuid) && (strcmp(pData->pszLevelName,pszLevelName)==0)) 7599#else 7600 if(IsEqualXUID (pData->xuid,xuid) && (strcmp(pData->pszLevelName,pszLevelName)==0)) 7601#endif 7602 { 7603 return true; 7604 } 7605 } 7606 7607 return false; 7608} 7609 7610void CMinecraftApp::RemoveLevelFromBannedLevelList(int iPad, PlayerUID xuid, char *pszLevelName) 7611{ 7612 //bool bFound=false; 7613 //bool bRes; 7614 7615 // we will have retrieved the banned level list from TMS, so remove this one from it and write it back to TMS 7616 for(AUTO_VAR(it, m_vBannedListA[iPad]->begin()); it != m_vBannedListA[iPad]->end(); ) 7617 { 7618 PBANNEDLISTDATA pBannedListData = *it; 7619 7620 if(pBannedListData!=NULL) 7621 { 7622#ifdef _XBOX_ONE 7623 PlayerUID bannedPlayerUID = pBannedListData->wchPlayerUID; 7624 if(IsEqualXUID (bannedPlayerUID,xuid) && (strcmp(pBannedListData->pszLevelName,pszLevelName)==0)) 7625#else 7626 if(IsEqualXUID (pBannedListData->xuid,xuid) && (strcmp(pBannedListData->pszLevelName,pszLevelName)==0)) 7627#endif 7628 { 7629 TelemetryManager->RecordUnBanLevel(iPad); 7630 7631 // match found, so remove this entry 7632 it = m_vBannedListA[iPad]->erase(it); 7633 } 7634 else 7635 { 7636 ++it; 7637 } 7638 } 7639 else 7640 { 7641 ++it; 7642 } 7643 } 7644 7645 DWORD dwDataBytes=(DWORD)(sizeof(BANNEDLISTDATA)*m_vBannedListA[iPad]->size()); 7646 if(dwDataBytes==0) 7647 { 7648 // wipe the file 7649#ifdef _XBOX 7650 StorageManager.DeleteTMSFile(iPad,C4JStorage::eGlobalStorage_TitleUser,L"BannedList"); 7651#elif defined _XBOX_ONE 7652 StorageManager.TMSPP_DeleteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"BannedList",NULL,NULL, 0); 7653#endif 7654 } 7655 else 7656 { 7657 PBANNEDLISTDATA pBannedList = (BANNEDLISTDATA *)(new BYTE [dwDataBytes]); 7658 7659 int iSize=(int)m_vBannedListA[iPad]->size(); 7660 for(int i=0;i<iSize;i++) 7661 { 7662 PBANNEDLISTDATA pBannedListData =m_vBannedListA[iPad]->at(i); 7663 7664 memcpy(&pBannedList[i],pBannedListData,sizeof(BANNEDLISTDATA)); 7665 } 7666#ifdef _XBOX 7667 StorageManager.WriteTMSFile(iPad,C4JStorage::eGlobalStorage_TitleUser,L"BannedList",(PBYTE)pBannedList, dwDataBytes); 7668#elif defined _XBOX_ONE 7669 StorageManager.TMSPP_WriteFile(iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,L"BannedList",(PBYTE) pBannedList, dwDataBytes,NULL,NULL, 0); 7670#endif 7671 delete [] pBannedList; 7672 } 7673 7674 // update telemetry too 7675} 7676 7677// function to add credits for the DLC packs 7678void CMinecraftApp::AddCreditText(LPCWSTR lpStr) 7679{ 7680 DebugPrintf("ADDING CREDIT - %ls\n",lpStr); 7681 // add a string from the DLC to a credits vector 7682 SCreditTextItemDef *pCreditStruct = new SCreditTextItemDef; 7683 pCreditStruct->m_eType=eSmallText; 7684 pCreditStruct->m_iStringID[0]=NO_TRANSLATED_STRING; 7685 pCreditStruct->m_iStringID[1]=NO_TRANSLATED_STRING; 7686 pCreditStruct->m_Text=new WCHAR [wcslen(lpStr)+1]; 7687 wcscpy((WCHAR *)pCreditStruct->m_Text,lpStr); 7688 7689 vDLCCredits.push_back(pCreditStruct); 7690} 7691 7692bool CMinecraftApp::AlreadySeenCreditText(const wstring &wstemp) 7693{ 7694 7695 for(unsigned int i=0;i<m_vCreditText.size();i++) 7696 { 7697 wstring temp=m_vCreditText.at(i); 7698 7699 // if they are the same, break out of the case 7700 if(temp.compare(wstemp)==0) 7701 { 7702 return true; 7703 } 7704 } 7705 7706 // add this text 7707 m_vCreditText.push_back((WCHAR * )wstemp.c_str()); 7708 return false; 7709} 7710 7711unsigned int CMinecraftApp::GetDLCCreditsCount() 7712{ 7713 return (unsigned int)vDLCCredits.size(); 7714} 7715 7716SCreditTextItemDef * CMinecraftApp::GetDLCCredits(int iIndex) 7717{ 7718 return vDLCCredits.at(iIndex); 7719} 7720 7721// Game Host options 7722 7723void CMinecraftApp::SetGameHostOption(eGameHostOption eVal,unsigned int uiVal) 7724{ 7725 SetGameHostOption(m_uiGameHostSettings,eVal,uiVal); 7726} 7727 7728 7729void CMinecraftApp::SetGameHostOption(unsigned int &uiHostSettings, eGameHostOption eVal, unsigned int uiVal) 7730{ 7731 switch(eVal) 7732 { 7733 case eGameHostOption_FriendsOfFriends: 7734 if(uiVal!=0) 7735 { 7736 uiHostSettings|=GAME_HOST_OPTION_BITMASK_FRIENDSOFFRIENDS; 7737 } 7738 else 7739 { 7740 // off 7741 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_FRIENDSOFFRIENDS; 7742 } 7743 break; 7744 case eGameHostOption_Difficulty: 7745 // clear the difficulty first 7746 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_DIFFICULTY; 7747 uiHostSettings|=(GAME_HOST_OPTION_BITMASK_DIFFICULTY&uiVal); 7748 break; 7749 case eGameHostOption_Gamertags: 7750 if(uiVal!=0) 7751 { 7752 uiHostSettings|=GAME_HOST_OPTION_BITMASK_GAMERTAGS; 7753 } 7754 else 7755 { 7756 // off 7757 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_GAMERTAGS; 7758 } 7759 7760 break; 7761 case eGameHostOption_GameType: 7762 // clear the game type first 7763 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_GAMETYPE; 7764 uiHostSettings|=(GAME_HOST_OPTION_BITMASK_GAMETYPE&(uiVal<<4)); 7765 break; 7766 case eGameHostOption_LevelType: 7767 if(uiVal!=0) 7768 { 7769 uiHostSettings|=GAME_HOST_OPTION_BITMASK_LEVELTYPE; 7770 } 7771 else 7772 { 7773 // off 7774 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_LEVELTYPE; 7775 } 7776 7777 break; 7778 case eGameHostOption_Structures: 7779 if(uiVal!=0) 7780 { 7781 uiHostSettings|=GAME_HOST_OPTION_BITMASK_STRUCTURES; 7782 } 7783 else 7784 { 7785 // off 7786 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_STRUCTURES; 7787 } 7788 7789 break; 7790 case eGameHostOption_BonusChest: 7791 if(uiVal!=0) 7792 { 7793 uiHostSettings|=GAME_HOST_OPTION_BITMASK_BONUSCHEST; 7794 } 7795 else 7796 { 7797 // off 7798 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_BONUSCHEST; 7799 } 7800 7801 break; 7802 case eGameHostOption_HasBeenInCreative: 7803 if(uiVal!=0) 7804 { 7805 uiHostSettings|=GAME_HOST_OPTION_BITMASK_BEENINCREATIVE; 7806 } 7807 else 7808 { 7809 // off 7810 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_BEENINCREATIVE; 7811 } 7812 7813 break; 7814 case eGameHostOption_PvP: 7815 if(uiVal!=0) 7816 { 7817 uiHostSettings|=GAME_HOST_OPTION_BITMASK_PVP; 7818 } 7819 else 7820 { 7821 // off 7822 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_PVP; 7823 } 7824 7825 break; 7826 case eGameHostOption_TrustPlayers: 7827 if(uiVal!=0) 7828 { 7829 uiHostSettings|=GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS; 7830 } 7831 else 7832 { 7833 // off 7834 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS; 7835 } 7836 7837 break; 7838 case eGameHostOption_TNT: 7839 if(uiVal!=0) 7840 { 7841 uiHostSettings|=GAME_HOST_OPTION_BITMASK_TNT; 7842 } 7843 else 7844 { 7845 // off 7846 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_TNT; 7847 } 7848 7849 break; 7850 case eGameHostOption_FireSpreads: 7851 if(uiVal!=0) 7852 { 7853 uiHostSettings|=GAME_HOST_OPTION_BITMASK_FIRESPREADS; 7854 } 7855 else 7856 { 7857 // off 7858 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_FIRESPREADS; 7859 } 7860 break; 7861 case eGameHostOption_CheatsEnabled: 7862 if(uiVal!=0) 7863 { 7864 uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTFLY; 7865 uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTHUNGER; 7866 uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE; 7867 } 7868 else 7869 { 7870 // off 7871 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTFLY; 7872 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTHUNGER; 7873 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE; 7874 } 7875 break; 7876 case eGameHostOption_HostCanFly: 7877 if(uiVal!=0) 7878 { 7879 uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTFLY; 7880 } 7881 else 7882 { 7883 // off 7884 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTFLY; 7885 } 7886 break; 7887 case eGameHostOption_HostCanChangeHunger: 7888 if(uiVal!=0) 7889 { 7890 uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTHUNGER; 7891 } 7892 else 7893 { 7894 // off 7895 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTHUNGER; 7896 } 7897 break; 7898 case eGameHostOption_HostCanBeInvisible: 7899 if(uiVal!=0) 7900 { 7901 uiHostSettings|=GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE; 7902 } 7903 else 7904 { 7905 // off 7906 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE; 7907 } 7908 break; 7909 7910 case eGameHostOption_BedrockFog: 7911 if(uiVal!=0) 7912 { 7913 uiHostSettings|=GAME_HOST_OPTION_BITMASK_BEDROCKFOG; 7914 } 7915 else 7916 { 7917 // off 7918 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_BEDROCKFOG; 7919 } 7920 break; 7921 case eGameHostOption_DisableSaving: 7922 if(uiVal!=0) 7923 { 7924 uiHostSettings|=GAME_HOST_OPTION_BITMASK_DISABLESAVE; 7925 } 7926 else 7927 { 7928 // off 7929 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_DISABLESAVE; 7930 } 7931 break; 7932 case eGameHostOption_WasntSaveOwner: 7933 if(uiVal!=0) 7934 { 7935 uiHostSettings|=GAME_HOST_OPTION_BITMASK_NOTOWNER; 7936 } 7937 else 7938 { 7939 // off 7940 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_NOTOWNER; 7941 } 7942 break; 7943 case eGameHostOption_MobGriefing: 7944 if(uiVal!=1) 7945 { 7946 uiHostSettings |= GAME_HOST_OPTION_BITMASK_MOBGRIEFING; 7947 } 7948 else 7949 { 7950 // off 7951 uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_MOBGRIEFING; 7952 } 7953 break; 7954 case eGameHostOption_KeepInventory: 7955 if(uiVal!=0) 7956 { 7957 uiHostSettings |= GAME_HOST_OPTION_BITMASK_KEEPINVENTORY; 7958 } 7959 else 7960 { 7961 // off 7962 uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_KEEPINVENTORY; 7963 } 7964 break; 7965 case eGameHostOption_DoMobSpawning: 7966 if(uiVal!=1) 7967 { 7968 uiHostSettings |= GAME_HOST_OPTION_BITMASK_DOMOBSPAWNING; 7969 } 7970 else 7971 { 7972 // off 7973 uiHostSettings &=~ GAME_HOST_OPTION_BITMASK_DOMOBSPAWNING; 7974 } 7975 break; 7976 case eGameHostOption_DoMobLoot: 7977 if(uiVal!=1) 7978 { 7979 uiHostSettings |= GAME_HOST_OPTION_BITMASK_DOMOBLOOT; 7980 } 7981 else 7982 { 7983 // off 7984 uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_DOMOBLOOT; 7985 } 7986 break; 7987 case eGameHostOption_DoTileDrops: 7988 if(uiVal!=1) 7989 { 7990 uiHostSettings |= GAME_HOST_OPTION_BITMASK_DOTILEDROPS; 7991 } 7992 else 7993 { 7994 // off 7995 uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_DOTILEDROPS; 7996 } 7997 break; 7998 case eGameHostOption_NaturalRegeneration: 7999 if(uiVal!=1) 8000 { 8001 uiHostSettings |= GAME_HOST_OPTION_BITMASK_NATURALREGEN; 8002 } 8003 else 8004 { 8005 // off 8006 uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_NATURALREGEN; 8007 } 8008 break; 8009 case eGameHostOption_DoDaylightCycle: 8010 if(uiVal!=1) 8011 { 8012 uiHostSettings |= GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE; 8013 } 8014 else 8015 { 8016 // off 8017 uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE; 8018 } 8019 break; 8020 case eGameHostOption_WorldSize: 8021 // clear the difficulty first 8022 uiHostSettings&=~GAME_HOST_OPTION_BITMASK_WORLDSIZE; 8023 uiHostSettings|=(GAME_HOST_OPTION_BITMASK_WORLDSIZE & (uiVal<<GAME_HOST_OPTION_BITMASK_WORLDSIZE_BITSHIFT)); 8024 break; 8025 case eGameHostOption_All: 8026 uiHostSettings=uiVal; 8027 break; 8028 } 8029} 8030 8031unsigned int CMinecraftApp::GetGameHostOption(eGameHostOption eVal) 8032{ 8033 return GetGameHostOption(m_uiGameHostSettings, eVal); 8034} 8035 8036unsigned int CMinecraftApp::GetGameHostOption(unsigned int uiHostSettings, eGameHostOption eVal) 8037{ 8038 //unsigned int uiVal=0; 8039 switch(eVal) 8040 { 8041 case eGameHostOption_FriendsOfFriends: 8042 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_FRIENDSOFFRIENDS); 8043 break; 8044 case eGameHostOption_Difficulty: 8045 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_DIFFICULTY); 8046 break; 8047 case eGameHostOption_Gamertags: 8048 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_GAMERTAGS); 8049 break; 8050 case eGameHostOption_GameType: 8051 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_GAMETYPE)>>4; 8052 break; 8053 case eGameHostOption_All: 8054 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_ALL); 8055 break; 8056 case eGameHostOption_Tutorial: 8057 // 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 8058 return ((uiHostSettings&GAME_HOST_OPTION_BITMASK_GAMERTAGS)| 8059 GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS| 8060 GAME_HOST_OPTION_BITMASK_FIRESPREADS| 8061 GAME_HOST_OPTION_BITMASK_TNT| 8062 GAME_HOST_OPTION_BITMASK_PVP| 8063 GAME_HOST_OPTION_BITMASK_STRUCTURES|1); 8064 break; 8065 case eGameHostOption_LevelType: 8066 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_LEVELTYPE); 8067 break; 8068 case eGameHostOption_Structures: 8069 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_STRUCTURES); 8070 break; 8071 case eGameHostOption_BonusChest: 8072 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_BONUSCHEST); 8073 break; 8074 case eGameHostOption_HasBeenInCreative: 8075 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_BEENINCREATIVE); 8076 break; 8077 case eGameHostOption_PvP: 8078 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_PVP); 8079 break; 8080 case eGameHostOption_TrustPlayers: 8081 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS); 8082 break; 8083 case eGameHostOption_TNT: 8084 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_TNT); 8085 break; 8086 case eGameHostOption_FireSpreads: 8087 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_FIRESPREADS); 8088 break; 8089 case eGameHostOption_CheatsEnabled: 8090 return (uiHostSettings&(GAME_HOST_OPTION_BITMASK_HOSTFLY|GAME_HOST_OPTION_BITMASK_HOSTHUNGER|GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE)); 8091 break; 8092 case eGameHostOption_HostCanFly: 8093 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HOSTFLY); 8094 break; 8095 case eGameHostOption_HostCanChangeHunger: 8096 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HOSTHUNGER); 8097 break; 8098 case eGameHostOption_HostCanBeInvisible: 8099 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE); 8100 break; 8101 case eGameHostOption_BedrockFog: 8102 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_BEDROCKFOG); 8103 break; 8104 case eGameHostOption_DisableSaving: 8105 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_DISABLESAVE); 8106 break; 8107 case eGameHostOption_WasntSaveOwner: 8108 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_NOTOWNER); 8109 case eGameHostOption_WorldSize: 8110 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_WORLDSIZE) >> GAME_HOST_OPTION_BITMASK_WORLDSIZE_BITSHIFT; 8111 case eGameHostOption_MobGriefing: 8112 return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_MOBGRIEFING); 8113 case eGameHostOption_KeepInventory: 8114 return (uiHostSettings&GAME_HOST_OPTION_BITMASK_KEEPINVENTORY); 8115 case eGameHostOption_DoMobSpawning: 8116 return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DOMOBSPAWNING); 8117 case eGameHostOption_DoMobLoot: 8118 return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DOMOBLOOT); 8119 case eGameHostOption_DoTileDrops: 8120 return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DOTILEDROPS); 8121 case eGameHostOption_NaturalRegeneration: 8122 return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_NATURALREGEN); 8123 case eGameHostOption_DoDaylightCycle: 8124 return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE); 8125 break; 8126 } 8127 8128 return false; 8129} 8130 8131bool CMinecraftApp::CanRecordStatsAndAchievements() 8132{ 8133 bool isTutorial = Minecraft::GetInstance() != NULL && Minecraft::GetInstance()->isTutorial(); 8134 // 4J Stu - All of these options give the host player some advantage, so should not allow achievements 8135 return !(app.GetGameHostOption(eGameHostOption_HasBeenInCreative) || 8136 app.GetGameHostOption(eGameHostOption_HostCanBeInvisible) || 8137 app.GetGameHostOption(eGameHostOption_HostCanChangeHunger) || 8138 app.GetGameHostOption(eGameHostOption_HostCanFly) || 8139 app.GetGameHostOption(eGameHostOption_WasntSaveOwner) || 8140 !app.GetGameHostOption(eGameHostOption_MobGriefing) || 8141 app.GetGameHostOption(eGameHostOption_KeepInventory) || 8142 !app.GetGameHostOption(eGameHostOption_DoMobSpawning) || 8143 (!app.GetGameHostOption(eGameHostOption_DoDaylightCycle) && !isTutorial ) 8144 ); 8145} 8146 8147void CMinecraftApp::processSchematics(LevelChunk *levelChunk) 8148{ 8149 m_gameRules.processSchematics(levelChunk); 8150} 8151 8152void CMinecraftApp::processSchematicsLighting(LevelChunk *levelChunk) 8153{ 8154 m_gameRules.processSchematicsLighting(levelChunk); 8155} 8156 8157void CMinecraftApp::loadDefaultGameRules() 8158{ 8159 m_gameRules.loadDefaultGameRules(); 8160} 8161 8162void CMinecraftApp::setLevelGenerationOptions(LevelGenerationOptions *levelGen) 8163{ 8164 m_gameRules.setLevelGenerationOptions(levelGen); 8165} 8166 8167LPCWSTR CMinecraftApp::GetGameRulesString(const wstring &key) 8168{ 8169 return m_gameRules.GetGameRulesString(key); 8170} 8171 8172unsigned char CMinecraftApp::m_szPNG[8]= 8173{ 8174 137,80,78,71,13,10,26,10 8175}; 8176 8177#define PNG_TAG_tEXt 0x74455874 8178 8179unsigned int CMinecraftApp::FromBigEndian(unsigned int uiValue) 8180{ 8181#if defined(__PS3__) || defined(_XBOX) 8182 // Keep it in big endian 8183 return uiValue; 8184#else 8185 unsigned int uiReturn = ( ( uiValue >> 24 ) & 0x000000ff ) | 8186 ( ( uiValue >> 8 ) & 0x0000ff00 ) | 8187 ( ( uiValue << 8 ) & 0x00ff0000 ) | 8188 ( ( uiValue << 24 ) & 0xff000000 ); 8189 return uiReturn; 8190#endif 8191} 8192 8193void CMinecraftApp::GetImageTextData(PBYTE pbImageData, DWORD dwImageBytes,unsigned char *pszSeed,unsigned int &uiHostOptions,bool &bHostOptionsRead,DWORD &uiTexturePack) 8194{ 8195 unsigned char *ucPtr=pbImageData; 8196 unsigned int uiCount=0; 8197 unsigned int uiChunkLen; 8198 unsigned int uiChunkType; 8199 unsigned int uiCRC; 8200 char szKeyword[80]; 8201 8202 // check it's a png 8203 for(int i=0;i<8;i++) 8204 { 8205 if(m_szPNG[i]!=ucPtr[i]) return; 8206 } 8207 8208 uiCount+=8; 8209 8210 while(uiCount<dwImageBytes) 8211 { 8212 uiChunkLen=*(unsigned int *)&ucPtr[uiCount]; 8213 uiChunkLen=FromBigEndian(uiChunkLen); 8214 uiCount+=sizeof(int); 8215 uiChunkType=*(unsigned int *)&ucPtr[uiCount]; 8216 uiChunkType=FromBigEndian(uiChunkType); 8217 uiCount+=sizeof(int); 8218 8219 if(uiChunkType==PNG_TAG_tEXt) // tEXt 8220 { 8221 // check that it's the 4J text 8222 unsigned char *pszKeyword=&ucPtr[uiCount]; 8223 while(pszKeyword < ucPtr + uiCount + uiChunkLen) 8224 { 8225 ZeroMemory(szKeyword,80); 8226 unsigned int uiKeywordC=0; 8227 while(*pszKeyword!=0) 8228 { 8229 szKeyword[uiKeywordC++]=*pszKeyword; 8230 pszKeyword++; 8231 } 8232 pszKeyword++; 8233 if(strcmp(szKeyword,"4J_SEED")==0) 8234 { 8235 // read the seed value 8236 unsigned int uiValueC=0; 8237 while(*pszKeyword!=0 && (pszKeyword < ucPtr + uiCount + uiChunkLen) ) 8238 { 8239 pszSeed[uiValueC++]=*pszKeyword; 8240 pszKeyword++; 8241 } 8242 //memcpy(pszSeed,pszKeyword,uiChunkLen-8); 8243 } 8244 else if(strcmp(szKeyword,"4J_HOSTOPTIONS")==0) 8245 { 8246 bHostOptionsRead = true; 8247 // read the host options value 8248 unsigned int uiValueC=0; 8249 unsigned char pszHostOptions[9]; // Hex representation of unsigned int 8250 ZeroMemory(&pszHostOptions,9); 8251 while(*pszKeyword!=0 && (pszKeyword < ucPtr + uiCount + uiChunkLen) && uiValueC < 8) 8252 { 8253 pszHostOptions[uiValueC++]=*pszKeyword; 8254 pszKeyword++; 8255 } 8256 8257 uiHostOptions = 0; 8258 std::stringstream ss; 8259 ss << pszHostOptions; 8260 ss >> std::hex >> uiHostOptions; 8261 } 8262 else if(strcmp(szKeyword,"4J_TEXTUREPACK")==0) 8263 { 8264 // read the texture pack value 8265 unsigned int uiValueC=0; 8266 unsigned char pszTexturePack[9]; // Hex representation of unsigned int 8267 ZeroMemory(&pszTexturePack,9); 8268 while(*pszKeyword!=0 && (pszKeyword < ucPtr + uiCount + uiChunkLen) && uiValueC < 8) 8269 { 8270 pszTexturePack[uiValueC++]=*pszKeyword; 8271 pszKeyword++; 8272 } 8273 8274 std::stringstream ss; 8275 ss << pszTexturePack; 8276 ss >> std::hex >> uiTexturePack; 8277 } 8278 } 8279 } 8280 uiCount+=uiChunkLen; 8281 uiCRC=*(unsigned int*)&ucPtr[uiCount]; 8282 uiCRC=FromBigEndian(uiCRC); 8283 uiCount+=sizeof(int); 8284 } 8285 8286 return; 8287} 8288 8289unsigned int CMinecraftApp::CreateImageTextData(PBYTE bTextMetadata, __int64 seed, bool hasSeed, unsigned int uiHostOptions, unsigned int uiTexturePackId) 8290{ 8291 int iTextMetadataBytes = 0; 8292 if(hasSeed) 8293 { 8294 strcpy((char *)bTextMetadata,"4J_SEED"); 8295 _i64toa_s(seed,(char *)&bTextMetadata[8],42,10); 8296 8297 // get the length 8298 iTextMetadataBytes+=8; 8299 while(bTextMetadata[iTextMetadataBytes]!=0) iTextMetadataBytes++; 8300 ++iTextMetadataBytes; // Add a null terminator at the end of the seed value 8301 } 8302 8303 // Save the host options that this world was last played with 8304 strcpy((char *)&bTextMetadata[iTextMetadataBytes],"4J_HOSTOPTIONS"); 8305 _itoa_s(uiHostOptions,(char *)&bTextMetadata[iTextMetadataBytes+15],9,16); 8306 8307 iTextMetadataBytes += 15; 8308 while(bTextMetadata[iTextMetadataBytes]!=0) iTextMetadataBytes++; 8309 ++iTextMetadataBytes; // Add a null terminator at the end of the host options value 8310 8311 // Save the texture pack id 8312 strcpy((char *)&bTextMetadata[iTextMetadataBytes],"4J_TEXTUREPACK"); 8313 _itoa_s(uiTexturePackId,(char *)&bTextMetadata[iTextMetadataBytes+15],9,16); 8314 8315 iTextMetadataBytes += 15; 8316 while(bTextMetadata[iTextMetadataBytes]!=0) iTextMetadataBytes++; 8317 8318 return iTextMetadataBytes; 8319} 8320 8321void CMinecraftApp::AddTerrainFeaturePosition(_eTerrainFeatureType eFeatureType,int x,int z) 8322{ 8323 // check we don't already have this in 8324 for(AUTO_VAR(it, m_vTerrainFeatures.begin()); it < m_vTerrainFeatures.end(); ++it) 8325 { 8326 FEATURE_DATA *pFeatureData=*it; 8327 8328 if((pFeatureData->eTerrainFeature==eFeatureType) &&(pFeatureData->x==x) && (pFeatureData->z==z)) return; 8329 } 8330 8331 FEATURE_DATA *pFeatureData= new FEATURE_DATA; 8332 pFeatureData->eTerrainFeature=eFeatureType; 8333 pFeatureData->x=x; 8334 pFeatureData->z=z; 8335 8336 m_vTerrainFeatures.push_back(pFeatureData); 8337} 8338 8339_eTerrainFeatureType CMinecraftApp::IsTerrainFeature(int x,int z) 8340{ 8341 for(AUTO_VAR(it, m_vTerrainFeatures.begin()); it < m_vTerrainFeatures.end(); ++it) 8342 { 8343 FEATURE_DATA *pFeatureData=*it; 8344 8345 if((pFeatureData->x==x) && (pFeatureData->z==z)) return pFeatureData->eTerrainFeature; 8346 } 8347 8348 return eTerrainFeature_None; 8349} 8350 8351bool CMinecraftApp::GetTerrainFeaturePosition(_eTerrainFeatureType eType,int *pX, int *pZ) 8352{ 8353 for(AUTO_VAR(it, m_vTerrainFeatures.begin()); it < m_vTerrainFeatures.end(); ++it) 8354 { 8355 FEATURE_DATA *pFeatureData=*it; 8356 8357 if(pFeatureData->eTerrainFeature==eType) 8358 { 8359 *pX=pFeatureData->x; 8360 *pZ=pFeatureData->z; 8361 return true; 8362 } 8363 } 8364 8365 return false; 8366} 8367 8368void CMinecraftApp::ClearTerrainFeaturePosition() 8369{ 8370 FEATURE_DATA *pFeatureData; 8371 while(m_vTerrainFeatures.size()>0) 8372 { 8373 pFeatureData = m_vTerrainFeatures.back(); 8374 m_vTerrainFeatures.pop_back(); 8375 delete pFeatureData; 8376 } 8377} 8378 8379void CMinecraftApp::UpdatePlayerInfo(BYTE networkSmallId, SHORT playerColourIndex, unsigned int playerGamePrivileges) 8380{ 8381 for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) 8382 { 8383 if(m_playerColours[i]==networkSmallId) 8384 { 8385 m_playerColours[i] = 0; 8386 m_playerGamePrivileges[i] = 0; 8387 } 8388 } 8389 if(playerColourIndex >=0 && playerColourIndex < MINECRAFT_NET_MAX_PLAYERS) 8390 { 8391 m_playerColours[playerColourIndex] = networkSmallId; 8392 m_playerGamePrivileges[playerColourIndex] = playerGamePrivileges; 8393 } 8394} 8395 8396short CMinecraftApp::GetPlayerColour(BYTE networkSmallId) 8397{ 8398 short index = -1; 8399 for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) 8400 { 8401 if(m_playerColours[i]==networkSmallId) 8402 { 8403 index = i; 8404 break; 8405 } 8406 } 8407 return index; 8408} 8409 8410 8411unsigned int CMinecraftApp::GetPlayerPrivileges(BYTE networkSmallId) 8412{ 8413 unsigned int privileges = 0; 8414 for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) 8415 { 8416 if(m_playerColours[i]==networkSmallId) 8417 { 8418 privileges = m_playerGamePrivileges[i]; 8419 break; 8420 } 8421 } 8422 return privileges; 8423} 8424 8425wstring CMinecraftApp::getEntityName(eINSTANCEOF type) 8426{ 8427 switch(type) 8428 { 8429 case eTYPE_WOLF: 8430 return app.GetString(IDS_WOLF); 8431 case eTYPE_CREEPER: 8432 return app.GetString(IDS_CREEPER); 8433 case eTYPE_SKELETON: 8434 return app.GetString(IDS_SKELETON); 8435 case eTYPE_SPIDER: 8436 return app.GetString(IDS_SPIDER); 8437 case eTYPE_ZOMBIE: 8438 return app.GetString(IDS_ZOMBIE); 8439 case eTYPE_PIGZOMBIE: 8440 return app.GetString(IDS_PIGZOMBIE); 8441 case eTYPE_ENDERMAN: 8442 return app.GetString(IDS_ENDERMAN); 8443 case eTYPE_SILVERFISH: 8444 return app.GetString(IDS_SILVERFISH); 8445 case eTYPE_CAVESPIDER: 8446 return app.GetString(IDS_CAVE_SPIDER); 8447 case eTYPE_GHAST: 8448 return app.GetString(IDS_GHAST); 8449 case eTYPE_SLIME: 8450 return app.GetString(IDS_SLIME); 8451 case eTYPE_ARROW: 8452 return app.GetString(IDS_ITEM_ARROW); 8453 case eTYPE_ENDERDRAGON: 8454 return app.GetString(IDS_ENDERDRAGON); 8455 case eTYPE_BLAZE: 8456 return app.GetString(IDS_BLAZE); 8457 case eTYPE_LAVASLIME: 8458 return app.GetString(IDS_LAVA_SLIME); 8459 // 4J-PB - fix for #107167 - Customer Encountered: TU12: Content: UI: There is no information what killed Player after being slain by Iron Golem. 8460 case eTYPE_VILLAGERGOLEM: 8461 return app.GetString(IDS_IRONGOLEM); 8462 case eTYPE_HORSE: 8463 return app.GetString(IDS_HORSE); 8464 case eTYPE_WITCH: 8465 return app.GetString(IDS_WITCH); 8466 case eTYPE_WITHERBOSS: 8467 return app.GetString(IDS_WITHER); 8468 case eTYPE_BAT: 8469 return app.GetString(IDS_BAT); 8470 }; 8471 8472 return L""; 8473} 8474 8475DWORD CMinecraftApp::m_dwContentTypeA[e_Marketplace_MAX]= 8476{ 8477 XMARKETPLACE_OFFERING_TYPE_CONTENT, // e_DLC_SkinPack, e_DLC_TexturePacks, e_DLC_MashupPacks 8478#ifndef _XBOX_ONE 8479 XMARKETPLACE_OFFERING_TYPE_THEME, // e_DLC_Themes 8480 XMARKETPLACE_OFFERING_TYPE_AVATARITEM, // e_DLC_AvatarItems 8481 XMARKETPLACE_OFFERING_TYPE_TILE, // e_DLC_Gamerpics 8482#endif 8483}; 8484 8485unsigned int CMinecraftApp::AddDLCRequest(eDLCMarketplaceType eType, bool bPromote) 8486{ 8487 // lock access 8488 EnterCriticalSection(&csDLCDownloadQueue); 8489 8490 // If it's already in there, promote it to the top of the list 8491 int iPosition=0; 8492 for(AUTO_VAR(it, m_DLCDownloadQueue.begin()); it != m_DLCDownloadQueue.end(); ++it) 8493 { 8494 DLCRequest *pCurrent = *it; 8495 8496 if(pCurrent->dwType==m_dwContentTypeA[eType]) 8497 { 8498 // already got this in the list 8499 if(pCurrent->eState == e_DLC_ContentState_Retrieving || pCurrent->eState == e_DLC_ContentState_Retrieved) 8500 { 8501 // already retrieved this 8502 LeaveCriticalSection(&csDLCDownloadQueue); 8503 return 0; 8504 } 8505 else 8506 { 8507 // promote 8508 if(bPromote) 8509 { 8510 m_DLCDownloadQueue.erase(m_DLCDownloadQueue.begin()+iPosition); 8511 m_DLCDownloadQueue.insert(m_DLCDownloadQueue.begin(),pCurrent); 8512 } 8513 LeaveCriticalSection(&csDLCDownloadQueue); 8514 return 0; 8515 } 8516 } 8517 iPosition++; 8518 } 8519 8520 DLCRequest *pDLCreq = new DLCRequest; 8521 pDLCreq->dwType=m_dwContentTypeA[eType]; 8522 pDLCreq->eState=e_DLC_ContentState_Idle; 8523 8524 m_DLCDownloadQueue.push_back(pDLCreq); 8525 8526 m_bAllDLCContentRetrieved=false; 8527 LeaveCriticalSection(&csDLCDownloadQueue); 8528 8529 app.DebugPrintf("[Consoles_App] Added DLC request.\n"); 8530 return 1; 8531} 8532 8533unsigned int CMinecraftApp::AddTMSPPFileTypeRequest(eDLCContentType eType, bool bPromote) 8534{ 8535#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__) 8536 // lock access 8537 EnterCriticalSection(&csTMSPPDownloadQueue); 8538 8539 // If it's already in there, promote it to the top of the list 8540 int iPosition=0; 8541 //ignore promoting for now 8542 /* 8543 bool bPromoted=false; 8544 8545 8546 for(AUTO_VAR(it, m_TMSPPDownloadQueue.begin()); it != m_TMSPPDownloadQueue.end(); ++it) 8547 { 8548 TMSPPRequest *pCurrent = *it; 8549 8550 if(pCurrent->eType==eType) 8551 { 8552 if(!(pCurrent->eState == e_TMS_ContentState_Retrieving || pCurrent->eState == e_TMS_ContentState_Retrieved)) 8553 { 8554 // promote 8555 if(bPromote) 8556 { 8557 m_TMSPPDownloadQueue.erase(m_TMSPPDownloadQueue.begin()+iPosition); 8558 m_TMSPPDownloadQueue.insert(m_TMSPPDownloadQueue.begin(),pCurrent); 8559 bPromoted=true; 8560 } 8561 } 8562 } 8563 iPosition++; 8564 } 8565 8566 if(bPromoted) 8567 { 8568 // re-ordered the list, so leave now 8569 LeaveCriticalSection(&csTMSPPDownloadQueue); 8570 return 0; 8571 } 8572 */ 8573 8574 // special case for data files (not image files) 8575 if(eType==e_DLC_TexturePackData) 8576 { 8577 8578 8579 int iCount=GetDLCInfoFullOffersCount(); 8580 8581 for(int i=0;i<iCount;i++) 8582 { 8583 8584 DLC_INFO *pDLC=GetDLCInfoFullOffer(i); 8585 8586 if((pDLC->eDLCType==e_DLC_TexturePacks) || (pDLC->eDLCType==e_DLC_MashupPacks)) 8587 { 8588 // first check if the image is already in the memory textures, since we might be loading some from the Title Update partition 8589 if(pDLC->wchDataFile[0]!=0) 8590 { 8591 //WCHAR *cString = pDLC->wchDataFile; 8592 // 4J-PB - shouldn't check this here - let the TMS files override it, so if they are on TMS, we'll take them first 8593 //int iIndex = app.GetLocalTMSFileIndex(pDLC->wchDataFile,true); 8594 8595 //if(iIndex!=-1) 8596 { 8597 bool bPresent = app.IsFileInTPD(pDLC->iConfig); 8598 8599 if(!bPresent) 8600 { 8601 // this may already be present in the vector because of a previous trial/full offer 8602 8603 bool bAlreadyInQueue=false; 8604 for(AUTO_VAR(it, m_TMSPPDownloadQueue.begin()); it != m_TMSPPDownloadQueue.end(); ++it) 8605 { 8606 TMSPPRequest *pCurrent = *it; 8607 8608 if(wcscmp(pDLC->wchDataFile,pCurrent->wchFilename)==0) 8609 { 8610 bAlreadyInQueue=true; 8611 break; 8612 } 8613 } 8614 8615 if(!bAlreadyInQueue) 8616 { 8617 TMSPPRequest *pTMSPPreq = new TMSPPRequest; 8618 8619 pTMSPPreq->CallbackFunc=&CMinecraftApp::TMSPPFileReturned; 8620 pTMSPPreq->lpCallbackParam=this; 8621 pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_Title; 8622 pTMSPPreq->eFileTypeVal=C4JStorage::TMS_FILETYPE_BINARY; 8623 memcpy(pTMSPPreq->wchFilename,pDLC->wchDataFile,sizeof(WCHAR)*MAX_BANNERNAME_SIZE); 8624 pTMSPPreq->eType=e_DLC_TexturePackData; 8625 pTMSPPreq->eState=e_TMS_ContentState_Queued; 8626 m_bAllTMSContentRetrieved=false; 8627 m_TMSPPDownloadQueue.push_back(pTMSPPreq); 8628 } 8629 } 8630 else 8631 { 8632 app.DebugPrintf("Texture data already present in the TPD\n"); 8633 } 8634 } 8635 } 8636 } 8637 } 8638 } 8639 else 8640 { // for all the files of type eType, add them to the download list 8641 8642 // run through the trial offers first, then the full offers. Any duplicates won't be added to the download queue 8643 int iCount; 8644#ifdef _XBOX // Only trial offers on Xbox 360 8645 iCount=GetDLCInfoTrialOffersCount(); 8646 for(int i=0;i<iCount;i++) 8647 { 8648 DLC_INFO *pDLC=GetDLCInfoTrialOffer(i); 8649 8650 // is this the right type? 8651 if(pDLC->eDLCType==eType) 8652 { 8653 8654 WCHAR *cString = pDLC->wchBanner; 8655 8656 // 4J-PB - shouldn't check this here - let the TMS files override it, so if they are on TMS, we'll take them first 8657 // is the file in the TMS XZP? 8658 //int iIndex = app.GetLocalTMSFileIndex(cString,true); 8659 8660 //if(iIndex!=-1) 8661 { 8662 bool bPresent = app.IsFileInMemoryTextures(cString); 8663 8664 if(!bPresent) // retrieve it from TMSPP 8665 { 8666 bool bAlreadyInQueue=false; 8667 for(AUTO_VAR(it, m_TMSPPDownloadQueue.begin()); it != m_TMSPPDownloadQueue.end(); ++it) 8668 { 8669 TMSPPRequest *pCurrent = *it; 8670 8671 if(wcscmp(pDLC->wchBanner,pCurrent->wchFilename)==0) 8672 { 8673 bAlreadyInQueue=true; 8674 break; 8675 } 8676 } 8677 8678 if(!bAlreadyInQueue) 8679 { 8680 TMSPPRequest *pTMSPPreq = new TMSPPRequest; 8681 8682 pTMSPPreq->CallbackFunc=&CMinecraftApp::TMSPPFileReturned; 8683 pTMSPPreq->lpCallbackParam=this; 8684 pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_Title; 8685 pTMSPPreq->eFileTypeVal=C4JStorage::TMS_FILETYPE_BINARY; 8686 //wcstombs(pTMSPPreq->szFilename,pDLC->wchBanner,MAX_TMSFILENAME_SIZE); 8687 memcpy(pTMSPPreq->wchFilename,pDLC->wchBanner,sizeof(WCHAR)*MAX_BANNERNAME_SIZE); 8688 pTMSPPreq->eType=eType; 8689 pTMSPPreq->eState=e_TMS_ContentState_Queued; 8690 8691 m_bAllTMSContentRetrieved=false; 8692 m_TMSPPDownloadQueue.push_back(pTMSPPreq); 8693 app.DebugPrintf("===m_TMSPPDownloadQueue Adding %ls, q size is %d\n",pTMSPPreq->wchFilename,m_TMSPPDownloadQueue.size()); 8694 } 8695 } 8696 } 8697 } 8698 } 8699#endif 8700 // and the full offers 8701 8702 iCount=GetDLCInfoFullOffersCount(); 8703 for(int i=0;i<iCount;i++) 8704 { 8705 DLC_INFO *pDLC=GetDLCInfoFullOffer(i); 8706 //if(wcscmp(pDLC->wchType,wchDLCTypeNames[eType])==0) 8707 if(pDLC->eDLCType==eType) 8708 { 8709 // first check if the image is already in the memory textures, since we might be loading some from the Title Update partition 8710 8711 WCHAR *cString = pDLC->wchBanner; 8712 // 4J-PB - shouldn't check this here - let the TMS files override it, so if they are on TMS, we'll take them first 8713 //int iIndex = app.GetLocalTMSFileIndex(cString,true); 8714 8715 //if(iIndex!=-1) 8716 { 8717 bool bPresent = app.IsFileInMemoryTextures(cString); 8718 8719 if(!bPresent) 8720 { 8721 // this may already be present in the vector because of a previous trial/full offer 8722 8723 bool bAlreadyInQueue=false; 8724 for(AUTO_VAR(it, m_TMSPPDownloadQueue.begin()); it != m_TMSPPDownloadQueue.end(); ++it) 8725 { 8726 TMSPPRequest *pCurrent = *it; 8727 8728 if(wcscmp(pDLC->wchBanner,pCurrent->wchFilename)==0) 8729 { 8730 bAlreadyInQueue=true; 8731 break; 8732 } 8733 } 8734 8735 if(!bAlreadyInQueue) 8736 { 8737 //app.DebugPrintf("Adding a request to the TMSPP download queue - %ls\n",pDLC->wchBanner); 8738 TMSPPRequest *pTMSPPreq = new TMSPPRequest; 8739 ZeroMemory(pTMSPPreq,sizeof(TMSPPRequest)); 8740 8741 pTMSPPreq->CallbackFunc=&CMinecraftApp::TMSPPFileReturned; 8742 pTMSPPreq->lpCallbackParam=this; 8743 // 4J-PB - testing for now 8744 //pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_TitleUser; 8745 pTMSPPreq->eStorageFacility=C4JStorage::eGlobalStorage_Title; 8746 pTMSPPreq->eFileTypeVal=C4JStorage::TMS_FILETYPE_BINARY; 8747 //wcstombs(pTMSPPreq->szFilename,pDLC->wchBanner,MAX_TMSFILENAME_SIZE); 8748 8749 memcpy(pTMSPPreq->wchFilename,pDLC->wchBanner,sizeof(WCHAR)*MAX_BANNERNAME_SIZE); 8750 pTMSPPreq->eType=eType; 8751 pTMSPPreq->eState=e_TMS_ContentState_Queued; 8752 m_bAllTMSContentRetrieved=false; 8753 m_TMSPPDownloadQueue.push_back(pTMSPPreq); 8754 app.DebugPrintf("===m_TMSPPDownloadQueue Adding %ls, q size is %d\n",pTMSPPreq->wchFilename,m_TMSPPDownloadQueue.size()); 8755 } 8756 } 8757 } 8758 } 8759 } 8760 } 8761 8762 LeaveCriticalSection(&csTMSPPDownloadQueue); 8763#endif 8764 return 1; 8765} 8766 8767bool CMinecraftApp::CheckTMSDLCCanStop() 8768{ 8769 EnterCriticalSection(&csTMSPPDownloadQueue); 8770 for(AUTO_VAR(it, m_TMSPPDownloadQueue.begin()); it != m_TMSPPDownloadQueue.end(); ++it) 8771 { 8772 TMSPPRequest *pCurrent = *it; 8773 8774 if(pCurrent->eState==e_TMS_ContentState_Retrieving) 8775 { 8776 LeaveCriticalSection(&csTMSPPDownloadQueue); 8777 return false; 8778 } 8779 } 8780 LeaveCriticalSection(&csTMSPPDownloadQueue); 8781 8782 return true; 8783} 8784 8785 8786bool CMinecraftApp::RetrieveNextDLCContent() 8787{ 8788 // If there's already a retrieve in progress, quit 8789 // we may have re-ordered the list, so need to check every item 8790 8791 // is there a primary player and a network connection? 8792 int primPad = ProfileManager.GetPrimaryPad(); 8793 if ( primPad == -1 || !ProfileManager.IsSignedInLive(primPad) ) 8794 { 8795 return true; // 4J-JEV: We need to wait until the primary player is online. 8796 } 8797 8798 EnterCriticalSection(&csDLCDownloadQueue); 8799 for(AUTO_VAR(it, m_DLCDownloadQueue.begin()); it != m_DLCDownloadQueue.end(); ++it) 8800 { 8801 DLCRequest *pCurrent = *it; 8802 8803 if(pCurrent->eState==e_DLC_ContentState_Retrieving) 8804 { 8805 LeaveCriticalSection(&csDLCDownloadQueue); 8806 return true; 8807 } 8808 } 8809 8810 // Now look for the next retrieval 8811 for(AUTO_VAR(it, m_DLCDownloadQueue.begin()); it != m_DLCDownloadQueue.end(); ++it) 8812 { 8813 DLCRequest *pCurrent = *it; 8814 8815 if(pCurrent->eState==e_DLC_ContentState_Idle) 8816 { 8817#ifdef _DEBUG 8818 app.DebugPrintf("RetrieveNextDLCContent - type = %d\n",pCurrent->dwType); 8819#endif 8820 8821 C4JStorage::EDLCStatus status = StorageManager.GetDLCOffers(ProfileManager.GetPrimaryPad(), &CMinecraftApp::DLCOffersReturned, this, pCurrent->dwType); 8822 if(status==C4JStorage::EDLC_Pending) 8823 { 8824 pCurrent->eState=e_DLC_ContentState_Retrieving; 8825 } 8826 else 8827 { 8828 // no content of this type, or some other problem 8829 app.DebugPrintf("RetrieveNextDLCContent - PROBLEM\n"); 8830 pCurrent->eState=e_DLC_ContentState_Retrieved; 8831 } 8832 LeaveCriticalSection(&csDLCDownloadQueue); 8833 return true; 8834 } 8835 } 8836 LeaveCriticalSection(&csDLCDownloadQueue); 8837 8838 app.DebugPrintf("[Consoles_App] Finished downloading dlc content.\n"); 8839 return false; 8840} 8841 8842#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__) 8843#ifdef _XBOX_ONE 8844int CMinecraftApp::TMSPPFileReturned(LPVOID pParam,int iPad,int iUserData,LPVOID lpvData, WCHAR* wchFilename) 8845{ 8846 C4JStorage::PTMSPP_FILEDATA pFileData=(C4JStorage::PTMSPP_FILEDATA)lpvData; 8847#else 8848int CMinecraftApp::TMSPPFileReturned(LPVOID pParam,int iPad,int iUserData,C4JStorage::PTMSPP_FILEDATA pFileData, LPCSTR szFilename) 8849{ 8850#endif 8851 8852 CMinecraftApp* pClass = (CMinecraftApp *) pParam; 8853 8854 // find the right one in the vector 8855 EnterCriticalSection(&pClass->csTMSPPDownloadQueue); 8856 for(AUTO_VAR(it, pClass->m_TMSPPDownloadQueue.begin()); it != pClass->m_TMSPPDownloadQueue.end(); ++it) 8857 { 8858 TMSPPRequest *pCurrent = *it; 8859#if defined(_XBOX) || defined(_WINDOWS64) 8860 char szFile[MAX_TMSFILENAME_SIZE]; 8861 wcstombs(szFile,pCurrent->wchFilename,MAX_TMSFILENAME_SIZE); 8862 8863 8864 if(strcmp(szFilename,szFile)==0) 8865#elif _XBOX_ONE 8866 if(wcscmp(wchFilename,pCurrent->wchFilename)==0) 8867#endif 8868 { 8869 // set this to retrieved whether it found it or not 8870 pCurrent->eState=e_TMS_ContentState_Retrieved; 8871 8872 if(pFileData!=NULL) 8873 { 8874 8875#ifdef _XBOX_ONE 8876 8877 8878 switch(pCurrent->eType) 8879 { 8880 case e_DLC_TexturePackData: 8881 { 8882 // 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 8883 PBYTE pbData = new BYTE [pFileData->dwSize]; 8884 memcpy(pbData,pFileData->pbData,pFileData->dwSize); 8885 8886 pClass->m_vTMSPPData.push_back(pbData); 8887 app.DebugPrintf("Got texturepack data\n"); 8888 // get the config value for the texture pack 8889 int iConfig=app.GetTPConfigVal(pCurrent->wchFilename); 8890 app.AddMemoryTPDFile(iConfig, pbData, pFileData->dwSize); 8891 } 8892 break; 8893 default: 8894 // 4J-PB - check the data is an image 8895 if(pFileData->pbData[0]==0x89) 8896 { 8897 // 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 8898 PBYTE pbData = new BYTE [pFileData->dwSize]; 8899 memcpy(pbData,pFileData->pbData,pFileData->dwSize); 8900 8901 pClass->m_vTMSPPData.push_back(pbData); 8902 app.DebugPrintf("Got image data - %ls\n",pCurrent->wchFilename); 8903 app.AddMemoryTextureFile(pCurrent->wchFilename, pbData, pFileData->dwSize); 8904 } 8905 else 8906 { 8907 app.DebugPrintf("Got image data, but it's not a png - %ls\n",pCurrent->wchFilename); 8908 } 8909 break; 8910 } 8911 8912#else 8913 switch(pCurrent->eType) 8914 { 8915 case e_DLC_TexturePackData: 8916 { 8917 app.DebugPrintf("--- Got texturepack data %ls\n",pCurrent->wchFilename); 8918 // get the config value for the texture pack 8919 int iConfig=app.GetTPConfigVal(pCurrent->wchFilename); 8920 app.AddMemoryTPDFile(iConfig, pFileData->pbData, pFileData->dwSize); 8921 } 8922 break; 8923 default: 8924 app.DebugPrintf("--- Got image data - %ls\n",pCurrent->wchFilename); 8925 app.AddMemoryTextureFile(pCurrent->wchFilename, pFileData->pbData, pFileData->dwSize); 8926 break; 8927 } 8928#endif 8929 } 8930 else 8931 { 8932#ifdef _XBOX_ONE 8933 app.DebugPrintf("TMSImageReturned failed (%ls)...\n",wchFilename); 8934#else 8935 app.DebugPrintf("TMSImageReturned failed (%s)...\n",szFilename); 8936#endif 8937 } 8938 break; 8939 } 8940 8941 } 8942 LeaveCriticalSection(&pClass->csTMSPPDownloadQueue); 8943 8944 return 0; 8945} 8946#endif 8947 8948bool CMinecraftApp::RetrieveNextTMSPPContent() 8949{ 8950#if defined _XBOX || defined _XBOX_ONE 8951 // If there's already a retrieve in progress, quit 8952 // we may have re-ordered the list, so need to check every item 8953 8954 // is there a primary player and a network connection? 8955 if(ProfileManager.GetPrimaryPad()==-1) return false; 8956 8957 if(ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad())==false) return false; 8958 8959 EnterCriticalSection(&csTMSPPDownloadQueue); 8960 for(AUTO_VAR(it, m_TMSPPDownloadQueue.begin()); it != m_TMSPPDownloadQueue.end(); ++it) 8961 { 8962 TMSPPRequest *pCurrent = *it; 8963 8964 if(pCurrent->eState==e_TMS_ContentState_Retrieving) 8965 { 8966 app.DebugPrintf("."); 8967 LeaveCriticalSection(&csTMSPPDownloadQueue); 8968 return true; 8969 } 8970 } 8971 8972 // Now look for the next retrieval 8973 for(AUTO_VAR(it, m_TMSPPDownloadQueue.begin()); it != m_TMSPPDownloadQueue.end(); ++it) 8974 { 8975 TMSPPRequest *pCurrent = *it; 8976 8977 if(pCurrent->eState==e_TMS_ContentState_Queued) 8978 { 8979 // 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 8980 // return right away with a ETMSStatus_Fail_ReadDetailsNotRetrieved 8981#ifdef _XBOX 8982 char szFilename[MAX_TMSFILENAME_SIZE]; 8983 wcstombs(szFilename,pCurrent->wchFilename,MAX_TMSFILENAME_SIZE); 8984 8985 app.DebugPrintf("\nRetrieveNextTMSPPContent - type = %d, %s\n",pCurrent->eType,szFilename); 8986 8987 C4JStorage::ETMSStatus status=StorageManager.TMSPP_ReadFile(ProfileManager.GetPrimaryPad(),pCurrent->eStorageFacility,pCurrent->eFileTypeVal,szFilename,pCurrent->CallbackFunc,this); 8988 switch(status) 8989 { 8990 case C4JStorage::ETMSStatus_Pending: 8991 pCurrent->eState=e_TMS_ContentState_Retrieving; 8992 break; 8993 case C4JStorage::ETMSStatus_Idle: 8994 pCurrent->eState=e_TMS_ContentState_Retrieved; 8995 break; 8996 case C4JStorage::ETMSStatus_Fail_ReadInProgress: 8997 case C4JStorage::ETMSStatus_ReadInProgress: 8998 pCurrent->eState=e_TMS_ContentState_Retrieving; 8999 if(pCurrent->eState==C4JStorage::ETMSStatus_Fail_ReadInProgress) 9000 { 9001 app.DebugPrintf("TMSPP_ReadFile failed - read in progress\n"); 9002 Sleep(50); 9003 LeaveCriticalSection(&csTMSPPDownloadQueue); 9004 return false; 9005 } 9006 break; 9007 default: 9008 pCurrent->eState=e_TMS_ContentState_Retrieved; 9009 break; 9010 } 9011#else 9012 eTitleStorageState status; 9013 app.DebugPrintf("RetrieveNextTMSPPContent - type = %d, %ls\n",pCurrent->eType,pCurrent->wchFilename); 9014 //eTitleStorageState status=StorageManager.TMSPP_ReadFile(ProfileManager.GetPrimaryPad(),pCurrent->eStorageFacility,pCurrent->eFileTypeVal,pCurrent->wchFilename,pCurrent->CallbackFunc,this,0); 9015 if(0)//wcscmp(pCurrent->wchFilename,L"TP01.png")==0) 9016 { 9017 // TP01 fails because the blob size returned is bigger than the global metadata says it should be 9018 status=eTitleStorage_readerror; 9019 } 9020 else 9021 { 9022 status=StorageManager.TMSPP_ReadFile(ProfileManager.GetPrimaryPad(),pCurrent->eStorageFacility,pCurrent->eFileTypeVal,pCurrent->wchFilename,pCurrent->CallbackFunc,this,0); 9023 } 9024 switch(status) 9025 { 9026 case eTitleStorage_pending: 9027 pCurrent->eState=e_TMS_ContentState_Retrieving; 9028 break; 9029 case eTitleStorage_idle: 9030 pCurrent->eState=e_TMS_ContentState_Retrieved; 9031 break; 9032 case eTitleStorage_busy: 9033 // try again next time 9034 { 9035 app.DebugPrintf("@@@@@@@@@@@@@@@@@ TMSPP_ReadFile failed - busy (probably reading already)\n"); 9036 Sleep(50); 9037 LeaveCriticalSection(&csTMSPPDownloadQueue); 9038 return false; 9039 } 9040 break; 9041 default: 9042 pCurrent->eState=e_TMS_ContentState_Retrieved; 9043 break; 9044 } 9045#endif 9046 9047 9048 9049 LeaveCriticalSection(&csTMSPPDownloadQueue); 9050 return true; 9051 } 9052 } 9053 9054 LeaveCriticalSection(&csTMSPPDownloadQueue); 9055 9056#endif 9057 return false; 9058} 9059 9060void CMinecraftApp::TickDLCOffersRetrieved() 9061{ 9062 if(!m_bAllDLCContentRetrieved) 9063 { 9064 if (!app.RetrieveNextDLCContent()) 9065 { 9066 app.DebugPrintf("[Consoles_App] All content retrieved.\n"); 9067 m_bAllDLCContentRetrieved=true; 9068 } 9069 } 9070} 9071void CMinecraftApp::ClearAndResetDLCDownloadQueue() 9072{ 9073 app.DebugPrintf("[Consoles_App] Clear and reset download queue.\n"); 9074 9075 int iPosition=0; 9076 EnterCriticalSection(&csTMSPPDownloadQueue); 9077 for(AUTO_VAR(it, m_DLCDownloadQueue.begin()); it != m_DLCDownloadQueue.end(); ++it) 9078 { 9079 DLCRequest *pCurrent = *it; 9080 9081 delete pCurrent; 9082 iPosition++; 9083 } 9084 m_DLCDownloadQueue.clear(); 9085 m_bAllDLCContentRetrieved=true; 9086 LeaveCriticalSection(&csTMSPPDownloadQueue); 9087} 9088 9089void CMinecraftApp::TickTMSPPFilesRetrieved() 9090{ 9091 if(m_bTickTMSDLCFiles && !m_bAllTMSContentRetrieved) 9092 { 9093 if(app.RetrieveNextTMSPPContent()==false) 9094 { 9095 m_bAllTMSContentRetrieved=true; 9096 } 9097 } 9098} 9099void CMinecraftApp::ClearTMSPPFilesRetrieved() 9100{ 9101 int iPosition=0; 9102 EnterCriticalSection(&csTMSPPDownloadQueue); 9103 for(AUTO_VAR(it, m_TMSPPDownloadQueue.begin()); it != m_TMSPPDownloadQueue.end(); ++it) 9104 { 9105 TMSPPRequest *pCurrent = *it; 9106 9107 delete pCurrent; 9108 iPosition++; 9109 } 9110 m_TMSPPDownloadQueue.clear(); 9111 m_bAllTMSContentRetrieved=true; 9112 LeaveCriticalSection(&csTMSPPDownloadQueue); 9113} 9114 9115int CMinecraftApp::DLCOffersReturned(void *pParam, int iOfferC, DWORD dwType, int iPad) 9116{ 9117 CMinecraftApp* pClass = (CMinecraftApp *) pParam; 9118 9119 // find the right one in the vector 9120 EnterCriticalSection(&pClass->csTMSPPDownloadQueue); 9121 for(AUTO_VAR(it, pClass->m_DLCDownloadQueue.begin()); it != pClass->m_DLCDownloadQueue.end(); ++it) 9122 { 9123 DLCRequest *pCurrent = *it; 9124 9125 // avatar items are coming back as type Content, so we can't trust the type setting 9126 if(pCurrent->dwType==dwType) 9127 { 9128 pClass->m_iDLCOfferC = iOfferC; 9129 app.DebugPrintf("DLCOffersReturned - type %d, count %d - setting to retrieved\n",dwType,iOfferC); 9130 pCurrent->eState=e_DLC_ContentState_Retrieved; 9131 break; 9132 } 9133 } 9134 LeaveCriticalSection(&pClass->csTMSPPDownloadQueue); 9135 return 0; 9136} 9137 9138eDLCContentType CMinecraftApp::Find_eDLCContentType(DWORD dwType) 9139{ 9140 for(int i=0;i<e_DLC_MAX;i++) 9141 { 9142 if(m_dwContentTypeA[i]==dwType) 9143 { 9144 return (eDLCContentType)i; 9145 } 9146 } 9147 return (eDLCContentType)0; 9148} 9149bool CMinecraftApp::DLCContentRetrieved(eDLCMarketplaceType eType) 9150{ 9151 // If there's already a retrieve in progress, quit 9152 // we may have re-ordered the list, so need to check every item 9153 EnterCriticalSection(&csDLCDownloadQueue); 9154 for(AUTO_VAR(it, m_DLCDownloadQueue.begin()); it != m_DLCDownloadQueue.end(); ++it) 9155 { 9156 DLCRequest *pCurrent = *it; 9157 9158 if((pCurrent->dwType==m_dwContentTypeA[eType]) && (pCurrent->eState==e_DLC_ContentState_Retrieved)) 9159 { 9160 LeaveCriticalSection(&csDLCDownloadQueue); 9161 return true; 9162 } 9163 } 9164 LeaveCriticalSection(&csDLCDownloadQueue); 9165 return false; 9166} 9167 9168void CMinecraftApp::SetAdditionalSkinBoxes(DWORD dwSkinID, SKIN_BOX *SkinBoxA, DWORD dwSkinBoxC) 9169{ 9170 EntityRenderer *renderer = EntityRenderDispatcher::instance->getRenderer(eTYPE_PLAYER); 9171 Model *pModel = renderer->getModel(); 9172 vector<ModelPart *> *pvModelPart = new vector<ModelPart *>; 9173 vector<SKIN_BOX *> *pvSkinBoxes = new vector<SKIN_BOX *>; 9174 9175 EnterCriticalSection( &csAdditionalModelParts ); 9176 EnterCriticalSection( &csAdditionalSkinBoxes ); 9177 9178 app.DebugPrintf("*** SetAdditionalSkinBoxes - Inserting model parts for skin %d from array of Skin Boxes\n",dwSkinID&0x0FFFFFFF); 9179 9180 // convert the skin boxes into model parts, and add to the humanoid model 9181 for(unsigned int i=0;i<dwSkinBoxC;i++) 9182 { 9183 if(pModel) 9184 { 9185 ModelPart *pModelPart=pModel->AddOrRetrievePart(&SkinBoxA[i]); 9186 pvModelPart->push_back(pModelPart); 9187 pvSkinBoxes->push_back(&SkinBoxA[i]); 9188 } 9189 } 9190 9191 9192 m_AdditionalModelParts.insert( std::pair<DWORD, vector<ModelPart *> *>(dwSkinID, pvModelPart) ); 9193 m_AdditionalSkinBoxes.insert( std::pair<DWORD, vector<SKIN_BOX *> *>(dwSkinID, pvSkinBoxes) ); 9194 9195 LeaveCriticalSection( &csAdditionalSkinBoxes ); 9196 LeaveCriticalSection( &csAdditionalModelParts ); 9197 9198} 9199 9200vector<ModelPart *> * CMinecraftApp::SetAdditionalSkinBoxes(DWORD dwSkinID, vector<SKIN_BOX *> *pvSkinBoxA) 9201{ 9202 EntityRenderer *renderer = EntityRenderDispatcher::instance->getRenderer(eTYPE_PLAYER); 9203 Model *pModel = renderer->getModel(); 9204 vector<ModelPart *> *pvModelPart = new vector<ModelPart *>; 9205 9206 EnterCriticalSection( &csAdditionalModelParts ); 9207 EnterCriticalSection( &csAdditionalSkinBoxes ); 9208 app.DebugPrintf("*** SetAdditionalSkinBoxes - Inserting model parts for skin %d from array of Skin Boxes\n",dwSkinID&0x0FFFFFFF); 9209 9210 // convert the skin boxes into model parts, and add to the humanoid model 9211 for(AUTO_VAR(it, pvSkinBoxA->begin());it != pvSkinBoxA->end(); ++it) 9212 { 9213 if(pModel) 9214 { 9215 ModelPart *pModelPart=pModel->AddOrRetrievePart(*it); 9216 pvModelPart->push_back(pModelPart); 9217 } 9218 } 9219 9220 m_AdditionalModelParts.insert( std::pair<DWORD, vector<ModelPart *> *>(dwSkinID, pvModelPart) ); 9221 m_AdditionalSkinBoxes.insert( std::pair<DWORD, vector<SKIN_BOX *> *>(dwSkinID, pvSkinBoxA) ); 9222 9223 LeaveCriticalSection( &csAdditionalSkinBoxes ); 9224 LeaveCriticalSection( &csAdditionalModelParts ); 9225 return pvModelPart; 9226} 9227 9228 9229vector<ModelPart *> *CMinecraftApp::GetAdditionalModelParts(DWORD dwSkinID) 9230{ 9231 EnterCriticalSection( &csAdditionalModelParts ); 9232 vector<ModelPart *> *pvModelParts=NULL; 9233 if(m_AdditionalModelParts.size()>0) 9234 { 9235 AUTO_VAR(it, m_AdditionalModelParts.find(dwSkinID)); 9236 if(it!=m_AdditionalModelParts.end()) 9237 { 9238 pvModelParts = (*it).second; 9239 } 9240 } 9241 9242 LeaveCriticalSection( &csAdditionalModelParts ); 9243 return pvModelParts; 9244} 9245 9246vector<SKIN_BOX *> *CMinecraftApp::GetAdditionalSkinBoxes(DWORD dwSkinID) 9247{ 9248 EnterCriticalSection( &csAdditionalSkinBoxes ); 9249 vector<SKIN_BOX *> *pvSkinBoxes=NULL; 9250 if(m_AdditionalSkinBoxes.size()>0) 9251 { 9252 AUTO_VAR(it,m_AdditionalSkinBoxes.find(dwSkinID)); 9253 if(it!=m_AdditionalSkinBoxes.end()) 9254 { 9255 pvSkinBoxes = (*it).second; 9256 } 9257 } 9258 9259 LeaveCriticalSection( &csAdditionalSkinBoxes ); 9260 return pvSkinBoxes; 9261} 9262 9263unsigned int CMinecraftApp::GetAnimOverrideBitmask(DWORD dwSkinID) 9264{ 9265 EnterCriticalSection( &csAnimOverrideBitmask ); 9266 unsigned int uiAnimOverrideBitmask=0L; 9267 9268 if(m_AnimOverrides.size()>0) 9269 { 9270 AUTO_VAR(it, m_AnimOverrides.find(dwSkinID)); 9271 if(it!=m_AnimOverrides.end()) 9272 { 9273 uiAnimOverrideBitmask = (*it).second; 9274 } 9275 } 9276 9277 LeaveCriticalSection( &csAnimOverrideBitmask ); 9278 return uiAnimOverrideBitmask; 9279} 9280 9281void CMinecraftApp::SetAnimOverrideBitmask(DWORD dwSkinID,unsigned int uiAnimOverrideBitmask) 9282{ 9283 // Make thread safe 9284 EnterCriticalSection( &csAnimOverrideBitmask ); 9285 9286 if(m_AnimOverrides.size()>0) 9287 { 9288 AUTO_VAR(it, m_AnimOverrides.find(dwSkinID)); 9289 if(it!=m_AnimOverrides.end()) 9290 { 9291 LeaveCriticalSection( &csAnimOverrideBitmask ); 9292 return; // already in here 9293 } 9294 } 9295 m_AnimOverrides.insert( std::pair<DWORD, unsigned long>(dwSkinID, uiAnimOverrideBitmask) ); 9296 LeaveCriticalSection( &csAnimOverrideBitmask ); 9297} 9298 9299DWORD CMinecraftApp::getSkinIdFromPath(const wstring &skin) 9300{ 9301 bool dlcSkin = false; 9302 unsigned int skinId = 0; 9303 9304 if(skin.size() >= 14) 9305 { 9306 dlcSkin = skin.substr(0,3).compare(L"dlc") == 0; 9307 9308 wstring skinValue = skin.substr(7,skin.size()); 9309 skinValue = skinValue.substr(0,skinValue.find_first_of(L'.')); 9310 9311 std::wstringstream ss; 9312 // 4J Stu - dlc skins are numbered using decimal to make it easier for artists/people to number manually 9313 // Everything else is numbered using hex 9314 if(dlcSkin) 9315 ss << std::dec << skinValue.c_str(); 9316 else 9317 ss << std::hex << skinValue.c_str(); 9318 ss >> skinId; 9319 9320 skinId = MAKE_SKIN_BITMASK(dlcSkin, skinId); 9321 } 9322 return skinId; 9323} 9324 9325wstring CMinecraftApp::getSkinPathFromId(DWORD skinId) 9326{ 9327 // 4J Stu - This function maps the encoded DWORD we store in the player profile 9328 // to a filename that is stored as a memory texture and shared between systems in game 9329 wchar_t chars[256]; 9330 if( GET_IS_DLC_SKIN_FROM_BITMASK(skinId) ) 9331 { 9332 // 4J Stu - DLC skins are numbered using decimal rather than hex to make it easier to number manually 9333 swprintf(chars, 256, L"dlcskin%08d.png", GET_DLC_SKIN_ID_FROM_BITMASK(skinId)); 9334 9335 } 9336 else 9337 { 9338 DWORD ugcSkinIndex = GET_UGC_SKIN_ID_FROM_BITMASK(skinId); 9339 DWORD defaultSkinIndex = GET_DEFAULT_SKIN_ID_FROM_BITMASK(skinId); 9340 if( ugcSkinIndex == 0 ) 9341 { 9342 swprintf(chars, 256, L"defskin%08X.png",defaultSkinIndex); 9343 } 9344 else 9345 { 9346 swprintf(chars, 256, L"ugcskin%08X.png",ugcSkinIndex); 9347 } 9348 } 9349 return chars; 9350} 9351 9352 9353int CMinecraftApp::TexturePackDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 9354{ 9355 9356 9357#if defined __PSVITA__ || defined __PS3__ || defined __ORBIS__ 9358 if(result==C4JStorage::EMessage_ResultAccept) 9359 { 9360 Minecraft *pMinecraft = Minecraft::GetInstance(); 9361 if( pMinecraft->skins->selectTexturePackById(app.GetRequiredTexturePackID()) ) 9362 { 9363 // it's been installed already 9364 } 9365 else 9366 { 9367 // we need to enable background downloading for the DLC 9368 XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); 9369 SONYDLC *pSONYDLCInfo=app.GetSONYDLCInfo(app.GetRequiredTexturePackID()); 9370 if(pSONYDLCInfo!=NULL) 9371 { 9372 char chName[42]; 9373 char chKeyName[20]; 9374 char chSkuID[SCE_NP_COMMERCE2_SKU_ID_LEN]; 9375 9376 memset(chSkuID,0,SCE_NP_COMMERCE2_SKU_ID_LEN); 9377 // we have to retrieve the skuid from the store info, it can't be hardcoded since Sony may change it. 9378 // So we assume the first sku for the product is the one we want 9379 // MGH - keyname in the DLC file is 16 chars long, but there's no space for a NULL terminating char 9380 memset(chKeyName, 0, sizeof(chKeyName)); 9381 strncpy(chKeyName, pSONYDLCInfo->chDLCKeyname, 16); 9382 9383 #ifdef __ORBIS__ 9384 strcpy(chName, chKeyName); 9385 #else 9386 sprintf(chName,"%s-%s",app.GetCommerceCategory(),chKeyName); 9387 #endif 9388 app.GetDLCSkuIDFromProductList(chName,chSkuID); 9389 // 4J-PB - need to check for an empty store 9390 if(app.CheckForEmptyStore(iPad)==false) 9391 { 9392 if(app.DLCAlreadyPurchased(chSkuID)) 9393 { 9394 app.DownloadAlreadyPurchased(chSkuID); 9395 } 9396 else 9397 { 9398 app.Checkout(chSkuID); 9399 } 9400 } 9401 } 9402 } 9403 } 9404 else 9405 { 9406 app.DebugPrintf("Continuing without installing texture pack\n"); 9407 } 9408#endif 9409 9410#ifdef _XBOX 9411 if(result!=C4JStorage::EMessage_Cancelled) 9412 { 9413 if(app.GetRequiredTexturePackID()!=0) 9414 { 9415 // we need to enable background downloading for the DLC 9416 XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); 9417 9418 ULONGLONG ullOfferID_Full; 9419 ULONGLONG ullIndexA[1]; 9420 app.GetDLCFullOfferIDForPackID(app.GetRequiredTexturePackID(),&ullOfferID_Full); 9421 9422 if( result==C4JStorage::EMessage_ResultAccept ) // Full version 9423 { 9424 ullIndexA[0]=ullOfferID_Full; 9425 StorageManager.InstallOffer(1,ullIndexA,NULL,NULL); 9426 } 9427 else // trial version 9428 { 9429 DLC_INFO *pDLCInfo=app.GetDLCInfoForFullOfferID(ullOfferID_Full); 9430 ullIndexA[0]=pDLCInfo->ullOfferID_Trial; 9431 StorageManager.InstallOffer(1,ullIndexA,NULL,NULL); 9432 } 9433 } 9434 } 9435#endif 9436 return 0; 9437} 9438 9439int CMinecraftApp::getArchiveFileSize(const wstring &filename) 9440{ 9441 TexturePack *tPack = NULL; 9442 Minecraft *pMinecraft = Minecraft::GetInstance(); 9443 if(pMinecraft && pMinecraft->skins) tPack = pMinecraft->skins->getSelected(); 9444 if(tPack && tPack->hasData() && tPack->getArchiveFile() && tPack->getArchiveFile()->hasFile(filename)) 9445 { 9446 return tPack->getArchiveFile()->getFileSize(filename); 9447 } 9448 else return m_mediaArchive->getFileSize(filename); 9449} 9450 9451bool CMinecraftApp::hasArchiveFile(const wstring &filename) 9452{ 9453 TexturePack *tPack = NULL; 9454 Minecraft *pMinecraft = Minecraft::GetInstance(); 9455 if(pMinecraft && pMinecraft->skins) tPack = pMinecraft->skins->getSelected(); 9456 if(tPack && tPack->hasData() && tPack->getArchiveFile() && tPack->getArchiveFile()->hasFile(filename)) return true; 9457 else return m_mediaArchive->hasFile(filename); 9458} 9459 9460byteArray CMinecraftApp::getArchiveFile(const wstring &filename) 9461{ 9462 TexturePack *tPack = NULL; 9463 Minecraft *pMinecraft = Minecraft::GetInstance(); 9464 if(pMinecraft && pMinecraft->skins) tPack = pMinecraft->skins->getSelected(); 9465 if(tPack && tPack->hasData() && tPack->getArchiveFile() && tPack->getArchiveFile()->hasFile(filename)) 9466 { 9467 return tPack->getArchiveFile()->getFile(filename); 9468 } 9469 else return m_mediaArchive->getFile(filename); 9470} 9471 9472// DLC 9473 9474#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) 9475int CMinecraftApp::GetDLCInfoCount() 9476{ 9477 return (int)DLCInfo.size(); 9478} 9479#elif defined _XBOX_ONE 9480int CMinecraftApp::GetDLCInfoTrialOffersCount() 9481{ 9482 return 0; 9483} 9484 9485int CMinecraftApp::GetDLCInfoFullOffersCount() 9486{ 9487 return (int)DLCInfo_Full.size(); 9488} 9489#else 9490int CMinecraftApp::GetDLCInfoTrialOffersCount() 9491{ 9492 return (int)DLCInfo_Trial.size(); 9493} 9494 9495int CMinecraftApp::GetDLCInfoFullOffersCount() 9496{ 9497 return (int)DLCInfo_Full.size(); 9498} 9499#endif 9500 9501int CMinecraftApp::GetDLCInfoTexturesOffersCount() 9502{ 9503 return (int)DLCTextures_PackID.size(); 9504} 9505 9506// AUTOSAVE 9507void CMinecraftApp::SetAutosaveTimerTime(void) 9508{ 9509#if defined(_XBOX_ONE) || defined(__ORBIS__) 9510 m_uiAutosaveTimer= GetTickCount()+1000*60; 9511#else 9512 m_uiAutosaveTimer= GetTickCount()+GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_Autosave)*1000*60*15; 9513#endif 9514}// value x 15 to get mins, x60 for secs 9515 9516bool CMinecraftApp::AutosaveDue(void) 9517{ 9518 return (GetTickCount()>m_uiAutosaveTimer); 9519} 9520 9521unsigned int CMinecraftApp::SecondsToAutosave() 9522{ 9523 return (m_uiAutosaveTimer - GetTickCount() ) / 1000; 9524} 9525 9526void CMinecraftApp::SetTrialTimerStart(void) 9527{ 9528 m_fTrialTimerStart=m_Time.fAppTime; mfTrialPausedTime=0.0f; 9529} 9530 9531float CMinecraftApp::getTrialTimer(void) 9532{ 9533 return m_Time.fAppTime-m_fTrialTimerStart-mfTrialPausedTime; 9534} 9535 9536bool CMinecraftApp::IsLocalMultiplayerAvailable() 9537{ 9538 DWORD connectedControllers = 0; 9539 for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) 9540 { 9541 if( InputManager.IsPadConnected(i) || ProfileManager.IsSignedIn(i) ) ++connectedControllers; 9542 } 9543 9544#ifdef _WINDOWS64 9545 bool available = connectedControllers > 1; 9546#else 9547 bool available = RenderManager.IsHiDef() && connectedControllers > 1; 9548#endif 9549 9550#ifdef __ORBIS__ 9551 // Check for remote play 9552 available = available && InputManager.IsLocalMultiplayerAvailable(); 9553#endif 9554 9555 return available; 9556 9557 // Found this in GameNetworkManager? 9558 //#ifdef _DURANGO 9559 // iOtherConnectedControllers = InputManager.GetConnectedGamepadCount(); 9560 // if((InputManager.IsPadConnected(userIndex) || ProfileManager.IsSignedIn(userIndex))) 9561 // { 9562 // --iOtherConnectedControllers; 9563 // } 9564 //#else 9565 // for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) 9566 // { 9567 // if( (i!=userIndex) && (InputManager.IsPadConnected(i) || ProfileManager.IsSignedIn(i)) ) 9568 // { 9569 // iOtherConnectedControllers++; 9570 // } 9571 // } 9572 //#endif 9573} 9574 9575 9576// 4J-PB - language and locale function 9577 9578void CMinecraftApp::getLocale(vector<wstring> &vecWstrLocales) 9579{ 9580 vector<eMCLang> locales; 9581 9582 DWORD dwSystemLanguage = XGetLanguage( ); 9583 9584 // 4J-PB - restrict the 360 language until we're ready to have them in 9585 9586#ifdef _XBOX 9587 switch(dwSystemLanguage) 9588 { 9589 case XC_LANGUAGE_FRENCH : 9590 locales.push_back(eMCLang_frFR); 9591 break; 9592 case XC_LANGUAGE_ITALIAN : 9593 locales.push_back(eMCLang_itIT); 9594 break; 9595 case XC_LANGUAGE_GERMAN : 9596 locales.push_back(eMCLang_deDE); 9597 break; 9598 case XC_LANGUAGE_SPANISH : 9599 locales.push_back(eMCLang_esES); 9600 break; 9601 case XC_LANGUAGE_PORTUGUESE : 9602 if(XGetLocale()==XC_LOCALE_BRAZIL) 9603 { 9604 locales.push_back(eMCLang_ptBR); 9605 } 9606 locales.push_back(eMCLang_ptPT); 9607 break; 9608 case XC_LANGUAGE_JAPANESE : 9609 locales.push_back(eMCLang_jaJP); 9610 break; 9611 case XC_LANGUAGE_KOREAN : 9612 locales.push_back(eMCLang_koKR); 9613 break; 9614 case XC_LANGUAGE_TCHINESE : 9615 locales.push_back(eMCLang_zhCHT); 9616 break; 9617 } 9618#else 9619 switch(dwSystemLanguage) 9620 { 9621 9622 case XC_LANGUAGE_ENGLISH: 9623 switch(XGetLocale()) 9624 { 9625 case XC_LOCALE_AUSTRALIA: 9626 case XC_LOCALE_CANADA: 9627 case XC_LOCALE_CZECH_REPUBLIC: 9628 case XC_LOCALE_GREECE: 9629 case XC_LOCALE_HONG_KONG: 9630 case XC_LOCALE_HUNGARY: 9631 case XC_LOCALE_INDIA: 9632 case XC_LOCALE_IRELAND: 9633 case XC_LOCALE_ISRAEL: 9634 case XC_LOCALE_NEW_ZEALAND: 9635 case XC_LOCALE_SAUDI_ARABIA: 9636 case XC_LOCALE_SINGAPORE: 9637 case XC_LOCALE_SLOVAK_REPUBLIC: 9638 case XC_LOCALE_SOUTH_AFRICA: 9639 case XC_LOCALE_UNITED_ARAB_EMIRATES: 9640 case XC_LOCALE_GREAT_BRITAIN: 9641 locales.push_back(eMCLang_enGB); 9642 break; 9643 default: //XC_LOCALE_UNITED_STATES 9644 break; 9645 } 9646 break; 9647 case XC_LANGUAGE_JAPANESE : 9648 locales.push_back(eMCLang_jaJP); 9649 break; 9650 case XC_LANGUAGE_GERMAN : 9651 switch(XGetLocale()) 9652 { 9653 case XC_LOCALE_AUSTRIA: 9654 locales.push_back(eMCLang_deAT); 9655 break; 9656 case XC_LOCALE_SWITZERLAND: 9657 locales.push_back(eMCLang_deCH); 9658 break; 9659 default:// XC_LOCALE_GERMANY: 9660 break; 9661 } 9662 locales.push_back(eMCLang_deDE); 9663 break; 9664 case XC_LANGUAGE_FRENCH : 9665 switch(XGetLocale()) 9666 { 9667 case XC_LOCALE_BELGIUM: 9668 locales.push_back(eMCLang_frBE); 9669 break; 9670 case XC_LOCALE_CANADA: 9671 locales.push_back(eMCLang_frCA); 9672 break; 9673 case XC_LOCALE_SWITZERLAND: 9674 locales.push_back(eMCLang_frCH); 9675 break; 9676 default:// XC_LOCALE_FRANCE: 9677 break; 9678 } 9679 locales.push_back(eMCLang_frFR); 9680 break; 9681 case XC_LANGUAGE_SPANISH : 9682 switch(XGetLocale()) 9683 { 9684 case XC_LOCALE_MEXICO: 9685 case XC_LOCALE_ARGENTINA: 9686 case XC_LOCALE_CHILE: 9687 case XC_LOCALE_COLOMBIA: 9688 case XC_LOCALE_UNITED_STATES: 9689 case XC_LOCALE_LATIN_AMERICA: 9690 locales.push_back(eMCLang_laLAS); 9691 locales.push_back(eMCLang_esMX); 9692 break; 9693 default://XC_LOCALE_SPAIN 9694 break; 9695 } 9696 locales.push_back(eMCLang_esES); 9697 break; 9698 case XC_LANGUAGE_ITALIAN : 9699 locales.push_back(eMCLang_itIT); 9700 break; 9701 case XC_LANGUAGE_KOREAN : 9702 locales.push_back(eMCLang_koKR); 9703 break; 9704 case XC_LANGUAGE_TCHINESE : 9705 switch(XGetLocale()) 9706 { 9707 case XC_LOCALE_HONG_KONG: 9708 locales.push_back(eMCLang_zhHK); 9709 locales.push_back(eMCLang_zhTW); 9710 break; 9711 case XC_LOCALE_TAIWAN: 9712 locales.push_back(eMCLang_zhTW); 9713 locales.push_back(eMCLang_zhHK); 9714 default: 9715 break; 9716 } 9717 locales.push_back(eMCLang_hant); 9718 locales.push_back(eMCLang_zhCHT); 9719 break; 9720 case XC_LANGUAGE_PORTUGUESE : 9721 if(XGetLocale()==XC_LOCALE_BRAZIL) 9722 { 9723 locales.push_back(eMCLang_ptBR); 9724 } 9725 locales.push_back(eMCLang_ptPT); 9726 break; 9727 case XC_LANGUAGE_POLISH : 9728 locales.push_back(eMCLang_plPL); 9729 break; 9730 case XC_LANGUAGE_RUSSIAN : 9731 locales.push_back(eMCLang_ruRU); 9732 break; 9733 case XC_LANGUAGE_SWEDISH : 9734 locales.push_back(eMCLang_svSV); 9735 locales.push_back(eMCLang_svSE); 9736 break; 9737 case XC_LANGUAGE_TURKISH : 9738 locales.push_back(eMCLang_trTR); 9739 break; 9740 case XC_LANGUAGE_BNORWEGIAN : 9741 locales.push_back(eMCLang_nbNO); 9742 locales.push_back(eMCLang_noNO); 9743 locales.push_back(eMCLang_nnNO); 9744 break; 9745 case XC_LANGUAGE_DUTCH : 9746 switch(XGetLocale()) 9747 { 9748 case XC_LOCALE_BELGIUM: 9749 locales.push_back(eMCLang_nlBE); 9750 break; 9751 default: 9752 break; 9753 } 9754 locales.push_back(eMCLang_nlNL); 9755 break; 9756 case XC_LANGUAGE_SCHINESE : 9757 switch(XGetLocale()) 9758 { 9759 case XC_LOCALE_SINGAPORE: 9760 locales.push_back(eMCLang_zhSG); 9761 break; 9762 default: 9763 break; 9764 } 9765 locales.push_back(eMCLang_hans); 9766 locales.push_back(eMCLang_csCS); 9767 locales.push_back(eMCLang_zhCN); 9768 break; 9769 9770#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ || defined _DURANGO 9771 case XC_LANGUAGE_DANISH: 9772 locales.push_back(eMCLang_daDA); 9773 locales.push_back(eMCLang_daDK); 9774 break; 9775 9776 case XC_LANGUAGE_FINISH : 9777 locales.push_back(eMCLang_fiFI); 9778 break; 9779 9780 case XC_LANGUAGE_CZECH : 9781 locales.push_back(eMCLang_csCZ); 9782 locales.push_back(eMCLang_enCZ); 9783 break; 9784 9785 case XC_LANGUAGE_SLOVAK : 9786 locales.push_back(eMCLang_skSK); 9787 locales.push_back(eMCLang_enSK); 9788 break; 9789 9790 case XC_LANGUAGE_GREEK : 9791 locales.push_back(eMCLang_elEL); 9792 locales.push_back(eMCLang_elGR); 9793 locales.push_back(eMCLang_enGR); 9794 locales.push_back(eMCLang_enGB); 9795 break; 9796#endif 9797 } 9798#endif 9799 9800 locales.push_back(eMCLang_enUS); 9801 locales.push_back(eMCLang_null); 9802 9803 for (int i=0; i<locales.size(); i++) 9804 { 9805 eMCLang lang = locales.at(i); 9806 vecWstrLocales.push_back( m_localeA[lang] ); 9807 } 9808} 9809 9810DWORD CMinecraftApp::get_eMCLang(WCHAR *pwchLocale) 9811{ 9812 return m_eMCLangA[pwchLocale]; 9813} 9814 9815 9816DWORD CMinecraftApp::get_xcLang(WCHAR *pwchLocale) 9817{ 9818 return m_xcLangA[pwchLocale]; 9819} 9820 9821void CMinecraftApp::LocaleAndLanguageInit() 9822{ 9823 m_localeA[eMCLang_zhCHT] =L"zh-CHT"; 9824 m_localeA[eMCLang_csCS] =L"cs-CS"; 9825 m_localeA[eMCLang_laLAS] =L"la-LAS"; 9826 m_localeA[eMCLang_null] =L"en-EN"; 9827 m_localeA[eMCLang_enUS] =L"en-US"; 9828 m_localeA[eMCLang_enGB] =L"en-GB"; 9829 m_localeA[eMCLang_enIE] =L"en-IE"; 9830 m_localeA[eMCLang_enAU] =L"en-AU"; 9831 m_localeA[eMCLang_enNZ] =L"en-NZ"; 9832 m_localeA[eMCLang_enCA] =L"en-CA"; 9833 m_localeA[eMCLang_jaJP] =L"ja-JP"; 9834 m_localeA[eMCLang_deDE] =L"de-DE"; 9835 m_localeA[eMCLang_deAT] =L"de-AT"; 9836 m_localeA[eMCLang_frFR] =L"fr-FR"; 9837 m_localeA[eMCLang_frCA] =L"fr-CA"; 9838 m_localeA[eMCLang_esES] =L"es-ES"; 9839 m_localeA[eMCLang_esMX] =L"es-MX"; 9840 m_localeA[eMCLang_itIT] =L"it-IT"; 9841 m_localeA[eMCLang_koKR] =L"ko-KR"; 9842 m_localeA[eMCLang_ptPT] =L"pt-PT"; 9843 m_localeA[eMCLang_ptBR] =L"pt-BR"; 9844 m_localeA[eMCLang_ruRU] =L"ru-RU"; 9845 m_localeA[eMCLang_nlNL] =L"nl-NL"; 9846 m_localeA[eMCLang_fiFI] =L"fi-FI"; 9847 m_localeA[eMCLang_svSV] =L"sv-SV"; 9848 m_localeA[eMCLang_daDA] =L"da-DA"; 9849 m_localeA[eMCLang_noNO] =L"no-NO"; 9850 m_localeA[eMCLang_plPL] =L"pl-PL"; 9851 m_localeA[eMCLang_trTR] =L"tr-TR"; 9852 m_localeA[eMCLang_elEL] =L"el-EL"; 9853 9854 m_localeA[eMCLang_zhSG] =L"zh-SG"; 9855 m_localeA[eMCLang_zhCN] =L"zh-CN"; 9856 m_localeA[eMCLang_zhHK] =L"zh-HK"; 9857 m_localeA[eMCLang_zhTW] =L"zh-TW"; 9858 m_localeA[eMCLang_nlBE] =L"nl-BE"; 9859 m_localeA[eMCLang_daDK] =L"da-DK"; 9860 m_localeA[eMCLang_frBE] =L"fr-BE"; 9861 m_localeA[eMCLang_frCH] =L"fr-CH"; 9862 m_localeA[eMCLang_deCH] =L"de-CH"; 9863 m_localeA[eMCLang_nbNO] =L"nb-NO"; 9864 m_localeA[eMCLang_enGR] =L"en-GR"; 9865 m_localeA[eMCLang_enHK] =L"en-HK"; 9866 m_localeA[eMCLang_enSA] =L"en-SA"; 9867 m_localeA[eMCLang_enHU] =L"en-HU"; 9868 m_localeA[eMCLang_enIN] =L"en-IN"; 9869 m_localeA[eMCLang_enIL] =L"en-IL"; 9870 m_localeA[eMCLang_enSG] =L"en-SG"; 9871 m_localeA[eMCLang_enSK] =L"en-SK"; 9872 m_localeA[eMCLang_enZA] =L"en-ZA"; 9873 m_localeA[eMCLang_enCZ] =L"en-CZ"; 9874 m_localeA[eMCLang_enAE] =L"en-AE"; 9875 m_localeA[eMCLang_esAR] =L"es-AR"; 9876 m_localeA[eMCLang_esCL] =L"es-CL"; 9877 m_localeA[eMCLang_esCO] =L"es-CO"; 9878 m_localeA[eMCLang_esUS] =L"es-US"; 9879 m_localeA[eMCLang_svSE] =L"sv-SE"; 9880 9881 m_localeA[eMCLang_csCZ] =L"cs-CZ"; 9882 m_localeA[eMCLang_elGR] =L"el-GR"; 9883 m_localeA[eMCLang_nnNO] =L"nn-NO"; 9884 m_localeA[eMCLang_skSK] =L"sk-SK"; 9885 9886 m_localeA[eMCLang_hans] =L"zh-HANS"; 9887 m_localeA[eMCLang_hant] =L"zh-HANT"; 9888 9889 m_eMCLangA[L"zh-CHT"] =eMCLang_zhCHT; 9890 m_eMCLangA[L"cs-CS"] =eMCLang_csCS; 9891 m_eMCLangA[L"la-LAS"] =eMCLang_laLAS; 9892 m_eMCLangA[L"en-EN"] =eMCLang_null; 9893 m_eMCLangA[L"en-US"] =eMCLang_enUS; 9894 m_eMCLangA[L"en-GB"] =eMCLang_enGB; 9895 m_eMCLangA[L"en-IE"] =eMCLang_enIE; 9896 m_eMCLangA[L"en-AU"] =eMCLang_enAU; 9897 m_eMCLangA[L"en-NZ"] =eMCLang_enNZ; 9898 m_eMCLangA[L"en-CA"] =eMCLang_enCA; 9899 m_eMCLangA[L"ja-JP"] =eMCLang_jaJP; 9900 m_eMCLangA[L"de-DE"] =eMCLang_deDE; 9901 m_eMCLangA[L"de-AT"] =eMCLang_deAT; 9902 m_eMCLangA[L"fr-FR"] =eMCLang_frFR; 9903 m_eMCLangA[L"fr-CA"] =eMCLang_frCA; 9904 m_eMCLangA[L"es-ES"] =eMCLang_esES; 9905 m_eMCLangA[L"es-MX"] =eMCLang_esMX; 9906 m_eMCLangA[L"it-IT"] =eMCLang_itIT; 9907 m_eMCLangA[L"ko-KR"] =eMCLang_koKR; 9908 m_eMCLangA[L"pt-PT"] =eMCLang_ptPT; 9909 m_eMCLangA[L"pt-BR"] =eMCLang_ptBR; 9910 m_eMCLangA[L"ru-RU"] =eMCLang_ruRU; 9911 m_eMCLangA[L"nl-NL"] =eMCLang_nlNL; 9912 m_eMCLangA[L"fi-FI"] =eMCLang_fiFI; 9913 m_eMCLangA[L"sv-SV"] =eMCLang_svSV; 9914 m_eMCLangA[L"da-DA"] =eMCLang_daDA; 9915 m_eMCLangA[L"no-NO"] =eMCLang_noNO; 9916 m_eMCLangA[L"pl-PL"] =eMCLang_plPL; 9917 m_eMCLangA[L"tr-TR"] =eMCLang_trTR; 9918 m_eMCLangA[L"el-EL"] =eMCLang_elEL; 9919 9920 m_eMCLangA[L"zh-SG"] =eMCLang_zhSG; 9921 m_eMCLangA[L"zh-CN"] =eMCLang_zhCN; 9922 m_eMCLangA[L"zh-HK"] =eMCLang_zhHK; 9923 m_eMCLangA[L"zh-TW"] =eMCLang_zhTW; 9924 m_eMCLangA[L"nl-BE"] =eMCLang_nlBE; 9925 m_eMCLangA[L"da-DK"] =eMCLang_daDK; 9926 m_eMCLangA[L"fr-BE"] =eMCLang_frBE; 9927 m_eMCLangA[L"fr-CH"] =eMCLang_frCH; 9928 m_eMCLangA[L"de-CH"] =eMCLang_deCH; 9929 m_eMCLangA[L"nb-NO"] =eMCLang_nbNO; 9930 m_eMCLangA[L"en-GR"] =eMCLang_enGR; 9931 m_eMCLangA[L"en-HK"] =eMCLang_enHK; 9932 m_eMCLangA[L"en-SA"] =eMCLang_enSA; 9933 m_eMCLangA[L"en-HU"] =eMCLang_enHU; 9934 m_eMCLangA[L"en-IN"] =eMCLang_enIN; 9935 m_eMCLangA[L"en-IL"] =eMCLang_enIL; 9936 m_eMCLangA[L"en-SG"] =eMCLang_enSG; 9937 m_eMCLangA[L"en-SK"] =eMCLang_enSK; 9938 m_eMCLangA[L"en-ZA"] =eMCLang_enZA; 9939 m_eMCLangA[L"en-CZ"] =eMCLang_enCZ; 9940 m_eMCLangA[L"en-AE"] =eMCLang_enAE; 9941 m_eMCLangA[L"es-AR"] =eMCLang_esAR; 9942 m_eMCLangA[L"es-CL"] =eMCLang_esCL; 9943 m_eMCLangA[L"es-CO"] =eMCLang_esCO; 9944 m_eMCLangA[L"es-US"] =eMCLang_esUS; 9945 m_eMCLangA[L"sv-SE"] =eMCLang_svSE; 9946 9947 m_eMCLangA[L"cs-CZ"] =eMCLang_csCZ; 9948 m_eMCLangA[L"el-GR"] =eMCLang_elGR; 9949 m_eMCLangA[L"nn-NO"] =eMCLang_nnNO; 9950 m_eMCLangA[L"sk-SK"] =eMCLang_skSK; 9951 9952 m_eMCLangA[L"zh-HANS"] =eMCLang_hans; 9953 m_eMCLangA[L"zh-HANT"] =eMCLang_hant; 9954 9955 m_xcLangA[L"zh-CHT"] =XC_LOCALE_CHINA; 9956 m_xcLangA[L"cs-CS"] =XC_LOCALE_CHINA; 9957 m_xcLangA[L"en-EN"] =XC_LOCALE_UNITED_STATES; 9958 m_xcLangA[L"en-US"] =XC_LOCALE_UNITED_STATES; 9959 m_xcLangA[L"en-GB"] =XC_LOCALE_GREAT_BRITAIN; 9960 m_xcLangA[L"en-IE"] =XC_LOCALE_IRELAND; 9961 m_xcLangA[L"en-AU"] =XC_LOCALE_AUSTRALIA; 9962 m_xcLangA[L"en-NZ"] =XC_LOCALE_NEW_ZEALAND; 9963 m_xcLangA[L"en-CA"] =XC_LOCALE_CANADA; 9964 m_xcLangA[L"ja-JP"] =XC_LOCALE_JAPAN; 9965 m_xcLangA[L"de-DE"] =XC_LOCALE_GERMANY; 9966 m_xcLangA[L"de-AT"] =XC_LOCALE_AUSTRIA; 9967 m_xcLangA[L"fr-FR"] =XC_LOCALE_FRANCE; 9968 m_xcLangA[L"fr-CA"] =XC_LOCALE_CANADA; 9969 m_xcLangA[L"es-ES"] =XC_LOCALE_SPAIN; 9970 m_xcLangA[L"es-MX"] =XC_LOCALE_MEXICO; 9971 m_xcLangA[L"it-IT"] =XC_LOCALE_ITALY; 9972 m_xcLangA[L"ko-KR"] =XC_LOCALE_KOREA; 9973 m_xcLangA[L"pt-PT"] =XC_LOCALE_PORTUGAL; 9974 m_xcLangA[L"pt-BR"] =XC_LOCALE_BRAZIL; 9975 m_xcLangA[L"ru-RU"] =XC_LOCALE_RUSSIAN_FEDERATION; 9976 m_xcLangA[L"nl-NL"] =XC_LOCALE_NETHERLANDS; 9977 m_xcLangA[L"fi-FI"] =XC_LOCALE_FINLAND; 9978 m_xcLangA[L"sv-SV"] =XC_LOCALE_SWEDEN; 9979 m_xcLangA[L"da-DA"] =XC_LOCALE_DENMARK; 9980 m_xcLangA[L"no-NO"] =XC_LOCALE_NORWAY; 9981 m_xcLangA[L"pl-PL"] =XC_LOCALE_POLAND; 9982 m_xcLangA[L"tr-TR"] =XC_LOCALE_TURKEY; 9983 m_xcLangA[L"el-EL"] =XC_LOCALE_GREECE; 9984#ifndef _XBOX 9985 m_xcLangA[L"la-LAS"] =XC_LOCALE_LATIN_AMERICA; 9986#endif 9987 9988 // New ones for Xbox One 9989 m_xcLangA[L"zh-SG"] =XC_LOCALE_SINGAPORE; 9990 m_xcLangA[L"Zh-CN"] =XC_LOCALE_CHINA; 9991 m_xcLangA[L"zh-HK"] =XC_LOCALE_HONG_KONG; 9992 m_xcLangA[L"zh-TW"] =XC_LOCALE_TAIWAN; 9993 m_xcLangA[L"nl-BE"] =XC_LOCALE_BELGIUM; 9994 m_xcLangA[L"da-DK"] =XC_LOCALE_DENMARK; 9995 m_xcLangA[L"fr-BE"] =XC_LOCALE_BELGIUM; 9996 m_xcLangA[L"fr-CH"] =XC_LOCALE_SWITZERLAND; 9997 m_xcLangA[L"de-CH"] =XC_LOCALE_SWITZERLAND; 9998 m_xcLangA[L"nb-NO"] =XC_LOCALE_NORWAY; 9999 m_xcLangA[L"en-GR"] =XC_LOCALE_GREECE; 10000 m_xcLangA[L"en-HK"] =XC_LOCALE_HONG_KONG; 10001 m_xcLangA[L"en-SA"] =XC_LOCALE_SAUDI_ARABIA; 10002 m_xcLangA[L"en-HU"] =XC_LOCALE_HUNGARY; 10003 m_xcLangA[L"en-IN"] =XC_LOCALE_INDIA; 10004 m_xcLangA[L"en-IL"] =XC_LOCALE_ISRAEL; 10005 m_xcLangA[L"en-SG"] =XC_LOCALE_SINGAPORE; 10006 m_xcLangA[L"en-SK"] =XC_LOCALE_SLOVAK_REPUBLIC; 10007 m_xcLangA[L"en-ZA"] =XC_LOCALE_SOUTH_AFRICA; 10008 m_xcLangA[L"en-CZ"] =XC_LOCALE_CZECH_REPUBLIC; 10009 m_xcLangA[L"en-AE"] =XC_LOCALE_UNITED_ARAB_EMIRATES; 10010 m_xcLangA[L"ja-IP"] =XC_LOCALE_JAPAN; 10011 m_xcLangA[L"es-AR"] =XC_LOCALE_ARGENTINA; 10012 m_xcLangA[L"es-CL"] =XC_LOCALE_CHILE; 10013 m_xcLangA[L"es-CO"] =XC_LOCALE_COLOMBIA; 10014 m_xcLangA[L"es-US"] =XC_LOCALE_UNITED_STATES; 10015 m_xcLangA[L"sv-SE"] =XC_LOCALE_SWEDEN; 10016 10017 m_xcLangA[L"cs-CZ"] =XC_LOCALE_CZECH_REPUBLIC; 10018 m_xcLangA[L"el-GR"] =XC_LOCALE_GREECE; 10019 m_xcLangA[L"sk-SK"] =XC_LOCALE_SLOVAK_REPUBLIC; 10020 10021 m_xcLangA[L"zh-HANS"] =XC_LOCALE_CHINA; 10022 m_xcLangA[L"zh-HANT"] =XC_LOCALE_CHINA; 10023} 10024 10025void CMinecraftApp::SetTickTMSDLCFiles(bool bVal) 10026{ 10027 // 4J-PB - we need to stop the retrieval of minecraft store images from TMS when we aren't in the DLC, since going in to Play Game will change the title id group 10028 m_bTickTMSDLCFiles=bVal; 10029} 10030 10031wstring CMinecraftApp::getFilePath(DWORD packId, wstring filename, bool bAddDataFolder, wstring mountPoint) 10032{ 10033 wstring path = getRootPath(packId, true, bAddDataFolder, mountPoint) + filename; 10034 File f(path); 10035 if(f.exists()) 10036 { 10037 return path; 10038 } 10039 return getRootPath(packId, false, true, mountPoint) + filename; 10040} 10041 10042#ifdef _XBOX 10043// Texture packs that have their data in the TU data 10044enum ETitleUpdateTexturePacks 10045{ 10046 eTUTP_MassEffect = 0x400, 10047 eTUTP_Skyrim = 0x401, 10048 eTUTP_Halo = 0x402, 10049 eTUTP_Festive = 0x405, 10050 10051 eTUTP_Plastic = 0x801, 10052 eTUTP_Candy = 0x802, 10053 eTUTP_Fantasy = 0x803, 10054 eTUTP_Halloween = 0x804, 10055 eTUTP_Natural = 0x805, 10056 eTUTP_City = 0x01000806, // 4J Stu - The released City pack had a sub-pack ID 10057 eTUTP_Cartoon = 0x807, 10058 eTUTP_Steampunk = 0x01000808, // 4J Stu - The released Steampunk pack had a sub-pack ID 10059}; 10060 10061#ifdef _TU_BUILD 10062wstring titleUpdateTexturePackRoot = L"UPDATE:\\res\\DLC\\"; 10063#else 10064wstring titleUpdateTexturePackRoot = L"GAME:\\res\\TitleUpdate\\DLC\\"; 10065#endif 10066#else 10067enum ETitleUpdateTexturePacks 10068{ 10069 //eTUTP_MassEffect = 0x400, 10070 //eTUTP_Skyrim = 0x401, 10071 //eTUTP_Halo = 0x402, 10072 //eTUTP_Festive = 0x405, 10073 10074 //eTUTP_Plastic = 0x801, 10075 //eTUTP_Candy = 0x802, 10076 //eTUTP_Fantasy = 0x803, 10077 eTUTP_Halloween = 0x804, 10078 //eTUTP_Natural = 0x805, 10079 //eTUTP_City = 0x01000806, // 4J Stu - The released City pack had a sub-pack ID 10080 //eTUTP_Cartoon = 0x807, 10081 //eTUTP_Steampunk = 0x01000808, // 4J Stu - The released Steampunk pack had a sub-pack ID 10082}; 10083 10084#ifdef _WINDOWS64 10085wstring titleUpdateTexturePackRoot = L"Windows64\\DLC\\"; 10086#elif defined(__ORBIS__) 10087wstring titleUpdateTexturePackRoot = L"/app0/orbis/CU/DLC/"; 10088#elif defined(__PSVITA__) 10089wstring titleUpdateTexturePackRoot = L"PSVita/CU/DLC/"; 10090#elif defined(__PS3__) 10091wstring titleUpdateTexturePackRoot = L"PS3/CU/DLC/"; 10092#else 10093wstring titleUpdateTexturePackRoot = L"CU\\DLC\\"; 10094#endif 10095 10096#endif 10097 10098wstring CMinecraftApp::getRootPath(DWORD packId, bool allowOverride, bool bAddDataFolder, wstring mountPoint) 10099{ 10100 wstring path = mountPoint; 10101#ifdef _XBOX 10102 if(allowOverride) 10103 { 10104 switch(packId) 10105 { 10106 case eTUTP_MassEffect: 10107 path = titleUpdateTexturePackRoot + L"MassEffect"; 10108 break; 10109 case eTUTP_Skyrim: 10110 path = titleUpdateTexturePackRoot + L"Skyrim"; 10111 break; 10112 case eTUTP_Halo: 10113 path = titleUpdateTexturePackRoot + L"Halo"; 10114 break; 10115 case eTUTP_Festive: 10116 path = titleUpdateTexturePackRoot + L"Festive"; 10117 break; 10118 case eTUTP_Plastic: 10119 path = titleUpdateTexturePackRoot + L"Plastic"; 10120 break; 10121 case eTUTP_Candy: 10122 path = titleUpdateTexturePackRoot + L"Candy"; 10123 break; 10124 case eTUTP_Fantasy: 10125 path = titleUpdateTexturePackRoot + L"Fantasy"; 10126 break; 10127 case eTUTP_Halloween: 10128 path = titleUpdateTexturePackRoot + L"Halloween"; 10129 break; 10130 case eTUTP_Natural: 10131 path = titleUpdateTexturePackRoot + L"Natural"; 10132 break; 10133 case eTUTP_City: 10134 path = titleUpdateTexturePackRoot + L"City"; 10135 break; 10136 case eTUTP_Cartoon: 10137 path = titleUpdateTexturePackRoot + L"Cartoon"; 10138 break; 10139 case eTUTP_Steampunk: 10140 path = titleUpdateTexturePackRoot + L"Steampunk"; 10141 break; 10142 }; 10143 File folder(path); 10144 if(!folder.exists()) 10145 { 10146 path = mountPoint; 10147 } 10148 } 10149#else 10150 if(allowOverride) 10151 { 10152 switch(packId) 10153 { 10154 case eTUTP_Halloween: 10155 path = titleUpdateTexturePackRoot + L"Halloween Texture Pack"; 10156 break; 10157 }; 10158 File folder(path); 10159 if(!folder.exists()) 10160 { 10161 path = mountPoint; 10162 } 10163 } 10164#endif 10165 10166 if(bAddDataFolder) 10167 { 10168 return path + L"\\Data\\"; 10169 } 10170 else 10171 { 10172 return path + L"\\"; 10173 } 10174 10175} 10176 10177#ifdef _XBOX_ONE 10178void CMinecraftApp::SetReachedMainMenu() 10179{ 10180 m_hasReachedMainMenu = true; 10181} 10182 10183bool CMinecraftApp::HasReachedMainMenu() 10184{ 10185 return m_hasReachedMainMenu; 10186} 10187#endif