update lcemp networking

This commit is contained in:
pieeebot committed 2026-08-02 03:33:11 +03:00
1 parent b87d044cf0
commit e254228cf5
15 files changed
+616 -138

No files matched your search

+65 -1
View File
@@ -50,11 +50,16 @@
#else #else
#include "Common\UI\UI.h" #include "Common\UI\UI.h"
#endif #endif
#ifdef __PS3__ #if defined __PS3__ && !defined DISABLE_PSN
#include "PS3/Network/SonyVoiceChat.h" #include "PS3/Network/SonyVoiceChat.h"
#endif #endif
#include "DLCTexturePack.h" #include "DLCTexturePack.h"
#if defined _WINDOWS64 || defined DISABLE_PSN || defined _DISABLE_XBLIVE
#include "Xbox\Network\NetworkPlayerXbox.h"
#include "Common\Network\PlatformNetworkManagerStub.h"
#endif
#ifdef _DURANGO #ifdef _DURANGO
#include "..\Minecraft.World\DurangoStats.h" #include "..\Minecraft.World\DurangoStats.h"
#include "..\Minecraft.World\GenericStats.h" #include "..\Minecraft.World\GenericStats.h"
@@ -781,6 +786,32 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
player->m_displayName = player->name; player->m_displayName = player->name;
#endif #endif
#if defined _WINDOWS64 || defined DISABLE_PSN || defined _DISABLE_XBLIVE
{
PlayerUID pktXuid = player->getXuid();
const PlayerUID WIN64_XUID_BASE = (PlayerUID)0xe000d45248242f2e;
if (pktXuid >= WIN64_XUID_BASE && pktXuid < WIN64_XUID_BASE + MINECRAFT_NET_MAX_PLAYERS)
{
BYTE smallId = (BYTE)(pktXuid - WIN64_XUID_BASE);
INetworkPlayer *np = g_NetworkManager.GetPlayerBySmallId(smallId);
if (np != NULL)
{
NetworkPlayerXbox *npx = (NetworkPlayerXbox *)np;
IQNetPlayer *qp = npx->GetQNetPlayer();
if (qp != NULL)
{
wcsncpy(qp->m_gamertag, packet->name.c_str(), 31);
qp->m_gamertag[31] = L'\0';
if (g_NetworkManager.IsHost())
{
g_NetworkManager.UpdateAndSetGameSessionData();
}
}
}
}
}
#endif
// printf("\t\t\t\t%d: Add player\n",packet->id,packet->yRot); // printf("\t\t\t\t%d: Add player\n",packet->id,packet->yRot);
int item = packet->carriedItem; int item = packet->carriedItem;
@@ -923,6 +954,39 @@ void ClientConnection::handleMoveEntitySmall(shared_ptr<MoveEntityPacketSmall> p
void ClientConnection::handleRemoveEntity(shared_ptr<RemoveEntitiesPacket> packet) void ClientConnection::handleRemoveEntity(shared_ptr<RemoveEntitiesPacket> packet)
{ {
#if defined _WINDOWS64 || defined DISABLE_PSN || defined _DISABLE_XBLIVE
if (!g_NetworkManager.IsHost())
{
for (int i = 0; i < packet->ids.length; i++)
{
shared_ptr<Entity> entity = getEntity(packet->ids[i]);
if (entity != NULL && entity->GetType() == eTYPE_PLAYER)
{
shared_ptr<Player> player = dynamic_pointer_cast<Player>(entity);
if (player != NULL)
{
PlayerUID xuid = player->getXuid();
INetworkPlayer *np = g_NetworkManager.GetPlayerByXuid(xuid);
if (np != NULL)
{
NetworkPlayerXbox *npx = (NetworkPlayerXbox *)np;
IQNetPlayer *qp = npx->GetQNetPlayer();
if (qp != NULL)
{
extern CPlatformNetworkManagerStub *g_pPlatformNetworkManager;
g_pPlatformNetworkManager->NotifyPlayerLeaving(qp);
qp->m_smallId = 0;
qp->m_isRemote = false;
qp->m_isHostPlayer = false;
qp->m_gamertag[0] = 0;
qp->SetCustomDataValue(0);
}
}
}
}
}
}
#endif
for (int i = 0; i < packet->ids.length; i++) for (int i = 0; i < packet->ids.length; i++)
{ {
level->removeEntity(packet->ids[i]); level->removeEntity(packet->ids[i]);
@@ -1502,7 +1502,10 @@ void CGameNetworkManager::CreateSocket( INetworkPlayer *pNetworkPlayer, bool loc
Minecraft *pMinecraft = Minecraft::GetInstance(); Minecraft *pMinecraft = Minecraft::GetInstance();
Socket *socket = NULL; 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( localPlayer && mpPlayer != NULL && mpPlayer->connection != NULL)
{ {
// If we already have a MultiplayerLocalPlayer here then we are doing a session type change // If we already have a MultiplayerLocalPlayer here then we are doing a session type change
@@ -94,7 +94,7 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer )
if( m_pIQNet->IsHost() ) if( m_pIQNet->IsHost() )
{ {
// 4J-PB - only the host should do this // 4J-PB - only the host should do this
// g_NetworkManager.UpdateAndSetGameSessionData(); g_NetworkManager.UpdateAndSetGameSessionData();
SystemFlagAddPlayer( networkPlayer ); SystemFlagAddPlayer( networkPlayer );
} }
@@ -141,6 +141,11 @@ void CPlatformNetworkManagerStub::NotifyPlayerLeaving(IQNetPlayer *pQNetPlayer)
g_NetworkManager.PlayerLeaving(networkPlayer); g_NetworkManager.PlayerLeaving(networkPlayer);
if (m_pIQNet->IsHost())
{
g_NetworkManager.UpdateAndSetGameSessionData(networkPlayer);
}
for (int idx = 0; idx < XUSER_MAX_COUNT; ++idx) for (int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
{ {
if (playerChangedCallback[idx] != NULL) if (playerChangedCallback[idx] != NULL)
@@ -239,6 +244,28 @@ void CPlatformNetworkManagerStub::DoWork()
IQNet::s_playerCount--; 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())
{
WinsockNetLayer::CloseConnectionBySmallId((BYTE)i);
}
}
}
if (_iQNetStubState == QNET_STATE_GAME_PLAY && !m_pIQNet->IsHost())
{
if (!WinsockNetLayer::IsConnected() && !g_NetworkManager.IsLeavingGame())
{
if (app.GetDisconnectReason() == DisconnectPacket::eDisconnect_None)
app.SetDisconnectReason(DisconnectPacket::eDisconnect_Quitting);
app.SetAction(ProfileManager.GetPrimaryPad(), eAppAction_ExitWorld, (void *)TRUE);
}
} }
} }
@@ -470,44 +497,48 @@ bool CPlatformNetworkManagerStub::_RunNetworkGame()
void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= NULL*/) void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= NULL*/)
{ {
// DWORD playerCount = m_pIQNet->GetPlayerCount(); if (this->m_bLeavingGame)
// return;
// if( this->m_bLeavingGame )
// return; if (!m_pIQNet->IsHost())
// return;
// if( GetHostPlayer() == NULL )
// return; DWORD playerCount = m_pIQNet->GetPlayerCount();
//
// for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All);
// { m_hostGameSessionData.playerCount = (unsigned char)playerCount;
// if( i < playerCount )
// { for (unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i)
// INetworkPlayer *pNetworkPlayer = GetPlayerByIndex(i); {
// if (i < playerCount)
// // We can call this from NotifyPlayerLeaving but at that point the player is still considered in the session {
// if( pNetworkPlayer != pNetworkPlayerLeaving ) INetworkPlayer *pNetworkPlayer = GetPlayerByIndex(i);
// {
// m_hostGameSessionData.players[i] = ((NetworkPlayerXbox *)pNetworkPlayer)->GetUID(); if (pNetworkPlayer != NULL && pNetworkPlayer != pNetworkPlayerLeaving)
// {
// char *temp; m_hostGameSessionData.players[i] = (GameSessionUID)(i + 1);
// temp = (char *)wstringtofilename( pNetworkPlayer->GetOnlineName() );
// memcpy(m_hostGameSessionData.szPlayers[i],temp,XUSER_NAME_SIZE); const wchar_t *name = pNetworkPlayer->GetOnlineName();
// } char nameBuf[XUSER_NAME_SIZE];
// else memset(nameBuf, 0, sizeof(nameBuf));
// { wcstombs(nameBuf, name, XUSER_NAME_SIZE - 1);
// m_hostGameSessionData.players[i] = NULL; memcpy(m_hostGameSessionData.szPlayers[i], nameBuf, XUSER_NAME_SIZE);
// memset(m_hostGameSessionData.szPlayers[i],0,XUSER_NAME_SIZE); }
// } else
// } {
// else m_hostGameSessionData.players[i] = 0;
// { memset(m_hostGameSessionData.szPlayers[i], 0, XUSER_NAME_SIZE);
// m_hostGameSessionData.players[i] = NULL; }
// memset(m_hostGameSessionData.szPlayers[i],0,XUSER_NAME_SIZE); }
// } else
// } {
// m_hostGameSessionData.players[i] = 0;
// m_hostGameSessionData.hostPlayerUID = ((NetworkPlayerXbox *)GetHostPlayer())->GetQNetPlayer()->GetXuid(); memset(m_hostGameSessionData.szPlayers[i], 0, XUSER_NAME_SIZE);
// m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All); }
}
// update the LAN advertiser with current player names and count
WinsockNetLayer::UpdateAdvertisePlayerNames(m_hostGameSessionData.playerCount, m_hostGameSessionData.szPlayers);
} }
int CPlatformNetworkManagerStub::RemovePlayerOnSocketClosedThreadProc( void* lpParam ) int CPlatformNetworkManagerStub::RemovePlayerOnSocketClosedThreadProc( void* lpParam )
@@ -728,6 +759,17 @@ void CPlatformNetworkManagerStub::SearchForGames()
info->data.playerCount = lanSessions[i].playerCount; info->data.playerCount = lanSessions[i].playerCount;
info->data.maxPlayers = lanSessions[i].maxPlayers; 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);
}
}
info->sessionId = (ULONGLONG)((unsigned __int64)inet_addr(lanSessions[i].hostIP) | ((unsigned __int64)lanSessions[i].hostPort << 32)); info->sessionId = (ULONGLONG)((unsigned __int64)inet_addr(lanSessions[i].hostIP) | ((unsigned __int64)lanSessions[i].hostPort << 32));
friendsSessions[0].push_back(info); friendsSessions[0].push_back(info);
@@ -760,7 +802,19 @@ vector<FriendSessionInfo *> *CPlatformNetworkManagerStub::GetSessionList(int iPa
bool CPlatformNetworkManagerStub::GetGameSessionInfo(int iPad, SessionID sessionId, FriendSessionInfo *foundSessionInfo) bool CPlatformNetworkManagerStub::GetGameSessionInfo(int iPad, SessionID sessionId, FriendSessionInfo *foundSessionInfo)
{ {
return false; 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 ) void CPlatformNetworkManagerStub::SetSessionsUpdatedCallback( void (*SessionsUpdatedCallback)(LPVOID pParam), LPVOID pSearchParam )
@@ -830,7 +884,19 @@ INetworkPlayer * CPlatformNetworkManagerStub::GetPlayerByXuid(PlayerUID xuid)
INetworkPlayer * CPlatformNetworkManagerStub::GetPlayerBySmallId(unsigned char smallId) INetworkPlayer * CPlatformNetworkManagerStub::GetPlayerBySmallId(unsigned char smallId)
{ {
return getNetworkPlayer(m_pIQNet->GetPlayerBySmallId(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() INetworkPlayer *CPlatformNetworkManagerStub::GetHostPlayer()
@@ -86,6 +86,9 @@ typedef struct _GameSessionData
unsigned char playerCount; // 1 byte unsigned char playerCount; // 1 byte
unsigned char maxPlayers; // 1 byte unsigned char maxPlayers; // 1 byte
GameSessionUID players[MINECRAFT_NET_MAX_PLAYERS];
char szPlayers[MINECRAFT_NET_MAX_PLAYERS][XUSER_NAME_SIZE];
_GameSessionData() _GameSessionData()
{ {
netVersion = 0; netVersion = 0;
@@ -99,6 +102,8 @@ typedef struct _GameSessionData
memset(hostName, 0, sizeof(hostName)); memset(hostName, 0, sizeof(hostName));
playerCount = 0; playerCount = 0;
maxPlayers = MINECRAFT_NET_MAX_PLAYERS; maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
memset(players, 0, sizeof(players));
memset(szPlayers, 0, sizeof(szPlayers));
} }
} GameSessionData; } GameSessionData;
#endif #endif
@@ -321,8 +321,18 @@ bool WinsockNetLayer::JoinGame(const char *ip, int port)
s_isHost = false; s_isHost = false;
s_hostSmallId = 0; s_hostSmallId = 0;
s_connected = false;
s_active = false;
const int maxAttempts = 3;
const int connectTimeoutMs = 3000;
#if defined _WINDOWS64 #if defined _WINDOWS64
if (s_hostConnectionSocket != INVALID_SOCKET)
{
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
}
struct addrinfo hints = {}; struct addrinfo hints = {};
struct addrinfo *result = NULL; struct addrinfo *result = NULL;
@@ -340,27 +350,97 @@ bool WinsockNetLayer::JoinGame(const char *ip, int port)
return false; return false;
} }
s_hostConnectionSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); bool connected = false;
if (s_hostConnectionSocket == INVALID_SOCKET) BYTE assignedSmallId = 0;
for (int attempt = 0; attempt < maxAttempts; ++attempt)
{ {
app.DebugPrintf("socket() failed: %d\n", WSAGetLastError()); s_hostConnectionSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
freeaddrinfo(result); if (s_hostConnectionSocket == INVALID_SOCKET)
return false; {
app.DebugPrintf("socket() failed: %d\n", WSAGetLastError());
break;
}
int noDelay = 1;
setsockopt(s_hostConnectionSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay));
u_long nonBlocking = 1;
ioctlsocket(s_hostConnectionSocket, FIONBIO, &nonBlocking);
iResult = connect(s_hostConnectionSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
fd_set writeFds, exceptFds;
FD_ZERO(&writeFds);
FD_ZERO(&exceptFds);
FD_SET(s_hostConnectionSocket, &writeFds);
FD_SET(s_hostConnectionSocket, &exceptFds);
struct timeval tv;
tv.tv_sec = connectTimeoutMs / 1000;
tv.tv_usec = (connectTimeoutMs % 1000) * 1000;
int selectResult = select(0, NULL, &writeFds, &exceptFds, &tv);
if (selectResult <= 0 || FD_ISSET(s_hostConnectionSocket, &exceptFds))
{
app.DebugPrintf("connect() to %s:%d timed out or failed (attempt %d/%d)\n", ip, port, attempt + 1, maxAttempts);
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
continue;
}
int sockErr = 0;
int sockErrLen = sizeof(sockErr);
getsockopt(s_hostConnectionSocket, SOL_SOCKET, SO_ERROR, (char *)&sockErr, &sockErrLen);
if (sockErr != 0)
{
app.DebugPrintf("connect() to %s:%d failed with SO_ERROR %d (attempt %d/%d)\n", ip, port, sockErr, attempt + 1, maxAttempts);
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
continue;
}
}
else
{
app.DebugPrintf("connect() to %s:%d failed (attempt %d/%d): %d\n", ip, port, attempt + 1, maxAttempts, err);
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
continue;
}
}
u_long blocking = 0;
ioctlsocket(s_hostConnectionSocket, FIONBIO, &blocking);
DWORD recvTimeout = 3000;
setsockopt(s_hostConnectionSocket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&recvTimeout, sizeof(recvTimeout));
BYTE assignBuf[1];
int bytesRecv = recv(s_hostConnectionSocket, (char *)assignBuf, 1, 0);
if (bytesRecv != 1)
{
app.DebugPrintf("Failed to receive small ID assignment from host (attempt %d/%d)\n", attempt + 1, maxAttempts);
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
continue;
}
assignedSmallId = assignBuf[0];
connected = true;
break;
} }
int noDelay = 1;
setsockopt(s_hostConnectionSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay));
iResult = connect(s_hostConnectionSocket, result->ai_addr, (int)result->ai_addrlen);
freeaddrinfo(result); freeaddrinfo(result);
if (iResult == SOCKET_ERROR) #elif defined _XBOX
if (s_hostConnectionSocket != INVALID_SOCKET)
{ {
app.DebugPrintf("connect() to %s:%d failed: %d\n", ip, port, WSAGetLastError());
closesocket(s_hostConnectionSocket); closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET; s_hostConnectionSocket = INVALID_SOCKET;
return false;
} }
#elif defined _XBOX
XNDNS *pDns = NULL; XNDNS *pDns = NULL;
int iResult = XNetDnsLookup(ip, NULL, &pDns); int iResult = XNetDnsLookup(ip, NULL, &pDns);
if (iResult != 0 || pDns == NULL) if (iResult != 0 || pDns == NULL)
@@ -387,25 +467,85 @@ bool WinsockNetLayer::JoinGame(const char *ip, int port)
addr.sin_addr = pDns->aina[0]; addr.sin_addr = pDns->aina[0];
XNetDnsRelease(pDns); XNetDnsRelease(pDns);
s_hostConnectionSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); bool connected = false;
if (s_hostConnectionSocket == INVALID_SOCKET) BYTE assignedSmallId = 0;
{
app.DebugPrintf("socket() failed: %d\n", WSAGetLastError());
return false;
}
int noDelay = 1; for (int attempt = 0; attempt < maxAttempts; ++attempt)
setsockopt(s_hostConnectionSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay));
iResult = connect(s_hostConnectionSocket, (struct sockaddr*)&addr, sizeof(addr));
if (iResult == SOCKET_ERROR)
{ {
app.DebugPrintf("connect() to %s:%d failed: %d\n", ip, port, WSAGetLastError()); s_hostConnectionSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
closesocket(s_hostConnectionSocket); if (s_hostConnectionSocket == INVALID_SOCKET)
s_hostConnectionSocket = INVALID_SOCKET; {
return false; app.DebugPrintf("socket() failed: %d\n", WSAGetLastError());
break;
}
int noDelay = 1;
setsockopt(s_hostConnectionSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay));
u_long nonBlocking = 1;
ioctlsocket(s_hostConnectionSocket, FIONBIO, &nonBlocking);
iResult = connect(s_hostConnectionSocket, (struct sockaddr*)&addr, sizeof(addr));
if (iResult == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
fd_set writeFds, exceptFds;
FD_ZERO(&writeFds);
FD_ZERO(&exceptFds);
FD_SET(s_hostConnectionSocket, &writeFds);
FD_SET(s_hostConnectionSocket, &exceptFds);
struct timeval tv;
tv.tv_sec = connectTimeoutMs / 1000;
tv.tv_usec = (connectTimeoutMs % 1000) * 1000;
int selectResult = select(0, NULL, &writeFds, &exceptFds, &tv);
if (selectResult <= 0 || FD_ISSET(s_hostConnectionSocket, &exceptFds))
{
app.DebugPrintf("connect() to %s:%d timed out or failed (attempt %d/%d)\n", ip, port, attempt + 1, maxAttempts);
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
continue;
}
}
else
{
app.DebugPrintf("connect() to %s:%d failed (attempt %d/%d): %d\n", ip, port, attempt + 1, maxAttempts, err);
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
continue;
}
}
u_long blocking = 0;
ioctlsocket(s_hostConnectionSocket, FIONBIO, &blocking);
DWORD recvTimeout = 3000;
setsockopt(s_hostConnectionSocket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&recvTimeout, sizeof(recvTimeout));
BYTE assignBuf[1];
int bytesRecv = recv(s_hostConnectionSocket, (char *)assignBuf, 1, 0);
if (bytesRecv != 1)
{
app.DebugPrintf("Failed to receive small ID assignment from host (attempt %d/%d)\n", attempt + 1, maxAttempts);
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
continue;
}
assignedSmallId = assignBuf[0];
connected = true;
break;
} }
#elif defined __PS3__ #elif defined __PS3__
if (s_hostConnectionSocket != -1)
{
socketclose(s_hostConnectionSocket);
s_hostConnectionSocket = -1;
}
struct sockaddr_in addr = {}; struct sockaddr_in addr = {};
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
@@ -418,38 +558,108 @@ bool WinsockNetLayer::JoinGame(const char *ip, int port)
return false; return false;
} }
int iResult = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); bool connected = false;
s_hostConnectionSocket = iResult; BYTE assignedSmallId = 0;
if (s_hostConnectionSocket < 0)
{
app.DebugPrintf("socket() failed: %d\n", s_hostConnectionSocket);
return false;
}
int noDelay = 1; for (int attempt = 0; attempt < maxAttempts; ++attempt)
setsockopt(s_hostConnectionSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay));
iResult = connect(s_hostConnectionSocket, (struct sockaddr*)&addr, sizeof(addr));
if (iResult < 0)
{ {
app.DebugPrintf("connect() to %s:%d failed: %d\n", ip, port, s_hostConnectionSocket); int iResult = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
socketclose(s_hostConnectionSocket); s_hostConnectionSocket = iResult;
s_hostConnectionSocket = -1; if (s_hostConnectionSocket < 0)
return false; {
app.DebugPrintf("socket() failed: %d\n", s_hostConnectionSocket);
break;
}
int noDelay = 1;
setsockopt(s_hostConnectionSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay));
int nonBlocking = 1;
setsockopt(s_hostConnectionSocket, SOL_SOCKET, SO_NBIO, &nonBlocking, sizeof(nonBlocking));
iResult = connect(s_hostConnectionSocket, (struct sockaddr*)&addr, sizeof(addr));
if (iResult < 0)
{
int err = sys_net_errno;
if (err == SYS_NET_EINPROGRESS)
{
fd_set writeFds, exceptFds;
FD_ZERO(&writeFds);
FD_ZERO(&exceptFds);
FD_SET(s_hostConnectionSocket, &writeFds);
FD_SET(s_hostConnectionSocket, &exceptFds);
struct timeval tv;
tv.tv_sec = connectTimeoutMs / 1000;
tv.tv_usec = (connectTimeoutMs % 1000) * 1000;
int selectResult = socketselect(s_hostConnectionSocket + 1, NULL, &writeFds, &exceptFds, &tv);
if (selectResult <= 0 || FD_ISSET(s_hostConnectionSocket, &exceptFds))
{
app.DebugPrintf("connect() to %s:%d timed out or failed (attempt %d/%d)\n", ip, port, attempt + 1, maxAttempts);
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
continue;
}
int sockErr = 0;
socklen_t sockErrLen = sizeof(sockErr);
getsockopt(s_hostConnectionSocket, SOL_SOCKET, SO_ERROR, (char *)&sockErr, &sockErrLen);
if (sockErr != 0)
{
app.DebugPrintf("connect() to %s:%d failed with SO_ERROR %d (attempt %d/%d)\n", ip, port, sockErr, attempt + 1, maxAttempts);
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
continue;
}
}
else
{
app.DebugPrintf("connect() to %s:%d failed (attempt %d/%d): %d\n", ip, port, attempt + 1, maxAttempts, err);
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
continue;
}
}
int blocking = 0;
setsockopt(s_hostConnectionSocket, SOL_SOCKET, SO_NBIO, &blocking, sizeof(blocking));
DWORD recvTimeout = 3000;
setsockopt(s_hostConnectionSocket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&recvTimeout, sizeof(recvTimeout));
/*
iResult = connect(s_hostConnectionSocket, (struct sockaddr*)&addr, sizeof(addr));
if (iResult < 0)
{
app.DebugPrintf("connect() to %s:%d failed: %d\n", ip, port, s_hostConnectionSocket);
socketclose(s_hostConnectionSocket);
s_hostConnectionSocket = -1;
return false;
}
*/
BYTE assignBuf[1];
int bytesRecv = recv(s_hostConnectionSocket, (char *)assignBuf, 1, 0);
if (bytesRecv != 1)
{
app.DebugPrintf("Failed to receive small ID assignment from host (attempt %d/%d)\n", attempt + 1, maxAttempts);
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
continue;
}
assignedSmallId = assignBuf[0];
connected = true;
break;
} }
#endif #endif
BYTE assignBuf[1]; if (!connected)
int bytesRecv = recv(s_hostConnectionSocket, (char *)assignBuf, 1, 0);
if (bytesRecv != 1)
{ {
app.DebugPrintf("Failed to receive small ID assignment from host\n");
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
return false; return false;
} }
s_localSmallId = assignBuf[0]; s_localSmallId = assignedSmallId;
app.DebugPrintf("Win64 LAN: Connected to %s:%d, assigned smallId=%d\n", ip, port, s_localSmallId); app.DebugPrintf("LAN: Connected to %s:%d, assigned smallId=%d\n", ip, port, s_localSmallId);
s_active = true; s_active = true;
s_connected = true; s_connected = true;
@@ -698,7 +908,8 @@ int WinsockNetLayer::RecvThreadProc(LPVOID param)
BYTE clientSmallId = s_connections[connIdx].smallId; BYTE clientSmallId = s_connections[connIdx].smallId;
LeaveCriticalSection(&s_connectionsLock); LeaveCriticalSection(&s_connectionsLock);
BYTE *recvBuf = new BYTE[WIN64_NET_RECV_BUFFER_SIZE]; std::vector<BYTE> recvBuf;
recvBuf.resize(WIN64_NET_RECV_BUFFER_SIZE);
while (s_active) while (s_active)
{ {
@@ -709,33 +920,47 @@ int WinsockNetLayer::RecvThreadProc(LPVOID param)
break; break;
} }
int packetSize = (header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3]; int packetSize =
((uint32_t)header[0] << 24) |
((uint32_t)header[1] << 16) |
((uint32_t)header[2] << 8) |
((uint32_t)header[3]);
if (packetSize <= 0 || packetSize > WIN64_NET_RECV_BUFFER_SIZE) if (packetSize <= 0 || packetSize > WIN64_NET_MAX_PACKET_SIZE)
{ {
app.DebugPrintf("Win64 LAN: Invalid packet size %d from client smallId=%d\n", packetSize, clientSmallId); app.DebugPrintf("LAN: Invalid packet size %d from client smallId=%d (max=%d)\n",
packetSize,
clientSmallId,
(int)WIN64_NET_MAX_PACKET_SIZE);
break; break;
} }
if (!RecvExact(sock, recvBuf, packetSize)) if ((int)recvBuf.size() < packetSize)
{ {
app.DebugPrintf("Win64 LAN: Client smallId=%d disconnected (body)\n", clientSmallId); recvBuf.resize(packetSize);
app.DebugPrintf("LAN: Resized host recv buffer to %d bytes for client smallId=%d\n", packetSize, clientSmallId);
}
if (!RecvExact(sock, &recvBuf[0], packetSize))
{
app.DebugPrintf("LAN: Client smallId=%d disconnected (body)\n", clientSmallId);
break; break;
} }
HandleDataReceived(clientSmallId, s_hostSmallId, recvBuf, packetSize); HandleDataReceived(clientSmallId, s_hostSmallId, &recvBuf[0], packetSize);
} }
delete[] recvBuf;
EnterCriticalSection(&s_connectionsLock); EnterCriticalSection(&s_connectionsLock);
for (size_t i = 0; i < s_connections.size(); i++) for (size_t i = 0; i < s_connections.size(); i++)
{ {
if (s_connections[i].smallId == clientSmallId) if (s_connections[i].smallId == clientSmallId)
{ {
s_connections[i].active = false; s_connections[i].active = false;
closesocket(s_connections[i].tcpSocket); if (s_connections[i].tcpSocket != INVALID_SOCKET)
s_connections[i].tcpSocket = INVALID_SOCKET; {
closesocket(s_connections[i].tcpSocket);
s_connections[i].tcpSocket = INVALID_SOCKET;
}
break; break;
} }
} }
@@ -769,9 +994,26 @@ void WinsockNetLayer::PushFreeSmallId(BYTE smallId)
LeaveCriticalSection(&s_freeSmallIdLock); LeaveCriticalSection(&s_freeSmallIdLock);
} }
void WinsockNetLayer::CloseConnectionBySmallId(BYTE smallId)
{
EnterCriticalSection(&s_connectionsLock);
for (size_t i = 0; i < s_connections.size(); i++)
{
if (s_connections[i].smallId == smallId && s_connections[i].active && s_connections[i].tcpSocket != INVALID_SOCKET)
{
closesocket(s_connections[i].tcpSocket);
s_connections[i].tcpSocket = INVALID_SOCKET;
app.DebugPrintf("Win64 LAN: Force-closed TCP connection for smallId=%d\n", smallId);
break;
}
}
LeaveCriticalSection(&s_connectionsLock);
}
int WinsockNetLayer::ClientRecvThreadProc(LPVOID param) int WinsockNetLayer::ClientRecvThreadProc(LPVOID param)
{ {
BYTE *recvBuf = new BYTE[WIN64_NET_RECV_BUFFER_SIZE]; std::vector<BYTE> recvBuf;
recvBuf.resize(WIN64_NET_RECV_BUFFER_SIZE);
#if defined _WINDOWS64 || defined _XBOX #if defined _WINDOWS64 || defined _XBOX
while (s_active && s_hostConnectionSocket != INVALID_SOCKET) while (s_active && s_hostConnectionSocket != INVALID_SOCKET)
@@ -782,29 +1024,33 @@ int WinsockNetLayer::ClientRecvThreadProc(LPVOID param)
BYTE header[4]; BYTE header[4];
if (!RecvExact(s_hostConnectionSocket, header, 4)) if (!RecvExact(s_hostConnectionSocket, header, 4))
{ {
app.DebugPrintf("Win64 LAN: Disconnected from host (header)\n"); app.DebugPrintf("LAN: Disconnected from host (header)\n");
break; break;
} }
int packetSize = (header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3]; int packetSize = (header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3];
if (packetSize <= 0 || packetSize > WIN64_NET_RECV_BUFFER_SIZE) if (packetSize <= 0 || packetSize > WIN64_NET_MAX_PACKET_SIZE)
{ {
app.DebugPrintf("Win64 LAN: Invalid packet size %d from host\n", packetSize); app.DebugPrintf("LAN: Invalid packet size %d from host\n", packetSize);
break; break;
} }
if (!RecvExact(s_hostConnectionSocket, recvBuf, packetSize)) if ((int)recvBuf.size() < packetSize)
{ {
app.DebugPrintf("Win64 LAN: Disconnected from host (body)\n"); recvBuf.resize(packetSize);
app.DebugPrintf("LAN: Resized client recv buffer to %d bytes\n", packetSize);
}
if (!RecvExact(s_hostConnectionSocket, &recvBuf[0], packetSize))
{
app.DebugPrintf("LAN: Disconnected from host (body)\n");
break; break;
} }
HandleDataReceived(s_hostSmallId, s_localSmallId, recvBuf, packetSize); HandleDataReceived(s_hostSmallId, s_localSmallId, &recvBuf[0], packetSize);
} }
delete[] recvBuf;
s_connected = false; s_connected = false;
return 0; return 0;
} }
@@ -887,6 +1133,18 @@ void WinsockNetLayer::UpdateAdvertisePlayerCount(BYTE count)
LeaveCriticalSection(&s_advertiseLock); LeaveCriticalSection(&s_advertiseLock);
} }
void WinsockNetLayer::UpdateAdvertisePlayerNames(BYTE count, const char playerNames[][XUSER_NAME_SIZE])
{
EnterCriticalSection(&s_advertiseLock);
memset(s_advertiseData.playerNames, 0, sizeof(s_advertiseData.playerNames));
s_advertiseData.playerCount = count;
for (int i = 0; i < count && i < 8; i++)
{
memcpy(s_advertiseData.playerNames[i], playerNames[i], XUSER_NAME_SIZE);
}
LeaveCriticalSection(&s_advertiseLock);
}
void WinsockNetLayer::UpdateAdvertiseJoinable(bool joinable) void WinsockNetLayer::UpdateAdvertiseJoinable(bool joinable)
{ {
EnterCriticalSection(&s_advertiseLock); EnterCriticalSection(&s_advertiseLock);
@@ -1028,16 +1286,18 @@ void WinsockNetLayer::StopDiscovery()
std::vector<Win64LANSession> WinsockNetLayer::GetDiscoveredSessions() std::vector<Win64LANSession> WinsockNetLayer::GetDiscoveredSessions()
{ {
std::vector<Win64LANSession> result; std::vector<Win64LANSession> result;
EnterCriticalSection(&s_discoveryLock); if (TryEnterCriticalSection(&s_discoveryLock))
result = s_discoveredSessions; {
LeaveCriticalSection(&s_discoveryLock); result = s_discoveredSessions;
LeaveCriticalSection(&s_discoveryLock);
}
return result; return result;
} }
int WinsockNetLayer::DiscoveryThreadProc(LPVOID param) int WinsockNetLayer::DiscoveryThreadProc(LPVOID param)
{ {
app.DebugPrintf("Discovery thread started\n"); app.DebugPrintf("Discovery thread started\n");
char recvBuf[512]; char recvBuf[1024];
while (s_discovering) while (s_discovering)
{ {
@@ -1111,6 +1371,7 @@ int WinsockNetLayer::DiscoveryThreadProc(LPVOID param)
s_discoveredSessions[i].subTexturePackId = broadcast->subTexturePackId; s_discoveredSessions[i].subTexturePackId = broadcast->subTexturePackId;
s_discoveredSessions[i].isJoinable = (broadcast->isJoinable != 0); s_discoveredSessions[i].isJoinable = (broadcast->isJoinable != 0);
s_discoveredSessions[i].lastSeenTick = now; s_discoveredSessions[i].lastSeenTick = now;
memcpy(s_discoveredSessions[i].playerNames, broadcast->playerNames, sizeof(broadcast->playerNames));
found = true; found = true;
break; break;
} }
@@ -1137,6 +1398,7 @@ int WinsockNetLayer::DiscoveryThreadProc(LPVOID param)
session.subTexturePackId = broadcast->subTexturePackId; session.subTexturePackId = broadcast->subTexturePackId;
session.isJoinable = (broadcast->isJoinable != 0); session.isJoinable = (broadcast->isJoinable != 0);
session.lastSeenTick = now; session.lastSeenTick = now;
memcpy(session.playerNames, broadcast->playerNames, sizeof(broadcast->playerNames));
s_discoveredSessions.push_back(session); s_discoveredSessions.push_back(session);
app.DebugPrintf("LAN: Discovered game \"%ls\" at %s:%d\n", app.DebugPrintf("LAN: Discovered game \"%ls\" at %s:%d\n",
@@ -4,6 +4,7 @@
#include <WinSock2.h> #include <WinSock2.h>
#include <WS2tcpip.h> #include <WS2tcpip.h>
#elif defined _XBOX #elif defined _XBOX
#include <stdint.h>
#include <winsockx.h> #include <winsockx.h>
#include <xtl.h> #include <xtl.h>
#elif defined __PS3__ #elif defined __PS3__
@@ -15,6 +16,8 @@
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/time.h>
#include <sys/select.h>
#endif #endif
#include <vector> #include <vector>
@@ -27,6 +30,7 @@
#define WIN64_NET_DEFAULT_PORT 25565 #define WIN64_NET_DEFAULT_PORT 25565
#define WIN64_NET_MAX_CLIENTS 7 #define WIN64_NET_MAX_CLIENTS 7
#define WIN64_NET_RECV_BUFFER_SIZE 65536 #define WIN64_NET_RECV_BUFFER_SIZE 65536
#define WIN64_NET_MAX_PACKET_SIZE (4 * 1024 * 1024)
#define WIN64_LAN_DISCOVERY_PORT 25566 #define WIN64_LAN_DISCOVERY_PORT 25566
#define WIN64_LAN_BROADCAST_MAGIC 0x4D434C4E #define WIN64_LAN_BROADCAST_MAGIC 0x4D434C4E
@@ -50,6 +54,7 @@ struct Win64LANBroadcast
DWORD texturePackParentId; DWORD texturePackParentId;
BYTE subTexturePackId; BYTE subTexturePackId;
BYTE isJoinable; BYTE isJoinable;
char playerNames[8][XUSER_NAME_SIZE];
}; };
#pragma pack(pop) #pragma pack(pop)
@@ -66,6 +71,7 @@ struct Win64LANSession
unsigned char subTexturePackId; unsigned char subTexturePackId;
bool isJoinable; bool isJoinable;
DWORD lastSeenTick; DWORD lastSeenTick;
char playerNames[8][XUSER_NAME_SIZE];
}; };
struct Win64RemoteConnection struct Win64RemoteConnection
@@ -101,11 +107,13 @@ public:
static bool PopDisconnectedSmallId(BYTE *outSmallId); static bool PopDisconnectedSmallId(BYTE *outSmallId);
static void PushFreeSmallId(BYTE smallId); static void PushFreeSmallId(BYTE smallId);
static void CloseConnectionBySmallId(BYTE smallId);
static bool StartAdvertising(int gamePort, const wchar_t *hostName, unsigned int gameSettings, unsigned int texPackId, unsigned char subTexId, unsigned short netVer); static bool StartAdvertising(int gamePort, const wchar_t *hostName, unsigned int gameSettings, unsigned int texPackId, unsigned char subTexId, unsigned short netVer);
static void StopAdvertising(); static void StopAdvertising();
static void UpdateAdvertisePlayerCount(BYTE count); static void UpdateAdvertisePlayerCount(BYTE count);
static void UpdateAdvertiseJoinable(bool joinable); static void UpdateAdvertiseJoinable(bool joinable);
static void UpdateAdvertisePlayerNames(BYTE count, const char playerNames[][XUSER_NAME_SIZE]);
static bool StartDiscovery(); static bool StartDiscovery();
static void StopDiscovery(); static void StopDiscovery();
@@ -105,6 +105,21 @@ void UIScene_JoinMenu::tick()
break; break;
} }
} }
#elif defined(_WINDOWS64) || defined(DISABLE_PSN)
for( int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++ )
{
if( m_selectedSession->data.players[i] != 0 && m_selectedSession->data.szPlayers[i][0] != 0 )
{
string playerName(m_selectedSession->data.szPlayers[i], XUSER_NAME_SIZE);
size_t end = playerName.find('\0');
if (end != string::npos) playerName.resize(end);
m_buttonListPlayers.addItem(playerName);
}
else
{
break;
}
}
#endif #endif
m_labelLabels[eLabel_Difficulty].init(app.GetString(IDS_LABEL_DIFFICULTY)); m_labelLabels[eLabel_Difficulty].init(app.GetString(IDS_LABEL_DIFFICULTY));
@@ -601,6 +616,30 @@ void UIScene_JoinMenu::handleTimerComplete(int id)
playersList.SetCurSel(selectedIndex); playersList.SetCurSel(selectedIndex);
} }
#endif #endif
#if defined(_WINDOWS64) || defined(DISABLE_PSN)
{
bool success = g_NetworkManager.GetGameSessionInfo(m_iPad, m_selectedSession->sessionId, m_selectedSession);
if (success)
{
m_buttonListPlayers.clearList();
for (unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i)
{
if (m_selectedSession->data.players[i] != 0 && m_selectedSession->data.szPlayers[i][0] != 0)
{
string playerName(m_selectedSession->data.szPlayers[i], XUSER_NAME_SIZE);
size_t end = playerName.find('\0');
if (end != string::npos) playerName.resize(end);
m_buttonListPlayers.addItem(playerName);
}
else
{
break;
}
}
}
}
#endif
addTimer(UPDATE_PLAYERS_TIMER_ID, UPDATE_PLAYERS_TIMER_TIME);
} }
break; break;
}; };
@@ -46,6 +46,7 @@ UIScene_SignEntryMenu::UIScene_SignEntryMenu(int iPad, void *_initData, UILayer
m_signRows[i].SetTitleAndText(IDS_SIGN_TITLE,IDS_SIGN_TITLE_TEXT); m_signRows[i].SetTitleAndText(IDS_SIGN_TITLE,IDS_SIGN_TITLE_TEXT);
#endif #endif
m_textInputLines[i].init(m_sign->GetMessage(i).c_str(), i); m_textInputLines[i].init(m_sign->GetMessage(i).c_str(), i);
m_textInputLines[i].SetCharLimit(15);
} }
parentLayer->addComponent(iPad,eUIComponent_MenuBackground); parentLayer->addComponent(iPad,eUIComponent_MenuBackground);
@@ -150,6 +151,7 @@ int UIScene_SignEntryMenu::KeyboardCompleteCallback(LPVOID lpParam,bool bRes)
uint16_t pchText[128]; uint16_t pchText[128];
ZeroMemory(pchText, 128 * sizeof(uint16_t) ); ZeroMemory(pchText, 128 * sizeof(uint16_t) );
InputManager.GetText(pchText); InputManager.GetText(pchText);
pchText[15] = 0;
pClass->m_textInputLines[pClass->m_iEditingLine].setLabel((wchar_t *)pchText); pClass->m_textInputLines[pClass->m_iEditingLine].setLabel((wchar_t *)pchText);
} }
return 0; return 0;
+32 -13
View File
@@ -178,7 +178,7 @@ void PIXSetMarkerDeprecated(int a, char *b, ...) {}
bool IsEqualXUID(PlayerUID a, PlayerUID b) bool IsEqualXUID(PlayerUID a, PlayerUID b)
{ {
#if !defined(DISABLE_PSN) && defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) || defined(_DURANGO) #if !defined(DISABLE_PSN) && defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) || defined(_DURANGO) || defined(_WINDOWS64) || defined(_XBOX)
return (a == b); return (a == b);
#elif defined(DISABLE_PSN) && defined(__PS3__) #elif defined(DISABLE_PSN) && defined(__PS3__)
return (a.XUID == b.XUID); return (a.XUID == b.XUID);
@@ -464,13 +464,17 @@ void Win64_SetupRemoteQNetPlayer(IQNetPlayer *player, BYTE smallId, bool isHost,
IQNet::s_playerCount = smallId + 1; IQNet::s_playerCount = smallId + 1;
} }
static bool Win64_IsActivePlayer(IQNetPlayer *p, DWORD index);
HRESULT IQNet::AddLocalPlayerByUserIndex(DWORD dwUserIndex){ return S_OK; } HRESULT IQNet::AddLocalPlayerByUserIndex(DWORD dwUserIndex){ return S_OK; }
IQNetPlayer *IQNet::GetHostPlayer() { return &m_player[0]; } IQNetPlayer *IQNet::GetHostPlayer() { return &m_player[0]; }
IQNetPlayer *IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex) IQNetPlayer *IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex)
{ {
if (s_isHosting) if (s_isHosting)
{ {
if (dwUserIndex < MINECRAFT_NET_MAX_PLAYERS && !m_player[dwUserIndex].m_isRemote) if (dwUserIndex < MINECRAFT_NET_MAX_PLAYERS &&
!m_player[dwUserIndex].m_isRemote &&
Win64_IsActivePlayer(&m_player[dwUserIndex], dwUserIndex))
return &m_player[dwUserIndex]; return &m_player[dwUserIndex];
return NULL; return NULL;
} }
@@ -478,7 +482,7 @@ IQNetPlayer *IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex)
return NULL; return NULL;
for (DWORD i = 0; i < s_playerCount; i++) for (DWORD i = 0; i < s_playerCount; i++)
{ {
if (!m_player[i].m_isRemote) if (!m_player[i].m_isRemote && Win64_IsActivePlayer(&m_player[i], i))
return &m_player[i]; return &m_player[i];
} }
return NULL; return NULL;
@@ -504,19 +508,21 @@ IQNetPlayer *IQNet::GetPlayerByIndex(DWORD dwPlayerIndex)
} }
IQNetPlayer *IQNet::GetPlayerBySmallId(BYTE SmallId) IQNetPlayer *IQNet::GetPlayerBySmallId(BYTE SmallId)
{ {
for (DWORD i = 0; i < s_playerCount; i++) if (SmallId >= MINECRAFT_NET_MAX_PLAYERS)
{ return NULL;
if (m_player[i].m_smallId == SmallId && Win64_IsActivePlayer(&m_player[i], i)) return &m_player[i];
} m_player[SmallId].m_smallId = SmallId;
return NULL; if (SmallId >= s_playerCount)
s_playerCount = SmallId + 1;
return &m_player[SmallId];
} }
IQNetPlayer *IQNet::GetPlayerByXuid(PlayerUID xuid) IQNetPlayer *IQNet::GetPlayerByXuid(PlayerUID xuid)
{ {
for (DWORD i = 0; i < s_playerCount; i++) for (DWORD i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++)
{ {
if (Win64_IsActivePlayer(&m_player[i], i) && m_player[i].GetXuid() == xuid) return &m_player[i]; if (Win64_IsActivePlayer(&m_player[i], i) && m_player[i].GetXuid() == xuid) return &m_player[i];
} }
return &m_player[0]; return NULL;
} }
DWORD IQNet::GetPlayerCount() DWORD IQNet::GetPlayerCount()
{ {
@@ -531,15 +537,28 @@ QNET_STATE IQNet::GetState() { return _iQNetStubState; }
bool IQNet::IsHost() { return s_isHosting; } bool IQNet::IsHost() { return s_isHosting; }
HRESULT IQNet::JoinGameFromInviteInfo(DWORD dwUserIndex, DWORD dwUserMask, const INVITE_INFO *pInviteInfo) { return S_OK; } HRESULT IQNet::JoinGameFromInviteInfo(DWORD dwUserIndex, DWORD dwUserMask, const INVITE_INFO *pInviteInfo) { return S_OK; }
void IQNet::HostGame() { _iQNetStubState = QNET_STATE_SESSION_STARTING; s_isHosting = true; } void IQNet::HostGame() { _iQNetStubState = QNET_STATE_SESSION_STARTING; s_isHosting = true; }
void IQNet::ClientJoinGame() { _iQNetStubState = QNET_STATE_SESSION_STARTING; s_isHosting = false; } void IQNet::ClientJoinGame()
{
_iQNetStubState = QNET_STATE_SESSION_STARTING;
s_isHosting = false;
for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++)
{
m_player[i].m_smallId = (BYTE)i;
m_player[i].m_isRemote = true;
m_player[i].m_isHostPlayer = false;
m_player[i].m_gamertag[0] = 0;
m_player[i].SetCustomDataValue(0);
}
}
void IQNet::EndGame() void IQNet::EndGame()
{ {
_iQNetStubState = QNET_STATE_IDLE; _iQNetStubState = QNET_STATE_IDLE;
s_isHosting = false; s_isHosting = false;
s_playerCount = 1; s_playerCount = 1;
for (int i = 1; i < MINECRAFT_NET_MAX_PLAYERS; i++) for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++)
{ {
m_player[i].m_smallId = 0; m_player[i].m_smallId = (BYTE)i;
m_player[i].m_isRemote = false; m_player[i].m_isRemote = false;
m_player[i].m_isHostPlayer = false; m_player[i].m_isHostPlayer = false;
m_player[i].m_gamertag[0] = 0; m_player[i].m_gamertag[0] = 0;
+2 -2
View File
@@ -160,7 +160,7 @@ bool PlayerUID::isPrimaryUser() const /* only true if we're on the local machine
#ifndef DISABLE_PSN
GameSessionUID::GameSessionUID() GameSessionUID::GameSessionUID()
{ {
memset(this,0,sizeof(GameSessionUID)); memset(this,0,sizeof(GameSessionUID));
@@ -194,4 +194,4 @@ GameSessionUID& GameSessionUID::operator=(const PlayerUID& rhs)
m_bSignedIntoPSN = rhs.isSignedIntoPSN(); m_bSignedIntoPSN = rhs.isSignedIntoPSN();
return *this; return *this;
} }
#endif
+3 -1
View File
@@ -55,7 +55,7 @@ private:
#ifndef DISABLE_PSN
class GameSessionUID class GameSessionUID
{ {
char m_onlineID[SCE_NET_NP_ONLINEID_MAX_LENGTH]; char m_onlineID[SCE_NET_NP_ONLINEID_MAX_LENGTH];
@@ -74,3 +74,5 @@ public:
int getQuadrant() const { return m_quadrant; } int getQuadrant() const { return m_quadrant; }
bool isSignedIntoPSN() const { return m_bSignedIntoPSN; } bool isSignedIntoPSN() const { return m_bSignedIntoPSN; }
}; };
#endif
+3 -1
View File
@@ -108,7 +108,9 @@ void PlayerList::placeNewPlayer(Connection *connection, shared_ptr<ServerPlayer>
{ {
NetworkPlayerXbox *nxp = (NetworkPlayerXbox *)networkPlayer; NetworkPlayerXbox *nxp = (NetworkPlayerXbox *)networkPlayer;
IQNetPlayer *qnp = nxp->GetQNetPlayer(); IQNetPlayer *qnp = nxp->GetQNetPlayer();
wcsncpy(qnp->m_gamertag, player->name.c_str(), 32); wcsncpy(qnp->m_gamertag, player->name.c_str(), 31);
qnp->m_gamertag[31] = L'\0';
g_NetworkManager.UpdateAndSetGameSessionData();
} }
#endif #endif
@@ -26,6 +26,8 @@ void CConsoleMinecraftApp::StoreLaunchData()
} }
void CConsoleMinecraftApp::ExitGame() void CConsoleMinecraftApp::ExitGame()
{ {
extern HWND g_hWnd;
PostMessage(g_hWnd, WM_CLOSE, 0, 0);
} }
void CConsoleMinecraftApp::FatalLoadError() void CConsoleMinecraftApp::FatalLoadError()
{ {
@@ -17,6 +17,7 @@
#include "..\..\Minecraft.World\Vec3.h" #include "..\..\Minecraft.World\Vec3.h"
#include "..\..\Minecraft.World\Level.h" #include "..\..\Minecraft.World\Level.h"
#include "..\..\Minecraft.World\net.minecraft.world.level.tile.h" #include "..\..\Minecraft.World\net.minecraft.world.level.tile.h"
#include "..\MultiplayerLocalPlayer.h"
#include "..\ClientConnection.h" #include "..\ClientConnection.h"
#include "..\User.h" #include "..\User.h"
@@ -261,7 +262,7 @@ HRESULT InitD3D( IDirect3DDevice9 **ppDevice,
pd3dPP->EnableAutoDepthStencil = TRUE; pd3dPP->EnableAutoDepthStencil = TRUE;
pd3dPP->AutoDepthStencilFormat = D3DFMT_D24S8; pd3dPP->AutoDepthStencilFormat = D3DFMT_D24S8;
pd3dPP->SwapEffect = D3DSWAPEFFECT_DISCARD; pd3dPP->SwapEffect = D3DSWAPEFFECT_DISCARD;
pd3dPP->PresentationInterval = D3DPRESENT_INTERVAL_ONE; pd3dPP->PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
//pd3dPP->Flags = D3DPRESENTFLAG_NO_LETTERBOX; //pd3dPP->Flags = D3DPRESENTFLAG_NO_LETTERBOX;
//ERR[D3D]: Can't set D3DPRESENTFLAG_NO_LETTERBOX when wide-screen is enabled //ERR[D3D]: Can't set D3DPRESENTFLAG_NO_LETTERBOX when wide-screen is enabled
// in the launcher/dashboard. // in the launcher/dashboard.
@@ -551,6 +552,8 @@ app.DebugPrintf("width: %d, height: %d\n", width, height);
descDSView.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDSView.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
descDSView.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; descDSView.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
descDSView.Texture2D.MipSlice = 0; descDSView.Texture2D.MipSlice = 0;
// when would this ever be a non-garbage value?
descDSView.Flags = 0;
hr = g_pd3dDevice->CreateDepthStencilView(g_pDepthStencilBuffer, &descDSView, &g_pDepthStencilView); hr = g_pd3dDevice->CreateDepthStencilView(g_pDepthStencilBuffer, &descDSView, &g_pDepthStencilView);
+1
View File
@@ -52,6 +52,7 @@ typedef SQRNetworkManager_Orbis::PresenceSyncInfo INVITE_INFO;
typedef SQRNetworkManager::SessionID SessionID; typedef SQRNetworkManager::SessionID SessionID;
typedef SQRNetworkManager::PresenceSyncInfo INVITE_INFO; typedef SQRNetworkManager::PresenceSyncInfo INVITE_INFO;
#else #else
typedef ULONGLONG GameSessionUID;
typedef ULONGLONG SessionID; typedef ULONGLONG SessionID;
class INVITE_INFO; class INVITE_INFO;
#endif #endif