From ebbd54288ba02bead81457fcc24263d7091ea413 Mon Sep 17 00:00:00 2001 From: qloak Date: Fri, 7 Aug 2026 17:14:12 +0000 Subject: [PATCH] Fix X360 Crossplay (#26) ^Reviewed-on: https://gitea.str1k3r.xyz/pieeebot/cafeberry/pulls/26 Co-authored-by: qloak --- Minecraft.Client/ClientConnection.cpp | 11 + Minecraft.Client/Common/Consoles_App.cpp | 4 + .../Common/Leaderboards/base64.cpp | 6 +- Minecraft.Client/Common/Leaderboards/base64.h | 2 +- .../Common/Network/GameNetworkManager.cpp | 35 +- .../Common/Network/NetworkSocketLayer.cpp | 2 +- .../Common/Network/PlatformNetworkManager.cpp | 1898 ++++++++--------- .../Common/Network/PlatformNetworkManager.h | 342 +-- .../Common/UI/UIScene_JoinMenu.cpp | 15 + .../Common/XUI/XUI_LoadSettings.cpp | 19 +- .../Common/XUI/XUI_MultiGameCreate.cpp | 19 +- .../Common/XUI/XUI_MultiGameInfo.cpp | 19 + .../Common/XUI/XUI_MultiGameJoinLoad.cpp | 15 +- Minecraft.Client/EnderDragonRenderer.cpp | 9 +- Minecraft.Client/EntityRenderDispatcher.cpp | 11 + Minecraft.Client/EntityRenderDispatcher.h | 3 +- Minecraft.Client/Extrax64Stubs.cpp | 1 + Minecraft.Client/GameRenderer.cpp | 60 +- Minecraft.Client/GameRenderer.h | 2 - Minecraft.Client/HorseRenderer.cpp | 8 +- Minecraft.Client/HorseRenderer.h | 2 +- Minecraft.Client/Minecraft.Client.vcxproj | 2 +- Minecraft.Client/Minecraft.cpp | 4 +- Minecraft.Client/MinecraftServer.cpp | 6 +- .../Orbis/Leaderboards/base64.cpp | 6 +- Minecraft.Client/Orbis/Leaderboards/base64.h | 2 +- Minecraft.Client/PS3/Leaderboards/base64.cpp | 6 +- Minecraft.Client/PS3/Leaderboards/base64.h | 2 +- Minecraft.Client/stdafx.h | 6 + Minecraft.World/AddEntityPacket.cpp | 12 - Minecraft.World/AddMobPacket.cpp | 12 - Minecraft.World/BlockRegionUpdatePacket.cpp | 4 +- Minecraft.World/ChunkTilesUpdatePacket.cpp | 12 - Minecraft.World/Connection.cpp | 6 +- Minecraft.World/LoginPacket.cpp | 4 - Minecraft.World/Minecraft.World.vcxproj | 3 +- Minecraft.World/RespawnPacket.cpp | 4 - Minecraft.World/TeleportEntityPacket.cpp | 12 - Minecraft.World/TileUpdatePacket.cpp | 33 - Minecraft.World/compression.cpp | 8 +- Minecraft.World/stdafx.h | 6 + 41 files changed, 1346 insertions(+), 1287 deletions(-) diff --git a/Minecraft.Client/ClientConnection.cpp b/Minecraft.Client/ClientConnection.cpp index 962d0fae..d44995e9 100644 --- a/Minecraft.Client/ClientConnection.cpp +++ b/Minecraft.Client/ClientConnection.cpp @@ -1856,6 +1856,7 @@ void ClientConnection::handlePreLogin(shared_ptr packet) } #ifdef _XBOX +#if !defined(_DISABLE_XBLIVE) if(!g_NetworkManager.IsHost() && !app.GetGameHostOption(eGameHostOption_FriendsOfFriends)) { if(m_userIndex == ProfileManager.GetPrimaryPad() ) @@ -1999,6 +2000,16 @@ void ClientConnection::handlePreLogin(shared_ptr packet) } } } +#else + // Offline/system-link games have no Xbox Live friend list, so grant all + // pre-login permissions (the Xbox Live-only checks above would otherwise + // fail and reject the client's own pre-login before Login is ever sent). + canPlay = TRUE; + canPlayLocal = TRUE; + isAtLeastOneFriend = TRUE; + isFriendsWithHost = TRUE; + cantPlayContentRestricted = FALSE; +#endif // _DISABLE_XBLIVE #else // TODO - handle this kind of things for non-360 platforms canPlay = TRUE; diff --git a/Minecraft.Client/Common/Consoles_App.cpp b/Minecraft.Client/Common/Consoles_App.cpp index a58a8247..56a374d7 100644 --- a/Minecraft.Client/Common/Consoles_App.cpp +++ b/Minecraft.Client/Common/Consoles_App.cpp @@ -4889,11 +4889,13 @@ void CMinecraftApp::SignInChangeCallback(LPVOID pParam,bool bPrimaryPlayerChange // 4J Stu - On PS4 we can also cause to exit players if they are signed out here, but we shouldn't do that if // we are going to switch to an offline game as it will likely crash due to incompatible parallel processes bool switchToOffline = false; +#ifndef _DISABLE_XBLIVE // If it's an online game, and the primary profile is no longer signed into LIVE then we act as if disconnected if( !ProfileManager.IsSignedInLive( ProfileManager.GetLockedProfile() ) && !g_NetworkManager.IsLocalGame() ) { switchToOffline = true; } +#endif //printf("Old: %x, New: %x, Changed: %x\n", m_ulLastSignInData, ulSignInData, changedPlayers); for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) @@ -4958,6 +4960,7 @@ void CMinecraftApp::SignInChangeCallback(LPVOID pParam,bool bPrimaryPlayerChange g_NetworkManager.HandleSignInChange(); } +#ifndef _DISABLE_XBLIVE // Some menus require the player to be signed in to live, so if this callback happens and the primary player is // no longer signed in then nav back else if ( pApp->GetLiveLinkRequired() && !ProfileManager.IsSignedInLive( ProfileManager.GetLockedProfile() ) ) @@ -4969,6 +4972,7 @@ void CMinecraftApp::SignInChangeCallback(LPVOID pParam,bool bPrimaryPlayerChange pApp->SetAction(iPrimaryPlayer,eAppAction_EthernetDisconnected); } } +#endif #if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ ) // 4J-JEV: Need to kick of loading of profile data for sub-sign in players. diff --git a/Minecraft.Client/Common/Leaderboards/base64.cpp b/Minecraft.Client/Common/Leaderboards/base64.cpp index 01aa4cf0..477a92c7 100644 --- a/Minecraft.Client/Common/Leaderboards/base64.cpp +++ b/Minecraft.Client/Common/Leaderboards/base64.cpp @@ -1,7 +1,7 @@ /* base64.cpp and base64.h - Copyright (C) 2004-2008 René Nyffenegger + Copyright (C) 2004-2008 René Nyffenegger This source code is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages @@ -21,7 +21,7 @@ 3. This notice may not be removed or altered from any source distribution. - René Nyffenegger rene.nyffenegger@adp-gmbh.ch + René Nyffenegger rene.nyffenegger@adp-gmbh.ch */ @@ -41,7 +41,7 @@ static inline bool is_base64(unsigned char c) { } // 4J ADDED, -std::string base64_encode(std::string str) +std::string base64_encode(const std::string& str) { return base64_encode( reinterpret_cast(str.c_str()), str.length() ); } diff --git a/Minecraft.Client/Common/Leaderboards/base64.h b/Minecraft.Client/Common/Leaderboards/base64.h index bdd8a9c1..5892a406 100644 --- a/Minecraft.Client/Common/Leaderboards/base64.h +++ b/Minecraft.Client/Common/Leaderboards/base64.h @@ -2,6 +2,6 @@ #include -std::string base64_encode(std::string str); +std::string base64_encode(const std::string& str); std::string base64_encode(unsigned char const* , unsigned int len); std::string base64_decode(std::string const& s); \ No newline at end of file diff --git a/Minecraft.Client/Common/Network/GameNetworkManager.cpp b/Minecraft.Client/Common/Network/GameNetworkManager.cpp index e7a63676..f422c3a0 100644 --- a/Minecraft.Client/Common/Network/GameNetworkManager.cpp +++ b/Minecraft.Client/Common/Network/GameNetworkManager.cpp @@ -100,12 +100,14 @@ void CGameNetworkManager::DoWork() { case XN_LIVE_LINK_STATE_CHANGED: { +#ifndef _DISABLE_XBLIVE int iPrimaryPlayer = g_NetworkManager.GetPrimaryPad(); bool bConnected = (pNotification->uiParam!=0)?true:false; if((g_NetworkManager.GetLockedProfile()!=-1) && iPrimaryPlayer!=-1 && bConnected == false && g_NetworkManager.IsInSession() ) { app.SetAction(iPrimaryPlayer,eAppAction_EthernetDisconnected); - } + } +#endif } break; case XN_LIVE_INVITE_ACCEPTED: @@ -782,7 +784,11 @@ int CGameNetworkManager::JoinFromInvite_SignInReturned(void *pParam,bool bContin app.DebugPrintf("JoinFromInvite_SignInReturned, iPad %d\n",iPad); // It's possible that the player has not signed in - they can back out +#ifndef _DISABLE_XBLIVE if(ProfileManager.IsSignedIn(iPad) && ProfileManager.IsSignedInLive(iPad) ) +#else + if(ProfileManager.IsSignedIn(iPad)) +#endif { app.DebugPrintf("JoinFromInvite_SignInReturned, passed sign-in tests\n"); int localUsersMask = 0; @@ -794,7 +800,9 @@ int CGameNetworkManager::JoinFromInvite_SignInReturned(void *pParam,bool bContin if(ProfileManager.IsSignedIn(index) ) { ++joiningUsers; +#ifndef _DISABLE_XBLIVE if( !ProfileManager.AllowedToPlayMultiplayer(index) ) noPrivileges = true; +#endif localUsersMask |= GetLocalPlayerMask( index ); } } @@ -890,6 +898,12 @@ bool CGameNetworkManager::IsNetworkThreadRunning() int CGameNetworkManager::RunNetworkGameThreadProc( void* lpParameter ) { + if( g_NetworkManager.m_bNetworkThreadRunning ) + { + return -1; + } + g_NetworkManager.m_bNetworkThreadRunning = true; + // Share AABB & Vec3 pools with default (main thread) - should be ok as long as we don't tick the main thread whilst this thread is running AABB::UseDefaultThreadStorage(); Vec3::UseDefaultThreadStorage(); @@ -897,7 +911,6 @@ int CGameNetworkManager::RunNetworkGameThreadProc( void* lpParameter ) Tile::CreateNewThreadStorage(); IntCache::CreateNewThreadStorage(); - g_NetworkManager.m_bNetworkThreadRunning = true; bool success = g_NetworkManager._RunNetworkGame(lpParameter); g_NetworkManager.m_bNetworkThreadRunning = false; if( !success) @@ -905,7 +918,7 @@ int CGameNetworkManager::RunNetworkGameThreadProc( void* lpParameter ) TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected(); while ( tPack->isLoadingData() || (Minecraft::GetInstance()->skins->needsUIUpdate() || ui.IsReloadingSkin()) ) { - Sleep(1); + Sleep(0); } ui.CleanUpSkinReload(); if(app.GetDisconnectReason() == DisconnectPacket::eDisconnect_None) @@ -942,7 +955,7 @@ int CGameNetworkManager::ServerThreadProc( void* lpParameter ) { while((Minecraft::GetInstance()->skins->needsUIUpdate() || ui.IsReloadingSkin())) { - Sleep(1); + Sleep(0); } param->levelGen->loadBaseSaveData(); } @@ -984,7 +997,7 @@ int CGameNetworkManager::ExitAndJoinFromInviteThreadProc( void* lpParam ) while( g_NetworkManager.IsInSession() ) { - Sleep(1); + Sleep(0); } // Xbox should always be online when receiving invites - on PS3 we need to check & ask the user to sign in @@ -1260,7 +1273,7 @@ int CGameNetworkManager::ChangeSessionTypeThreadProc( void* lpParam ) // wait for the current session to end while( g_NetworkManager.IsInSession() ) { - Sleep(1); + Sleep(0); } // Reset this flag as the we don't need to know that we only lost the room only from this point onwards, the behaviour is exactly the same @@ -1665,6 +1678,7 @@ void CGameNetworkManager::GameInviteReceived( int userIndex, const INVITE_INFO * { if (ProfileManager.IsSignedIn(i) && (i == ProfileManager.GetPrimaryPad() || isLocalMultiplayerAvailable)) { +#ifndef _DISABLE_XBLIVE if (isSignedInLive && !ProfileManager.IsSignedInLive(i)) { // Record the first non signed in live pad @@ -1672,6 +1686,9 @@ void CGameNetworkManager::GameInviteReceived( int userIndex, const INVITE_INFO * } isSignedInLive = isSignedInLive && ProfileManager.IsSignedInLive(i); +#else + isSignedInLive = true; +#endif } } @@ -1743,7 +1760,9 @@ void CGameNetworkManager::GameInviteReceived( int userIndex, const INVITE_INFO * if(index==userIndex || pMinecraft->localplayers[index]!=NULL ) { ++joiningUsers; +#ifndef _DISABLE_XBLIVE if( !ProfileManager.AllowedToPlayMultiplayer(index) ) noPrivileges = true; +#endif localUsersMask |= GetLocalPlayerMask( index ); } } @@ -1898,6 +1917,7 @@ void CGameNetworkManager::HandleInviteWhenInMenus( int userIndex, const INVITE_I if(!app.IsLocalMultiplayerAvailable()) #endif { +#ifndef _DISABLE_XBLIVE bool noPrivileges=!ProfileManager.AllowedToPlayMultiplayer(userIndex); if(noPrivileges) @@ -1908,6 +1928,7 @@ void CGameNetworkManager::HandleInviteWhenInMenus( int userIndex, const INVITE_I } else { +#endif ProfileManager.SetLockedProfile(userIndex); ProfileManager.SetPrimaryPad(userIndex); @@ -1930,7 +1951,9 @@ void CGameNetworkManager::HandleInviteWhenInMenus( int userIndex, const INVITE_I { app.DebugPrintf( "Failed joining game from invite\n" ); } +#ifndef _DISABLE_XBLIVE } +#endif } else { diff --git a/Minecraft.Client/Common/Network/NetworkSocketLayer.cpp b/Minecraft.Client/Common/Network/NetworkSocketLayer.cpp index 36d68a5f..008a94dd 100644 --- a/Minecraft.Client/Common/Network/NetworkSocketLayer.cpp +++ b/Minecraft.Client/Common/Network/NetworkSocketLayer.cpp @@ -1,4 +1,4 @@ -#include "stdafx.h" +#include "stdafx.h" #include "NetworkSocketLayer.h" #include "..\..\Common\Network\PlatformNetworkManager.h" diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManager.cpp b/Minecraft.Client/Common/Network/PlatformNetworkManager.cpp index 5f6d43e1..56f40fbe 100644 --- a/Minecraft.Client/Common/Network/PlatformNetworkManager.cpp +++ b/Minecraft.Client/Common/Network/PlatformNetworkManager.cpp @@ -1,949 +1,949 @@ -#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; - if (m_pIQNet->IsHost()) - NetworkSocketLayer::UpdateAdvertiseJoinable(true); - - 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 && g_MultiplayerIP[0] != '\0') - { - 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); - } - } - -#if defined(__ORBIS__) || defined(__PSVITA__) - 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; + if (m_pIQNet->IsHost()) + NetworkSocketLayer::UpdateAdvertiseJoinable(true); + + 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 && g_MultiplayerIP[0] != '\0') + { + 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); + } + } + +#if defined(__ORBIS__) || defined(__PSVITA__) + 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; +} diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManager.h b/Minecraft.Client/Common/Network/PlatformNetworkManager.h index 919efd71..b0f9fdcb 100644 --- a/Minecraft.Client/Common/Network/PlatformNetworkManager.h +++ b/Minecraft.Client/Common/Network/PlatformNetworkManager.h @@ -1,171 +1,171 @@ -#pragma once -using namespace std; -#include -#include "..\..\..\Minecraft.World\C4JThread.h" -#include "NetworkPlayerInterface.h" -#include "PlatformNetworkManagerInterface.h" -#include "SessionInfo.h" - -class CPlatformNetworkManagerStub : public CPlatformNetworkManager -{ - friend class CGameNetworkManager; -public: - virtual bool Initialise(CGameNetworkManager *pGameNetworkManager, int flagIndexSize); - virtual void Terminate(); - virtual int GetJoiningReadyPercentage(); - virtual int CorrectErrorIDS(int IDS); - - virtual void DoWork(); - virtual int GetPlayerCount(); - virtual int GetOnlinePlayerCount(); - virtual int GetLocalPlayerMask(int playerIndex); - virtual bool AddLocalPlayerByUserIndex( int userIndex ); - virtual bool RemoveLocalPlayerByUserIndex( int userIndex ); - virtual INetworkPlayer *GetLocalPlayerByUserIndex( int userIndex ); - virtual INetworkPlayer *GetPlayerByIndex(int playerIndex); - virtual INetworkPlayer * GetPlayerByXuid(PlayerUID xuid); - virtual INetworkPlayer * GetPlayerBySmallId(unsigned char smallId); - virtual bool ShouldMessageForFullSession(); - - virtual INetworkPlayer *GetHostPlayer(); - virtual bool IsHost(); - virtual bool JoinGameFromInviteInfo( int userIndex, int userMask, const INVITE_INFO *pInviteInfo); - virtual bool LeaveGame(bool bMigrateHost); - - virtual bool IsInSession(); - virtual bool IsInGameplay(); - virtual bool IsReadyToPlayOrIdle(); - virtual bool IsInStatsEnabledSession(); - virtual bool SessionHasSpace(unsigned int spaceRequired = 1); - virtual void SendInviteGUI(int quadrant); - virtual bool IsAddingPlayer(); - - virtual void HostGame(int localUsersMask, bool bOnlineGame, bool bIsPrivate, unsigned char publicSlots = MINECRAFT_NET_MAX_PLAYERS, unsigned char privateSlots = 0); - virtual int JoinGame(FriendSessionInfo *searchResult, int localUsersMask, int primaryUserIndex ); - virtual bool SetLocalGame(bool isLocal); - virtual bool IsLocalGame() { return m_bIsOfflineGame; } - virtual void SetPrivateGame(bool isPrivate); - virtual bool IsPrivateGame() { return m_bIsPrivateGame; } - virtual bool IsLeavingGame() { return m_bLeavingGame; } - virtual void ResetLeavingGame() { m_bLeavingGame = false; } - - virtual void RegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam); - virtual void UnRegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam); - - virtual void HandleSignInChange(); - - virtual bool _RunNetworkGame(); - -private: - bool isSystemPrimaryPlayer(IQNetPlayer *pQNetPlayer); - virtual bool _LeaveGame(bool bMigrateHost, bool bLeaveRoom); - virtual void _HostGame(int dwUsersMask, unsigned char publicSlots = MINECRAFT_NET_MAX_PLAYERS, unsigned char privateSlots = 0); - virtual bool _StartGame(); - - IQNet * m_pIQNet; // pointer to QNet interface - - HANDLE m_notificationListener; - - vector m_machineQNetPrimaryPlayers; // collection of players that we deem to be the main one for that system - - bool m_bLeavingGame; - bool m_bLeaveGameOnTick; - bool m_migrateHostOnLeave; - bool m_bHostChanged; - - bool m_bIsOfflineGame; - bool m_bIsPrivateGame; - int m_flagIndexSize; - - // This is only maintained by the host, and is not valid on client machines - GameSessionData m_hostGameSessionData; - CGameNetworkManager *m_pGameNetworkManager; -public: - virtual void UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving = NULL); - -private: - // TODO 4J Stu - Do we need to be able to have more than one of these? - void (*playerChangedCallback[XUSER_MAX_COUNT])(void *callbackParam, INetworkPlayer *pPlayer, bool leaving); - void *playerChangedCallbackParam[XUSER_MAX_COUNT]; - - static int RemovePlayerOnSocketClosedThreadProc( void* lpParam ); - virtual bool RemoveLocalPlayer( INetworkPlayer *pNetworkPlayer ); - - // Things for handling per-system flags - class PlayerFlags - { - public: - INetworkPlayer *m_pNetworkPlayer; - unsigned char *flags; - unsigned int count; - PlayerFlags(INetworkPlayer *pNetworkPlayer, unsigned int count); - ~PlayerFlags(); - }; - vector m_playerFlags; - void SystemFlagAddPlayer(INetworkPlayer *pNetworkPlayer); - void SystemFlagRemovePlayer(INetworkPlayer *pNetworkPlayer); - void SystemFlagReset(); -public: - virtual void SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index); - virtual bool SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index); - - // For telemetry -private: - float m_lastPlayerEventTimeStart; - -public: - wstring GatherStats(); - wstring GatherRTTStats(); - -private: - vector friendsSessions[XUSER_MAX_COUNT]; - int m_searchResultsCount[XUSER_MAX_COUNT]; - int m_lastSearchStartTime[XUSER_MAX_COUNT]; - - // The results that will be filled in with the current search - XSESSION_SEARCHRESULT_HEADER *m_pSearchResults[XUSER_MAX_COUNT]; - XNQOS *m_pQoSResult[XUSER_MAX_COUNT]; - - // The results from the previous search, which are currently displayed in the game - XSESSION_SEARCHRESULT_HEADER *m_pCurrentSearchResults[XUSER_MAX_COUNT]; - XNQOS *m_pCurrentQoSResult[XUSER_MAX_COUNT]; - int m_currentSearchResultsCount[XUSER_MAX_COUNT]; - - int m_lastSearchPad; - bool m_bSearchResultsReady; - bool m_bSearchPending; - LPVOID m_pSearchParam; - void (*m_SessionsUpdatedCallback)(LPVOID pParam); - - C4JThread* m_SearchingThread; - - void TickSearch(); - void SearchForGames(); - static int SearchForGamesThreadProc( void* lpParameter ); - - void SetSearchResultsReady(int resultCount = 0); - - vectorcurrentNetworkPlayers; - INetworkPlayer *addNetworkPlayer(IQNetPlayer *pQNetPlayer); - void removeNetworkPlayer(IQNetPlayer *pQNetPlayer); - static INetworkPlayer *getNetworkPlayer(IQNetPlayer *pQNetPlayer); - - virtual void SetSessionTexturePackParentId( int id ); - virtual void SetSessionSubTexturePackId( int id ); - virtual void Notify(int ID, ULONG_PTR Param); - -public: - virtual vector *GetSessionList(int iPad, int localPlayers, bool partyOnly); - virtual bool GetGameSessionInfo(int iPad, SessionID sessionId,FriendSessionInfo *foundSession); - virtual void SetSessionsUpdatedCallback( void (*SessionsUpdatedCallback)(LPVOID pParam), LPVOID pSearchParam ); - virtual void GetFullFriendSessionInfo( FriendSessionInfo *foundSession, void (* FriendSessionUpdatedFn)(bool success, void *pParam), void *pParam ); - virtual void ForceFriendsSessionRefresh(); - -public: - void NotifyPlayerJoined( IQNetPlayer *pQNetPlayer ); - void NotifyPlayerLeaving( IQNetPlayer *pQNetPlayer ); - -#ifndef _XBOX - void FakeLocalPlayerJoined() { NotifyPlayerJoined(m_pIQNet->GetLocalPlayerByUserIndex(0)); } -#endif -}; +#pragma once +using namespace std; +#include +#include "..\..\..\Minecraft.World\C4JThread.h" +#include "NetworkPlayerInterface.h" +#include "PlatformNetworkManagerInterface.h" +#include "SessionInfo.h" + +class CPlatformNetworkManagerStub : public CPlatformNetworkManager +{ + friend class CGameNetworkManager; +public: + virtual bool Initialise(CGameNetworkManager *pGameNetworkManager, int flagIndexSize); + virtual void Terminate(); + virtual int GetJoiningReadyPercentage(); + virtual int CorrectErrorIDS(int IDS); + + virtual void DoWork(); + virtual int GetPlayerCount(); + virtual int GetOnlinePlayerCount(); + virtual int GetLocalPlayerMask(int playerIndex); + virtual bool AddLocalPlayerByUserIndex( int userIndex ); + virtual bool RemoveLocalPlayerByUserIndex( int userIndex ); + virtual INetworkPlayer *GetLocalPlayerByUserIndex( int userIndex ); + virtual INetworkPlayer *GetPlayerByIndex(int playerIndex); + virtual INetworkPlayer * GetPlayerByXuid(PlayerUID xuid); + virtual INetworkPlayer * GetPlayerBySmallId(unsigned char smallId); + virtual bool ShouldMessageForFullSession(); + + virtual INetworkPlayer *GetHostPlayer(); + virtual bool IsHost(); + virtual bool JoinGameFromInviteInfo( int userIndex, int userMask, const INVITE_INFO *pInviteInfo); + virtual bool LeaveGame(bool bMigrateHost); + + virtual bool IsInSession(); + virtual bool IsInGameplay(); + virtual bool IsReadyToPlayOrIdle(); + virtual bool IsInStatsEnabledSession(); + virtual bool SessionHasSpace(unsigned int spaceRequired = 1); + virtual void SendInviteGUI(int quadrant); + virtual bool IsAddingPlayer(); + + virtual void HostGame(int localUsersMask, bool bOnlineGame, bool bIsPrivate, unsigned char publicSlots = MINECRAFT_NET_MAX_PLAYERS, unsigned char privateSlots = 0); + virtual int JoinGame(FriendSessionInfo *searchResult, int localUsersMask, int primaryUserIndex ); + virtual bool SetLocalGame(bool isLocal); + virtual bool IsLocalGame() { return m_bIsOfflineGame; } + virtual void SetPrivateGame(bool isPrivate); + virtual bool IsPrivateGame() { return m_bIsPrivateGame; } + virtual bool IsLeavingGame() { return m_bLeavingGame; } + virtual void ResetLeavingGame() { m_bLeavingGame = false; } + + virtual void RegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam); + virtual void UnRegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam); + + virtual void HandleSignInChange(); + + virtual bool _RunNetworkGame(); + +private: + bool isSystemPrimaryPlayer(IQNetPlayer *pQNetPlayer); + virtual bool _LeaveGame(bool bMigrateHost, bool bLeaveRoom); + virtual void _HostGame(int dwUsersMask, unsigned char publicSlots = MINECRAFT_NET_MAX_PLAYERS, unsigned char privateSlots = 0); + virtual bool _StartGame(); + + IQNet * m_pIQNet; // pointer to QNet interface + + HANDLE m_notificationListener; + + vector m_machineQNetPrimaryPlayers; // collection of players that we deem to be the main one for that system + + bool m_bLeavingGame; + bool m_bLeaveGameOnTick; + bool m_migrateHostOnLeave; + bool m_bHostChanged; + + bool m_bIsOfflineGame; + bool m_bIsPrivateGame; + int m_flagIndexSize; + + // This is only maintained by the host, and is not valid on client machines + GameSessionData m_hostGameSessionData; + CGameNetworkManager *m_pGameNetworkManager; +public: + virtual void UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving = NULL); + +private: + // TODO 4J Stu - Do we need to be able to have more than one of these? + void (*playerChangedCallback[XUSER_MAX_COUNT])(void *callbackParam, INetworkPlayer *pPlayer, bool leaving); + void *playerChangedCallbackParam[XUSER_MAX_COUNT]; + + static int RemovePlayerOnSocketClosedThreadProc( void* lpParam ); + virtual bool RemoveLocalPlayer( INetworkPlayer *pNetworkPlayer ); + + // Things for handling per-system flags + class PlayerFlags + { + public: + INetworkPlayer *m_pNetworkPlayer; + unsigned char *flags; + unsigned int count; + PlayerFlags(INetworkPlayer *pNetworkPlayer, unsigned int count); + ~PlayerFlags(); + }; + vector m_playerFlags; + void SystemFlagAddPlayer(INetworkPlayer *pNetworkPlayer); + void SystemFlagRemovePlayer(INetworkPlayer *pNetworkPlayer); + void SystemFlagReset(); +public: + virtual void SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index); + virtual bool SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index); + + // For telemetry +private: + float m_lastPlayerEventTimeStart; + +public: + wstring GatherStats(); + wstring GatherRTTStats(); + +private: + vector friendsSessions[XUSER_MAX_COUNT]; + int m_searchResultsCount[XUSER_MAX_COUNT]; + int m_lastSearchStartTime[XUSER_MAX_COUNT]; + + // The results that will be filled in with the current search + XSESSION_SEARCHRESULT_HEADER *m_pSearchResults[XUSER_MAX_COUNT]; + XNQOS *m_pQoSResult[XUSER_MAX_COUNT]; + + // The results from the previous search, which are currently displayed in the game + XSESSION_SEARCHRESULT_HEADER *m_pCurrentSearchResults[XUSER_MAX_COUNT]; + XNQOS *m_pCurrentQoSResult[XUSER_MAX_COUNT]; + int m_currentSearchResultsCount[XUSER_MAX_COUNT]; + + int m_lastSearchPad; + bool m_bSearchResultsReady; + bool m_bSearchPending; + LPVOID m_pSearchParam; + void (*m_SessionsUpdatedCallback)(LPVOID pParam); + + C4JThread* m_SearchingThread; + + void TickSearch(); + void SearchForGames(); + static int SearchForGamesThreadProc( void* lpParameter ); + + void SetSearchResultsReady(int resultCount = 0); + + vectorcurrentNetworkPlayers; + INetworkPlayer *addNetworkPlayer(IQNetPlayer *pQNetPlayer); + void removeNetworkPlayer(IQNetPlayer *pQNetPlayer); + static INetworkPlayer *getNetworkPlayer(IQNetPlayer *pQNetPlayer); + + virtual void SetSessionTexturePackParentId( int id ); + virtual void SetSessionSubTexturePackId( int id ); + virtual void Notify(int ID, ULONG_PTR Param); + +public: + virtual vector *GetSessionList(int iPad, int localPlayers, bool partyOnly); + virtual bool GetGameSessionInfo(int iPad, SessionID sessionId,FriendSessionInfo *foundSession); + virtual void SetSessionsUpdatedCallback( void (*SessionsUpdatedCallback)(LPVOID pParam), LPVOID pSearchParam ); + virtual void GetFullFriendSessionInfo( FriendSessionInfo *foundSession, void (* FriendSessionUpdatedFn)(bool success, void *pParam), void *pParam ); + virtual void ForceFriendsSessionRefresh(); + +public: + void NotifyPlayerJoined( IQNetPlayer *pQNetPlayer ); + void NotifyPlayerLeaving( IQNetPlayer *pQNetPlayer ); + +#ifndef _XBOX + void FakeLocalPlayerJoined() { NotifyPlayerJoined(m_pIQNet->GetLocalPlayerByUserIndex(0)); } +#endif +}; diff --git a/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp b/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp index ec0fd459..f6d47048 100644 --- a/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp @@ -600,6 +600,21 @@ void UIScene_JoinMenu::JoinGame(UIScene_JoinMenu* pClass) ui.NavigateToHomeMenu(); } } + else + { + LoadingInputParams *loadingParams = new LoadingInputParams(); + loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc; + loadingParams->lpParam = NULL; + + UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); + completionData->bShowBackground = TRUE; + completionData->bShowLogo = TRUE; + completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; + completionData->iPad = DEFAULT_XUI_MENU_USER; + loadingParams->completionData = completionData; + + ui.NavigateToScene(ProfileManager.GetPrimaryPad(), eUIScene_FullscreenProgress, loadingParams); + } } } diff --git a/Minecraft.Client/Common/XUI/XUI_LoadSettings.cpp b/Minecraft.Client/Common/XUI/XUI_LoadSettings.cpp index 7f32ff89..de2084be 100644 --- a/Minecraft.Client/Common/XUI/XUI_LoadSettings.cpp +++ b/Minecraft.Client/Common/XUI/XUI_LoadSettings.cpp @@ -76,7 +76,19 @@ HRESULT CScene_LoadGameSettings::OnInit( XUIMessageInit* pInitData, BOOL& bHandl XuiControlSetText(m_ButtonLoad,app.GetString(IDS_LOAD)); XuiControlSetText(m_pTexturePacksList->m_hObj,app.GetString(IDS_DLC_MENU_TEXTUREPACKS)); +#ifndef _DISABLE_XBLIVE +#ifndef _DISABLE_XBLIVE +#ifndef _DISABLE_XBLIVE m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); +#else + m_bMultiplayerAllowed = true; +#endif +#else + m_bMultiplayerAllowed = true; +#endif +#else + m_bMultiplayerAllowed = true; +#endif // 4J-PB - read the settings for the online flag. We'll only save this setting if the user changed it. bool bGameSetting_Online=(app.GetGameSettings(m_iPad,eGameSetting_Online)!=0); m_MoreOptionsParams.bOnlineSettingChangedBySystem=false; @@ -741,7 +753,10 @@ HRESULT CScene_LoadGameSettings::OnTimer( XUIMessageTimer *pTimer, BOOL& bHandle { case GAME_CREATE_ONLINE_TIMER_ID: { - bool bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); + bool bMultiplayerAllowed = true; +#ifndef _DISABLE_XBLIVE + bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); +#endif if(bMultiplayerAllowed != m_bMultiplayerAllowed) { @@ -1015,7 +1030,9 @@ int CScene_LoadGameSettings::StartGame_SignInReturned(void *pParam,bool bContinu { if(ProfileManager.IsSignedIn(index) ) { +#ifndef _DISABLE_XBLIVE if( !ProfileManager.AllowedToPlayMultiplayer(index) ) noPrivileges = true; +#endif dwLocalUsersMask |= CGameNetworkManager::GetLocalPlayerMask(index); } } diff --git a/Minecraft.Client/Common/XUI/XUI_MultiGameCreate.cpp b/Minecraft.Client/Common/XUI/XUI_MultiGameCreate.cpp index b3608b06..09bd4359 100644 --- a/Minecraft.Client/Common/XUI/XUI_MultiGameCreate.cpp +++ b/Minecraft.Client/Common/XUI/XUI_MultiGameCreate.cpp @@ -67,7 +67,19 @@ HRESULT CScene_MultiGameCreate::OnInit( XUIMessageInit* pInitData, BOOL& bHandle m_iPad=params->iPad; delete params; +#ifndef _DISABLE_XBLIVE +#ifndef _DISABLE_XBLIVE +#ifndef _DISABLE_XBLIVE m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); +#else + m_bMultiplayerAllowed = true; +#endif +#else + m_bMultiplayerAllowed = true; +#endif +#else + m_bMultiplayerAllowed = true; +#endif // 4J-PB - read the settings for the online flag. We'll only save this setting if the user changed it. bool bGameSetting_Online=(app.GetGameSettings(m_iPad,eGameSetting_Online)!=0); m_MoreOptionsParams.bOnlineSettingChangedBySystem=false; @@ -663,7 +675,10 @@ HRESULT CScene_MultiGameCreate::OnTimer( XUIMessageTimer *pTimer, BOOL& bHandled case GAME_CREATE_ONLINE_TIMER_ID: { - bool bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); + bool bMultiplayerAllowed = true; +#ifndef _DISABLE_XBLIVE + bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); +#endif if(bMultiplayerAllowed != m_bMultiplayerAllowed) { @@ -824,7 +839,9 @@ int CScene_MultiGameCreate::StartGame_SignInReturned(void *pParam,bool bContinue { if(ProfileManager.IsSignedIn(index) ) { +#ifndef _DISABLE_XBLIVE if( !ProfileManager.AllowedToPlayMultiplayer(index) ) noPrivileges = true; +#endif dwLocalUsersMask |= CGameNetworkManager::GetLocalPlayerMask(index); } } diff --git a/Minecraft.Client/Common/XUI/XUI_MultiGameInfo.cpp b/Minecraft.Client/Common/XUI/XUI_MultiGameInfo.cpp index 1d59730a..0f22aab0 100644 --- a/Minecraft.Client/Common/XUI/XUI_MultiGameInfo.cpp +++ b/Minecraft.Client/Common/XUI/XUI_MultiGameInfo.cpp @@ -274,7 +274,9 @@ void CScene_MultiGameInfo::JoinGame(CScene_MultiGameInfo* pClass) if(ProfileManager.IsSignedIn(index) ) { ++dwSignedInUsers; +#ifndef _DISABLE_XBLIVE if( !ProfileManager.AllowedToPlayMultiplayer(index) ) noPrivileges = true; +#endif dwLocalUsersMask |= CGameNetworkManager::GetLocalPlayerMask(index); } } @@ -284,7 +286,9 @@ void CScene_MultiGameInfo::JoinGame(CScene_MultiGameInfo* pClass) if(ProfileManager.IsSignedIn(ProfileManager.GetPrimaryPad()) ) { ++dwSignedInUsers; +#ifndef _DISABLE_XBLIVE if( !ProfileManager.AllowedToPlayMultiplayer(ProfileManager.GetPrimaryPad()) ) noPrivileges = true; +#endif dwLocalUsersMask |= CGameNetworkManager::GetLocalPlayerMask(ProfileManager.GetPrimaryPad()); } } @@ -348,6 +352,21 @@ void CScene_MultiGameInfo::JoinGame(CScene_MultiGameInfo* pClass) app.NavigateToHomeMenu(); } } + else + { + LoadingInputParams *loadingParams = new LoadingInputParams(); + loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc; + loadingParams->lpParam = NULL; + + UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); + completionData->bShowBackground = TRUE; + completionData->bShowLogo = TRUE; + completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; + completionData->iPad = DEFAULT_XUI_MENU_USER; + loadingParams->completionData = completionData; + + app.NavigateToScene(ProfileManager.GetPrimaryPad(), eUIScene_FullscreenProgress, loadingParams); + } } } diff --git a/Minecraft.Client/Common/XUI/XUI_MultiGameJoinLoad.cpp b/Minecraft.Client/Common/XUI/XUI_MultiGameJoinLoad.cpp index 1c4f3f21..84a42945 100644 --- a/Minecraft.Client/Common/XUI/XUI_MultiGameJoinLoad.cpp +++ b/Minecraft.Client/Common/XUI/XUI_MultiGameJoinLoad.cpp @@ -73,7 +73,11 @@ HRESULT CScene_MultiGameJoinLoad::OnInit( XUIMessageInit* pInitData, BOOL& bHand // } m_initData= new JoinMenuInitData(); +#ifndef _DISABLE_XBLIVE m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); +#else + m_bMultiplayerAllowed = true; +#endif XPARTY_USER_LIST partyList; @@ -768,7 +772,11 @@ HRESULT CScene_MultiGameJoinLoad::OnNavReturn(HXUIOBJ hSceneFrom,BOOL& rfHandled // start the texture pack timer again XuiSetTimer(m_hObj,CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID,CHECKFORAVAILABLETEXTUREPACKS_TIMER_TIME); - m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); +#ifndef _DISABLE_XBLIVE + m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); +#else + m_bMultiplayerAllowed = true; +#endif // re-enable button presses m_bIgnoreInput=false; @@ -1643,7 +1651,10 @@ HRESULT CScene_MultiGameJoinLoad::OnTimer( XUIMessageTimer *pTimer, BOOL& bHandl m_bInParty=false; } - bool bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); + bool bMultiplayerAllowed = true; +#ifndef _DISABLE_XBLIVE + bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); +#endif if(bMultiplayerAllowed != m_bMultiplayerAllowed) { if( bMultiplayerAllowed ) diff --git a/Minecraft.Client/EnderDragonRenderer.cpp b/Minecraft.Client/EnderDragonRenderer.cpp index 1d9a3ff0..41ba91b6 100644 --- a/Minecraft.Client/EnderDragonRenderer.cpp +++ b/Minecraft.Client/EnderDragonRenderer.cpp @@ -145,10 +145,11 @@ void EnderDragonRenderer::render(shared_ptr _mob, double x, double y, do int steps = 8; for (int i = 0; i <= steps; i++) { - double d=i % steps * PI * 2 / steps; - float s = sin(i % steps * PI * 2 / steps) * 0.75f; - float c = cos(i % steps * PI * 2 / steps) * 0.75f; - float u = i % steps * 1.0f / steps; + int idx = i % steps; + double d = idx * PI * 2 / steps; + float s = sin(d) * 0.75f; + float c = cos(d) * 0.75f; + float u = idx * 1.0f / steps; //t->color(0x000000); t->vertexUV(s * 0.2f, c * 0.2f, 0, u, v1); //t->color(0xffffff); diff --git a/Minecraft.Client/EntityRenderDispatcher.cpp b/Minecraft.Client/EntityRenderDispatcher.cpp index dd3231a6..b1934199 100644 --- a/Minecraft.Client/EntityRenderDispatcher.cpp +++ b/Minecraft.Client/EntityRenderDispatcher.cpp @@ -94,6 +94,17 @@ void EntityRenderDispatcher::staticCtor() instance = new EntityRenderDispatcher(); } +EntityRenderDispatcher::~EntityRenderDispatcher() +{ + AUTO_VAR(itEnd, renderers.end()); + for( classToRendererMap::iterator it = renderers.begin(); it != itEnd; it++ ) + { + delete it->second; + it->second = NULL; + } + renderers.clear(); +} + EntityRenderDispatcher::EntityRenderDispatcher() { glEnable(GL_LIGHTING); diff --git a/Minecraft.Client/EntityRenderDispatcher.h b/Minecraft.Client/EntityRenderDispatcher.h index 86132178..029f44b3 100644 --- a/Minecraft.Client/EntityRenderDispatcher.h +++ b/Minecraft.Client/EntityRenderDispatcher.h @@ -1,7 +1,7 @@ #pragma once #include "EntityRenderer.h" -#include "..\Minecraft.World\Entity.h" #include "..\Minecraft.World\JavaIntHash.h" +class Entity; class font; using namespace std; @@ -37,6 +37,7 @@ public: private: EntityRenderDispatcher(); + ~EntityRenderDispatcher(); public: EntityRenderer *getRenderer(eINSTANCEOF e); diff --git a/Minecraft.Client/Extrax64Stubs.cpp b/Minecraft.Client/Extrax64Stubs.cpp index 1c8df457..299639c4 100644 --- a/Minecraft.Client/Extrax64Stubs.cpp +++ b/Minecraft.Client/Extrax64Stubs.cpp @@ -78,6 +78,7 @@ HRESULT XPartyGetUserList(XPARTY_USER_LIST *pUserList) { return S_OK; } DWORD XContentGetThumbnail(DWORD dwUserIndex, const XCONTENT_DATA *pContentData, PBYTE pbThumbnail, PDWORD pcbThumbnail, PXOVERLAPPED *pOverlapped) { return 0; } void XShowAchievementsUI(int i) {} DWORD XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE Mode) { return 0; } +DWORD XamBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE Mode) { return 0; } #ifndef _DURANGO void PIXAddNamedCounter(int a, char *b, ...) {} diff --git a/Minecraft.Client/GameRenderer.cpp b/Minecraft.Client/GameRenderer.cpp index a43f83f0..fc404da4 100644 --- a/Minecraft.Client/GameRenderer.cpp +++ b/Minecraft.Client/GameRenderer.cpp @@ -105,8 +105,6 @@ GameRenderer::GameRenderer(Minecraft *mc) zoom = 1; zoom_x = 0; zoom_y = 0; - rainXa = NULL; - rainZa = NULL; lastActiveTime = Minecraft::currentTimeMillis(); lastNsTime = 0; random = new Random(); @@ -181,8 +179,9 @@ GameRenderer::GameRenderer(Minecraft *mc) // 4J Stu Added to go with 1.8.2 change GameRenderer::~GameRenderer() { - if(rainXa != NULL) delete [] rainXa; - if(rainZa != NULL) delete [] rainZa; + delete random; + delete cameraPos; + delete lb; } void GameRenderer::tick(bool first) // 4J - add bFirst @@ -838,19 +837,21 @@ void GameRenderer::updateLightTexture(float a) Level *level = player->level; // 4J - was mc->level when it was just to update the one light texture float skyDarken1 = level->getSkyDarken((float) 1); + float darken = skyDarken1 * 0.95f + 0.05f; + float rsGsMul = skyDarken1 * 0.65f + 0.35f; + float blockMul = blr * 0.1f + 1.5f; for (int i = 0; i < 256; i++) { - float darken = skyDarken1 * 0.95f + 0.05f; float sky = level->dimension->brightnessRamp[i / 16] * darken; - float block = level->dimension->brightnessRamp[i % 16] * (blr * 0.1f + 1.5f); + float block = level->dimension->brightnessRamp[i % 16] * blockMul; if (level->skyFlashTime > 0) { sky = level->dimension->brightnessRamp[i / 16]; } - float rs = sky * (skyDarken1 * 0.65f + 0.35f); - float gs = sky * (skyDarken1 * 0.65f + 0.35f); + float rs = sky * rsGsMul; + float gs = sky * rsGsMul; float bs = sky; float rb = block; @@ -1526,27 +1527,30 @@ void GameRenderer::tickRain() int x = x0 + random->nextInt(r) - random->nextInt(r); int z = z0 + random->nextInt(r) - random->nextInt(r); int y = level->getTopRainBlock(x, z); - int t = level->getTile(x, y - 1, z); - Biome *biome = level->getBiome(x,z); - if (y <= y0 + r && y >= y0 - r && biome->hasRain() && biome->getTemperature() >= 0.2f) + if (y <= y0 + r && y >= y0 - r) { - float xa = random->nextFloat(); - float za = random->nextFloat(); - if (t > 0) + int t = level->getTile(x, y - 1, z); + Biome *biome = level->getBiome(x,z); + if (biome->hasRain() && biome->getTemperature() >= 0.2f) { - if (Tile::tiles[t]->material == Material::lava) + float xa = random->nextFloat(); + float za = random->nextFloat(); + if (t > 0) { - mc->particleEngine->add( shared_ptr( new SmokeParticle(level, x + xa, y + 0.1f - Tile::tiles[t]->getShapeY0(), z + za, 0, 0, 0) ) ); - } - else - { - if (random->nextInt(++rainPosSamples) == 0) + if (Tile::tiles[t]->material == Material::lava) { - rainPosX = x + xa; - rainPosY = y + 0.1f - Tile::tiles[t]->getShapeY0(); - rainPosZ = z + za; + mc->particleEngine->add( shared_ptr( new SmokeParticle(level, x + xa, y + 0.1f - Tile::tiles[t]->getShapeY0(), z + za, 0, 0, 0) ) ); + } + else + { + if (random->nextInt(++rainPosSamples) == 0) + { + rainPosX = x + xa; + rainPosY = y + 0.1f - Tile::tiles[t]->getShapeY0(); + rainPosZ = z + za; + } + mc->particleEngine->add( shared_ptr( new WaterDropParticle(level, x + xa, y + 0.1f - Tile::tiles[t]->getShapeY0(), z + za) ) ); } - mc->particleEngine->add( shared_ptr( new WaterDropParticle(level, x + xa, y + 0.1f - Tile::tiles[t]->getShapeY0(), z + za) ) ); } } } @@ -1581,10 +1585,12 @@ void GameRenderer::renderSnowAndRain(float a) turnOnLightLayer(a); - if (rainXa == NULL) + static float rainXa[32 * 32]; + static float rainZa[32 * 32]; + static bool rainArraysInitialized = false; + if (!rainArraysInitialized) { - rainXa = new float[32 * 32]; - rainZa = new float[32 * 32]; + rainArraysInitialized = true; for (int z = 0; z < 32; z++) { diff --git a/Minecraft.Client/GameRenderer.h b/Minecraft.Client/GameRenderer.h index 7c5632d2..04d52ccb 100644 --- a/Minecraft.Client/GameRenderer.h +++ b/Minecraft.Client/GameRenderer.h @@ -128,8 +128,6 @@ private: void tickRain(); private: // 4J - brought forward from 1.8.2 - float *rainXa; - float *rainZa; protected: void renderSnowAndRain(float a); volatile int xMod; diff --git a/Minecraft.Client/HorseRenderer.cpp b/Minecraft.Client/HorseRenderer.cpp index 97f75df1..6a0c5120 100644 --- a/Minecraft.Client/HorseRenderer.cpp +++ b/Minecraft.Client/HorseRenderer.cpp @@ -10,7 +10,7 @@ ResourceLocation HorseRenderer::HORSE_DONKEY_LOCATION = ResourceLocation(TN_MOB_ ResourceLocation HorseRenderer::HORSE_ZOMBIE_LOCATION = ResourceLocation(TN_MOB_HORSE_ZOMBIE); ResourceLocation HorseRenderer::HORSE_SKELETON_LOCATION = ResourceLocation(TN_MOB_HORSE_SKELETON); -std::map HorseRenderer::LAYERED_LOCATION_CACHE; +std::map HorseRenderer::LAYERED_LOCATION_CACHE; HorseRenderer::HorseRenderer(Model *model, float f) : MobRenderer(model, f) { @@ -114,14 +114,14 @@ ResourceLocation *HorseRenderer::getOrCreateLayeredTextureLocation(shared_ptrsecond; + location = &(it->second); } else { - LAYERED_LOCATION_CACHE[textureName] = new ResourceLocation(horse->getLayeredTextureLayers()); + LAYERED_LOCATION_CACHE[textureName] = ResourceLocation(horse->getLayeredTextureLayers()); it = LAYERED_LOCATION_CACHE.find(textureName); - location = it->second; + location = &(it->second); } return location; diff --git a/Minecraft.Client/HorseRenderer.h b/Minecraft.Client/HorseRenderer.h index 71ebde15..9f85f471 100644 --- a/Minecraft.Client/HorseRenderer.h +++ b/Minecraft.Client/HorseRenderer.h @@ -8,7 +8,7 @@ class PathfinderMob; class HorseRenderer : public MobRenderer { private: - static std::map LAYERED_LOCATION_CACHE; + static std::map LAYERED_LOCATION_CACHE; static ResourceLocation HORSE_LOCATION; static ResourceLocation HORSE_MULE_LOCATION; diff --git a/Minecraft.Client/Minecraft.Client.vcxproj b/Minecraft.Client/Minecraft.Client.vcxproj index 8f0e115c..b71c2a79 100644 --- a/Minecraft.Client/Minecraft.Client.vcxproj +++ b/Minecraft.Client/Minecraft.Client.vcxproj @@ -36516,4 +36516,4 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU - \ No newline at end of file + diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 7ec3330f..96111185 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -1298,9 +1298,9 @@ void Minecraft::run_middle() INetworkPlayer *pHostPlayer = g_NetworkManager.GetHostPlayer(); #ifdef _XBOX - PlayerUID xuid=((NetworkPlayerXbox *)pHostPlayer)->GetUID(); + PlayerUID xuid=((pHostPlayer != NULL) ? ((NetworkPlayerXbox *)pHostPlayer)->GetUID() : 0); #else - PlayerUID xuid=pHostPlayer->GetUID(); + PlayerUID xuid=(pHostPlayer != NULL) ? pHostPlayer->GetUID() : 0; #endif if(app.IsInBannedLevelList(i,xuid,app.GetUniqueMapName())) diff --git a/Minecraft.Client/MinecraftServer.cpp b/Minecraft.Client/MinecraftServer.cpp index 026c3fa4..626b5d08 100644 --- a/Minecraft.Client/MinecraftServer.cpp +++ b/Minecraft.Client/MinecraftServer.cpp @@ -165,7 +165,7 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW //localIp = settings->getString(L"server-ip", L""); //onlineMode = settings->getBoolean(L"online-mode", true); //motd = settings->getString(L"motd", L"A Minecraft Server"); - //motd.replace('§', '$'); + //motd.replace('§', '$'); setAnimals(settings->getBoolean(L"spawn-animals", true)); setNpcsEnabled(settings->getBoolean(L"spawn-npcs", true)); @@ -210,7 +210,7 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW // 4J-JEV: Need to wait for levelGenerationOptions to load. while ( app.getLevelGenerationOptions() != NULL && !app.getLevelGenerationOptions()->hasLoadedData() ) - Sleep(1); + Sleep(0); if ( app.getLevelGenerationOptions() != NULL && !app.getLevelGenerationOptions()->ready() ) { @@ -319,7 +319,7 @@ int MinecraftServer::runPostUpdate(void* lpParam) { LeaveCriticalSection(&server->m_postProcessCS); } - Sleep(1); + Sleep(0); } while (!server->m_postUpdateTerminate && ShutdownManager::ShouldRun(ShutdownManager::ePostProcessThread)); //#ifndef __PS3__ // One final pass through updates to make sure we're done diff --git a/Minecraft.Client/Orbis/Leaderboards/base64.cpp b/Minecraft.Client/Orbis/Leaderboards/base64.cpp index 01aa4cf0..477a92c7 100644 --- a/Minecraft.Client/Orbis/Leaderboards/base64.cpp +++ b/Minecraft.Client/Orbis/Leaderboards/base64.cpp @@ -1,7 +1,7 @@ /* base64.cpp and base64.h - Copyright (C) 2004-2008 René Nyffenegger + Copyright (C) 2004-2008 René Nyffenegger This source code is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages @@ -21,7 +21,7 @@ 3. This notice may not be removed or altered from any source distribution. - René Nyffenegger rene.nyffenegger@adp-gmbh.ch + René Nyffenegger rene.nyffenegger@adp-gmbh.ch */ @@ -41,7 +41,7 @@ static inline bool is_base64(unsigned char c) { } // 4J ADDED, -std::string base64_encode(std::string str) +std::string base64_encode(const std::string& str) { return base64_encode( reinterpret_cast(str.c_str()), str.length() ); } diff --git a/Minecraft.Client/Orbis/Leaderboards/base64.h b/Minecraft.Client/Orbis/Leaderboards/base64.h index bdd8a9c1..5892a406 100644 --- a/Minecraft.Client/Orbis/Leaderboards/base64.h +++ b/Minecraft.Client/Orbis/Leaderboards/base64.h @@ -2,6 +2,6 @@ #include -std::string base64_encode(std::string str); +std::string base64_encode(const std::string& str); std::string base64_encode(unsigned char const* , unsigned int len); std::string base64_decode(std::string const& s); \ No newline at end of file diff --git a/Minecraft.Client/PS3/Leaderboards/base64.cpp b/Minecraft.Client/PS3/Leaderboards/base64.cpp index 01aa4cf0..477a92c7 100644 --- a/Minecraft.Client/PS3/Leaderboards/base64.cpp +++ b/Minecraft.Client/PS3/Leaderboards/base64.cpp @@ -1,7 +1,7 @@ /* base64.cpp and base64.h - Copyright (C) 2004-2008 René Nyffenegger + Copyright (C) 2004-2008 René Nyffenegger This source code is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages @@ -21,7 +21,7 @@ 3. This notice may not be removed or altered from any source distribution. - René Nyffenegger rene.nyffenegger@adp-gmbh.ch + René Nyffenegger rene.nyffenegger@adp-gmbh.ch */ @@ -41,7 +41,7 @@ static inline bool is_base64(unsigned char c) { } // 4J ADDED, -std::string base64_encode(std::string str) +std::string base64_encode(const std::string& str) { return base64_encode( reinterpret_cast(str.c_str()), str.length() ); } diff --git a/Minecraft.Client/PS3/Leaderboards/base64.h b/Minecraft.Client/PS3/Leaderboards/base64.h index bdd8a9c1..5892a406 100644 --- a/Minecraft.Client/PS3/Leaderboards/base64.h +++ b/Minecraft.Client/PS3/Leaderboards/base64.h @@ -2,6 +2,6 @@ #include -std::string base64_encode(std::string str); +std::string base64_encode(const std::string& str); std::string base64_encode(unsigned char const* , unsigned int len); std::string base64_decode(std::string const& s); \ No newline at end of file diff --git a/Minecraft.Client/stdafx.h b/Minecraft.Client/stdafx.h index 15d157cb..2a125937 100644 --- a/Minecraft.Client/stdafx.h +++ b/Minecraft.Client/stdafx.h @@ -5,6 +5,12 @@ #pragma once +#ifdef _XBOX +#ifndef _DISABLE_XBLIVE +#define _DISABLE_XBLIVE +#endif +#endif + //#include //#include diff --git a/Minecraft.World/AddEntityPacket.cpp b/Minecraft.World/AddEntityPacket.cpp index 313c4ca6..138b5de9 100644 --- a/Minecraft.World/AddEntityPacket.cpp +++ b/Minecraft.World/AddEntityPacket.cpp @@ -56,15 +56,9 @@ void AddEntityPacket::read(DataInputStream *dis) // throws IOException TODO 4J { id = dis->readShort(); type = dis->readByte(); -#ifdef _LARGE_WORLDS x = dis->readInt(); y = dis->readInt(); z = dis->readInt(); -#else - x = dis->readShort(); - y = dis->readShort(); - z = dis->readShort(); -#endif yRot = dis->readByte(); xRot = dis->readByte(); data = dis->readInt(); @@ -80,15 +74,9 @@ void AddEntityPacket::write(DataOutputStream *dos) // throws IOException TODO 4J { dos->writeShort(id); dos->writeByte(type); -#ifdef _LARGE_WORLDS dos->writeInt(x); dos->writeInt(y); dos->writeInt(z); -#else - dos->writeShort(x); - dos->writeShort(y); - dos->writeShort(z); -#endif dos->writeByte(yRot); dos->writeByte(xRot); dos->writeInt(data); diff --git a/Minecraft.World/AddMobPacket.cpp b/Minecraft.World/AddMobPacket.cpp index 0843c333..d0d0c89f 100644 --- a/Minecraft.World/AddMobPacket.cpp +++ b/Minecraft.World/AddMobPacket.cpp @@ -68,15 +68,9 @@ void AddMobPacket::read(DataInputStream *dis) //throws IOException { id = dis->readShort(); type = dis->readByte() & 0xff; -#ifdef _LARGE_WORLDS x = dis->readInt(); y = dis->readInt(); z = dis->readInt(); -#else - x = dis->readShort(); - y = dis->readShort(); - z = dis->readShort(); -#endif yRot = dis->readByte(); xRot = dis->readByte(); yHeadRot = dis->readByte(); @@ -92,15 +86,9 @@ void AddMobPacket::write(DataOutputStream *dos) //throws IOException { dos->writeShort(id); dos->writeByte(type & 0xff); -#ifdef _LARGE_WORLDS dos->writeInt(x); dos->writeInt(y); dos->writeInt(z); -#else - dos->writeShort(x); - dos->writeShort(y); - dos->writeShort(z); -#endif dos->writeByte(yRot); dos->writeByte(xRot); dos->writeByte(yHeadRot); diff --git a/Minecraft.World/BlockRegionUpdatePacket.cpp b/Minecraft.World/BlockRegionUpdatePacket.cpp index 441501d6..d5484e5a 100644 --- a/Minecraft.World/BlockRegionUpdatePacket.cpp +++ b/Minecraft.World/BlockRegionUpdatePacket.cpp @@ -74,7 +74,7 @@ BlockRegionUpdatePacket::BlockRegionUpdatePacket(int x, int y, int z, int xs, in unsigned char *ucTemp = new unsigned char[(256 * 16 * 16 * 5)/2]; unsigned int inputSize = (256 * 16 * 16 * 5)/2; - Compression::getCompression()->CompressLZXRLE(ucTemp, &inputSize, rawBuffer.data, (unsigned int) rawBuffer.length); + Compression::getCompression()->CompressRLE(ucTemp, &inputSize, rawBuffer.data, (unsigned int) rawBuffer.length); //app.DebugPrintf("Chunk (%d,%d) compressed from %d to size %d\n", x>>4, z>>4, rawBuffer.length, inputSize); unsigned char *ucTemp2 = new unsigned char[inputSize]; memcpy(ucTemp2,ucTemp,inputSize); @@ -120,7 +120,7 @@ void BlockRegionUpdatePacket::read(DataInputStream *dis) //throws IOException if( success ) { - Compression::getCompression()->DecompressLZXRLE( buffer.data, &outputSize, compressedBuffer.data, size); + Compression::getCompression()->DecompressRLE( buffer.data, &outputSize, compressedBuffer.data, size); } else { diff --git a/Minecraft.World/ChunkTilesUpdatePacket.cpp b/Minecraft.World/ChunkTilesUpdatePacket.cpp index 0072de4d..eab1a65c 100644 --- a/Minecraft.World/ChunkTilesUpdatePacket.cpp +++ b/Minecraft.World/ChunkTilesUpdatePacket.cpp @@ -51,17 +51,10 @@ ChunkTilesUpdatePacket::ChunkTilesUpdatePacket(int xc, int zc, shortArray positi void ChunkTilesUpdatePacket::read(DataInputStream *dis) //throws IOException { // 4J - changed format. See comments in write method. -#ifdef _LARGE_WORLDS xc = dis->readShort(); zc = dis->readShort(); xc = ( xc << 16 ) >> 16; zc = ( zc << 16 ) >> 16; -#else - xc = dis->read(); - zc = dis->read(); - xc = ( xc << 24 ) >> 24; - zc = ( zc << 24 ) >> 24; -#endif int countAndFlags = dis->readByte(); bool dataAllZero = (( countAndFlags & 0x80 ) == 0x80 ); @@ -97,13 +90,8 @@ void ChunkTilesUpdatePacket::read(DataInputStream *dis) //throws IOException void ChunkTilesUpdatePacket::write(DataOutputStream *dos) //throws IOException { // 4J - changed format to reduce size of these packets. -#ifdef _LARGE_WORLDS dos->writeShort(xc); dos->writeShort(zc); -#else - dos->write(xc); - dos->write(zc); -#endif // Determine if we've got any data elements that are non-zero - a large % of these packets set all data to zero, so we don't // bother sending all those zeros in that case. bool dataAllZero = true; diff --git a/Minecraft.World/Connection.cpp b/Minecraft.World/Connection.cpp index f37f0f1d..d3fb5694 100644 --- a/Minecraft.World/Connection.cpp +++ b/Minecraft.World/Connection.cpp @@ -341,7 +341,7 @@ bool Connection::readTick() // printf("Con:0x%x readTick close EOS\n",this); // 4J Stu - Remove this line - // Fix for #10410 - UI: If the player is removed from a splitscreened host’s game, the next game that player joins will produce a message stating that the host has left. + // Fix for #10410 - UI: If the player is removed from a splitscreened hostÂ’s game, the next game that player joins will produce a message stating that the host has left. //close(DisconnectPacket::eDisconnect_EndOfStream); } @@ -666,7 +666,7 @@ int Connection::runClose(void* lpParam) //try { - Sleep(2000); + Sleep(500); if (con->running) { // 4J TODO writeThread.interrupt(); @@ -690,7 +690,7 @@ int Connection::runSendAndQuit(void* lpParam) //try { - Sleep(2000); + Sleep(500); if (con->running) { // 4J TODO writeThread.interrupt(); diff --git a/Minecraft.World/LoginPacket.cpp b/Minecraft.World/LoginPacket.cpp index 25e53880..caadb5b4 100644 --- a/Minecraft.World/LoginPacket.cpp +++ b/Minecraft.World/LoginPacket.cpp @@ -123,10 +123,8 @@ void LoginPacket::read(DataInputStream *dis) //throws IOException m_isGuest = dis->readBoolean(); m_newSeaLevel = dis->readBoolean(); m_uiGamePrivileges = dis->readInt(); -#ifdef _LARGE_WORLDS m_xzSize = dis->readShort(); m_hellScale = dis->read(); -#endif app.DebugPrintf("LoginPacket::read - Difficulty = %d\n",difficulty); } @@ -160,10 +158,8 @@ void LoginPacket::write(DataOutputStream *dos) //throws IOException dos->writeBoolean(m_isGuest); dos->writeBoolean(m_newSeaLevel); dos->writeInt(m_uiGamePrivileges); -#ifdef _LARGE_WORLDS dos->writeShort(m_xzSize); dos->write(m_hellScale); -#endif } void LoginPacket::handle(PacketListener *listener) diff --git a/Minecraft.World/Minecraft.World.vcxproj b/Minecraft.World/Minecraft.World.vcxproj index 43c52d16..9680f74e 100644 --- a/Minecraft.World/Minecraft.World.vcxproj +++ b/Minecraft.World/Minecraft.World.vcxproj @@ -1,4 +1,4 @@ - + @@ -201,6 +201,7 @@ StaticLibrary MultiByte v110 + true StaticLibrary diff --git a/Minecraft.World/RespawnPacket.cpp b/Minecraft.World/RespawnPacket.cpp index 0e251f59..7c3e3fcf 100644 --- a/Minecraft.World/RespawnPacket.cpp +++ b/Minecraft.World/RespawnPacket.cpp @@ -55,10 +55,8 @@ void RespawnPacket::read(DataInputStream *dis) //throws IOException difficulty = dis->readByte(); m_newSeaLevel = dis->readBoolean(); m_newEntityId = dis->readShort(); -#ifdef _LARGE_WORLDS m_xzSize = dis->readShort(); m_hellScale = dis->read(); -#endif app.DebugPrintf("RespawnPacket::read - Difficulty = %d\n",difficulty); } @@ -80,10 +78,8 @@ void RespawnPacket::write(DataOutputStream *dos) //throws IOException dos->writeByte(difficulty); dos->writeBoolean(m_newSeaLevel); dos->writeShort(m_newEntityId); -#ifdef _LARGE_WORLDS dos->writeShort(m_xzSize); dos->write(m_hellScale); -#endif } int RespawnPacket::getEstimatedSize() diff --git a/Minecraft.World/TeleportEntityPacket.cpp b/Minecraft.World/TeleportEntityPacket.cpp index 2527a1a5..4325c9ac 100644 --- a/Minecraft.World/TeleportEntityPacket.cpp +++ b/Minecraft.World/TeleportEntityPacket.cpp @@ -40,15 +40,9 @@ TeleportEntityPacket::TeleportEntityPacket(int id, int x, int y, int z, byte yRo void TeleportEntityPacket::read(DataInputStream *dis) //throws IOException { id = dis->readShort(); -#ifdef _LARGE_WORLDS x = dis->readInt(); y = dis->readInt(); z = dis->readInt(); -#else - x = dis->readShort(); - y = dis->readShort(); - z = dis->readShort(); -#endif yRot = dis->readByte(); xRot = dis->readByte(); } @@ -56,15 +50,9 @@ void TeleportEntityPacket::read(DataInputStream *dis) //throws IOException void TeleportEntityPacket::write(DataOutputStream *dos) //throws IOException { dos->writeShort(id); -#ifdef _LARGE_WORLDS dos->writeInt(x); dos->writeInt(y); dos->writeInt(z); -#else - dos->writeShort(x); - dos->writeShort(y); - dos->writeShort(z); -#endif dos->write(yRot); dos->write(xRot); } diff --git a/Minecraft.World/TileUpdatePacket.cpp b/Minecraft.World/TileUpdatePacket.cpp index d19d1e55..a91f0287 100644 --- a/Minecraft.World/TileUpdatePacket.cpp +++ b/Minecraft.World/TileUpdatePacket.cpp @@ -26,7 +26,6 @@ TileUpdatePacket::TileUpdatePacket(int x, int y, int z, Level *level) void TileUpdatePacket::read(DataInputStream *dis) //throws IOException { -#ifdef _LARGE_WORLDS x = dis->readInt(); y = dis->readUnsignedByte(); z = dis->readInt(); @@ -36,26 +35,10 @@ void TileUpdatePacket::read(DataInputStream *dis) //throws IOException BYTE dataLevel = dis->readByte(); data = dataLevel & 0xf; levelIdx = (dataLevel>>4) & 0xf; -#else - // 4J - See comments in write for packing - int xyzdata = dis->readInt(); - x = ( xyzdata >> 22 ) & 0x3ff; - y = ( xyzdata >> 14 ) & 0xff; - z = ( xyzdata >> 4 ) & 0x3ff; - x = ( x << 22 ) >> 22; - z = ( z << 22 ) >> 22; - data = xyzdata & 0xf; - block = (int)dis->readShort() & 0xffff; - //levelIdx = ( xyzdata >> 31 ) & 1; - - // Can't pack this as it's now 2 bits - levelIdx = (int)dis->readByte(); -#endif } void TileUpdatePacket::write(DataOutputStream *dos) //throws IOException { -#ifdef _LARGE_WORLDS dos->writeInt(x); dos->write(y); dos->writeInt(z); @@ -63,18 +46,6 @@ void TileUpdatePacket::write(DataOutputStream *dos) //throws IOException BYTE dataLevel = ((levelIdx & 0xf ) << 4) | (data & 0xf); dos->writeByte(dataLevel); -#else - // 4J - for our fixed size map, we can pack x & z into 10 bits each (-512 -> 511), y into 8 bits (0 to 255) - // block type could really be 7 bits but leaving that as 8 for future ease of expansion. Data only needs to be 4-bits as that is how it - // is ultimately stored - int xyzdata = ( ( x & 0x3ff ) << 22 ) | ( ( y & 0xff ) << 14 ) | ( ( z & 0x3ff ) << 4 ) | ( data & 0xf); - //xyzdata |= levelIdx << 31; - dos->writeInt(xyzdata); - dos->writeShort(block); - - // Can't pack this as it's now 2 bits - dos->write(levelIdx); -#endif } void TileUpdatePacket::handle(PacketListener *listener) @@ -84,9 +55,5 @@ void TileUpdatePacket::handle(PacketListener *listener) int TileUpdatePacket::getEstimatedSize() { -#ifdef _LARGE_WORLDS return 12; -#else - return 5; -#endif } diff --git a/Minecraft.World/compression.cpp b/Minecraft.World/compression.cpp index bada5069..9bbf0a8e 100644 --- a/Minecraft.World/compression.cpp +++ b/Minecraft.World/compression.cpp @@ -1,6 +1,6 @@ #include "stdafx.h" #include "compression.h" -#if defined __ORBIS__ || defined __PS3__ || defined _DURANGO || defined _WIN64 +#if defined __ORBIS__ || defined __PS3__ || defined _DURANGO || defined _WIN64 || defined _XBOX #include "..\Minecraft.Client\Common\zlib\zlib.h" #endif @@ -299,7 +299,7 @@ HRESULT Compression::DecompressRLE(void *pDestination, unsigned int *pDestSize, HRESULT Compression::Compress(void *pDestination, unsigned int *pDestSize, void *pSource, unsigned int SrcSize) { - // Using zlib for x64 compression - 360 is using native 360 compression and PS3 a stubbed non-compressing version of this + // Using zlib for x64 compression - 360 is using native 64 compression and PS3 a stubbed non-compressing version of this #if defined __ORBIS__ || defined _DURANGO || defined _WIN64 || defined __PSVITA__ SIZE_T destSize = (SIZE_T)(*pDestSize); int res = ::compress((Bytef *)pDestination, (uLongf *)&destSize, (Bytef *)pSource, SrcSize); @@ -327,7 +327,7 @@ HRESULT Compression::Decompress(void *pDestination, unsigned int *pDestSize, voi return DecompressWithType(pDestination, pDestSize, pSource, SrcSize); } - // Using zlib for x64 compression - 360 is using native 360 compression and PS3 a stubbed non-compressing version of this + // Using zlib for x64 and 360 compression - 360 is using native 360 compression and PS3 a stubbed non-compressing version of this #if defined __ORBIS__ || defined _DURANGO || defined _WIN64 || defined __PSVITA__ SIZE_T destSize = (SIZE_T)(*pDestSize); int res = ::uncompress((Bytef *)pDestination, (uLongf *)&destSize, (Bytef *)pSource, SrcSize); @@ -406,7 +406,7 @@ HRESULT Compression::DecompressWithType(void *pDestination, unsigned int *pDestS } break; case eCompressionType_ZLIBRLE: -#if (defined __ORBIS__ || defined __PS3__ || defined _DURANGO || defined _WIN64) +#if (defined __ORBIS__ || defined __PS3__ || defined _DURANGO || defined _WIN64 || defined _XBOX) if (pDestination != NULL) return ::uncompress((PBYTE)pDestination, (unsigned long *) pDestSize, (PBYTE) pSource, SrcSize); // Decompress else break; // Cannot decompress when destination is NULL diff --git a/Minecraft.World/stdafx.h b/Minecraft.World/stdafx.h index 979a5fa7..864648d9 100644 --- a/Minecraft.World/stdafx.h +++ b/Minecraft.World/stdafx.h @@ -4,6 +4,12 @@ // #pragma once +#ifdef _XBOX +#ifndef _DISABLE_XBLIVE +#define _DISABLE_XBLIVE +#endif +#endif + #ifdef __PS3__ #else #define AUTO_VAR(_var, _val) auto _var = _val