|
|
|
|
@@ -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;
|
|
|
|
|
|
|
|
|
|
@@ -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++ )
|
|
|
|
|
{
|
|
|
|
|
@@ -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()
|
|
|
|
|
@@ -232,6 +301,10 @@ 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())
|
|
|
|
|
{
|
|
|
|
|
@@ -239,6 +312,22 @@ bool CPlatformNetworkManagerStub::LeaveGame(bool bMigrateHost)
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -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)
|
|
|
|
|
@@ -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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -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 )
|
|
|
|
|
@@ -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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|