Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Minecraft.Client/ClientConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
return;
}
}
#ifdef _WINDOWS64
/*#ifdef _WINDOWS64
// On Windows64 all XUIDs are INVALID_XUID so the XUID check above never fires.
// packet->m_playerIndex is the server-assigned sequential index (set via LoginPacket),
// NOT the controller slot — so we must scan all local player slots and match by
Expand All @@ -771,7 +771,7 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
return;
}
}
#endif
#endif*/

double x = packet->x / 32.0;
double y = packet->y / 32.0;
Expand Down
2 changes: 1 addition & 1 deletion Minecraft.Client/Common/Consoles_App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3402,7 +3402,7 @@ void CMinecraftApp::HandleXuiActions(void)
bool gameStarted = false;
for(int j = 0; j < pMinecraft->levels.length; j++)
{
if (pMinecraft->levels.data[i] != NULL)
if (pMinecraft->levels.data[i] != nullptr)
{
gameStarted = true;
break;
Expand Down
10 changes: 9 additions & 1 deletion Minecraft.Client/Common/Network/GameNetworkManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ bool CGameNetworkManager::_RunNetworkGame(LPVOID lpParameter)
return true;
}
}
else
{
// Client needs QNET_STATE_GAME_PLAY so that IsInGameplay() returns true
s_pPlatformNetworkManager->SetGamePlayState();
}

if( g_NetworkManager.IsLeavingGame() ) return false;

Expand Down Expand Up @@ -1479,7 +1484,10 @@ void CGameNetworkManager::CreateSocket( INetworkPlayer *pNetworkPlayer, bool loc
Minecraft *pMinecraft = Minecraft::GetInstance();

Socket *socket = NULL;
shared_ptr<MultiplayerLocalPlayer> mpPlayer = pMinecraft->localplayers[pNetworkPlayer->GetUserIndex()];
shared_ptr<MultiplayerLocalPlayer> mpPlayer = nullptr;
int userIdx = pNetworkPlayer->GetUserIndex();
if (userIdx >= 0 && userIdx < XUSER_MAX_COUNT)
mpPlayer = pMinecraft->localplayers[userIdx];
if( localPlayer && mpPlayer != NULL && mpPlayer->connection != NULL)
{
// If we already have a MultiplayerLocalPlayer here then we are doing a session type change
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class CPlatformNetworkManager
virtual void HandleSignInChange() = 0;

virtual bool _RunNetworkGame() = 0;
virtual void SetGamePlayState() {}

private:
virtual bool _LeaveGame(bool bMigrateHost, bool bLeaveRoom) = 0;
Expand Down
225 changes: 222 additions & 3 deletions Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
#include "..\..\..\Minecraft.World\Socket.h"
#include "..\..\..\Minecraft.World\StringHelpers.h"
#include "PlatformNetworkManagerStub.h"
#include "..\..\Xbox\Network\NetworkPlayerXbox.h" // TODO - stub version of this?
#include "..\..\Xbox\Network\NetworkPlayerXbox.h"
#ifdef _WINDOWS64
#include "..\..\Windows64\Network\WinsockNetLayer.h"
#include "..\..\Minecraft.h"
#include "..\..\User.h"
#endif

CPlatformNetworkManagerStub *g_pPlatformNetworkManager;

Expand Down Expand Up @@ -114,10 +119,43 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer )
}
}

