From ba5652dff2291c0a61564f56520e993c2cdf0d3f Mon Sep 17 00:00:00 2001 From: NaN Date: Mon, 3 Aug 2026 16:48:16 -0400 Subject: [PATCH] fix: restore PlatformNetworkManager line endings --- .../Common/Network/PlatformNetworkManager.cpp | 1894 ++++++++--------- 1 file changed, 947 insertions(+), 947 deletions(-) diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManager.cpp b/Minecraft.Client/Common/Network/PlatformNetworkManager.cpp index f0ff0dd0..59ce1a0b 100644 --- a/Minecraft.Client/Common/Network/PlatformNetworkManager.cpp +++ b/Minecraft.Client/Common/Network/PlatformNetworkManager.cpp @@ -1,947 +1,947 @@ -#include "stdafx.h" -#include "..\..\..\Minecraft.World\Socket.h" -#include "..\..\..\Minecraft.World\StringHelpers.h" -#include "PlatformNetworkManager.h" -#include "..\..\Xbox\Network\NetworkPlayerXbox.h" // TODO - stub version of this? -#include "..\..\Minecraft.h" -#include "..\..\User.h" -#include "..\..\Common\Network\NetworkSocketLayer.h" - -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); - - if (m_pIQNet->IsHost()) - { - g_NetworkManager.UpdateAndSetGameSessionData(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() -{ - extern QNET_STATE _iQNetStubState; - if (_iQNetStubState == QNET_STATE_SESSION_STARTING && app.GetGameStarted()) - { - _iQNetStubState = QNET_STATE_GAME_PLAY; - if (m_pIQNet->IsHost()) - NetworkSocketLayer::UpdateAdvertiseJoinable(true); - } - if (_iQNetStubState == QNET_STATE_IDLE) - TickSearch(); - if (_iQNetStubState == QNET_STATE_GAME_PLAY && m_pIQNet->IsHost()) - { - BYTE disconnectedSmallId; - while (NetworkSocketLayer::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); - NetworkSocketLayer::PushFreeSmallId(disconnectedSmallId); - if (IQNet::s_playerCount > 1) - IQNet::s_playerCount--; - } - } - - for (int i = 1; i < MINECRAFT_NET_MAX_PLAYERS; i++) - { - IQNetPlayer *qp = &IQNet::m_player[i]; - if (qp->GetCustomDataValue() == 0) - continue; - INetworkPlayer *np = (INetworkPlayer *)qp->GetCustomDataValue(); - Socket *sock = np->GetSocket(); - if (sock != NULL && sock->isClosing()) - { - NetworkSocketLayer::CloseConnectionBySmallId((BYTE)i); - } - } - } - if (_iQNetStubState == QNET_STATE_GAME_PLAY && !m_pIQNet->IsHost()) - { - if (!NetworkSocketLayer::IsConnected() && !g_NetworkManager.IsLeavingGame()) - { - if (app.GetDisconnectReason() == DisconnectPacket::eDisconnect_None) - app.SetDisconnectReason(DisconnectPacket::eDisconnect_Quitting); - app.SetAction(ProfileManager.GetPrimaryPad(), eAppAction_ExitWorld, (void *)TRUE); - } - } -} - -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; - NetworkSocketLayer::StopAdvertising(); - - // 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(); - - NetworkSocketLayer::Shutdown(); - NetworkSocketLayer::Initialize(); - - 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(); - - 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; - - _HostGame( localUsersMask, publicSlots, privateSlots ); - - int port = NETWORK_LAN_DEFAULT_PORT; - if (!NetworkSocketLayer::IsActive()) - NetworkSocketLayer::HostGame(port); - - const wchar_t *hostName = IQNet::m_player[0].m_gamertag; - unsigned int settings = app.GetGameHostOption(eGameHostOption_All); - NetworkSocketLayer::StartAdvertising(port, hostName, settings, 0, 0, MINECRAFT_NET_VERSION); -//#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) -{ - 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(IQNet::m_player[0].m_gamertag, searchResult->data.hostName, 31); - - NetworkSocketLayer::StopDiscovery(); - - if (!NetworkSocketLayer::JoinGame(hostIP, hostPort)) - { - app.DebugPrintf("Win64 LAN: Failed to connect to %s:%d\n", hostIP, hostPort); - return CGameNetworkManager::JOINGAME_FAIL_GENERAL; - } - - BYTE localSmallId = NetworkSocketLayer::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(); - wcsncpy(IQNet::m_player[localSmallId].m_gamertag, pMinecraft->user->name.c_str(), 32); - IQNet::s_playerCount = localSmallId + 1; - - NotifyPlayerJoined(&IQNet::m_player[0]); - NotifyPlayerJoined(&IQNet::m_player[localSmallId]); - - m_pGameNetworkManager->StateChange_AnyToStarting(); - - return CGameNetworkManager::JOINGAME_SUCCESS; -} - -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() -{ - 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()); - } - } - } - - return true; -} - -void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= NULL*/) -{ - if (this->m_bLeavingGame) - return; - - if (!m_pIQNet->IsHost()) - return; - - DWORD playerCount = m_pIQNet->GetPlayerCount(); - - m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All); - m_hostGameSessionData.playerCount = (unsigned char)playerCount; - - for (unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) - { - if (i < playerCount) - { - INetworkPlayer *pNetworkPlayer = GetPlayerByIndex(i); - - if (pNetworkPlayer != NULL && pNetworkPlayer != pNetworkPlayerLeaving) - { - m_hostGameSessionData.players[i] = (GameSessionUID)(i + 1); - - const wchar_t *name = pNetworkPlayer->GetOnlineName(); - char nameBuf[XUSER_NAME_SIZE]; - memset(nameBuf, 0, sizeof(nameBuf)); - wcstombs(nameBuf, name, XUSER_NAME_SIZE - 1); - memcpy(m_hostGameSessionData.szPlayers[i], nameBuf, XUSER_NAME_SIZE); - } - else - { - m_hostGameSessionData.players[i] = 0; - memset(m_hostGameSessionData.szPlayers[i], 0, XUSER_NAME_SIZE); - } - } - else - { - m_hostGameSessionData.players[i] = 0; - memset(m_hostGameSessionData.szPlayers[i], 0, XUSER_NAME_SIZE); - } - } - - // update the LAN advertiser with current player names and count - NetworkSocketLayer::UpdateAdvertisePlayerNames(m_hostGameSessionData.playerCount, m_hostGameSessionData.szPlayers); -} - -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() -{ - if (m_SessionsUpdatedCallback == NULL) - return; - - static DWORD lastSearchTime = 0; - DWORD now = GetTickCount(); - if (now - lastSearchTime < 2000) - return; - lastSearchTime = now; - - SearchForGames(); -} - -void CPlatformNetworkManagerStub::SearchForGames() -{ - std::vector lanSessions = NetworkSocketLayer::GetDiscoveredSessions(); - - if (g_MultiplayerJoin) - { - bool alreadyPresent = false; - for (size_t i = 0; i < lanSessions.size(); i++) - { - if (strcmp(lanSessions[i].hostIP, g_MultiplayerIP) == 0 && - lanSessions[i].hostPort == g_MultiplayerPort) - { - alreadyPresent = true; - break; - } - } - if (!alreadyPresent) - { - LANSession manual; - memset(&manual, 0, sizeof(manual)); - strncpy(manual.hostIP, g_MultiplayerIP, sizeof(manual.hostIP) - 1); - manual.hostIP[sizeof(manual.hostIP) - 1] = '\0'; - - manual.hostPort = g_MultiplayerPort; - - swprintf(manual.hostName, 32, L"%hs:%d", g_MultiplayerIP, g_MultiplayerPort); - manual.hostName[31] = L'\0'; - manual.playerCount = 0; - manual.maxPlayers = MINECRAFT_NET_MAX_PLAYERS; - manual.isJoinable = true; - manual.lastSeenTick = GetTickCount(); - lanSessions.push_back(manual); - } - } - - 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]; - wcsncpy(info->displayLabel, lanSessions[i].hostName, nameLen); - info->displayLabel[nameLen] = L'\0'; - 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(info->data.hostIP, lanSessions[i].hostIP, sizeof(info->data.hostIP) - 1); - info->data.hostIP[sizeof(info->data.hostIP) - 1] = '\0'; - info->data.hostPort = lanSessions[i].hostPort; - wcsncpy(info->data.hostName, lanSessions[i].hostName, XUSER_NAME_SIZE - 1); - info->data.hostName[XUSER_NAME_SIZE - 1] = L'\0'; - info->data.playerCount = lanSessions[i].playerCount; - info->data.maxPlayers = lanSessions[i].maxPlayers; - - memset(info->data.players, 0, sizeof(info->data.players)); - memset(info->data.szPlayers, 0, sizeof(info->data.szPlayers)); - for (int p = 0; p < MINECRAFT_NET_MAX_PLAYERS && p < lanSessions[i].playerCount; p++) - { - if (lanSessions[i].playerNames[p][0] != 0) - { - info->data.players[p] = (GameSessionUID)(p + 1); - memcpy(info->data.szPlayers[p], lanSessions[i].playerNames[p], XUSER_NAME_SIZE); - } - } - -#ifdef __ORBIS__ - SceNetInAddr ip_addr = {}; - sceNetInetPton(SCE_NET_AF_INET, lanSessions[i].hostIP, &ip_addr); - info->sessionId = (ULONGLONG)((uint64_t)ip_addr.s_addr | ((uint64_t)lanSessions[i].hostPort << 32)); -#else - info->sessionId = (ULONGLONG)((unsigned __int64)inet_addr(lanSessions[i].hostIP) | ((unsigned __int64)lanSessions[i].hostPort << 32)); -#endif - friendsSessions[0].push_back(info); - } - - m_searchResultsCount[0] = (int)friendsSessions[0].size(); - - if (m_SessionsUpdatedCallback != NULL) - m_SessionsUpdatedCallback(m_pSearchParam); -} - -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) -{ - for (size_t i = 0; i < friendsSessions[0].size(); i++) - { - if (friendsSessions[0][i]->sessionId == sessionId) - { - if (foundSessionInfo != NULL) - { - foundSessionInfo->sessionId = friendsSessions[0][i]->sessionId; - foundSessionInfo->data = friendsSessions[0][i]->data; - foundSessionInfo->hasPartyMember = friendsSessions[0][i]->hasPartyMember; - } - return true; - } - } -} - -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) -{ - IQNetPlayer *qnetPlayer = m_pIQNet->GetPlayerBySmallId(smallId); - if (qnetPlayer == NULL) - return NULL; - - INetworkPlayer *networkPlayer = getNetworkPlayer(qnetPlayer); - if (networkPlayer == NULL && smallId != 0 && !m_pIQNet->IsHost()) - { - qnetPlayer->m_isRemote = true; - qnetPlayer->m_isHostPlayer = false; - NotifyPlayerJoined(qnetPlayer); - networkPlayer = getNetworkPlayer(qnetPlayer); - } - return networkPlayer; -} - -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; -} +#include "stdafx.h" +#include "..\..\..\Minecraft.World\Socket.h" +#include "..\..\..\Minecraft.World\StringHelpers.h" +#include "PlatformNetworkManager.h" +#include "..\..\Xbox\Network\NetworkPlayerXbox.h" // TODO - stub version of this? +#include "..\..\Minecraft.h" +#include "..\..\User.h" +#include "..\..\Common\Network\NetworkSocketLayer.h" + +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); + + if (m_pIQNet->IsHost()) + { + g_NetworkManager.UpdateAndSetGameSessionData(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() +{ + extern QNET_STATE _iQNetStubState; + if (_iQNetStubState == QNET_STATE_SESSION_STARTING && app.GetGameStarted()) + { + _iQNetStubState = QNET_STATE_GAME_PLAY; + if (m_pIQNet->IsHost()) + NetworkSocketLayer::UpdateAdvertiseJoinable(true); + } + if (_iQNetStubState == QNET_STATE_IDLE) + TickSearch(); + if (_iQNetStubState == QNET_STATE_GAME_PLAY && m_pIQNet->IsHost()) + { + BYTE disconnectedSmallId; + while (NetworkSocketLayer::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); + NetworkSocketLayer::PushFreeSmallId(disconnectedSmallId); + if (IQNet::s_playerCount > 1) + IQNet::s_playerCount--; + } + } + + for (int i = 1; i < MINECRAFT_NET_MAX_PLAYERS; i++) + { + IQNetPlayer *qp = &IQNet::m_player[i]; + if (qp->GetCustomDataValue() == 0) + continue; + INetworkPlayer *np = (INetworkPlayer *)qp->GetCustomDataValue(); + Socket *sock = np->GetSocket(); + if (sock != NULL && sock->isClosing()) + { + NetworkSocketLayer::CloseConnectionBySmallId((BYTE)i); + } + } + } + if (_iQNetStubState == QNET_STATE_GAME_PLAY && !m_pIQNet->IsHost()) + { + if (!NetworkSocketLayer::IsConnected() && !g_NetworkManager.IsLeavingGame()) + { + if (app.GetDisconnectReason() == DisconnectPacket::eDisconnect_None) + app.SetDisconnectReason(DisconnectPacket::eDisconnect_Quitting); + app.SetAction(ProfileManager.GetPrimaryPad(), eAppAction_ExitWorld, (void *)TRUE); + } + } +} + +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; + NetworkSocketLayer::StopAdvertising(); + + // 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(); + + NetworkSocketLayer::Shutdown(); + NetworkSocketLayer::Initialize(); + + 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(); + + 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; + + _HostGame( localUsersMask, publicSlots, privateSlots ); + + int port = NETWORK_LAN_DEFAULT_PORT; + if (!NetworkSocketLayer::IsActive()) + NetworkSocketLayer::HostGame(port); + + const wchar_t *hostName = IQNet::m_player[0].m_gamertag; + unsigned int settings = app.GetGameHostOption(eGameHostOption_All); + NetworkSocketLayer::StartAdvertising(port, hostName, settings, 0, 0, MINECRAFT_NET_VERSION); +//#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) +{ + 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(IQNet::m_player[0].m_gamertag, searchResult->data.hostName, 31); + + NetworkSocketLayer::StopDiscovery(); + + if (!NetworkSocketLayer::JoinGame(hostIP, hostPort)) + { + app.DebugPrintf("Win64 LAN: Failed to connect to %s:%d\n", hostIP, hostPort); + return CGameNetworkManager::JOINGAME_FAIL_GENERAL; + } + + BYTE localSmallId = NetworkSocketLayer::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(); + wcsncpy(IQNet::m_player[localSmallId].m_gamertag, pMinecraft->user->name.c_str(), 32); + IQNet::s_playerCount = localSmallId + 1; + + NotifyPlayerJoined(&IQNet::m_player[0]); + NotifyPlayerJoined(&IQNet::m_player[localSmallId]); + + m_pGameNetworkManager->StateChange_AnyToStarting(); + + return CGameNetworkManager::JOINGAME_SUCCESS; +} + +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() +{ + 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()); + } + } + } + + return true; +} + +void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= NULL*/) +{ + if (this->m_bLeavingGame) + return; + + if (!m_pIQNet->IsHost()) + return; + + DWORD playerCount = m_pIQNet->GetPlayerCount(); + + m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All); + m_hostGameSessionData.playerCount = (unsigned char)playerCount; + + for (unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) + { + if (i < playerCount) + { + INetworkPlayer *pNetworkPlayer = GetPlayerByIndex(i); + + if (pNetworkPlayer != NULL && pNetworkPlayer != pNetworkPlayerLeaving) + { + m_hostGameSessionData.players[i] = (GameSessionUID)(i + 1); + + const wchar_t *name = pNetworkPlayer->GetOnlineName(); + char nameBuf[XUSER_NAME_SIZE]; + memset(nameBuf, 0, sizeof(nameBuf)); + wcstombs(nameBuf, name, XUSER_NAME_SIZE - 1); + memcpy(m_hostGameSessionData.szPlayers[i], nameBuf, XUSER_NAME_SIZE); + } + else + { + m_hostGameSessionData.players[i] = 0; + memset(m_hostGameSessionData.szPlayers[i], 0, XUSER_NAME_SIZE); + } + } + else + { + m_hostGameSessionData.players[i] = 0; + memset(m_hostGameSessionData.szPlayers[i], 0, XUSER_NAME_SIZE); + } + } + + // update the LAN advertiser with current player names and count + NetworkSocketLayer::UpdateAdvertisePlayerNames(m_hostGameSessionData.playerCount, m_hostGameSessionData.szPlayers); +} + +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() +{ + if (m_SessionsUpdatedCallback == NULL) + return; + + static DWORD lastSearchTime = 0; + DWORD now = GetTickCount(); + if (now - lastSearchTime < 2000) + return; + lastSearchTime = now; + + SearchForGames(); +} + +void CPlatformNetworkManagerStub::SearchForGames() +{ + std::vector lanSessions = NetworkSocketLayer::GetDiscoveredSessions(); + + if (g_MultiplayerJoin) + { + bool alreadyPresent = false; + for (size_t i = 0; i < lanSessions.size(); i++) + { + if (strcmp(lanSessions[i].hostIP, g_MultiplayerIP) == 0 && + lanSessions[i].hostPort == g_MultiplayerPort) + { + alreadyPresent = true; + break; + } + } + if (!alreadyPresent) + { + LANSession manual; + memset(&manual, 0, sizeof(manual)); + strncpy(manual.hostIP, g_MultiplayerIP, sizeof(manual.hostIP) - 1); + manual.hostIP[sizeof(manual.hostIP) - 1] = '\0'; + + manual.hostPort = g_MultiplayerPort; + + swprintf(manual.hostName, 32, L"%hs:%d", g_MultiplayerIP, g_MultiplayerPort); + manual.hostName[31] = L'\0'; + manual.playerCount = 0; + manual.maxPlayers = MINECRAFT_NET_MAX_PLAYERS; + manual.isJoinable = true; + manual.lastSeenTick = GetTickCount(); + lanSessions.push_back(manual); + } + } + + 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]; + wcsncpy(info->displayLabel, lanSessions[i].hostName, nameLen); + info->displayLabel[nameLen] = L'\0'; + 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(info->data.hostIP, lanSessions[i].hostIP, sizeof(info->data.hostIP) - 1); + info->data.hostIP[sizeof(info->data.hostIP) - 1] = '\0'; + info->data.hostPort = lanSessions[i].hostPort; + wcsncpy(info->data.hostName, lanSessions[i].hostName, XUSER_NAME_SIZE - 1); + info->data.hostName[XUSER_NAME_SIZE - 1] = L'\0'; + info->data.playerCount = lanSessions[i].playerCount; + info->data.maxPlayers = lanSessions[i].maxPlayers; + + memset(info->data.players, 0, sizeof(info->data.players)); + memset(info->data.szPlayers, 0, sizeof(info->data.szPlayers)); + for (int p = 0; p < MINECRAFT_NET_MAX_PLAYERS && p < lanSessions[i].playerCount; p++) + { + if (lanSessions[i].playerNames[p][0] != 0) + { + info->data.players[p] = (GameSessionUID)(p + 1); + memcpy(info->data.szPlayers[p], lanSessions[i].playerNames[p], XUSER_NAME_SIZE); + } + } + +#ifdef __ORBIS__ + SceNetInAddr ip_addr = {}; + sceNetInetPton(SCE_NET_AF_INET, lanSessions[i].hostIP, &ip_addr); + info->sessionId = (ULONGLONG)((uint64_t)ip_addr.s_addr | ((uint64_t)lanSessions[i].hostPort << 32)); +#else + info->sessionId = (ULONGLONG)((unsigned __int64)inet_addr(lanSessions[i].hostIP) | ((unsigned __int64)lanSessions[i].hostPort << 32)); +#endif + friendsSessions[0].push_back(info); + } + + m_searchResultsCount[0] = (int)friendsSessions[0].size(); + + if (m_SessionsUpdatedCallback != NULL) + m_SessionsUpdatedCallback(m_pSearchParam); +} + +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) +{ + for (size_t i = 0; i < friendsSessions[0].size(); i++) + { + if (friendsSessions[0][i]->sessionId == sessionId) + { + if (foundSessionInfo != NULL) + { + foundSessionInfo->sessionId = friendsSessions[0][i]->sessionId; + foundSessionInfo->data = friendsSessions[0][i]->data; + foundSessionInfo->hasPartyMember = friendsSessions[0][i]->hasPartyMember; + } + return true; + } + } +} + +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) +{ + IQNetPlayer *qnetPlayer = m_pIQNet->GetPlayerBySmallId(smallId); + if (qnetPlayer == NULL) + return NULL; + + INetworkPlayer *networkPlayer = getNetworkPlayer(qnetPlayer); + if (networkPlayer == NULL && smallId != 0 && !m_pIQNet->IsHost()) + { + qnetPlayer->m_isRemote = true; + qnetPlayer->m_isHostPlayer = false; + NotifyPlayerJoined(qnetPlayer); + networkPlayer = getNetworkPlayer(qnetPlayer); + } + return networkPlayer; +} + +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; +}