the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 1462 lines 45 kB view raw
1#include "stdafx.h" 2#include "..\..\..\Minecraft.World\Socket.h" 3#include "..\..\..\Minecraft.World\StringHelpers.h" 4#include "PlatformNetworkManagerSony.h" 5#include "NetworkPlayerSony.h" 6#include "..\..\Common\Network\GameNetworkManager.h" 7 8CPlatformNetworkManagerSony *g_pPlatformNetworkManager; 9 10bool CPlatformNetworkManagerSony::IsLocalGame() 11{ 12 return m_bIsOfflineGame; 13} 14bool CPlatformNetworkManagerSony::IsPrivateGame() 15{ 16 return m_bIsPrivateGame; 17} 18bool CPlatformNetworkManagerSony::IsLeavingGame() 19{ 20 return m_bLeavingGame; 21} 22void CPlatformNetworkManagerSony::ResetLeavingGame() 23{ 24 m_bLeavingGame = false; 25} 26 27 28void CPlatformNetworkManagerSony::HandleStateChange(SQRNetworkManager::eSQRNetworkManagerState oldState, SQRNetworkManager::eSQRNetworkManagerState newState, bool idleReasonIsSessionFull) 29{ 30 static const char * c_apszStateNames[] = 31 { 32 "SNM_STATE_INITIALISING", 33 "SNM_STATE_INITIALISE_FAILED", 34 "SNM_STATE_IDLE", 35 "SNM_STATE_HOSTING", 36 "SNM_STATE_JOINING", 37 "SNM_STATE_STARTING", 38 "SNM_STATE_PLAYING", 39 "SNM_STATE_LEAVING", 40 "SNM_STATE_ENDING", 41 }; 42 43 app.DebugPrintf( "Network State: %s ==> %s\n", 44 c_apszStateNames[ oldState ], 45 c_apszStateNames[ newState ] ); 46 47 if( newState == SQRNetworkManager::SNM_STATE_HOSTING ) 48 { 49 m_bLeavingGame = false; 50 m_bLeaveGameOnTick = false; 51 m_bHostChanged = false; 52 g_NetworkManager.StateChange_AnyToHosting(); 53 } 54 else if( newState == SQRNetworkManager::SNM_STATE_JOINING ) 55 { 56 // 4J Stu - We may be accepting an invite from the DLC menu, so hide the icon 57#if defined __ORBIS__ || defined __PSVITA__ 58 app.GetCommerce()->HidePsStoreIcon(); 59#endif 60 m_bLeavingGame = false; 61 m_bLeaveGameOnTick = false; 62 m_bHostChanged = false; 63 g_NetworkManager.StateChange_AnyToJoining(); 64 } 65 else if( newState == SQRNetworkManager::SNM_STATE_IDLE && oldState == SQRNetworkManager::SNM_STATE_JOINING ) 66 { 67 if( idleReasonIsSessionFull ) 68 { 69 g_NetworkManager.StateChange_JoiningToIdle(JOIN_FAILED_SERVER_FULL); 70 } 71 else 72 { 73 g_NetworkManager.StateChange_JoiningToIdle(JOIN_FAILED_NONSPECIFIC); 74 } 75 } 76 else if( newState == SQRNetworkManager::SNM_STATE_IDLE && oldState == SQRNetworkManager::SNM_STATE_HOSTING ) 77 { 78 m_bLeavingGame = true; 79 } 80 else if( newState == SQRNetworkManager::SNM_STATE_STARTING ) 81 { 82 m_lastPlayerEventTimeStart = app.getAppTime(); 83 84 g_NetworkManager.StateChange_AnyToStarting(); 85 } 86 // Fix for #93148 - TCR 001: BAS Game Stability: Title will crash for the multiplayer client if host of the game will exit during the clients loading to created world. 87 // 4J Stu - If the client joins just as the host is exiting, then they can skip to leaving without passing through ending 88 else if( newState == SQRNetworkManager::SNM_STATE_ENDING ) 89 { 90 g_NetworkManager.StateChange_AnyToEnding( oldState == SQRNetworkManager::SNM_STATE_PLAYING ); 91 92 // 4J-PB - Only the host can leave here - the clients will hang if m_bLeavingGame is set to true here 93 if( m_pSQRNet->IsHost() ) 94 { 95 m_bLeavingGame = true; 96 } 97 } 98 99 if( newState == SQRNetworkManager::SNM_STATE_IDLE ) 100 { 101 // On PS3, sometimes we're getting a SNM_STATE_ENDING transition to SNM_STATE_IDLE on joining, because the server context being deleted sets the state away from SNM_STATE_JOINING before we detect 102 // the cause for the disconnection. This means we don't pick up on the joining->idle transition. Set disconnection reason here too for this case. 103 if( idleReasonIsSessionFull ) 104 { 105 app.SetDisconnectReason( DisconnectPacket::eDisconnect_ServerFull ); 106 } 107 g_NetworkManager.StateChange_AnyToIdle(); 108 } 109} 110 111void CPlatformNetworkManagerSony::HandleDataReceived(SQRNetworkPlayer *playerFrom, SQRNetworkPlayer *playerTo, unsigned char *data, unsigned int dataSize) 112{ 113 if(m_pSQRNet->GetState() == SQRNetworkManager::SNM_STATE_ENDING) 114 { 115 return; 116 } 117 118 if( playerTo->IsHost() ) 119 { 120 // If we are the host we care who this came from 121 //app.DebugPrintf( "Pushing data into host read queue for user \"%ls\"\n", pPlayerFrom->GetGamertag()); 122 // Push this data into the read queue for the player that sent it 123 INetworkPlayer *pPlayerFrom = getNetworkPlayer(playerFrom); 124 Socket *socket = pPlayerFrom->GetSocket(); 125 126 if(socket != NULL) 127 socket->pushDataToQueue(data, dataSize, false); 128 } 129 else 130 { 131 // If we are not the host the message must have come from the host, so we care more about who it is addressed to 132 INetworkPlayer *pPlayerTo = getNetworkPlayer(playerTo); 133 Socket *socket = pPlayerTo->GetSocket(); 134 //app.DebugPrintf( "Pushing data into read queue for user \"%ls\"\n", apPlayersTo[dwPlayer]->GetGamertag()); 135 if(socket != NULL) 136 socket->pushDataToQueue(data, dataSize); 137 } 138} 139 140void CPlatformNetworkManagerSony::HandlePlayerJoined(SQRNetworkPlayer * pSQRPlayer) 141{ 142 const char * pszDescription; 143 144 // 4J Stu - We create a fake socket for every where that we need an INBOUND queue of game data. Outbound 145 // is all handled by QNet so we don't need that. Therefore each client player has one, and the host has one 146 // for each client player. 147 bool createFakeSocket = false; 148 bool localPlayer = false; 149 150 NetworkPlayerSony *networkPlayer = (NetworkPlayerSony *)addNetworkPlayer(pSQRPlayer); 151 152 if( pSQRPlayer->IsLocal() ) 153 { 154 localPlayer = true; 155 if( pSQRPlayer->IsHost() ) 156 { 157 pszDescription = "local host"; 158 // 4J Stu - No socket for the localhost as it uses a special loopback queue 159 160 m_machineSQRPrimaryPlayers.push_back( pSQRPlayer ); 161 } 162 else 163 { 164 pszDescription = "local"; 165 166 // We need an inbound queue on all local players to receive data from the host 167 createFakeSocket = true; 168 } 169 } 170 else 171 { 172 if( pSQRPlayer->IsHost() ) 173 { 174 pszDescription = "remote host"; 175 } 176 else 177 { 178 pszDescription = "remote"; 179 180 // If we are the host, then create a fake socket for every remote player 181 if( m_pSQRNet->IsHost() ) 182 { 183 createFakeSocket = true; 184 } 185 } 186 187 if( m_pSQRNet->IsHost() && !m_bHostChanged ) 188 { 189 // Do we already have a primary player for this system? 190 bool systemHasPrimaryPlayer = false; 191 for(AUTO_VAR(it, m_machineSQRPrimaryPlayers.begin()); it < m_machineSQRPrimaryPlayers.end(); ++it) 192 { 193 SQRNetworkPlayer *pQNetPrimaryPlayer = *it; 194 if( pSQRPlayer->IsSameSystem(pQNetPrimaryPlayer) ) 195 { 196 systemHasPrimaryPlayer = true; 197 break; 198 } 199 } 200 if( !systemHasPrimaryPlayer ) 201 m_machineSQRPrimaryPlayers.push_back( pSQRPlayer ); 202 } 203 } 204 g_NetworkManager.PlayerJoining( networkPlayer ); 205 206 if( createFakeSocket == true && !m_bHostChanged ) 207 { 208 g_NetworkManager.CreateSocket( networkPlayer, localPlayer ); 209 } 210 211#if 0 212 app.DebugPrintf( "Player 0x%p \"%ls\" joined; %s; voice %i; camera %i.\n", 213 pSQRPlayer, 214 pSQRPlayer->GetGamertag(), 215 pszDescription, 216 (int) pSQRPlayer->HasVoice(), 217 (int) pSQRPlayer->HasCamera() ); 218#endif 219 220 221 if( m_pSQRNet->IsHost() ) 222 { 223 // 4J-PB - only the host should do this 224 g_NetworkManager.UpdateAndSetGameSessionData(); 225 SystemFlagAddPlayer( networkPlayer ); 226 } 227 228 for( int idx = 0; idx < XUSER_MAX_COUNT; ++idx) 229 { 230 if(playerChangedCallback[idx] != NULL) 231 playerChangedCallback[idx]( playerChangedCallbackParam[idx], networkPlayer, false ); 232 } 233 234 if(true) // TODO m_pSQRNet->GetState() == QNET_STATE_GAME_PLAY) 235 { 236 int localPlayerCount = 0; 237 for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) 238 { 239 if( m_pSQRNet->GetLocalPlayerByUserIndex(idx) != NULL ) ++localPlayerCount; 240 } 241 242 float appTime = app.getAppTime(); 243 244 // Only record stats for the primary player here 245 m_lastPlayerEventTimeStart = appTime; 246 } 247} 248 249void CPlatformNetworkManagerSony::HandlePlayerLeaving(SQRNetworkPlayer *pSQRPlayer) 250{ 251 //__debugbreak(); 252 253 app.DebugPrintf( "Player 0x%p leaving.\n", 254 pSQRPlayer ); 255 256 INetworkPlayer *networkPlayer = getNetworkPlayer(pSQRPlayer); 257 258 if( networkPlayer ) 259 { 260 // Get our wrapper object associated with this player. 261 Socket *socket = networkPlayer->GetSocket(); 262 if( socket != NULL ) 263 { 264 // If we are in game then remove this player from the game as well. 265 // We may get here either from the player requesting to exit the game, 266 // in which case we they will already have left the game server, or from a disconnection 267 // where we then have to remove them from the game server 268 if( m_pSQRNet->IsHost() && !m_bHostChanged ) 269 { 270 g_NetworkManager.CloseConnection(networkPlayer); 271 } 272 273 // Free the wrapper object memory. 274 // TODO 4J Stu - We may still be using this at the point that the player leaves the session. 275 // We need this as long as the game server still needs to communicate with the player 276 //delete socket; 277 278 networkPlayer->SetSocket( NULL ); 279 } 280 281 if( m_pSQRNet->IsHost() && !m_bHostChanged ) 282 { 283 if( isSystemPrimaryPlayer(pSQRPlayer) ) 284 { 285 SQRNetworkPlayer *pNewSQRPrimaryPlayer = NULL; 286 for(unsigned int i = 0; i < m_pSQRNet->GetPlayerCount(); ++i ) 287 { 288 SQRNetworkPlayer *pSQRPlayer2 = m_pSQRNet->GetPlayerByIndex( i ); 289 290 if ( pSQRPlayer2 != NULL && pSQRPlayer2 != pSQRPlayer && pSQRPlayer2->IsSameSystem( pSQRPlayer ) ) 291 { 292 pNewSQRPrimaryPlayer = pSQRPlayer2; 293 break; 294 } 295 } 296 AUTO_VAR(it, find( m_machineSQRPrimaryPlayers.begin(), m_machineSQRPrimaryPlayers.end(), pSQRPlayer)); 297 if( it != m_machineSQRPrimaryPlayers.end() ) 298 { 299 m_machineSQRPrimaryPlayers.erase( it ); 300 } 301 302 if( pNewSQRPrimaryPlayer != NULL ) 303 m_machineSQRPrimaryPlayers.push_back( pNewSQRPrimaryPlayer ); 304 } 305 306 g_NetworkManager.UpdateAndSetGameSessionData( networkPlayer ); 307 SystemFlagRemovePlayer( networkPlayer ); 308 309 } 310 311 g_NetworkManager.PlayerLeaving( networkPlayer ); 312 313 for( int idx = 0; idx < XUSER_MAX_COUNT; ++idx) 314 { 315 if(playerChangedCallback[idx] != NULL) 316 playerChangedCallback[idx]( playerChangedCallbackParam[idx], networkPlayer, true ); 317 } 318 319 if(m_pSQRNet->GetState() == SQRNetworkManager::SNM_STATE_PLAYING) 320 { 321 int localPlayerCount = 0; 322 for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) 323 { 324 if( m_pSQRNet->GetLocalPlayerByUserIndex(idx) != NULL ) ++localPlayerCount; 325 } 326 327 float appTime = app.getAppTime(); 328 m_lastPlayerEventTimeStart = appTime; 329 } 330 331 removeNetworkPlayer(pSQRPlayer); 332 } 333} 334 335// Update our external data to match the current internal player slots, and resync back out (host only) 336void CPlatformNetworkManagerSony::HandleResyncPlayerRequest(SQRNetworkPlayer **aPlayers) 337{ 338 m_hostGameSessionData.playerCount = 0; 339 for(int i = 0; i < SQRNetworkManager::MAX_ONLINE_PLAYER_COUNT; i++ ) 340 { 341 if( aPlayers[i] ) 342 { 343 m_hostGameSessionData.players[i] = aPlayers[i]->GetUID(); 344 m_hostGameSessionData.playerCount++; 345 } 346 else 347 { 348 memset(&m_hostGameSessionData.players[i],0,sizeof(m_hostGameSessionData.players[i])); 349 } 350 } 351 m_pSQRNet->UpdateExternalRoomData(); 352} 353 354void CPlatformNetworkManagerSony::HandleAddLocalPlayerFailed(int idx) 355{ 356 g_NetworkManager.AddLocalPlayerFailed(idx); 357} 358 359void CPlatformNetworkManagerSony::HandleDisconnect(bool bLostRoomOnly,bool bPSNSignOut) 360{ 361 g_NetworkManager.HandleDisconnect(bLostRoomOnly,bPSNSignOut); 362} 363 364void CPlatformNetworkManagerSony::HandleInviteReceived( int userIndex, const SQRNetworkManager::PresenceSyncInfo *pInviteInfo) 365{ 366 g_NetworkManager.GameInviteReceived( userIndex, pInviteInfo ); 367} 368 369extern SQRNetworkManager *testSQRNetworkManager; 370 371bool CPlatformNetworkManagerSony::Initialise(CGameNetworkManager *pGameNetworkManager, int flagIndexSize) 372{ 373 // Create a sony network manager, and go online 374#ifdef __ORBIS__ 375 m_pSQRNet = new SQRNetworkManager_Orbis(this); 376 m_pSQRNet->Initialise(); 377#elif defined __PS3__ 378 m_pSQRNet = new SQRNetworkManager_PS3(this); 379 m_pSQRNet->Initialise(); 380#else // __PSVITA__ 381 // m_pSQRNet = new SQRNetworkManager_Vita(this); 382 m_bUsingAdhocMode = false; 383 m_pSQRNet_Vita_Adhoc = new SQRNetworkManager_AdHoc_Vita(this); 384 m_pSQRNet_Vita = new SQRNetworkManager_Vita(this); 385 386 m_pSQRNet = m_pSQRNet_Vita; 387 388 // 4J-PB - seems we can't initialise both adhoc and psn comms - from Rohan - "having adhoc matching and matching2 library initialised together results in undesired behaviour", but probably having other parts initialised also is 'undesirable' 389 390 m_pSQRNet_Vita->Initialise(); 391 392 if(ProfileManager.IsSignedInPSN(ProfileManager.GetPrimaryPad())) 393 { 394 // we're signed into the PSN, but we won't be online yet, force a sign-in online here 395 m_pSQRNet_Vita->AttemptPSNSignIn(NULL, NULL); 396 } 397 398 399#endif 400 401 m_pGameNetworkManager = pGameNetworkManager; 402 m_flagIndexSize = flagIndexSize; 403 g_pPlatformNetworkManager = this; 404 for( int i = 0; i < XUSER_MAX_COUNT; i++ ) 405 { 406 playerChangedCallback[ i ] = NULL; 407 } 408 409 m_bLeavingGame = false; 410 m_bLeaveGameOnTick = false; 411 m_bHostChanged = false; 412 m_bLeaveRoomWhenLeavingGame = true; 413 414 m_bSearchPending = false; 415 416 m_bIsOfflineGame = false; 417 m_pSearchParam = NULL; 418 m_SessionsUpdatedCallback = NULL; 419 420 m_searchResultsCount = 0; 421 m_pSearchResults = NULL; 422 423 m_lastSearchStartTime = 0; 424 425 // Success! 426 return true; 427} 428 429void CPlatformNetworkManagerSony::Terminate() 430{ 431 m_pSQRNet->Terminate(); 432} 433 434int CPlatformNetworkManagerSony::GetJoiningReadyPercentage() 435{ 436 return m_pSQRNet->GetJoiningReadyPercentage(); 437} 438 439int CPlatformNetworkManagerSony::CorrectErrorIDS(int IDS) 440{ 441 // Attempts to remap the following messages to provide something that PS3 TCRs are happier with 442 // 443 // IDS_CONNECTION_LOST - "Connection lost" 444 // IDS_CONNECTION_FAILED - "Connection failed" 445 // IDS_CONNECTION_LOST_LIVE - "Connection to "PSN" was lost. Exiting to the main menu." 446 // IDS_CONNECTION_LOST_LIVE_NO_EXIT - "Connection to "PSN" was lost." 447 // IDS_CONNECTION_LOST_SERVER - "Connection to the server was lost. Exiting to the main menu." 448 // 449 // Map to: 450 // 451 // IDS_ERROR_NETWORK - "A network error has occurred" 452 // IDS_ERROR_NETWORK_TITLE - "Network Error" 453 // IDS_ERROR_NETWORK_EXIT - "A network error has occurred. Exiting to Main Menu." 454 // IDS_ERROR_PSN_SIGN_OUT - You have been signed out from the "PSN". 455 // IDS_ERROR_PSN_SIGN_OUT_EXIT - You have been signed out from the "PSN". Exiting to Main Menu 456 457 // Determine if we'd prefer to present errors as a signing out issue, rather than a network issue, based on whether we have a network connection at all or not 458 bool preferSignoutError = false; 459 int state; 460 461#if defined __PSVITA__ // MGH - to fix devtrack #6258 462 if(!ProfileManager.IsSignedInPSN(ProfileManager.GetPrimaryPad())) 463 preferSignoutError = true; 464#elif defined __ORBIS__ 465 if(!ProfileManager.isSignedInPSN(ProfileManager.GetPrimaryPad())) 466 preferSignoutError = true; 467#elif defined __PS3__ 468 int ret = cellNetCtlGetState( &state ); 469 int IPObtainedState = CELL_NET_CTL_STATE_IPObtained; 470 if( ret == 0 ) 471 { 472 if( state == IPObtainedState ) 473 { 474 preferSignoutError = true; 475 } 476 } 477#endif 478 479#ifdef __PSVITA__ 480 // If we're in ad-hoc mode this problem definitely wasn't PSN related 481 if (usingAdhocMode()) preferSignoutError = false; 482#endif 483 484 // If we're the host we haven't lost connection to the server 485 if (IDS == IDS_CONNECTION_LOST_SERVER && g_NetworkManager.IsHost()) 486 { 487 IDS = IDS_CONNECTION_LOST_LIVE; 488 } 489 490 switch(IDS) 491 { 492 case IDS_CONNECTION_LOST: 493 case IDS_CONNECTION_FAILED: 494 return IDS_ERROR_NETWORK_TITLE; 495 case IDS_CONNECTION_LOST_LIVE: 496 if( preferSignoutError ) 497 { 498 return IDS_ERROR_PSN_SIGN_OUT_EXIT; 499 } 500 else 501 { 502 return IDS_ERROR_NETWORK_EXIT; 503 } 504 case IDS_CONNECTION_LOST_LIVE_NO_EXIT: 505 if( preferSignoutError ) 506 { 507 return IDS_ERROR_PSN_SIGN_OUT; 508 } 509 else 510 { 511 return IDS_ERROR_NETWORK_TITLE; 512 } 513 break; 514#ifdef __PSVITA__ 515 case IDS_CONNECTION_LOST_SERVER: 516 if(preferSignoutError) 517 { 518 if(ProfileManager.IsSignedInPSN(ProfileManager.GetPrimaryPad()) == false) 519 return IDS_ERROR_PSN_SIGN_OUT_EXIT; 520 } 521#endif 522 default: 523 return IDS; 524 } 525 526 527} 528 529bool CPlatformNetworkManagerSony::isSystemPrimaryPlayer(SQRNetworkPlayer *pSQRPlayer) 530{ 531 bool playerIsSystemPrimary = false; 532 for(AUTO_VAR(it, m_machineSQRPrimaryPlayers.begin()); it < m_machineSQRPrimaryPlayers.end(); ++it) 533 { 534 SQRNetworkPlayer *pSQRPrimaryPlayer = *it; 535 if( pSQRPrimaryPlayer == pSQRPlayer ) 536 { 537 playerIsSystemPrimary = true; 538 break; 539 } 540 } 541 return playerIsSystemPrimary; 542} 543 544// We call this twice a frame, either side of the render call so is a good place to "tick" things 545void CPlatformNetworkManagerSony::DoWork() 546{ 547#if 0 548 DWORD dwNotifyId; 549 ULONG_PTR ulpNotifyParam; 550 551 while( XNotifyGetNext( 552 m_notificationListener, 553 0, // Any notification 554 &dwNotifyId, 555 &ulpNotifyParam) 556 ) 557 { 558 559 switch(dwNotifyId) 560 { 561 562 case XN_SYS_SIGNINCHANGED: 563 app.DebugPrintf("Signinchanged - %d\n", ulpNotifyParam); 564 break; 565 case XN_LIVE_INVITE_ACCEPTED: 566 // ignore these - we're catching them from the game listener, so we can get the one from the dashboard 567 break; 568 default: 569 m_pIQNet->Notify(dwNotifyId,ulpNotifyParam); 570 break; 571 } 572 573 } 574 575 TickSearch(); 576 577 if( m_bLeaveGameOnTick ) 578 { 579 m_pIQNet->LeaveGame(m_migrateHostOnLeave); 580 m_bLeaveGameOnTick = false; 581 } 582 583 m_pIQNet->DoWork(); 584#else 585 TickSearch(); 586 587 if( m_bLeaveGameOnTick ) 588 { 589 m_pSQRNet->LeaveRoom(m_bLeaveRoomWhenLeavingGame); 590 m_bLeaveGameOnTick = false; 591 } 592 593 m_pSQRNet->Tick(); 594#endif 595} 596 597int CPlatformNetworkManagerSony::GetPlayerCount() 598{ 599 return m_pSQRNet->GetPlayerCount(); 600} 601 602bool CPlatformNetworkManagerSony::ShouldMessageForFullSession() 603{ 604 return false; 605} 606 607int CPlatformNetworkManagerSony::GetOnlinePlayerCount() 608{ 609 return m_pSQRNet->GetOnlinePlayerCount(); 610} 611 612int CPlatformNetworkManagerSony::GetLocalPlayerMask(int playerIndex) 613{ 614 return 1 << playerIndex; 615} 616 617bool CPlatformNetworkManagerSony::AddLocalPlayerByUserIndex( int userIndex ) 618{ 619 return m_pSQRNet->AddLocalPlayerByUserIndex(userIndex); 620} 621 622bool CPlatformNetworkManagerSony::RemoveLocalPlayerByUserIndex( int userIndex ) 623{ 624 SQRNetworkPlayer *pSQRPlayer = m_pSQRNet->GetLocalPlayerByUserIndex(userIndex); 625 INetworkPlayer *pNetworkPlayer = getNetworkPlayer(pSQRPlayer); 626 627 if(pNetworkPlayer != NULL) 628 { 629 Socket *socket = pNetworkPlayer->GetSocket(); 630 631 if( socket != NULL ) 632 { 633 // We can't remove the player from qnet until we have stopped using it to communicate 634 C4JThread* thread = new C4JThread(&CPlatformNetworkManagerSony::RemovePlayerOnSocketClosedThreadProc, pNetworkPlayer, "RemovePlayerOnSocketClosed"); 635 thread->SetProcessor( CPU_CORE_REMOVE_PLAYER ); 636 thread->Run(); 637 } 638 else 639 { 640 // Safe to remove the player straight away 641 return m_pSQRNet->RemoveLocalPlayerByUserIndex(userIndex); 642 } 643 } 644 return true; 645} 646 647bool CPlatformNetworkManagerSony::IsInStatsEnabledSession() 648{ 649#if 0 650 DWORD dataSize = sizeof(QNET_LIVE_STATS_MODE); 651 QNET_LIVE_STATS_MODE statsMode; 652 m_pIQNet->GetOpt(QNET_OPTION_LIVE_STATS_MODE, &statsMode , &dataSize ); 653 654 // Use QNET_LIVE_STATS_MODE_AUTO if there is another way to check if stats are enabled or not 655 bool statsEnabled = statsMode == QNET_LIVE_STATS_MODE_ENABLED; 656 return m_pIQNet->GetState() != QNET_STATE_IDLE && statsEnabled; 657#endif 658 return true; 659} 660 661bool CPlatformNetworkManagerSony::SessionHasSpace(unsigned int spaceRequired /*= 1*/) 662{ 663 return m_pSQRNet->SessionHasSpace(spaceRequired); 664#if 0 665 // This function is used while a session is running, so all players trying to join 666 // should use public slots, 667 DWORD publicSlots = 0; 668 DWORD filledPublicSlots = 0; 669 DWORD privateSlots = 0; 670 DWORD filledPrivateSlots = 0; 671 672 DWORD dataSize = sizeof(DWORD); 673 m_pIQNet->GetOpt(QNET_OPTION_TOTAL_PUBLIC_SLOTS, &publicSlots, &dataSize ); 674 m_pIQNet->GetOpt(QNET_OPTION_FILLED_PUBLIC_SLOTS, &filledPublicSlots, &dataSize ); 675 m_pIQNet->GetOpt(QNET_OPTION_TOTAL_PRIVATE_SLOTS, &privateSlots, &dataSize ); 676 m_pIQNet->GetOpt(QNET_OPTION_FILLED_PRIVATE_SLOTS, &filledPrivateSlots, &dataSize ); 677 678 DWORD spaceLeft = (publicSlots - filledPublicSlots) + (privateSlots - filledPrivateSlots); 679 680 return spaceLeft >= spaceRequired; 681#else 682 return true; 683#endif 684} 685 686void CPlatformNetworkManagerSony::SendInviteGUI(int quadrant) 687{ 688 m_pSQRNet->SendInviteGUI(); 689} 690 691bool CPlatformNetworkManagerSony::IsAddingPlayer() 692{ 693 return false; 694} 695 696bool CPlatformNetworkManagerSony::LeaveGame(bool bMigrateHost) 697{ 698 if( m_bLeavingGame ) return true; 699 700 m_bLeavingGame = true; 701 702 // If we are a client, wait for all client connections to close 703 // TODO Possibly need to do multiple objects depending on how split screen online works 704 SQRNetworkPlayer *pSQRPlayer = m_pSQRNet->GetLocalPlayerByUserIndex(g_NetworkManager.GetPrimaryPad()); 705 INetworkPlayer *pNetworkPlayer = getNetworkPlayer(pSQRPlayer); 706 707 if(pNetworkPlayer != NULL) 708 { 709 Socket *socket = pNetworkPlayer->GetSocket(); 710 711 if( socket != NULL ) 712 { 713 //printf("Waiting for socket closed event\n"); 714 DWORD result = socket->m_socketClosedEvent->WaitForSignal(INFINITE); 715 716 // The session might be gone once the socket releases 717 if( IsInSession() ) 718 { 719 //printf("Socket closed event has fired\n"); 720 // 4J Stu - Clear our reference to this socket 721 pSQRPlayer = m_pSQRNet->GetLocalPlayerByUserIndex(g_NetworkManager.GetPrimaryPad()); 722 pNetworkPlayer = getNetworkPlayer(pSQRPlayer); 723 pNetworkPlayer->SetSocket( NULL ); 724 } 725 delete socket; 726 } 727 else 728 { 729 //printf("Socket is already NULL\n"); 730 } 731 } 732 733 // If we are the host wait for the game server to end 734 if(m_pSQRNet->IsHost() && g_NetworkManager.ServerStoppedValid()) 735 { 736 m_pSQRNet->EndGame(); 737 g_NetworkManager.ServerStoppedWait(); 738 g_NetworkManager.ServerStoppedDestroy(); 739 } 740 741 return _LeaveGame(bMigrateHost, true); 742} 743 744bool CPlatformNetworkManagerSony::_LeaveGame(bool bMigrateHost, bool bLeaveRoom) 745{ 746 // 4J Stu - Fix for #10490 - TCR 001 BAS Game Stability: When a party of four players leave a world to join another world without saving the title will crash. 747 // Changed this to make it threadsafe 748 m_bLeavingGame = true; // Added for Sony platforms but unsure why the 360 doesn't need it - without this, the leaving triggered by this causes the game to respond by leaving again when it transitions to the SNM_STATE_ENDING state 749 m_bLeaveRoomWhenLeavingGame = bLeaveRoom; 750 m_bLeaveGameOnTick = true; 751 m_migrateHostOnLeave = bMigrateHost; 752 753 return true; 754} 755 756void CPlatformNetworkManagerSony::HostGame(int localUsersMask, bool bOnlineGame, bool bIsPrivate, unsigned char publicSlots /*= MINECRAFT_NET_MAX_PLAYERS*/, unsigned char privateSlots /*= 0*/) 757{ 758// #ifdef _XBOX 759 // 4J Stu - We probably did this earlier as well, but just to be sure! 760 SetLocalGame( !bOnlineGame ); 761 SetPrivateGame( bIsPrivate ); 762 SystemFlagReset(); 763 764 // Make sure that the Primary Pad is in by default 765 localUsersMask |= GetLocalPlayerMask( g_NetworkManager.GetPrimaryPad() ); 766 767 _HostGame( localUsersMask, publicSlots, privateSlots ); 768//#endif 769} 770 771void CPlatformNetworkManagerSony::_HostGame(int usersMask, unsigned char publicSlots /*= MINECRAFT_NET_MAX_PLAYERS*/, unsigned char privateSlots /*= 0*/) 772{ 773 // Start hosting a new game 774 775 memset(&m_hostGameSessionData,0,sizeof(m_hostGameSessionData)); 776 m_hostGameSessionData.netVersion = MINECRAFT_NET_VERSION; 777 m_hostGameSessionData.isJoinable = !IsPrivateGame(); 778 m_hostGameSessionData.isReadyToJoin = false; 779 m_hostGameSessionData.playerCount = 0; 780 m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All); 781 for( int i = 0; i < SQRNetworkManager::MAX_LOCAL_PLAYER_COUNT; i++ ) 782 { 783 if( usersMask & ( 1 << i ) ) 784 { 785 m_hostGameSessionData.playerCount++; 786 } 787 } 788 789 m_pSQRNet->CreateAndJoinRoom(g_NetworkManager.GetPrimaryPad(),usersMask, &m_hostGameSessionData, sizeof(m_hostGameSessionData), IsLocalGame()); // Should be using: g_NetworkManager.GetLockedProfile() but that isn't being set currently 790} 791 792bool CPlatformNetworkManagerSony::_StartGame() 793{ 794#if 0 795 // Set the options that now allow players to join this game 796 BOOL enableJip = TRUE; // Must always be true othewise nobody can join the game while in the PLAY state 797 m_pIQNet->SetOpt( QNET_OPTION_JOIN_IN_PROGRESS_ALLOWED, &enableJip, sizeof BOOL ); 798 BOOL enableInv = !IsLocalGame(); 799 m_pIQNet->SetOpt( QNET_OPTION_INVITES_ALLOWED, &enableInv, sizeof BOOL ); 800 BOOL enablePres = !IsPrivateGame() && !IsLocalGame(); 801 m_pIQNet->SetOpt( QNET_OPTION_PRESENCE_JOIN_MODE, &enablePres, sizeof BOOL ); 802 803 return ( m_pIQNet->StartGame() == S_OK ); 804#else 805 m_pSQRNet->StartGame(); 806 return true; 807#endif 808} 809 810int CPlatformNetworkManagerSony::JoinGame(FriendSessionInfo *searchResult, int localUsersMask, int primaryUserIndex) 811{ 812 int joinPlayerCount = 0; 813 for( int i = 0; i < SQRNetworkManager::MAX_LOCAL_PLAYER_COUNT; i++ ) 814 { 815 if( localUsersMask & ( 1 << i ) ) 816 { 817 joinPlayerCount++; 818 } 819 } 820 GameSessionData *gameSession = (GameSessionData *)(&searchResult->data); 821 if( ( gameSession->playerCount + joinPlayerCount ) > SQRNetworkManager::MAX_ONLINE_PLAYER_COUNT ) 822 { 823 return CGameNetworkManager::JOINGAME_FAIL_SERVER_FULL; 824 } 825 826 if( m_pSQRNet->JoinRoom(&searchResult->searchResult, localUsersMask) ) 827 { 828 return CGameNetworkManager::JOINGAME_SUCCESS; 829 } 830 else 831 { 832 return CGameNetworkManager::JOINGAME_FAIL_GENERAL; 833 } 834} 835 836bool CPlatformNetworkManagerSony::SetLocalGame(bool isLocal) 837{ 838 if( m_pSQRNet->GetState() == SQRNetworkManager::SNM_STATE_IDLE) 839 { 840#if 0 841 QNET_SESSIONTYPE sessionType = isLocal ? QNET_SESSIONTYPE_LOCAL : QNET_SESSIONTYPE_LIVE_STANDARD; 842 m_pIQNet->SetOpt(QNET_OPTION_TYPE_SESSIONTYPE, &sessionType , sizeof QNET_SESSIONTYPE); 843 844 // The default value for this is QNET_LIVE_STATS_MODE_AUTO, but that decides based on the players 845 // in when the game starts. As we may want a non-live player to join the game we cannot have stats enabled 846 // when we create the sessions. As a result of this, the NotifyWriteStats callback will not be called for 847 // LIVE players that are connected to LIVE so we write their stats data on a state change. 848 QNET_LIVE_STATS_MODE statsMode = isLocal ? QNET_LIVE_STATS_MODE_DISABLED : QNET_LIVE_STATS_MODE_ENABLED; 849 m_pIQNet->SetOpt(QNET_OPTION_LIVE_STATS_MODE, &statsMode , sizeof QNET_LIVE_STATS_MODE); 850 851 // Also has a default of QNET_LIVE_PRESENCE_MODE_AUTO as above, although the effects are less of an issue 852 QNET_LIVE_PRESENCE_MODE presenceMode = isLocal ? QNET_LIVE_PRESENCE_MODE_NOT_ADVERTISED : QNET_LIVE_PRESENCE_MODE_ADVERTISED; 853 m_pIQNet->SetOpt(QNET_OPTION_LIVE_PRESENCE_MODE, &presenceMode , sizeof QNET_LIVE_PRESENCE_MODE); 854#endif 855 856 m_bIsOfflineGame = isLocal; 857 app.DebugPrintf("Setting as local game: %s\n", isLocal ? "yes" : "no" ); 858 } 859 else 860 { 861 app.DebugPrintf("Tried to change session type while not in idle or offline state\n"); 862 } 863 864 return true; 865} 866 867void CPlatformNetworkManagerSony::SetPrivateGame(bool isPrivate) 868{ 869 app.DebugPrintf("Setting as private game: %s\n", isPrivate ? "yes" : "no" ); 870 m_bIsPrivateGame = isPrivate; 871} 872 873void CPlatformNetworkManagerSony::RegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam) 874{ 875 playerChangedCallback[iPad] = callback; 876 playerChangedCallbackParam[iPad] = callbackParam; 877} 878 879void CPlatformNetworkManagerSony::UnRegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam) 880{ 881 if(playerChangedCallbackParam[iPad] == callbackParam) 882 { 883 playerChangedCallback[iPad] = NULL; 884 playerChangedCallbackParam[iPad] = NULL; 885 } 886} 887 888void CPlatformNetworkManagerSony::HandleSignInChange() 889{ 890 return; 891} 892 893bool CPlatformNetworkManagerSony::_RunNetworkGame() 894{ 895#if 0 896 // We delay actually starting the session so that we know the game server is running by the time the clients try to join 897 // This does result in a host advantage 898 HRESULT hr = m_pIQNet->StartGame(); 899 if(FAILED(hr)) return false; 900 901 // Set the options that now allow players to join this game 902 BOOL enableJip = TRUE; // Must always be true othewise nobody can join the game while in the PLAY state 903 m_pIQNet->SetOpt( QNET_OPTION_JOIN_IN_PROGRESS_ALLOWED, &enableJip, sizeof BOOL ); 904 BOOL enableInv = !IsLocalGame(); 905 m_pIQNet->SetOpt( QNET_OPTION_INVITES_ALLOWED, &enableInv, sizeof BOOL ); 906 BOOL enablePres = !IsPrivateGame() && !IsLocalGame(); 907 m_pIQNet->SetOpt( QNET_OPTION_PRESENCE_JOIN_MODE, &enablePres, sizeof BOOL ); 908#endif 909 if( IsHost() ) 910 { 911 m_pSQRNet->StartGame(); 912 m_hostGameSessionData.isReadyToJoin = true; 913 m_pSQRNet->UpdateExternalRoomData(); 914 m_pSQRNet->SetPresenceDataStartHostingGame(); 915 } 916 917 return true; 918} 919 920// Note that this does less than the xbox equivalent as we have HandleResyncPlayerRequest that is called by the underlying SQRNetworkManager when players are added/removed etc., so this 921// call is only used to update the game host settings & then do the final push out of the data. 922void CPlatformNetworkManagerSony::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= NULL*/) 923{ 924 if( this->m_bLeavingGame ) 925 return; 926 927 m_hostGameSessionData.hostPlayerUID = GetHostPlayer()->GetUID(); 928#ifdef __PSVITA__ 929 if(usingAdhocMode()) 930 { 931 m_hostGameSessionData.hostPlayerUID.setForAdhoc(); 932 } 933#endif 934 935 m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All); 936 937 // If this is called With a pNetworkPlayerLeaving, then the call has ultimately started within SQRNetworkManager::RemoveRemotePlayersAndSync, so we don't need to sync each change 938 // as that function does a sync at the end of all changes. 939 if( pNetworkPlayerLeaving == NULL ) 940 { 941 m_pSQRNet->UpdateExternalRoomData(); 942 } 943} 944 945int CPlatformNetworkManagerSony::RemovePlayerOnSocketClosedThreadProc( void* lpParam ) 946{ 947 INetworkPlayer *pNetworkPlayer = (INetworkPlayer *)lpParam; 948 949 Socket *socket = pNetworkPlayer->GetSocket(); 950 951 if( socket != NULL ) 952 { 953 //printf("Waiting for socket closed event\n"); 954 socket->m_socketClosedEvent->WaitForSignal(INFINITE); 955 956 //printf("Socket closed event has fired\n"); 957 // 4J Stu - Clear our reference to this socket 958 pNetworkPlayer->SetSocket( NULL ); 959 delete socket; 960 } 961 962 return g_pPlatformNetworkManager->RemoveLocalPlayer( pNetworkPlayer ); 963} 964 965bool CPlatformNetworkManagerSony::RemoveLocalPlayer( INetworkPlayer *pNetworkPlayer ) 966{ 967 if( pNetworkPlayer->IsLocal() ) 968 { 969 return m_pSQRNet->RemoveLocalPlayerByUserIndex( pNetworkPlayer->GetUserIndex() ); 970 } 971 972 return true; 973} 974 975CPlatformNetworkManagerSony::PlayerFlags::PlayerFlags(INetworkPlayer *pNetworkPlayer, unsigned int count) 976{ 977 // 4J Stu - Don't assert, just make it a multiple of 8! This count is calculated from a load of separate values, 978 // and makes tweaking world/render sizes a pain if we hit an assert here 979 count = (count + 8 - 1) & ~(8 - 1); 980 //assert( ( count % 8 ) == 0 ); 981 this->m_pNetworkPlayer = pNetworkPlayer; 982 this->flags = new unsigned char [ count / 8 ]; 983 memset( this->flags, 0, count / 8 ); 984 this->count = count; 985} 986CPlatformNetworkManagerSony::PlayerFlags::~PlayerFlags() 987{ 988 delete [] flags; 989} 990 991// Add a player to the per system flag storage - if we've already got a player from that system, copy its flags over 992void CPlatformNetworkManagerSony::SystemFlagAddPlayer(INetworkPlayer *pNetworkPlayer) 993{ 994 PlayerFlags *newPlayerFlags = new PlayerFlags( pNetworkPlayer, m_flagIndexSize); 995 // If any of our existing players are on the same system, then copy over flags from that one 996 for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) 997 { 998 if( pNetworkPlayer->IsSameSystem(m_playerFlags[i]->m_pNetworkPlayer) ) 999 { 1000 memcpy( newPlayerFlags->flags, m_playerFlags[i]->flags, m_playerFlags[i]->count / 8 ); 1001 break; 1002 } 1003 } 1004 m_playerFlags.push_back(newPlayerFlags); 1005} 1006 1007// Remove a player from the per system flag storage - just maintains the m_playerFlags vector without any gaps in it 1008void CPlatformNetworkManagerSony::SystemFlagRemovePlayer(INetworkPlayer *pNetworkPlayer) 1009{ 1010 for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) 1011 { 1012 if( m_playerFlags[i]->m_pNetworkPlayer == pNetworkPlayer ) 1013 { 1014 delete m_playerFlags[i]; 1015 m_playerFlags[i] = m_playerFlags.back(); 1016 m_playerFlags.pop_back(); 1017 return; 1018 } 1019 } 1020} 1021 1022void CPlatformNetworkManagerSony::SystemFlagReset() 1023{ 1024 for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) 1025 { 1026 delete m_playerFlags[i]; 1027 } 1028 m_playerFlags.clear(); 1029} 1030 1031// Set a per system flag - this is done by setting the flag on every player that shares that system 1032void CPlatformNetworkManagerSony::SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index) 1033{ 1034 if( ( index < 0 ) || ( index >= m_flagIndexSize ) ) return; 1035 if( pNetworkPlayer == NULL ) return; 1036 1037 for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) 1038 { 1039 if( pNetworkPlayer->IsSameSystem(m_playerFlags[i]->m_pNetworkPlayer) ) 1040 { 1041 m_playerFlags[i]->flags[ index / 8 ] |= ( 128 >> ( index % 8 ) ); 1042 } 1043 } 1044} 1045 1046// Get value of a per system flag - can be read from the flags of the passed in player as anything else sent to that 1047// system should also have been duplicated here 1048bool CPlatformNetworkManagerSony::SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index) 1049{ 1050 if( ( index < 0 ) || ( index >= m_flagIndexSize ) ) return false; 1051 if( pNetworkPlayer == NULL ) 1052 { 1053 return false; 1054 } 1055 1056 for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) 1057 { 1058 if( m_playerFlags[i]->m_pNetworkPlayer == pNetworkPlayer ) 1059 { 1060 return ( ( m_playerFlags[i]->flags[ index / 8 ] & ( 128 >> ( index % 8 ) ) ) != 0 ); 1061 } 1062 } 1063 return false; 1064} 1065 1066wstring CPlatformNetworkManagerSony::GatherStats() 1067{ 1068#if 0 1069 return L"Queue messages: " + _toString(((NetworkPlayerXbox *)GetHostPlayer())->GetQNetPlayer()->GetSendQueueSize( NULL, QNET_GETSENDQUEUESIZE_MESSAGES ) ) 1070 + L" Queue bytes: " + _toString( ((NetworkPlayerXbox *)GetHostPlayer())->GetQNetPlayer()->GetSendQueueSize( NULL, QNET_GETSENDQUEUESIZE_BYTES ) ); 1071#else 1072 return L""; 1073#endif 1074} 1075 1076wstring CPlatformNetworkManagerSony::GatherRTTStats() 1077{ 1078#if 0 1079 wstring stats(L"Rtt: "); 1080 1081 wchar_t stat[32]; 1082 1083 for(unsigned int i = 0; i < GetPlayerCount(); ++i) 1084 { 1085 SQRNetworkPlayer *pSQRPlayer = ((NetworkPlayerXbox *)GetPlayerByIndex( i ))->GetQNetPlayer(); 1086 1087 if(!pSQRPlayer->IsLocal()) 1088 { 1089 ZeroMemory(stat,32); 1090 swprintf(stat, 32, L"%d: %d/", i, pSQRPlayer->GetCurrentRtt() ); 1091 stats.append(stat); 1092 } 1093 } 1094 return stats; 1095#else 1096 return L""; 1097#endif 1098} 1099 1100void CPlatformNetworkManagerSony::TickSearch() 1101{ 1102 if( m_bSearchPending ) 1103 { 1104 if( !m_pSQRNet->FriendRoomManagerIsBusy() ) 1105 { 1106 m_searchResultsCount = m_pSQRNet->FriendRoomManagerGetCount(); 1107 delete m_pSearchResults; 1108 m_pSearchResults = new SQRNetworkManager::SessionSearchResult[m_searchResultsCount]; 1109 1110 for( int i = 0; i < m_searchResultsCount; i++ ) 1111 { 1112 m_pSQRNet->FriendRoomManagerGetRoomInfo(i, &m_pSearchResults[i] ); 1113 } 1114 m_bSearchPending = false; 1115 1116 if( m_SessionsUpdatedCallback != NULL ) m_SessionsUpdatedCallback(m_pSearchParam); 1117 } 1118 } 1119 else 1120 { 1121 if( !m_pSQRNet->FriendRoomManagerIsBusy() ) 1122 { 1123 // Don't start searches unless we have registered a callback 1124 int searchDelay = MINECRAFT_PS3ROOM_SEARCH_DELAY_MILLISECONDS; 1125#ifdef __PSVITA__ 1126 // in adhoc mode we can keep searching, as the friend list is populated in callbacks 1127 // 4J Stu - Every second seems a bit much as it makes the friend list flash every time it updates. Changed this to 5 seconds. 1128 if( usingAdhocMode()) 1129 searchDelay = 5000; 1130#endif 1131 if( m_SessionsUpdatedCallback != NULL && (m_lastSearchStartTime + searchDelay) < GetTickCount() ) 1132 { 1133 if( m_pSQRNet->FriendRoomManagerSearch() ) 1134 { 1135 m_bSearchPending = true; 1136 m_lastSearchStartTime = GetTickCount(); 1137 } 1138 } 1139 } 1140 } 1141} 1142 1143vector<FriendSessionInfo *> *CPlatformNetworkManagerSony::GetSessionList(int iPad, int localPlayers, bool partyOnly) 1144{ 1145 vector<FriendSessionInfo *> *filteredList = new vector<FriendSessionInfo *>(); 1146 for( int i = 0; i < m_searchResultsCount; i++ ) 1147 { 1148 if( m_pSearchResults[i].m_extData ) 1149 { 1150 FriendSessionInfo *newInfo = new FriendSessionInfo(); 1151 newInfo->displayLabel = new wchar_t[17]; 1152 ZeroMemory(newInfo->displayLabel, sizeof(wchar_t)*17); 1153 // TODO - this mbstowcs shouldn't encounter any non-ascii characters, but I imagine we'll want to actually use the online name here which is UTF-8 1154 mbstowcs(newInfo->displayLabel, m_pSearchResults[i].m_NpId.handle.data, 17); 1155 newInfo->displayLabelLength = strlen(m_pSearchResults[i].m_NpId.handle.data); 1156 newInfo->hasPartyMember = false; 1157 newInfo->searchResult = m_pSearchResults[i]; 1158 newInfo->sessionId = m_pSearchResults[i].m_sessionId; 1159 memcpy(&newInfo->data, m_pSearchResults[i].m_extData, sizeof(GameSessionData)); 1160 if( ( newInfo->data.isReadyToJoin ) && 1161 ( newInfo->data.isJoinable ) && 1162 ( newInfo->data.netVersion == MINECRAFT_NET_VERSION ) ) 1163 { 1164 filteredList->push_back(newInfo); 1165 } 1166 else 1167 { 1168 delete newInfo; 1169 } 1170 } 1171 } 1172 1173 return filteredList; 1174} 1175 1176bool CPlatformNetworkManagerSony::GetGameSessionInfo(int iPad, SessionID sessionId, FriendSessionInfo *foundSessionInfo) 1177{ 1178#if 0 1179 HRESULT hr = E_FAIL; 1180 1181 const XSESSION_SEARCHRESULT *pSearchResult; 1182 const XNQOSINFO * pxnqi; 1183 1184 if( m_currentSearchResultsCount[iPad] > 0 ) 1185 { 1186 // Loop through all the results. 1187 for( DWORD dwResult = 0; dwResult < m_currentSearchResultsCount[iPad]; dwResult++ ) 1188 { 1189 pSearchResult = &m_pCurrentSearchResults[iPad]->pResults[dwResult]; 1190 1191 if(memcmp( &pSearchResult->info.sessionID, &sessionId, sizeof(SessionID) ) != 0) continue; 1192 1193 bool foundSession = false; 1194 FriendSessionInfo *sessionInfo = NULL; 1195 AUTO_VAR(itFriendSession, friendsSessions[iPad].begin()); 1196 for(itFriendSession = friendsSessions[iPad].begin(); itFriendSession < friendsSessions[iPad].end(); ++itFriendSession) 1197 { 1198 sessionInfo = *itFriendSession; 1199 if(memcmp( &pSearchResult->info.sessionID, &sessionInfo->sessionId, sizeof(SessionID) ) == 0) 1200 { 1201 sessionInfo->searchResult = *pSearchResult; 1202 sessionInfo->displayLabel = new wchar_t[100]; 1203 ZeroMemory( sessionInfo->displayLabel, 100 * sizeof(wchar_t) ); 1204 foundSession = true; 1205 break; 1206 } 1207 } 1208 1209 // We received a search result for a session no longer in our list of friends sessions 1210 if(!foundSession) break; 1211 1212 // See if this result was contacted successfully via QoS probes. 1213 pxnqi = &m_pCurrentQoSResult[iPad]->axnqosinfo[dwResult]; 1214 if( pxnqi->bFlags & XNET_XNQOSINFO_TARGET_CONTACTED ) 1215 { 1216 1217 if(pxnqi->cbData > 0) 1218 { 1219 sessionInfo->data = *(GameSessionData *)pxnqi->pbData; 1220 1221 wstring gamerName = convStringToWstring(sessionInfo->data.hostName); 1222 swprintf(sessionInfo->displayLabel,app.GetString(IDS_GAME_HOST_NAME),L"MWWWWWWWWWWWWWWM");// gamerName.c_str() ); 1223 } 1224 else 1225 { 1226 swprintf(sessionInfo->displayLabel,app.GetString(IDS_GAME_HOST_NAME_UNKNOWN)); 1227 } 1228 sessionInfo->displayLabelLength = wcslen( sessionInfo->displayLabel ); 1229 1230 // If this host wasn't disabled use this one. 1231 if( !( pxnqi->bFlags & XNET_XNQOSINFO_TARGET_DISABLED ) && 1232 sessionInfo->data.netVersion == MINECRAFT_NET_VERSION && 1233 sessionInfo->data.isJoinable) 1234 { 1235 foundSessionInfo->data = sessionInfo->data; 1236 if(foundSessionInfo->displayLabel != NULL) delete [] foundSessionInfo->displayLabel; 1237 foundSessionInfo->displayLabel = new wchar_t[100]; 1238 memcpy(foundSessionInfo->displayLabel, sessionInfo->displayLabel, 100 * sizeof(wchar_t) ); 1239 foundSessionInfo->displayLabelLength = sessionInfo->displayLabelLength; 1240 foundSessionInfo->hasPartyMember = sessionInfo->hasPartyMember; 1241 foundSessionInfo->searchResult = sessionInfo->searchResult; 1242 foundSessionInfo->sessionId = sessionInfo->sessionId; 1243 1244 hr = S_OK; 1245 } 1246 } 1247 } 1248 } 1249 1250 return ( hr == S_OK ); 1251#else 1252 return false; 1253#endif 1254} 1255 1256void CPlatformNetworkManagerSony::SetSessionsUpdatedCallback( void (*SessionsUpdatedCallback)(LPVOID pParam), LPVOID pSearchParam ) 1257{ 1258 m_SessionsUpdatedCallback = SessionsUpdatedCallback; m_pSearchParam = pSearchParam; 1259} 1260 1261void CPlatformNetworkManagerSony::GetFullFriendSessionInfo( FriendSessionInfo *foundSession, void (* FriendSessionUpdatedFn)(bool success, void *pParam), void *pParam ) 1262{ 1263 m_pSQRNet->GetExtDataForRoom( foundSession->sessionId.m_RoomId, &foundSession->data, FriendSessionUpdatedFn, pParam); 1264} 1265 1266void CPlatformNetworkManagerSony::ForceFriendsSessionRefresh() 1267{ 1268 app.DebugPrintf("Resetting friends session search data\n"); 1269 m_lastSearchStartTime = 0; 1270 m_searchResultsCount = 0; 1271 delete m_pSearchResults; 1272 m_pSearchResults = NULL; 1273} 1274 1275INetworkPlayer *CPlatformNetworkManagerSony::addNetworkPlayer(SQRNetworkPlayer *pSQRPlayer) 1276{ 1277 NetworkPlayerSony *pNetworkPlayer = new NetworkPlayerSony(pSQRPlayer); 1278 pSQRPlayer->SetCustomDataValue((ULONG_PTR)pNetworkPlayer); 1279 currentNetworkPlayers.push_back( pNetworkPlayer ); 1280 return pNetworkPlayer; 1281} 1282 1283void CPlatformNetworkManagerSony::removeNetworkPlayer(SQRNetworkPlayer *pSQRPlayer) 1284{ 1285 INetworkPlayer *pNetworkPlayer = getNetworkPlayer(pSQRPlayer); 1286 for( AUTO_VAR(it, currentNetworkPlayers.begin()); it != currentNetworkPlayers.end(); it++ ) 1287 { 1288 if( *it == pNetworkPlayer ) 1289 { 1290 currentNetworkPlayers.erase(it); 1291 return; 1292 } 1293 } 1294} 1295 1296INetworkPlayer *CPlatformNetworkManagerSony::getNetworkPlayer(SQRNetworkPlayer *pSQRPlayer) 1297{ 1298 return pSQRPlayer ? (INetworkPlayer *)(pSQRPlayer->GetCustomDataValue()) : NULL; 1299} 1300 1301 1302INetworkPlayer *CPlatformNetworkManagerSony::GetLocalPlayerByUserIndex(int userIndex ) 1303{ 1304 return getNetworkPlayer(m_pSQRNet->GetLocalPlayerByUserIndex(userIndex)); 1305} 1306 1307INetworkPlayer *CPlatformNetworkManagerSony::GetPlayerByIndex(int playerIndex) 1308{ 1309 return getNetworkPlayer(m_pSQRNet->GetPlayerByIndex(playerIndex)); 1310} 1311 1312INetworkPlayer * CPlatformNetworkManagerSony::GetPlayerByXuid(PlayerUID xuid) 1313{ 1314 return getNetworkPlayer(m_pSQRNet->GetPlayerByXuid(xuid)); 1315} 1316 1317INetworkPlayer * CPlatformNetworkManagerSony::GetPlayerBySmallId(unsigned char smallId) 1318{ 1319 return getNetworkPlayer(m_pSQRNet->GetPlayerBySmallId(smallId)); 1320} 1321 1322INetworkPlayer *CPlatformNetworkManagerSony::GetHostPlayer() 1323{ 1324 return getNetworkPlayer(m_pSQRNet->GetHostPlayer()); 1325} 1326 1327bool CPlatformNetworkManagerSony::IsHost() 1328{ 1329 return m_pSQRNet->IsHost() && !m_bHostChanged; 1330} 1331 1332bool CPlatformNetworkManagerSony::JoinGameFromInviteInfo( int userIndex, int userMask, const INVITE_INFO *pInviteInfo) 1333{ 1334 return m_pSQRNet->JoinRoom( pInviteInfo->m_RoomId, pInviteInfo->m_ServerId, userMask, pInviteInfo ); 1335} 1336 1337void CPlatformNetworkManagerSony::SetSessionTexturePackParentId( int id ) 1338{ 1339 m_hostGameSessionData.texturePackParentId = id; 1340} 1341 1342void CPlatformNetworkManagerSony::SetSessionSubTexturePackId( int id ) 1343{ 1344 m_hostGameSessionData.subTexturePackId = id; 1345} 1346 1347void CPlatformNetworkManagerSony::Notify(int ID, ULONG_PTR Param) 1348{ 1349#if 0 1350 m_pSQRNet->Notify( ID, Param ); 1351#endif 1352} 1353 1354bool CPlatformNetworkManagerSony::IsInSession() 1355{ 1356 return m_pSQRNet->IsInSession(); 1357} 1358 1359bool CPlatformNetworkManagerSony::IsInGameplay() 1360{ 1361 return m_pSQRNet->GetState() == SQRNetworkManager::SNM_STATE_PLAYING; 1362} 1363 1364bool CPlatformNetworkManagerSony::IsReadyToPlayOrIdle() 1365{ 1366 return m_pSQRNet->IsReadyToPlayOrIdle(); 1367} 1368 1369void CPlatformNetworkManagerSony::SetSQRPresenceInfoFromExtData(SQRNetworkManager::PresenceSyncInfo *presence, void *pExtData, SceNpMatching2RoomId roomId, SceNpMatching2ServerId serverId) 1370{ 1371 GameSessionData *gsd = (GameSessionData *)pExtData; 1372 1373 memcpy(&presence->hostPlayerUID, &gsd->hostPlayerUID, sizeof(GameSessionUID) ); 1374 presence->m_RoomId = roomId; 1375 presence->m_ServerId = serverId; 1376 presence->texturePackParentId = gsd->texturePackParentId; 1377 presence->subTexturePackId = gsd->subTexturePackId; 1378 presence->netVersion = gsd->netVersion; 1379 presence->inviteOnly = !gsd->isJoinable; 1380} 1381 1382void CPlatformNetworkManagerSony::MallocAndSetExtDataFromSQRPresenceInfo(void **pExtData, SQRNetworkManager::PresenceSyncInfo *presence) 1383{ 1384 GameSessionData *gsd = (GameSessionData *)malloc(sizeof(GameSessionData)); 1385 memset(gsd, 0, sizeof(GameSessionData)); 1386 if( presence->netVersion != 0 ) 1387 { 1388 memcpy(&gsd->hostPlayerUID, &presence->hostPlayerUID, sizeof(GameSessionUID) ); 1389 gsd->texturePackParentId = presence->texturePackParentId; 1390 gsd->subTexturePackId = presence->subTexturePackId; 1391 gsd->netVersion = presence->netVersion; 1392 gsd->isJoinable = !presence->inviteOnly; 1393 gsd->isReadyToJoin = true; 1394 } 1395 *pExtData = gsd; 1396} 1397 1398#ifdef __PSVITA__ 1399bool CPlatformNetworkManagerSony::setAdhocMode( bool bAdhoc ) 1400{ 1401 if(m_bUsingAdhocMode != bAdhoc) 1402 { 1403 m_bUsingAdhocMode = bAdhoc; 1404 if(m_bUsingAdhocMode) 1405 { 1406 // uninit the PSN, and init adhoc 1407 if(m_pSQRNet_Vita->IsInitialised()) 1408 { 1409 m_pSQRNet_Vita->UnInitialise(); 1410 } 1411 1412 if(m_pSQRNet_Vita_Adhoc->IsInitialised()==false) 1413 { 1414 m_pSQRNet_Vita_Adhoc->Initialise(); 1415 } 1416 1417 m_pSQRNet = m_pSQRNet_Vita_Adhoc; 1418 } 1419 else 1420 { 1421 if(m_pSQRNet_Vita_Adhoc->IsInitialised()) 1422 { 1423 int ret = sceNetCtlAdhocDisconnect(); 1424 // uninit the adhoc, and init psn 1425 m_pSQRNet_Vita_Adhoc->UnInitialise(); 1426 } 1427 1428 if(m_pSQRNet_Vita->IsInitialised()==false) 1429 { 1430 m_pSQRNet_Vita->Initialise(); 1431 } 1432 1433 m_pSQRNet = m_pSQRNet_Vita; 1434 } 1435 } 1436 1437 return true; 1438} 1439 1440void CPlatformNetworkManagerSony::startAdhocMatching( ) 1441{ 1442 assert(m_pSQRNet == m_pSQRNet_Vita_Adhoc); 1443 ((SQRNetworkManager_AdHoc_Vita*)m_pSQRNet_Vita_Adhoc)->startMatching(); 1444} 1445 1446bool CPlatformNetworkManagerSony::checkValidInviteData(const INVITE_INFO* pInviteInfo) 1447{ 1448 SQRNetworkManager_Vita* pSQR = (SQRNetworkManager_Vita*)m_pSQRNet_Vita; 1449 if(pSQR->IsOnlineGame() && !pSQR->IsHost()&& (pSQR->GetHostUID() == pInviteInfo->hostPlayerUID)) 1450 { 1451 // we're trying to join a game we're already in, so we just ignore this 1452 return false; 1453 } 1454 else 1455 { 1456 return true; 1457 } 1458} 1459 1460 1461 1462#endif // __PSVITA__