void CPlatformNetworkManagerStub::NotifyPlayerLeaving(IQNetPlayer* pQNetPlayer)
{
app.DebugPrintf("Player 0x%p \"%ls\" leaving.\n", pQNetPlayer, pQNetPlayer->GetGamertag());

INetworkPlayer* networkPlayer = getNetworkPlayer(pQNetPlayer);
if (networkPlayer == NULL)
return;

Socket* socket = networkPlayer->GetSocket();
if (socket != NULL)
{
if (m_pIQNet->IsHost())
g_NetworkManager.CloseConnection(networkPlayer);
}

if (m_pIQNet->IsHost())
{
SystemFlagRemovePlayer(networkPlayer);
}

g_NetworkManager.PlayerLeaving(networkPlayer);

for (int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
{
if (playerChangedCallback[idx] != NULL)
playerChangedCallback[idx](playerChangedCallbackParam[idx], networkPlayer, true);
}

removeNetworkPlayer(pQNetPlayer);
}


bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkManager, int flagIndexSize)
{
m_pGameNetworkManager = pGameNetworkManager;
m_flagIndexSize = flagIndexSize;
m_pIQNet = new IQNet();
g_pPlatformNetworkManager = this;
for( int i = 0; i < XUSER_MAX_COUNT; i++ )
{
Expand Down Expand Up @@ -174,6 +212,37 @@ bool CPlatformNetworkManagerStub::isSystemPrimaryPlayer(IQNetPlayer *pQNetPlayer
// We call this twice a frame, either side of the render call so is a good place to "tick" things
void CPlatformNetworkManagerStub::DoWork()
{
#ifdef _WINDOWS64
extern QNET_STATE _iQNetStubState;
if (_iQNetStubState == QNET_STATE_SESSION_STARTING && app.GetGameStarted())
{
_iQNetStubState = QNET_STATE_GAME_PLAY;
if (m_pIQNet->IsHost())
WinsockNetLayer::UpdateAdvertiseJoinable(true);
}
if (_iQNetStubState == QNET_STATE_IDLE)
TickSearch();
if (_iQNetStubState == QNET_STATE_GAME_PLAY && m_pIQNet->IsHost())
{
BYTE disconnectedSmallId;
while (WinsockNetLayer::PopDisconnectedSmallId(&disconnectedSmallId))
{
IQNetPlayer* qnetPlayer = m_pIQNet->GetPlayerBySmallId(disconnectedSmallId);
if (qnetPlayer != NULL && qnetPlayer->m_smallId == disconnectedSmallId)
{
NotifyPlayerLeaving(qnetPlayer);
qnetPlayer->m_smallId = 0;
qnetPlayer->m_isRemote = false;
qnetPlayer->m_isHostPlayer = false;
qnetPlayer->m_gamertag[0] = 0;
qnetPlayer->SetCustomDataValue(0);
WinsockNetLayer::PushFreeSmallId(disconnectedSmallId);
if (IQNet::s_playerCount > 1)
IQNet::s_playerCount--;
}
}
}
#endif
}

int CPlatformNetworkManagerStub::GetPlayerCount()
Expand Down Expand Up @@ -232,13 +301,33 @@ bool CPlatformNetworkManagerStub::LeaveGame(bool bMigrateHost)

m_bLeavingGame = true;

#ifdef _WINDOWS64
WinsockNetLayer::StopAdvertising();
#endif

// If we are the host wait for the game server to end
if(m_pIQNet->IsHost() && g_NetworkManager.ServerStoppedValid())
{
m_pIQNet->EndGame();
g_NetworkManager.ServerStoppedWait();
g_NetworkManager.ServerStoppedDestroy();
}
else
{
m_pIQNet->EndGame();
}

for (AUTO_VAR(it, currentNetworkPlayers.begin()); it != currentNetworkPlayers.end(); it++)
delete* it;
currentNetworkPlayers.clear();
m_machineQNetPrimaryPlayers.clear();
SystemFlagReset();

#ifdef _WINDOWS64
WinsockNetLayer::Shutdown();
WinsockNetLayer::Initialize();
#endif

return true;
}

Expand All @@ -262,7 +351,24 @@ void CPlatformNetworkManagerStub::HostGame(int localUsersMask, bool bOnlineGame,

m_pIQNet->HostGame();

#ifdef _WINDOWS64
IQNet::m_player[0].m_smallId = 0;
IQNet::m_player[0].m_isRemote = false;
IQNet::m_player[0].m_isHostPlayer = true;
IQNet::s_playerCount = 1;
#endif

_HostGame( localUsersMask, publicSlots, privateSlots );

#ifdef _WINDOWS64
int port = WIN64_NET_DEFAULT_PORT;
if (!WinsockNetLayer::IsActive())
WinsockNetLayer::HostGame(port);

const wchar_t* hostName = IQNet::m_player[0].m_gamertag;
unsigned int settings = app.GetGameHostOption(eGameHostOption_All);
WinsockNetLayer::StartAdvertising(port, hostName, settings, 0, 0, MINECRAFT_NET_VERSION);
#endif
//#endif
}

Expand All @@ -275,9 +381,54 @@ bool CPlatformNetworkManagerStub::_StartGame()
return true;
}

int CPlatformNetworkManagerStub::JoinGame(FriendSessionInfo *searchResult, int localUsersMask, int primaryUserIndex)
int CPlatformNetworkManagerStub::JoinGame(FriendSessionInfo* searchResult, int localUsersMask, int primaryUserIndex)
{
#ifdef _WINDOWS64
if (searchResult == NULL)
return CGameNetworkManager::JOINGAME_FAIL_GENERAL;

const char* hostIP = searchResult->data.hostIP;
int hostPort = searchResult->data.hostPort;

if (hostPort <= 0 || hostIP[0] == 0)
return CGameNetworkManager::JOINGAME_FAIL_GENERAL;

m_bLeavingGame = false;
IQNet::s_isHosting = false;
m_pIQNet->ClientJoinGame();

IQNet::m_player[0].m_smallId = 0;
IQNet::m_player[0].m_isRemote = true;
IQNet::m_player[0].m_isHostPlayer = true;
wcsncpy_s(IQNet::m_player[0].m_gamertag, 32, searchResult->data.hostName, _TRUNCATE);

WinsockNetLayer::StopDiscovery();

if (!WinsockNetLayer::JoinGame(hostIP, hostPort))
{
app.DebugPrintf("Win64 LAN: Failed to connect to %s:%d\n", hostIP, hostPort);
return CGameNetworkManager::JOINGAME_FAIL_GENERAL;
}

BYTE localSmallId = WinsockNetLayer::GetLocalSmallId();

IQNet::m_player[localSmallId].m_smallId = localSmallId;
IQNet::m_player[localSmallId].m_isRemote = false;
IQNet::m_player[localSmallId].m_isHostPlayer = false;

Minecraft* pMinecraft = Minecraft::GetInstance();
wcscpy_s(IQNet::m_player[localSmallId].m_gamertag, 32, pMinecraft->user->name.c_str());
IQNet::s_playerCount = localSmallId + 1;

NotifyPlayerJoined(&IQNet::m_player[0]);
NotifyPlayerJoined(&IQNet::m_player[localSmallId]);

m_pGameNetworkManager->StateChange_AnyToStarting();

return CGameNetworkManager::JOINGAME_SUCCESS;
#else
return CGameNetworkManager::JOINGAME_SUCCESS;
#endif
}

bool CPlatformNetworkManagerStub::SetLocalGame(bool isLocal)
Expand Down Expand Up @@ -315,6 +466,22 @@ void CPlatformNetworkManagerStub::HandleSignInChange()

bool CPlatformNetworkManagerStub::_RunNetworkGame()
{
#ifdef _WINDOWS64
extern QNET_STATE _iQNetStubState;
_iQNetStubState = QNET_STATE_GAME_PLAY;

for (DWORD i = 0; i < IQNet::s_playerCount; i++)
{
if (IQNet::m_player[i].m_isRemote)
{
INetworkPlayer* pNetworkPlayer = getNetworkPlayer(&IQNet::m_player[i]);
if (pNetworkPlayer != NULL && pNetworkPlayer->GetSocket() != NULL)
{
Socket::addIncomingSocket(pNetworkPlayer->GetSocket());
}
}
}
#endif
return true;
}

Expand Down Expand Up @@ -503,10 +670,60 @@ wstring CPlatformNetworkManagerStub::GatherRTTStats()

void CPlatformNetworkManagerStub::TickSearch()
{
#ifdef _WINDOWS64
if (m_SessionsUpdatedCallback == NULL)
return;

static DWORD lastSearchTime = 0;
DWORD now = GetTickCount();
if (now - lastSearchTime < 2000)
return;
lastSearchTime = now;

SearchForGames();
#endif
}

void CPlatformNetworkManagerStub::SearchForGames()
{
#ifdef _WINDOWS64
std::vector<Win64LANSession> lanSessions = WinsockNetLayer::GetDiscoveredSessions();

for (size_t i = 0; i < friendsSessions[0].size(); i++)
delete friendsSessions[0][i];
friendsSessions[0].clear();

for (size_t i = 0; i < lanSessions.size(); i++)
{
FriendSessionInfo* info = new FriendSessionInfo();
size_t nameLen = wcslen(lanSessions[i].hostName);
info->displayLabel = new wchar_t[nameLen + 1];
wcscpy_s(info->displayLabel, nameLen + 1, lanSessions[i].hostName);
info->displayLabelLength = (unsigned char)nameLen;
info->displayLabelViewableStartIndex = 0;

info->data.netVersion = lanSessions[i].netVersion;
info->data.m_uiGameHostSettings = lanSessions[i].gameHostSettings;
info->data.texturePackParentId = lanSessions[i].texturePackParentId;
info->data.subTexturePackId = lanSessions[i].subTexturePackId;
info->data.isReadyToJoin = lanSessions[i].isJoinable;
info->data.isJoinable = lanSessions[i].isJoinable;
strncpy_s(info->data.hostIP, sizeof(info->data.hostIP), lanSessions[i].hostIP, _TRUNCATE);
info->data.hostPort = lanSessions[i].hostPort;
wcsncpy_s(info->data.hostName, XUSER_NAME_SIZE, lanSessions[i].hostName, _TRUNCATE);
info->data.playerCount = lanSessions[i].playerCount;
info->data.maxPlayers = lanSessions[i].maxPlayers;

info->sessionId = (SessionID)((unsigned __int64)inet_addr(lanSessions[i].hostIP) | ((unsigned __int64)lanSessions[i].hostPort << 32));

friendsSessions[0].push_back(info);
}

m_searchResultsCount[0] = (int)friendsSessions[0].size();

if (m_SessionsUpdatedCallback != NULL)
m_SessionsUpdatedCallback(m_pSearchParam);
#endif
}

int CPlatformNetworkManagerStub::SearchForGamesThreadProc( void* lpParameter )
Expand All @@ -522,7 +739,9 @@ void CPlatformNetworkManagerStub::SetSearchResultsReady(int resultCount)

vector<FriendSessionInfo *> *CPlatformNetworkManagerStub::GetSessionList(int iPad, int localPlayers, bool partyOnly)
{
vector<FriendSessionInfo *> *filteredList = new vector<FriendSessionInfo *>();;
vector<FriendSessionInfo*>* filteredList = new vector<FriendSessionInfo*>();
for (size_t i = 0; i < friendsSessions[0].size(); i++)
filteredList->push_back(friendsSessions[0][i]);
return filteredList;
}

Expand Down
3 changes: 2 additions & 1 deletion Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,9 @@ class CPlatformNetworkManagerStub : public CPlatformNetworkManager
virtual void GetFullFriendSessionInfo( FriendSessionInfo *foundSession, void (* FriendSessionUpdatedFn)(bool success, void *pParam), void *pParam );
virtual void ForceFriendsSessionRefresh();

private:
public:
void NotifyPlayerJoined( IQNetPlayer *pQNetPlayer );
void NotifyPlayerLeaving(IQNetPlayer* pQNetPlayer);

#ifndef _XBOX
void FakeLocalPlayerJoined() { NotifyPlayerJoined(m_pIQNet->GetLocalPlayerByUserIndex(0)); }
Expand Down
Loading