#include "stdafx.h" #include "..\..\..\Minecraft.World\Socket.h" #include "..\..\..\Minecraft.World\StringHelpers.h" #include "PlatformNetworkManagerStub.h" #include "..\..\Xbox\Network\NetworkPlayerXbox.h" #ifdef _WINDOWS64 #include "..\..\Windows64\Network\WinsockNetLayer.h" #include "..\..\Minecraft.h" #include "..\..\User.h" #endif CPlatformNetworkManagerStub *g_pPlatformNetworkManager; void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer ) { const char * pszDescription; // 4J Stu - We create a fake socket for every where that we need an INBOUND queue of game data. Outbound // is all handled by QNet so we don't need that. Therefore each client player has one, and the host has one // for each client player. bool createFakeSocket = false; bool localPlayer = false; NetworkPlayerXbox *networkPlayer = (NetworkPlayerXbox *)addNetworkPlayer(pQNetPlayer); if( pQNetPlayer->IsLocal() ) { localPlayer = true; if( pQNetPlayer->IsHost() ) { pszDescription = "local host"; // 4J Stu - No socket for the localhost as it uses a special loopback queue m_machineQNetPrimaryPlayers.push_back( pQNetPlayer ); } else { pszDescription = "local"; // We need an inbound queue on all local players to receive data from the host createFakeSocket = true; } } else { if( pQNetPlayer->IsHost() ) { pszDescription = "remote host"; } else { pszDescription = "remote"; // If we are the host, then create a fake socket for every remote player if( m_pIQNet->IsHost() ) { createFakeSocket = true; } } if( m_pIQNet->IsHost() && !m_bHostChanged ) { // Do we already have a primary player for this system? bool systemHasPrimaryPlayer = false; for(AUTO_VAR(it, m_machineQNetPrimaryPlayers.begin()); it < m_machineQNetPrimaryPlayers.end(); ++it) { IQNetPlayer *pQNetPrimaryPlayer = *it; if( pQNetPlayer->IsSameSystem(pQNetPrimaryPlayer) ) { systemHasPrimaryPlayer = true; break; } } if( !systemHasPrimaryPlayer ) m_machineQNetPrimaryPlayers.push_back( pQNetPlayer ); } } g_NetworkManager.PlayerJoining( networkPlayer ); if( createFakeSocket == true && !m_bHostChanged ) { g_NetworkManager.CreateSocket( networkPlayer, localPlayer ); } app.DebugPrintf( "Player 0x%p \"%ls\" joined; %s; voice %i; camera %i.\n", pQNetPlayer, pQNetPlayer->GetGamertag(), pszDescription, (int) pQNetPlayer->HasVoice(), (int) pQNetPlayer->HasCamera() ); if( m_pIQNet->IsHost() ) { // 4J-PB - only the host should do this // g_NetworkManager.UpdateAndSetGameSessionData(); SystemFlagAddPlayer( networkPlayer ); } for( int idx = 0; idx < XUSER_MAX_COUNT; ++idx) { if(playerChangedCallback[idx] != NULL) playerChangedCallback[idx]( playerChangedCallbackParam[idx], networkPlayer, false ); } if(m_pIQNet->GetState() == QNET_STATE_GAME_PLAY) { int localPlayerCount = 0; for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx) { if( m_pIQNet->GetLocalPlayerByUserIndex(idx) != NULL ) ++localPlayerCount; } float appTime = app.getAppTime(); // Only record stats for the primary player here m_lastPlayerEventTimeStart = appTime; } } void CPlatformNetworkManagerStub::NotifyPlayerLeaving(IQNetPlayer* pQNetPlayer) { app.DebugPrintf("Player 0x%p \"%ls\" leaving.\n", pQNetPlayer, pQNetPlayer->GetGamertag()); INetworkPlayer* networkPlayer = getNetworkPlayer(pQNetPlayer); if (networkPlayer == NULL) return; Socket* socket = networkPlayer->GetSocket(); if (socket != NULL) { if (m_pIQNet->IsHost()) g_NetworkManager.CloseConnection(networkPlayer); } if (m_pIQNet->IsHost()) { SystemFlagRemovePlayer(networkPlayer); } g_NetworkManager.PlayerLeaving(networkPlayer); for (int idx = 0; idx < XUSER_MAX_COUNT; ++idx) { if (playerChangedCallback[idx] != NULL) playerChangedCallback[idx](playerChangedCallbackParam[idx], networkPlayer, true); } removeNetworkPlayer(pQNetPlayer); } bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkManager, int flagIndexSize) { m_pGameNetworkManager = pGameNetworkManager; m_flagIndexSize = flagIndexSize; m_pIQNet = new IQNet(); g_pPlatformNetworkManager = this; for( int i = 0; i < XUSER_MAX_COUNT; i++ ) { playerChangedCallback[ i ] = NULL; } m_bLeavingGame = false; m_bLeaveGameOnTick = false; m_bHostChanged = false; m_bSearchResultsReady = false; m_bSearchPending = false; m_bIsOfflineGame = false; m_pSearchParam = NULL; m_SessionsUpdatedCallback = NULL; for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) { m_searchResultsCount[i] = 0; m_lastSearchStartTime[i] = 0; // The results that will be filled in with the current search m_pSearchResults[i] = NULL; m_pQoSResult[i] = NULL; m_pCurrentSearchResults[i] = NULL; m_pCurrentQoSResult[i] = NULL; m_currentSearchResultsCount[i] = 0; } // Success! return true; } void CPlatformNetworkManagerStub::Terminate() { } int CPlatformNetworkManagerStub::GetJoiningReadyPercentage() { return 100; } int CPlatformNetworkManagerStub::CorrectErrorIDS(int IDS) { return IDS; } bool CPlatformNetworkManagerStub::isSystemPrimaryPlayer(IQNetPlayer *pQNetPlayer) { return true; } // We call this twice a frame, either side of the render call so is a good place to "tick" things void CPlatformNetworkManagerStub::DoWork() { #ifdef _WINDOWS64 extern QNET_STATE _iQNetStubState; if (_iQNetStubState == QNET_STATE_SESSION_STARTING && app.GetGameStarted()) { _iQNetStubState = QNET_STATE_GAME_PLAY; if (m_pIQNet->IsHost()) WinsockNetLayer::UpdateAdvertiseJoinable(true); } if (_iQNetStubState == QNET_STATE_IDLE) TickSearch(); if (_iQNetStubState == QNET_STATE_GAME_PLAY && m_pIQNet->IsHost()) { BYTE disconnectedSmallId; while (WinsockNetLayer::PopDisconnectedSmallId(&disconnectedSmallId)) { IQNetPlayer* qnetPlayer = m_pIQNet->GetPlayerBySmallId(disconnectedSmallId); if (qnetPlayer != NULL && qnetPlayer->m_smallId == disconnectedSmallId) { NotifyPlayerLeaving(qnetPlayer); qnetPlayer->m_smallId = 0; qnetPlayer->m_isRemote = false; qnetPlayer->m_isHostPlayer = false; qnetPlayer->m_gamertag[0] = 0; qnetPlayer->SetCustomDataValue(0); WinsockNetLayer::PushFreeSmallId(disconnectedSmallId); if (IQNet::s_playerCount > 1) IQNet::s_playerCount--; } } } #endif } int CPlatformNetworkManagerStub::GetPlayerCount() { return m_pIQNet->GetPlayerCount(); } bool CPlatformNetworkManagerStub::ShouldMessageForFullSession() { return false; } int CPlatformNetworkManagerStub::GetOnlinePlayerCount() { return 1; } int CPlatformNetworkManagerStub::GetLocalPlayerMask(int playerIndex) { return 1 << playerIndex; } bool CPlatformNetworkManagerStub::AddLocalPlayerByUserIndex( int userIndex ) { NotifyPlayerJoined(m_pIQNet->GetLocalPlayerByUserIndex(userIndex)); return ( m_pIQNet->AddLocalPlayerByUserIndex(userIndex) == S_OK ); } bool CPlatformNetworkManagerStub::RemoveLocalPlayerByUserIndex( int userIndex ) { return true; } bool CPlatformNetworkManagerStub::IsInStatsEnabledSession() { return true; } bool CPlatformNetworkManagerStub::SessionHasSpace(unsigned int spaceRequired /*= 1*/) { return true; } void CPlatformNetworkManagerStub::SendInviteGUI(int quadrant) { } bool CPlatformNetworkManagerStub::IsAddingPlayer() { return false; } bool CPlatformNetworkManagerStub::LeaveGame(bool bMigrateHost) { if( m_bLeavingGame ) return true; m_bLeavingGame = true; #ifdef _WINDOWS64 WinsockNetLayer::StopAdvertising(); #endif // If we are the host wait for the game server to end if(m_pIQNet->IsHost() && g_NetworkManager.ServerStoppedValid()) { m_pIQNet->EndGame(); g_NetworkManager.ServerStoppedWait(); g_NetworkManager.ServerStoppedDestroy(); } else { m_pIQNet->EndGame(); } for (AUTO_VAR(it, currentNetworkPlayers.begin()); it != currentNetworkPlayers.end(); it++) delete* it; currentNetworkPlayers.clear(); m_machineQNetPrimaryPlayers.clear(); SystemFlagReset(); #ifdef _WINDOWS64 WinsockNetLayer::Shutdown(); WinsockNetLayer::Initialize(); #endif return true; } bool CPlatformNetworkManagerStub::_LeaveGame(bool bMigrateHost, bool bLeaveRoom) { return true; } void CPlatformNetworkManagerStub::HostGame(int localUsersMask, bool bOnlineGame, bool bIsPrivate, unsigned char publicSlots /*= MINECRAFT_NET_MAX_PLAYERS*/, unsigned char privateSlots /*= 0*/) { // #ifdef _XBOX // 4J Stu - We probably did this earlier as well, but just to be sure! SetLocalGame( !bOnlineGame ); SetPrivateGame( bIsPrivate ); SystemFlagReset(); // Make sure that the Primary Pad is in by default localUsersMask |= GetLocalPlayerMask( g_NetworkManager.GetPrimaryPad() ); m_bLeavingGame = false; m_pIQNet->HostGame(); #ifdef _WINDOWS64 IQNet::m_player[0].m_smallId = 0; IQNet::m_player[0].m_isRemote = false; IQNet::m_player[0].m_isHostPlayer = true; IQNet::s_playerCount = 1; #endif _HostGame( localUsersMask, publicSlots, privateSlots ); #ifdef _WINDOWS64 int port = WIN64_NET_DEFAULT_PORT; if (!WinsockNetLayer::IsActive()) WinsockNetLayer::HostGame(port); const wchar_t* hostName = IQNet::m_player[0].m_gamertag; unsigned int settings = app.GetGameHostOption(eGameHostOption_All); WinsockNetLayer::StartAdvertising(port, hostName, settings, 0, 0, MINECRAFT_NET_VERSION); #endif //#endif } void CPlatformNetworkManagerStub::_HostGame(int usersMask, unsigned char publicSlots /*= MINECRAFT_NET_MAX_PLAYERS*/, unsigned char privateSlots /*= 0*/) { } bool CPlatformNetworkManagerStub::_StartGame() { return true; } int CPlatformNetworkManagerStub::JoinGame(FriendSessionInfo* searchResult, int localUsersMask, int primaryUserIndex) { #ifdef _WINDOWS64 if (searchResult == NULL) return CGameNetworkManager::JOINGAME_FAIL_GENERAL; const char* hostIP = searchResult->data.hostIP; int hostPort = searchResult->data.hostPort; if (hostPort <= 0 || hostIP[0] == 0) return CGameNetworkManager::JOINGAME_FAIL_GENERAL; m_bLeavingGame = false; IQNet::s_isHosting = false; m_pIQNet->ClientJoinGame(); IQNet::m_player[0].m_smallId = 0; IQNet::m_player[0].m_isRemote = true; IQNet::m_player[0].m_isHostPlayer = true; wcsncpy_s(IQNet::m_player[0].m_gamertag, 32, searchResult->data.hostName, _TRUNCATE); WinsockNetLayer::StopDiscovery(); if (!WinsockNetLayer::JoinGame(hostIP, hostPort)) { app.DebugPrintf("Win64 LAN: Failed to connect to %s:%d\n", hostIP, hostPort); return CGameNetworkManager::JOINGAME_FAIL_GENERAL; } BYTE localSmallId = WinsockNetLayer::GetLocalSmallId(); IQNet::m_player[localSmallId].m_smallId = localSmallId; IQNet::m_player[localSmallId].m_isRemote = false; IQNet::m_player[localSmallId].m_isHostPlayer = false; Minecraft* pMinecraft = Minecraft::GetInstance(); wcscpy_s(IQNet::m_player[localSmallId].m_gamertag, 32, pMinecraft->user->name.c_str()); IQNet::s_playerCount = localSmallId + 1; NotifyPlayerJoined(&IQNet::m_player[0]); NotifyPlayerJoined(&IQNet::m_player[localSmallId]); m_pGameNetworkManager->StateChange_AnyToStarting(); return CGameNetworkManager::JOINGAME_SUCCESS; #else return CGameNetworkManager::JOINGAME_SUCCESS; #endif } bool CPlatformNetworkManagerStub::SetLocalGame(bool isLocal) { m_bIsOfflineGame = isLocal; return true; } void CPlatformNetworkManagerStub::SetPrivateGame(bool isPrivate) { app.DebugPrintf("Setting as private game: %s\n", isPrivate ? "yes" : "no" ); m_bIsPrivateGame = isPrivate; } void CPlatformNetworkManagerStub::RegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam) { playerChangedCallback[iPad] = callback; playerChangedCallbackParam[iPad] = callbackParam; } void CPlatformNetworkManagerStub::UnRegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam) { if(playerChangedCallbackParam[iPad] == callbackParam) { playerChangedCallback[iPad] = NULL; playerChangedCallbackParam[iPad] = NULL; } } void CPlatformNetworkManagerStub::HandleSignInChange() { return; } bool CPlatformNetworkManagerStub::_RunNetworkGame() { #ifdef _WINDOWS64 extern QNET_STATE _iQNetStubState; _iQNetStubState = QNET_STATE_GAME_PLAY; for (DWORD i = 0; i < IQNet::s_playerCount; i++) { if (IQNet::m_player[i].m_isRemote) { INetworkPlayer* pNetworkPlayer = getNetworkPlayer(&IQNet::m_player[i]); if (pNetworkPlayer != NULL && pNetworkPlayer->GetSocket() != NULL) { Socket::addIncomingSocket(pNetworkPlayer->GetSocket()); } } } #endif return true; } void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= NULL*/) { // DWORD playerCount = m_pIQNet->GetPlayerCount(); // // if( this->m_bLeavingGame ) // return; // // if( GetHostPlayer() == NULL ) // return; // // for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) // { // if( i < playerCount ) // { // INetworkPlayer *pNetworkPlayer = GetPlayerByIndex(i); // // // We can call this from NotifyPlayerLeaving but at that point the player is still considered in the session // if( pNetworkPlayer != pNetworkPlayerLeaving ) // { // m_hostGameSessionData.players[i] = ((NetworkPlayerXbox *)pNetworkPlayer)->GetUID(); // // char *temp; // temp = (char *)wstringtofilename( pNetworkPlayer->GetOnlineName() ); // memcpy(m_hostGameSessionData.szPlayers[i],temp,XUSER_NAME_SIZE); // } // else // { // m_hostGameSessionData.players[i] = NULL; // memset(m_hostGameSessionData.szPlayers[i],0,XUSER_NAME_SIZE); // } // } // else // { // m_hostGameSessionData.players[i] = NULL; // memset(m_hostGameSessionData.szPlayers[i],0,XUSER_NAME_SIZE); // } // } // // m_hostGameSessionData.hostPlayerUID = ((NetworkPlayerXbox *)GetHostPlayer())->GetQNetPlayer()->GetXuid(); // m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All); } int CPlatformNetworkManagerStub::RemovePlayerOnSocketClosedThreadProc( void* lpParam ) { INetworkPlayer *pNetworkPlayer = (INetworkPlayer *)lpParam; Socket *socket = pNetworkPlayer->GetSocket(); if( socket != NULL ) { //printf("Waiting for socket closed event\n"); socket->m_socketClosedEvent->WaitForSignal(INFINITE); //printf("Socket closed event has fired\n"); // 4J Stu - Clear our reference to this socket pNetworkPlayer->SetSocket( NULL ); delete socket; } return g_pPlatformNetworkManager->RemoveLocalPlayer( pNetworkPlayer ); } bool CPlatformNetworkManagerStub::RemoveLocalPlayer( INetworkPlayer *pNetworkPlayer ) { return true; } CPlatformNetworkManagerStub::PlayerFlags::PlayerFlags(INetworkPlayer *pNetworkPlayer, unsigned int count) { // 4J Stu - Don't assert, just make it a multiple of 8! This count is calculated from a load of separate values, // and makes tweaking world/render sizes a pain if we hit an assert here count = (count + 8 - 1) & ~(8 - 1); //assert( ( count % 8 ) == 0 ); this->m_pNetworkPlayer = pNetworkPlayer; this->flags = new unsigned char [ count / 8 ]; memset( this->flags, 0, count / 8 ); this->count = count; } CPlatformNetworkManagerStub::PlayerFlags::~PlayerFlags() { delete [] flags; } // Add a player to the per system flag storage - if we've already got a player from that system, copy its flags over void CPlatformNetworkManagerStub::SystemFlagAddPlayer(INetworkPlayer *pNetworkPlayer) { PlayerFlags *newPlayerFlags = new PlayerFlags( pNetworkPlayer, m_flagIndexSize); // If any of our existing players are on the same system, then copy over flags from that one for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) { if( pNetworkPlayer->IsSameSystem(m_playerFlags[i]->m_pNetworkPlayer) ) { memcpy( newPlayerFlags->flags, m_playerFlags[i]->flags, m_playerFlags[i]->count / 8 ); break; } } m_playerFlags.push_back(newPlayerFlags); } // Remove a player from the per system flag storage - just maintains the m_playerFlags vector without any gaps in it void CPlatformNetworkManagerStub::SystemFlagRemovePlayer(INetworkPlayer *pNetworkPlayer) { for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) { if( m_playerFlags[i]->m_pNetworkPlayer == pNetworkPlayer ) { delete m_playerFlags[i]; m_playerFlags[i] = m_playerFlags.back(); m_playerFlags.pop_back(); return; } } } void CPlatformNetworkManagerStub::SystemFlagReset() { for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) { delete m_playerFlags[i]; } m_playerFlags.clear(); } // Set a per system flag - this is done by setting the flag on every player that shares that system void CPlatformNetworkManagerStub::SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index) { if( ( index < 0 ) || ( index >= m_flagIndexSize ) ) return; if( pNetworkPlayer == NULL ) return; for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) { if( pNetworkPlayer->IsSameSystem(m_playerFlags[i]->m_pNetworkPlayer) ) { m_playerFlags[i]->flags[ index / 8 ] |= ( 128 >> ( index % 8 ) ); } } } // Get value of a per system flag - can be read from the flags of the passed in player as anything else sent to that // system should also have been duplicated here bool CPlatformNetworkManagerStub::SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index) { if( ( index < 0 ) || ( index >= m_flagIndexSize ) ) return false; if( pNetworkPlayer == NULL ) { return false; } for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) { if( m_playerFlags[i]->m_pNetworkPlayer == pNetworkPlayer ) { return ( ( m_playerFlags[i]->flags[ index / 8 ] & ( 128 >> ( index % 8 ) ) ) != 0 ); } } return false; } wstring CPlatformNetworkManagerStub::GatherStats() { return L""; } wstring CPlatformNetworkManagerStub::GatherRTTStats() { wstring stats(L"Rtt: "); wchar_t stat[32]; for(unsigned int i = 0; i < GetPlayerCount(); ++i) { IQNetPlayer *pQNetPlayer = ((NetworkPlayerXbox *)GetPlayerByIndex( i ))->GetQNetPlayer(); if(!pQNetPlayer->IsLocal()) { ZeroMemory(stat,32*sizeof(WCHAR)); swprintf(stat, 32, L"%d: %d/", i, pQNetPlayer->GetCurrentRtt() ); stats.append(stat); } } return stats; } void CPlatformNetworkManagerStub::TickSearch() { #ifdef _WINDOWS64 if (m_SessionsUpdatedCallback == NULL) return; static DWORD lastSearchTime = 0; DWORD now = GetTickCount(); if (now - lastSearchTime < 2000) return; lastSearchTime = now; SearchForGames(); #endif } void CPlatformNetworkManagerStub::SearchForGames() { #ifdef _WINDOWS64 std::vector lanSessions = WinsockNetLayer::GetDiscoveredSessions(); for (size_t i = 0; i < friendsSessions[0].size(); i++) delete friendsSessions[0][i]; friendsSessions[0].clear(); for (size_t i = 0; i < lanSessions.size(); i++) { FriendSessionInfo* info = new FriendSessionInfo(); size_t nameLen = wcslen(lanSessions[i].hostName); info->displayLabel = new wchar_t[nameLen + 1]; wcscpy_s(info->displayLabel, nameLen + 1, lanSessions[i].hostName); info->displayLabelLength = (unsigned char)nameLen; info->displayLabelViewableStartIndex = 0; info->data.netVersion = lanSessions[i].netVersion; info->data.m_uiGameHostSettings = lanSessions[i].gameHostSettings; info->data.texturePackParentId = lanSessions[i].texturePackParentId; info->data.subTexturePackId = lanSessions[i].subTexturePackId; info->data.isReadyToJoin = lanSessions[i].isJoinable; info->data.isJoinable = lanSessions[i].isJoinable; strncpy_s(info->data.hostIP, sizeof(info->data.hostIP), lanSessions[i].hostIP, _TRUNCATE); info->data.hostPort = lanSessions[i].hostPort; wcsncpy_s(info->data.hostName, XUSER_NAME_SIZE, lanSessions[i].hostName, _TRUNCATE); info->data.playerCount = lanSessions[i].playerCount; info->data.maxPlayers = lanSessions[i].maxPlayers; info->sessionId = (SessionID)((unsigned __int64)inet_addr(lanSessions[i].hostIP) | ((unsigned __int64)lanSessions[i].hostPort << 32)); friendsSessions[0].push_back(info); } m_searchResultsCount[0] = (int)friendsSessions[0].size(); if (m_SessionsUpdatedCallback != NULL) m_SessionsUpdatedCallback(m_pSearchParam); #endif } int CPlatformNetworkManagerStub::SearchForGamesThreadProc( void* lpParameter ) { return 0; } void CPlatformNetworkManagerStub::SetSearchResultsReady(int resultCount) { m_bSearchResultsReady = true; m_searchResultsCount[m_lastSearchPad] = resultCount; } vector *CPlatformNetworkManagerStub::GetSessionList(int iPad, int localPlayers, bool partyOnly) { vector* filteredList = new vector(); for (size_t i = 0; i < friendsSessions[0].size(); i++) filteredList->push_back(friendsSessions[0][i]); return filteredList; } bool CPlatformNetworkManagerStub::GetGameSessionInfo(int iPad, SessionID sessionId, FriendSessionInfo *foundSessionInfo) { return false; } void CPlatformNetworkManagerStub::SetSessionsUpdatedCallback( void (*SessionsUpdatedCallback)(LPVOID pParam), LPVOID pSearchParam ) { m_SessionsUpdatedCallback = SessionsUpdatedCallback; m_pSearchParam = pSearchParam; } void CPlatformNetworkManagerStub::GetFullFriendSessionInfo( FriendSessionInfo *foundSession, void (* FriendSessionUpdatedFn)(bool success, void *pParam), void *pParam ) { FriendSessionUpdatedFn(true, pParam); } void CPlatformNetworkManagerStub::ForceFriendsSessionRefresh() { app.DebugPrintf("Resetting friends session search data\n"); for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) { m_searchResultsCount[i] = 0; m_lastSearchStartTime[i] = 0; delete m_pSearchResults[i]; m_pSearchResults[i] = NULL; } } INetworkPlayer *CPlatformNetworkManagerStub::addNetworkPlayer(IQNetPlayer *pQNetPlayer) { NetworkPlayerXbox *pNetworkPlayer = new NetworkPlayerXbox(pQNetPlayer); pQNetPlayer->SetCustomDataValue((ULONG_PTR)pNetworkPlayer); currentNetworkPlayers.push_back( pNetworkPlayer ); return pNetworkPlayer; } void CPlatformNetworkManagerStub::removeNetworkPlayer(IQNetPlayer *pQNetPlayer) { INetworkPlayer *pNetworkPlayer = getNetworkPlayer(pQNetPlayer); for( AUTO_VAR(it, currentNetworkPlayers.begin()); it != currentNetworkPlayers.end(); it++ ) { if( *it == pNetworkPlayer ) { currentNetworkPlayers.erase(it); return; } } } INetworkPlayer *CPlatformNetworkManagerStub::getNetworkPlayer(IQNetPlayer *pQNetPlayer) { return pQNetPlayer ? (INetworkPlayer *)(pQNetPlayer->GetCustomDataValue()) : NULL; } INetworkPlayer *CPlatformNetworkManagerStub::GetLocalPlayerByUserIndex(int userIndex ) { return getNetworkPlayer(m_pIQNet->GetLocalPlayerByUserIndex(userIndex)); } INetworkPlayer *CPlatformNetworkManagerStub::GetPlayerByIndex(int playerIndex) { return getNetworkPlayer(m_pIQNet->GetPlayerByIndex(playerIndex)); } INetworkPlayer * CPlatformNetworkManagerStub::GetPlayerByXuid(PlayerUID xuid) { return getNetworkPlayer( m_pIQNet->GetPlayerByXuid(xuid)) ; } INetworkPlayer * CPlatformNetworkManagerStub::GetPlayerBySmallId(unsigned char smallId) { return getNetworkPlayer(m_pIQNet->GetPlayerBySmallId(smallId)); } INetworkPlayer *CPlatformNetworkManagerStub::GetHostPlayer() { return getNetworkPlayer(m_pIQNet->GetHostPlayer()); } bool CPlatformNetworkManagerStub::IsHost() { return m_pIQNet->IsHost() && !m_bHostChanged; } bool CPlatformNetworkManagerStub::JoinGameFromInviteInfo( int userIndex, int userMask, const INVITE_INFO *pInviteInfo) { return ( m_pIQNet->JoinGameFromInviteInfo( userIndex, userMask, pInviteInfo ) == S_OK); } void CPlatformNetworkManagerStub::SetSessionTexturePackParentId( int id ) { m_hostGameSessionData.texturePackParentId = id; } void CPlatformNetworkManagerStub::SetSessionSubTexturePackId( int id ) { m_hostGameSessionData.subTexturePackId = id; } void CPlatformNetworkManagerStub::Notify(int ID, ULONG_PTR Param) { } bool CPlatformNetworkManagerStub::IsInSession() { return m_pIQNet->GetState() != QNET_STATE_IDLE; } bool CPlatformNetworkManagerStub::IsInGameplay() { return m_pIQNet->GetState() == QNET_STATE_GAME_PLAY; } bool CPlatformNetworkManagerStub::IsReadyToPlayOrIdle() { return true; }