the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 940 lines 28 kB view raw
1#include "stdafx.h" 2#include "..\..\..\Minecraft.World\Socket.h" 3#include "..\..\..\Minecraft.World\StringHelpers.h" 4#include "PlatformNetworkManagerDurango.h" 5#include "NetworkPlayerDurango.h" 6 7CPlatformNetworkManagerDurango *g_pPlatformNetworkManager; 8 9void CPlatformNetworkManagerDurango::HandleStateChange(DQRNetworkManager::eDQRNetworkManagerState oldState, DQRNetworkManager::eDQRNetworkManagerState newState) 10{ 11 static const char * c_apszStateNames[] = 12 { 13 "DNM_STATE_INITIALISING", 14 "DNM_STATE_INITIALISE_FAILED", 15 "DNM_STATE_IDLE", 16 "DNM_STATE_HOSTING", 17 "DNM_STATE_JOINING", 18 "DNM_STATE_STARTING", 19 "DNM_STATE_PLAYING", 20 "DNM_STATE_LEAVING", 21 "DNM_STATE_ENDING", 22 }; 23 24 app.DebugPrintf( "Network State: %s ==> %s\n", 25 c_apszStateNames[ oldState ], 26 c_apszStateNames[ newState ] ); 27 28 if( newState == DQRNetworkManager::DNM_STATE_HOSTING ) 29 { 30 m_bLeavingGame = false; 31 m_bLeaveGameOnTick = false; 32 m_bHostChanged = false; 33 g_NetworkManager.StateChange_AnyToHosting(); 34 } 35 else if( newState == DQRNetworkManager::DNM_STATE_JOINING ) 36 { 37 m_bLeavingGame = false; 38 m_bLeaveGameOnTick = false; 39 m_bHostChanged = false; 40 g_NetworkManager.StateChange_AnyToJoining(); 41 } 42 else if( newState == DQRNetworkManager::DNM_STATE_IDLE && oldState == DQRNetworkManager::DNM_STATE_JOINING ) 43 { 44 g_NetworkManager.StateChange_JoiningToIdle(JOIN_FAILED_NONSPECIFIC); 45 } 46 else if( newState == DQRNetworkManager::DNM_STATE_IDLE && oldState == DQRNetworkManager::DNM_STATE_HOSTING ) 47 { 48 m_bLeavingGame = true; 49 } 50 else if( newState == DQRNetworkManager::DNM_STATE_STARTING ) 51 { 52 m_lastPlayerEventTimeStart = app.getAppTime(); 53 54 g_NetworkManager.StateChange_AnyToStarting(); 55 } 56 // 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. 57 // 4J Stu - If the client joins just as the host is exiting, then they can skip to leaving without passing through ending 58 else if( newState == DQRNetworkManager::DNM_STATE_ENDING ) 59 { 60 g_NetworkManager.StateChange_AnyToEnding( oldState == DQRNetworkManager::DNM_STATE_PLAYING ); 61 62 if( m_pDQRNet->IsHost() ) 63 { 64 m_bLeavingGame = true; 65 } 66 } 67 68 if( newState == DQRNetworkManager::DNM_STATE_IDLE ) 69 { 70 g_NetworkManager.StateChange_AnyToIdle(); 71 } 72} 73 74void CPlatformNetworkManagerDurango::HandlePlayerJoined(DQRNetworkPlayer *pDQRPlayer) 75{ 76 const char * pszDescription; 77 78 // If this is a local player, we need to inform the chat system that it has joined 79 if( pDQRPlayer->IsLocal() ) 80 { 81 m_pDQRNet->ChatPlayerJoined(pDQRPlayer->GetLocalPlayerIndex()); 82 } 83 84 // 4J Stu - We create a fake socket for every where that we need an INBOUND queue of game data. Outbound 85 // is all handled by QNet so we don't need that. Therefore each client player has one, and the host has one 86 // for each client player. 87 bool createFakeSocket = false; 88 bool localPlayer = false; 89 90 NetworkPlayerDurango *networkPlayer = (NetworkPlayerDurango *)addNetworkPlayer(pDQRPlayer); 91 92 // Request full display name for this player 93 m_pDQRNet->RequestDisplayName(pDQRPlayer); 94 95 if( pDQRPlayer->IsLocal() ) 96 { 97 localPlayer = true; 98 if( pDQRPlayer->IsHost() ) 99 { 100 pszDescription = "local host"; 101 // 4J Stu - No socket for the localhost as it uses a special loopback queue 102 103 m_machineDQRPrimaryPlayers.push_back( pDQRPlayer ); 104 } 105 else 106 { 107 pszDescription = "local"; 108 109 // We need an inbound queue on all local players to receive data from the host 110 createFakeSocket = true; 111 } 112 } 113 else 114 { 115 if( pDQRPlayer->IsHost() ) 116 { 117 pszDescription = "remote host"; 118 } 119 else 120 { 121 pszDescription = "remote"; 122 123 // If we are the host, then create a fake socket for every remote player 124 if( m_pDQRNet->IsHost() ) 125 { 126 createFakeSocket = true; 127 } 128 } 129 130 if( m_pDQRNet->IsHost() && !m_bHostChanged ) 131 { 132 // Do we already have a primary player for this system? 133 bool systemHasPrimaryPlayer = false; 134 for(AUTO_VAR(it, m_machineDQRPrimaryPlayers.begin()); it < m_machineDQRPrimaryPlayers.end(); ++it) 135 { 136 DQRNetworkPlayer *pQNetPrimaryPlayer = *it; 137 if( pDQRPlayer->IsSameSystem(pQNetPrimaryPlayer) ) 138 { 139 systemHasPrimaryPlayer = true; 140 break; 141 } 142 } 143 if( !systemHasPrimaryPlayer ) 144 m_machineDQRPrimaryPlayers.push_back( pDQRPlayer ); 145 } 146 } 147 g_NetworkManager.PlayerJoining( networkPlayer ); 148 149 if( createFakeSocket == true && !m_bHostChanged ) 150 { 151 g_NetworkManager.CreateSocket( networkPlayer, localPlayer ); 152 } 153 154 app.DebugPrintf( "Player 0x%p \"%ls\" joined; %s; voice %i; camera %i.\n", 155 pDQRPlayer, 156 pDQRPlayer->GetGamertag(), 157 pszDescription, 158 (int) pDQRPlayer->HasVoice(), 159 (int) pDQRPlayer->HasCamera() ); 160 161 162 if( m_pDQRNet->IsHost() ) 163 { 164 g_NetworkManager.UpdateAndSetGameSessionData(); 165 SystemFlagAddPlayer( networkPlayer ); 166 } 167 168 for( int idx = 0; idx < XUSER_MAX_COUNT; ++idx) 169 { 170 if(playerChangedCallback[idx] != NULL) 171 playerChangedCallback[idx]( playerChangedCallbackParam[idx], networkPlayer, false ); 172 } 173 174 if(m_pDQRNet->GetState() == QNET_STATE_GAME_PLAY) 175 { 176 int localPlayerCount = 0; 177 for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) 178 { 179 if( m_pDQRNet->GetLocalPlayerByUserIndex(idx) != NULL ) ++localPlayerCount; 180 } 181 182 float appTime = app.getAppTime(); 183 184 // Only record stats for the primary player here 185 m_lastPlayerEventTimeStart = appTime; 186 } 187} 188 189void CPlatformNetworkManagerDurango::HandlePlayerLeaving(DQRNetworkPlayer *pDQRPlayer) 190{ 191 //__debugbreak(); 192 193 app.DebugPrintf( "Player 0x%p leaving.\n", 194 pDQRPlayer ); 195 196 INetworkPlayer *networkPlayer = getNetworkPlayer(pDQRPlayer); 197 198 if( networkPlayer ) 199 { 200 // Get our wrapper object associated with this player. 201 Socket *socket = networkPlayer->GetSocket(); 202 if( socket != NULL ) 203 { 204 // If we are in game then remove this player from the game as well. 205 // We may get here either from the player requesting to exit the game, 206 // in which case we they will already have left the game server, or from a disconnection 207 // where we then have to remove them from the game server 208 if( m_pDQRNet->IsHost() && !m_bHostChanged ) 209 { 210 g_NetworkManager.CloseConnection(networkPlayer); 211 } 212 213 // Free the wrapper object memory. 214 // TODO 4J Stu - We may still be using this at the point that the player leaves the session. 215 // We need this as long as the game server still needs to communicate with the player 216 //delete socket; 217 218 networkPlayer->SetSocket( NULL ); 219 } 220 221 if( m_pDQRNet->IsHost() && !m_bHostChanged ) 222 { 223 if( isSystemPrimaryPlayer(pDQRPlayer) ) 224 { 225 DQRNetworkPlayer *pNewDQRPrimaryPlayer = NULL; 226 for(unsigned int i = 0; i < m_pDQRNet->GetPlayerCount(); ++i ) 227 { 228 DQRNetworkPlayer *pDQRPlayer2 = m_pDQRNet->GetPlayerByIndex( i ); 229 230 if( pDQRPlayer2 != pDQRPlayer && pDQRPlayer2->IsSameSystem( pDQRPlayer ) ) 231 { 232 pNewDQRPrimaryPlayer = pDQRPlayer2; 233 break; 234 } 235 } 236 AUTO_VAR(it, find( m_machineDQRPrimaryPlayers.begin(), m_machineDQRPrimaryPlayers.end(), pDQRPlayer)); 237 if( it != m_machineDQRPrimaryPlayers.end() ) 238 { 239 m_machineDQRPrimaryPlayers.erase( it ); 240 } 241 242 if( pNewDQRPrimaryPlayer != NULL ) 243 m_machineDQRPrimaryPlayers.push_back( pNewDQRPrimaryPlayer ); 244 } 245 246 g_NetworkManager.UpdateAndSetGameSessionData( networkPlayer ); 247 SystemFlagRemovePlayer( networkPlayer ); 248 249 } 250 251 g_NetworkManager.PlayerLeaving( networkPlayer ); 252 253 for( int idx = 0; idx < XUSER_MAX_COUNT; ++idx) 254 { 255 if(playerChangedCallback[idx] != NULL) 256 playerChangedCallback[idx]( playerChangedCallbackParam[idx], networkPlayer, true ); 257 } 258 259 if(m_pDQRNet->GetState() == DQRNetworkManager::DNM_STATE_PLAYING) 260 { 261 int localPlayerCount = 0; 262 for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) 263 { 264 if( m_pDQRNet->GetLocalPlayerByUserIndex(idx) != NULL ) ++localPlayerCount; 265 } 266 267 float appTime = app.getAppTime(); 268 m_lastPlayerEventTimeStart = appTime; 269 } 270 271 removeNetworkPlayer(pDQRPlayer); 272 } 273} 274 275void CPlatformNetworkManagerDurango::HandleDataReceived(DQRNetworkPlayer *playerFrom, DQRNetworkPlayer *playerTo, unsigned char *data, unsigned int dataSize) 276{ 277#if 0 278 // TODO - put this back in 279 if(m_pSQRNet->GetState() == SQRNetworkManager::SNM_STATE_ENDING) 280 { 281 return; 282 } 283#endif 284 285 if( playerTo->IsHost() ) 286 { 287 // If we are the host we care who this came from 288 //app.DebugPrintf( "Pushing data into host read queue for user \"%ls\"\n", pPlayerFrom->GetGamertag()); 289 // Push this data into the read queue for the player that sent it 290 INetworkPlayer *pPlayerFrom = getNetworkPlayer(playerFrom); 291 Socket *socket = pPlayerFrom->GetSocket(); 292 293 if(socket != NULL) 294 socket->pushDataToQueue(data, dataSize, false); 295 } 296 else 297 { 298 // If we are not the host the message must have come from the host, so we care more about who it is addressed to 299 INetworkPlayer *pPlayerTo = getNetworkPlayer(playerTo); 300 Socket *socket = pPlayerTo->GetSocket(); 301 //app.DebugPrintf( "Pushing data into read queue for user \"%ls\"\n", apPlayersTo[dwPlayer]->GetGamertag()); 302 if(socket != NULL) 303 socket->pushDataToQueue(data, dataSize); 304 } 305} 306 307void CPlatformNetworkManagerDurango::HandleInviteReceived(int playerIndex, DQRNetworkManager::SessionInfo *pInviteInfo) 308{ 309 g_NetworkManager.GameInviteReceived(playerIndex, pInviteInfo); 310} 311 312bool CPlatformNetworkManagerDurango::Initialise(CGameNetworkManager *pGameNetworkManager, int flagIndexSize) 313{ 314 m_pDQRNet = new DQRNetworkManager(this); 315 m_pDQRNet->Initialise(); 316 317 m_hostGameSessionIsJoinable = false; 318 m_pGameNetworkManager = pGameNetworkManager; 319 m_flagIndexSize = flagIndexSize; 320 g_pPlatformNetworkManager = this; 321 for( int i = 0; i < XUSER_MAX_COUNT; i++ ) 322 { 323 playerChangedCallback[ i ] = NULL; 324 } 325 326 m_bLeavingGame = false; 327 m_bLeaveGameOnTick = false; 328 m_bHostChanged = false; 329 330 m_bSearchResultsReady = false; 331 m_bSearchPending = false; 332 333 m_bIsOfflineGame = false; 334 m_pSearchParam = NULL; 335 m_SessionsUpdatedCallback = NULL; 336 337 m_searchResultsCount = 0; 338 m_lastSearchStartTime = 0; 339 340 // The results that will be filled in with the current search 341 m_pSearchResults = NULL; 342 343 Windows::Networking::Connectivity::NetworkInformation::NetworkStatusChanged += ref new Windows::Networking::Connectivity::NetworkStatusChangedEventHandler( []( Platform::Object^ pxObject ) 344 { 345 app.DebugPrintf("NetworkStatusChanged callback\n" ); 346 auto internetProfile = Windows::Networking::Connectivity::NetworkInformation::GetInternetConnectionProfile(); 347 if (internetProfile != nullptr) 348 { 349 auto connectionLevel = internetProfile->GetNetworkConnectivityLevel(); 350 app.DebugPrintf("Connection level has changed to (%d)\n", connectionLevel); 351 352 //int iPrimaryPlayer = g_NetworkManager.GetPrimaryPad(); 353 //bool bConnected = (connectionLevel == Windows::Networking::Connectivity::NetworkConnectivityLevel::XboxLiveAccess)?true:false; 354 //if((g_NetworkManager.GetLockedProfile()!=-1) && iPrimaryPlayer!=-1 && bConnected == false && g_NetworkManager.IsInSession() ) 355 //{ 356 // app.SetAction(iPrimaryPlayer,eAppAction_EthernetDisconnected); 357 //} 358 } 359 }); 360 361 // Success! 362 return true; 363} 364 365void CPlatformNetworkManagerDurango::Terminate() 366{ 367} 368 369int CPlatformNetworkManagerDurango::GetJoiningReadyPercentage() 370{ 371 return 100; 372} 373 374int CPlatformNetworkManagerDurango::CorrectErrorIDS(int IDS) 375{ 376 return IDS; 377} 378 379bool CPlatformNetworkManagerDurango::isSystemPrimaryPlayer(DQRNetworkPlayer *pDQRPlayer) 380{ 381 bool playerIsSystemPrimary = false; 382 for(auto it = m_machineDQRPrimaryPlayers.begin(); it < m_machineDQRPrimaryPlayers.end(); ++it) 383 { 384 DQRNetworkPlayer *pDQRPrimaryPlayer = *it; 385 if( pDQRPrimaryPlayer == pDQRPlayer ) 386 { 387 playerIsSystemPrimary = true; 388 break; 389 } 390 } 391 return playerIsSystemPrimary; 392} 393 394// We call this twice a frame, either side of the render call so is a good place to "tick" things 395void CPlatformNetworkManagerDurango::DoWork() 396{ 397 m_pDQRNet->Tick(); 398 399 TickSearch(); 400 401 if( m_bLeaveGameOnTick ) 402 { 403 m_pDQRNet->LeaveRoom(); 404 m_bLeaveGameOnTick = false; 405 } 406} 407 408int CPlatformNetworkManagerDurango::GetPlayerCount() 409{ 410 return m_pDQRNet->GetPlayerCount(); 411} 412 413bool CPlatformNetworkManagerDurango::ShouldMessageForFullSession() 414{ 415 return m_pDQRNet->ShouldMessageForFullSession(); 416} 417 418int CPlatformNetworkManagerDurango::GetOnlinePlayerCount() 419{ 420 return m_pDQRNet->GetOnlinePlayerCount(); 421} 422 423int CPlatformNetworkManagerDurango::GetLocalPlayerMask(int playerIndex) 424{ 425 return 1 << playerIndex; 426} 427 428bool CPlatformNetworkManagerDurango::AddLocalPlayerByUserIndex( int userIndex ) 429{ 430 return m_pDQRNet->AddLocalPlayerByUserIndex( userIndex ); 431} 432 433bool CPlatformNetworkManagerDurango::RemoveLocalPlayerByUserIndex( int userIndex ) 434{ 435 return m_pDQRNet->RemoveLocalPlayerByUserIndex( userIndex ); 436} 437 438bool CPlatformNetworkManagerDurango::IsInStatsEnabledSession() 439{ 440 return true; 441} 442 443bool CPlatformNetworkManagerDurango::SessionHasSpace(unsigned int spaceRequired /*= 1*/) 444{ 445 return true; 446} 447 448void CPlatformNetworkManagerDurango::SendInviteGUI(int quadrant) 449{ 450 m_pDQRNet->SendInviteGUI(quadrant); 451} 452 453bool CPlatformNetworkManagerDurango::IsAddingPlayer() 454{ 455 return m_pDQRNet->IsAddingPlayer(); 456} 457 458bool CPlatformNetworkManagerDurango::LeaveGame(bool bMigrateHost) 459{ 460 if( m_bLeavingGame ) return true; 461 462 m_bLeavingGame = true; 463 464 // If we are the host wait for the game server to end 465 if(m_pDQRNet->IsHost() && g_NetworkManager.ServerStoppedValid()) 466 { 467// m_pDQRNet->EndGame(); 468 g_NetworkManager.ServerStoppedWait(); 469 g_NetworkManager.ServerStoppedDestroy(); 470 } 471 return _LeaveGame(bMigrateHost, true);; 472} 473 474bool CPlatformNetworkManagerDurango::_LeaveGame(bool bMigrateHost, bool bLeaveRoom) 475{ 476 m_bLeavingGame = true; 477 m_bLeaveGameOnTick = true; 478 m_migrateHostOnLeave = bMigrateHost; 479 return true; 480} 481 482void CPlatformNetworkManagerDurango::HostGame(int localUsersMask, bool bOnlineGame, bool bIsPrivate, unsigned char publicSlots /*= MINECRAFT_NET_MAX_PLAYERS*/, unsigned char privateSlots /*= 0*/) 483{ 484// #ifdef _XBOX 485 // 4J Stu - We probably did this earlier as well, but just to be sure! 486 SetLocalGame( !bOnlineGame ); 487 SetPrivateGame( bIsPrivate ); 488 SystemFlagReset(); 489 490 // Make sure that the Primary Pad is in by default 491 localUsersMask |= GetLocalPlayerMask( g_NetworkManager.GetPrimaryPad() ); 492 493 m_bLeavingGame = false; 494 495 _HostGame( localUsersMask, publicSlots, privateSlots ); 496//#endif 497} 498 499void CPlatformNetworkManagerDurango::_HostGame(int usersMask, unsigned char publicSlots /*= MINECRAFT_NET_MAX_PLAYERS*/, unsigned char privateSlots /*= 0*/) 500{ 501 memset(&m_hostGameSessionData,0,sizeof(m_hostGameSessionData)); 502 m_hostGameSessionData.netVersion = MINECRAFT_NET_VERSION; 503 m_hostGameSessionData.isReadyToJoin = false; 504 m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All); 505 m_hostGameSessionIsJoinable = !IsPrivateGame(); 506 507 m_pDQRNet->CreateAndJoinSession(usersMask, (unsigned char *)&m_hostGameSessionData, sizeof(m_hostGameSessionData), IsLocalGame() ); 508} 509 510bool CPlatformNetworkManagerDurango::_StartGame() 511{ 512 return true; 513} 514 515int CPlatformNetworkManagerDurango::JoinGame(FriendSessionInfo *searchResult, int localUsersMask, int primaryUserIndex) 516{ 517 app.DebugPrintf("Joining game party from search result\n"); 518 519 int joinPlayerCount = 0; 520 for( int i = 0; i < DQRNetworkManager::MAX_LOCAL_PLAYER_COUNT; i++ ) 521 { 522 if( localUsersMask & ( 1 << i ) ) 523 { 524 // Check if this joining user is already in the session, in which case we don't need to count it 525 bool isJoiningUser = false; 526 for( int j = 0; j < searchResult->searchResult.m_usedSlotCount; j++ ) 527 { 528 Platform::String^ xuid = ref new Platform::String(searchResult->searchResult.m_sessionXuids[j].c_str()); 529 if( xuid == ProfileManager.GetUser(i)->XboxUserId ) 530 { 531 app.DebugPrintf("Joining user found to be already in session, so won't be counting to our total\n"); 532 isJoiningUser = true; 533 break; 534 } 535 } 536 if( !isJoiningUser ) 537 { 538 joinPlayerCount++; 539 } 540 } 541 } 542 app.DebugPrintf("Used slots: %d, fully playing players: %d, trying to join %d\n", searchResult->searchResult.m_usedSlotCount, searchResult->searchResult.m_playerCount, joinPlayerCount); 543 GameSessionData *gameSession = (GameSessionData *)(&searchResult->data); 544 if( ( searchResult->searchResult.m_usedSlotCount + joinPlayerCount ) > DQRNetworkManager::MAX_ONLINE_PLAYER_COUNT ) 545 { 546 return CGameNetworkManager::JOINGAME_FAIL_SERVER_FULL; 547 } 548 549 if(m_pDQRNet->JoinPartyFromSearchResult(&searchResult->searchResult, localUsersMask)) 550 { 551 app.DebugPrintf("Join success\n"); 552 return CGameNetworkManager::JOINGAME_SUCCESS; 553 } 554 else 555 { 556 app.DebugPrintf("Join fail\n"); 557 return CGameNetworkManager::JOINGAME_FAIL_GENERAL; 558 } 559} 560 561void CPlatformNetworkManagerDurango::CancelJoinGame() 562{ 563 m_pDQRNet->CancelJoinPartyFromSearchResult(); 564} 565 566bool CPlatformNetworkManagerDurango::SetLocalGame(bool isLocal) 567{ 568 m_bIsOfflineGame = isLocal; 569 570 return true; 571} 572 573void CPlatformNetworkManagerDurango::SetPrivateGame(bool isPrivate) 574{ 575 app.DebugPrintf("Setting as private game: %s\n", isPrivate ? "yes" : "no" ); 576 m_bIsPrivateGame = isPrivate; 577} 578 579void CPlatformNetworkManagerDurango::RegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam) 580{ 581 playerChangedCallback[iPad] = callback; 582 playerChangedCallbackParam[iPad] = callbackParam; 583} 584 585void CPlatformNetworkManagerDurango::UnRegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam) 586{ 587 if(playerChangedCallbackParam[iPad] == callbackParam) 588 { 589 playerChangedCallback[iPad] = NULL; 590 playerChangedCallbackParam[iPad] = NULL; 591 } 592} 593 594void CPlatformNetworkManagerDurango::HandleSignInChange() 595{ 596 return; 597} 598 599void CPlatformNetworkManagerDurango::HandleAddLocalPlayerFailed(int idx, bool serverFull) 600{ 601 g_NetworkManager.AddLocalPlayerFailed(idx, serverFull); 602} 603 604void CPlatformNetworkManagerDurango::HandleDisconnect(bool bLostRoomOnly) 605{ 606 g_NetworkManager.HandleDisconnect(bLostRoomOnly); 607} 608 609bool CPlatformNetworkManagerDurango::_RunNetworkGame() 610{ 611 m_pDQRNet->StartGame(); 612 m_hostGameSessionData.isReadyToJoin = true; 613 m_pDQRNet->UpdateCustomSessionData(); 614 return true; 615} 616 617void CPlatformNetworkManagerDurango::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= NULL*/) 618{ 619 if( this->m_bLeavingGame ) 620 return; 621 622 if( GetHostPlayer() == NULL ) 623 return; 624 625 m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All); 626 627 m_pDQRNet->UpdateCustomSessionData(); 628} 629 630int CPlatformNetworkManagerDurango::RemovePlayerOnSocketClosedThreadProc( void* lpParam ) 631{ 632 INetworkPlayer *pNetworkPlayer = (INetworkPlayer *)lpParam; 633 634 Socket *socket = pNetworkPlayer->GetSocket(); 635 636 if( socket != NULL ) 637 { 638 //printf("Waiting for socket closed event\n"); 639 socket->m_socketClosedEvent->WaitForSignal(INFINITE); 640 641 //printf("Socket closed event has fired\n"); 642 // 4J Stu - Clear our reference to this socket 643 pNetworkPlayer->SetSocket( NULL ); 644 delete socket; 645 } 646 647 return g_pPlatformNetworkManager->RemoveLocalPlayer( pNetworkPlayer ); 648} 649 650bool CPlatformNetworkManagerDurango::RemoveLocalPlayer( INetworkPlayer *pNetworkPlayer ) 651{ 652 return true; 653} 654 655CPlatformNetworkManagerDurango::PlayerFlags::PlayerFlags(INetworkPlayer *pNetworkPlayer, unsigned int count) 656{ 657 // 4J Stu - Don't assert, just make it a multiple of 8! This count is calculated from a load of separate values, 658 // and makes tweaking world/render sizes a pain if we hit an assert here 659 count = (count + 8 - 1) & ~(8 - 1); 660 //assert( ( count % 8 ) == 0 ); 661 this->m_pNetworkPlayer = pNetworkPlayer; 662 this->flags = new unsigned char [ count / 8 ]; 663 memset( this->flags, 0, count / 8 ); 664 this->count = count; 665} 666 667CPlatformNetworkManagerDurango::PlayerFlags::~PlayerFlags() 668{ 669 delete [] flags; 670} 671 672// Add a player to the per system flag storage - if we've already got a player from that system, copy its flags over 673void CPlatformNetworkManagerDurango::SystemFlagAddPlayer(INetworkPlayer *pNetworkPlayer) 674{ 675 PlayerFlags *newPlayerFlags = new PlayerFlags( pNetworkPlayer, m_flagIndexSize); 676 // If any of our existing players are on the same system, then copy over flags from that one 677 for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) 678 { 679 if( pNetworkPlayer->IsSameSystem(m_playerFlags[i]->m_pNetworkPlayer) ) 680 { 681 memcpy( newPlayerFlags->flags, m_playerFlags[i]->flags, m_playerFlags[i]->count / 8 ); 682 break; 683 } 684 } 685 m_playerFlags.push_back(newPlayerFlags); 686} 687 688// Remove a player from the per system flag storage - just maintains the m_playerFlags vector without any gaps in it 689void CPlatformNetworkManagerDurango::SystemFlagRemovePlayer(INetworkPlayer *pNetworkPlayer) 690{ 691 for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) 692 { 693 if( m_playerFlags[i]->m_pNetworkPlayer == pNetworkPlayer ) 694 { 695 delete m_playerFlags[i]; 696 m_playerFlags[i] = m_playerFlags.back(); 697 m_playerFlags.pop_back(); 698 return; 699 } 700 } 701} 702 703void CPlatformNetworkManagerDurango::SystemFlagReset() 704{ 705 for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) 706 { 707 delete m_playerFlags[i]; 708 } 709 m_playerFlags.clear(); 710} 711 712// Set a per system flag - this is done by setting the flag on every player that shares that system 713void CPlatformNetworkManagerDurango::SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index) 714{ 715 if( ( index < 0 ) || ( index >= m_flagIndexSize ) ) return; 716 if( pNetworkPlayer == NULL ) return; 717 718 for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) 719 { 720 if( pNetworkPlayer->IsSameSystem(m_playerFlags[i]->m_pNetworkPlayer) ) 721 { 722 m_playerFlags[i]->flags[ index / 8 ] |= ( 128 >> ( index % 8 ) ); 723 } 724 } 725} 726 727// Get value of a per system flag - can be read from the flags of the passed in player as anything else sent to that 728// system should also have been duplicated here 729bool CPlatformNetworkManagerDurango::SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index) 730{ 731 if( ( index < 0 ) || ( index >= m_flagIndexSize ) ) return false; 732 if( pNetworkPlayer == NULL ) 733 { 734 return false; 735 } 736 737 for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) 738 { 739 if( m_playerFlags[i]->m_pNetworkPlayer == pNetworkPlayer ) 740 { 741 return ( ( m_playerFlags[i]->flags[ index / 8 ] & ( 128 >> ( index % 8 ) ) ) != 0 ); 742 } 743 } 744 return false; 745} 746 747wstring CPlatformNetworkManagerDurango::GatherStats() 748{ 749 return L""; 750} 751 752wstring CPlatformNetworkManagerDurango::GatherRTTStats() 753{ 754 return L""; 755} 756 757void CPlatformNetworkManagerDurango::TickSearch() 758{ 759 if( m_bSearchPending ) 760 { 761 if( !m_pDQRNet->FriendPartyManagerIsBusy() ) 762 { 763 m_searchResultsCount = m_pDQRNet->FriendPartyManagerGetCount(); 764 delete [] m_pSearchResults; 765 m_pSearchResults = new DQRNetworkManager::SessionSearchResult[m_searchResultsCount]; 766 767 for( int i = 0; i < m_searchResultsCount; i++ ) 768 { 769 m_pDQRNet->FriendPartyManagerGetSessionInfo(i, &m_pSearchResults[i] ); 770 } 771 m_bSearchPending = false; 772 773 if( m_SessionsUpdatedCallback != NULL ) m_SessionsUpdatedCallback(m_pSearchParam); 774 } 775 } 776 else 777 { 778 if( !m_pDQRNet->FriendPartyManagerIsBusy() ) 779 { 780 // Don't start searches unless we have registered a callback 781 if( m_SessionsUpdatedCallback != NULL && (m_lastSearchStartTime + MINECRAFT_DURANGO_PARTY_SEARCH_DELAY_MILLISECONDS) < GetTickCount() ) 782 { 783 if( m_pDQRNet->FriendPartyManagerSearch() ); 784 { 785 m_bSearchPending = true; 786 m_lastSearchStartTime = GetTickCount(); 787 } 788 } 789 } 790 } 791} 792 793vector<FriendSessionInfo *> *CPlatformNetworkManagerDurango::GetSessionList(int iPad, int localPlayers, bool partyOnly) 794{ 795 vector<FriendSessionInfo *> *filteredList = new vector<FriendSessionInfo *>(); 796 for( int i = 0; i < m_searchResultsCount; i++ ) 797 { 798 GameSessionData *gameSessionData = (GameSessionData *)m_pSearchResults[i].m_extData; 799 if( ( gameSessionData->netVersion == MINECRAFT_NET_VERSION ) && 800 ( gameSessionData->isReadyToJoin ) ) 801 { 802 FriendSessionInfo *session = new FriendSessionInfo(); 803 session->searchResult = m_pSearchResults[i]; 804 session->searchResult.m_extData = NULL; // We have another copy of the GameSessionData, so don't need to make another copy of this here 805 session->displayLabelLength = session->searchResult.m_playerNames[0].size(); 806 session->displayLabel = new wchar_t[ session->displayLabelLength + 1 ]; 807 memcpy(&session->data, gameSessionData, sizeof(GameSessionData)); 808 wcscpy_s(session->displayLabel, session->displayLabelLength + 1, session->searchResult.m_playerNames[0].c_str() ); 809 filteredList->push_back(session); 810 } 811 } 812 return filteredList; 813} 814 815bool CPlatformNetworkManagerDurango::GetGameSessionInfo(int iPad, SessionID sessionId, FriendSessionInfo *foundSessionInfo) 816{ 817 return false; 818} 819 820void CPlatformNetworkManagerDurango::SetSessionsUpdatedCallback( void (*SessionsUpdatedCallback)(LPVOID pParam), LPVOID pSearchParam ) 821{ 822 m_SessionsUpdatedCallback = SessionsUpdatedCallback; m_pSearchParam = pSearchParam; 823} 824 825void CPlatformNetworkManagerDurango::GetFullFriendSessionInfo( FriendSessionInfo *foundSession, void (* FriendSessionUpdatedFn)(bool success, void *pParam), void *pParam ) 826{ 827 FriendSessionUpdatedFn(true, pParam); 828} 829 830void CPlatformNetworkManagerDurango::ForceFriendsSessionRefresh() 831{ 832 app.DebugPrintf("Resetting friends session search data\n"); 833 m_lastSearchStartTime = 0; 834 m_searchResultsCount = 0; 835 delete [] m_pSearchResults; 836 m_pSearchResults = NULL; 837} 838 839INetworkPlayer *CPlatformNetworkManagerDurango::addNetworkPlayer(DQRNetworkPlayer *pDQRPlayer) 840{ 841 NetworkPlayerDurango *pNetworkPlayer = new NetworkPlayerDurango(pDQRPlayer); 842 pDQRPlayer->SetCustomDataValue((ULONG_PTR)pNetworkPlayer); 843 currentNetworkPlayers.push_back( pNetworkPlayer ); 844 return pNetworkPlayer; 845} 846 847void CPlatformNetworkManagerDurango::removeNetworkPlayer(DQRNetworkPlayer *pDQRPlayer) 848{ 849 INetworkPlayer *pNetworkPlayer = getNetworkPlayer(pDQRPlayer); 850 for( AUTO_VAR(it, currentNetworkPlayers.begin()); it != currentNetworkPlayers.end(); it++ ) 851 { 852 if( *it == pNetworkPlayer ) 853 { 854 currentNetworkPlayers.erase(it); 855 return; 856 } 857 } 858} 859 860INetworkPlayer *CPlatformNetworkManagerDurango::getNetworkPlayer(DQRNetworkPlayer *pDQRPlayer) 861{ 862 return pDQRPlayer ? (INetworkPlayer *)(pDQRPlayer->GetCustomDataValue()) : NULL; 863} 864 865 866INetworkPlayer *CPlatformNetworkManagerDurango::GetLocalPlayerByUserIndex(int userIndex ) 867{ 868 return getNetworkPlayer(m_pDQRNet->GetLocalPlayerByUserIndex(userIndex)); 869} 870 871INetworkPlayer *CPlatformNetworkManagerDurango::GetPlayerByIndex(int playerIndex) 872{ 873 return getNetworkPlayer(m_pDQRNet->GetPlayerByIndex(playerIndex)); 874} 875 876INetworkPlayer * CPlatformNetworkManagerDurango::GetPlayerByXuid(PlayerUID xuid) 877{ 878 return getNetworkPlayer(m_pDQRNet->GetPlayerByXuid(xuid)) ; 879} 880 881INetworkPlayer * CPlatformNetworkManagerDurango::GetPlayerBySmallId(unsigned char smallId) 882{ 883 return getNetworkPlayer(m_pDQRNet->GetPlayerBySmallId(smallId)); 884} 885 886wstring CPlatformNetworkManagerDurango::GetDisplayNameByGamertag(wstring gamertag) 887{ 888 return m_pDQRNet->GetDisplayNameByGamertag(gamertag); 889} 890 891INetworkPlayer *CPlatformNetworkManagerDurango::GetHostPlayer() 892{ 893 return getNetworkPlayer(m_pDQRNet->GetHostPlayer()); 894} 895 896bool CPlatformNetworkManagerDurango::IsHost() 897{ 898 return m_pDQRNet->IsHost() && !m_bHostChanged; 899} 900 901bool CPlatformNetworkManagerDurango::JoinGameFromInviteInfo( int userIndex, int userMask, const INVITE_INFO *pInviteInfo) 902{ 903 m_pDQRNet->m_currentUserMask = userMask; 904 m_pDQRNet->JoinSessionFromInviteInfo(userMask); 905 return true; 906} 907 908void CPlatformNetworkManagerDurango::SetSessionTexturePackParentId( int id ) 909{ 910 m_hostGameSessionData.texturePackParentId = id; 911} 912 913void CPlatformNetworkManagerDurango::SetSessionSubTexturePackId( int id ) 914{ 915 m_hostGameSessionData.subTexturePackId = id; 916} 917 918void CPlatformNetworkManagerDurango::Notify(int ID, ULONG_PTR Param) 919{ 920} 921 922bool CPlatformNetworkManagerDurango::IsInSession() 923{ 924 return m_pDQRNet->IsInSession(); 925} 926 927bool CPlatformNetworkManagerDurango::IsInGameplay() 928{ 929 return m_pDQRNet->GetState() == DQRNetworkManager::DNM_STATE_PLAYING; 930} 931 932bool CPlatformNetworkManagerDurango::IsReadyToPlayOrIdle() 933{ 934 return m_pDQRNet->IsReadyToPlayOrIdle(); 935} 936 937bool CPlatformNetworkManagerDurango::IsSessionJoinable() 938{ 939 return m_hostGameSessionIsJoinable; 940}