ps4 support final

This commit is contained in:
NaN
2026-08-04 01:31:46 -04:00
parent ada85f871e
commit d06e2e5eba
3 changed files with 104 additions and 10 deletions
@@ -3,6 +3,11 @@
#include "NetworkSocketLayer.h"
#include "..\..\Common\Network\PlatformNetworkManager.h"
#include "..\..\..\Minecraft.World\Socket.h"
#ifdef __ORBIS__
#include <libnetctl.h>
#endif
static const DWORD NETWORK_LAN_DISCOVERY_QUERY_MAGIC = 0x4D435152;
#if defined _WINDOWS64 || defined _XBOX
SOCKET NetworkSocketLayer::s_listenSocket = INVALID_SOCKET;
@@ -1290,7 +1295,6 @@ int NetworkSocketLayer::AdvertiseThreadProc(LPVOID param)
app.DebugPrintf("PS3 LAN: Broadcast sendto failed: %d\n", sent);
}
#endif
C4JThread::Sleep(1000);
}
@@ -1299,8 +1303,14 @@ int NetworkSocketLayer::AdvertiseThreadProc(LPVOID param)
bool NetworkSocketLayer::StartDiscovery()
{
if (s_discovering) return true;
if (!s_initialized) return false;
if (s_discovering)
{
return true;
}
if (!s_initialized)
{
return false;
}
s_discoverySock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
#if defined _WINDOWS64 || defined _XBOX
@@ -1321,6 +1331,8 @@ bool NetworkSocketLayer::StartDiscovery()
BOOL reuseAddr = TRUE;
setsockopt(s_discoverySock, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuseAddr, sizeof(reuseAddr));
BOOL broadcast = TRUE;
setsockopt(s_discoverySock, SOL_SOCKET, SO_BROADCAST, (const char *)&broadcast, sizeof(broadcast));
struct sockaddr_in bindAddr;
memset(&bindAddr, 0, sizeof(bindAddr));
@@ -1337,7 +1349,8 @@ bool NetworkSocketLayer::StartDiscovery()
return false;
}
#elif defined __PS3__ || defined __ORBIS__
if (::bind(s_discoverySock, (struct sockaddr *)&bindAddr, sizeof(bindAddr)) < 0)
int bindResult = ::bind(s_discoverySock, (struct sockaddr *)&bindAddr, sizeof(bindAddr));
if (bindResult < 0)
{
#if defined(__PS3__)
app.DebugPrintf("PS3 LAN: Discovery bind failed: %d\n", sys_net_errno);
@@ -1349,8 +1362,15 @@ bool NetworkSocketLayer::StartDiscovery()
return false;
}
#endif
#if defined _WINDOWS64 || defined _XBOX
DWORD timeout = 500;
setsockopt(s_discoverySock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout));
#elif defined __PS3__ || defined __ORBIS__
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 500000;
setsockopt(s_discoverySock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout));
#endif
s_discovering = true;
s_discoveryThread = new C4JThread(DiscoveryThreadProc, NULL, "DiscoveryThreadProc");
@@ -1393,6 +1413,54 @@ void NetworkSocketLayer::StopDiscovery()
std::vector<LANSession> NetworkSocketLayer::GetDiscoveredSessions()
{
std::vector<LANSession> result;
if (!s_discovering && !StartDiscovery())
{
return result;
}
DWORD query = htonl(NETWORK_LAN_DISCOVERY_QUERY_MAGIC);
struct sockaddr_in destination;
memset(&destination, 0, sizeof(destination));
destination.sin_family = AF_INET;
destination.sin_port = htons(NETWORK_LAN_DISCOVERY_PORT);
destination.sin_addr.s_addr = INADDR_BROADCAST;
sendto(s_discoverySock, (const char *)&query, sizeof(query), 0,
(struct sockaddr *)&destination, sizeof(destination));
#ifdef __ORBIS__
SceNetCtlInfo ipInfo;
SceNetCtlInfo maskInfo;
int ipResult = sceNetCtlGetInfo(SCE_NET_CTL_INFO_IP_ADDRESS, &ipInfo);
int maskResult = sceNetCtlGetInfo(SCE_NET_CTL_INFO_NETMASK, &maskInfo);
if (ipResult == SCE_OK && maskResult == SCE_OK)
{
struct in_addr localAddress;
struct in_addr netmask;
if (inet_pton(AF_INET, ipInfo.ip_address, &localAddress) == 1 &&
inet_pton(AF_INET, maskInfo.netmask, &netmask) == 1)
{
DWORD local = ntohl(localAddress.s_addr);
DWORD mask = ntohl(netmask.s_addr);
DWORD first = (local & mask) + 1;
DWORD last = (local | ~mask) - 1;
if (last - first > 1023)
{
first = local & 0xFFFFFF00;
last = first + 254;
++first;
}
for (DWORD address = first; address <= last; ++address)
{
if (address == local)
continue;
destination.sin_addr.s_addr = htonl(address);
sendto(s_discoverySock, (const char *)&query, sizeof(query), 0,
(struct sockaddr *)&destination, sizeof(destination));
}
}
}
#endif
if (TryEnterCriticalSection(&s_discoveryLock))
{
result = s_discoveredSessions;
@@ -1430,8 +1498,30 @@ int NetworkSocketLayer::DiscoveryThreadProc(LPVOID param)
}
#endif
if (recvLen < (int)sizeof(LANBroadcast))
if (recvLen == (int)sizeof(DWORD))
{
DWORD query;
memcpy(&query, recvBuf, sizeof(query));
if (ntohl(query) == NETWORK_LAN_DISCOVERY_QUERY_MAGIC && s_advertising)
{
EnterCriticalSection(&s_advertiseLock);
LANBroadcast response = s_advertiseData;
LeaveCriticalSection(&s_advertiseLock);
response.magic = htonl(response.magic);
response.netVersion = htons(response.netVersion);
response.gamePort = htons(response.gamePort);
response.gameHostSettings = htonl(response.gameHostSettings);
response.texturePackParentId = htonl(response.texturePackParentId);
sendto(s_discoverySock, (const char *)&response, sizeof(response), 0,
(struct sockaddr *)&senderAddr, senderLen);
}
continue;
}
if (recvLen < (int)sizeof(LANBroadcast))
{
continue;
}
LANBroadcast *broadcast = (LANBroadcast *)recvBuf;
@@ -1442,7 +1532,9 @@ int NetworkSocketLayer::DiscoveryThreadProc(LPVOID param)
broadcast->texturePackParentId = ntohl(broadcast->texturePackParentId);
if (broadcast->magic != NETWORK_LAN_BROADCAST_MAGIC)
{
continue;
}
char senderIP[64];
#if defined _XBOX
@@ -1453,7 +1545,6 @@ int NetworkSocketLayer::DiscoveryThreadProc(LPVOID param)
#else
inet_ntop(AF_INET, &senderAddr.sin_addr, senderIP, sizeof(senderIP));
#endif
DWORD now = GetTickCount();
EnterCriticalSection(&s_discoveryLock);
@@ -477,6 +477,8 @@ 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++)
{
@@ -698,7 +700,7 @@ void CPlatformNetworkManagerStub::SearchForGames()
{
std::vector<LANSession> lanSessions = NetworkSocketLayer::GetDiscoveredSessions();
if (g_MultiplayerJoin)
if (g_MultiplayerJoin && g_MultiplayerIP[0] != '\0')
{
bool alreadyPresent = false;
for (size_t i = 0; i < lanSessions.size(); i++)
+4 -3
View File
@@ -1059,9 +1059,10 @@ int main(int argc, const char *argv[] )
// XN_SYS_SIGNINCHANGED notifications. This does mean that we need to have a callback in the
// ProfileManager for XN_LIVE_INVITE_ACCEPTED for QNet.
g_NetworkManager.Initialise();
// debug switch to trial version
g_NetworkManager.Initialise();
NetworkSocketLayer::Initialize();
// debug switch to trial version
ProfileManager.SetDebugFullOverride(true);
#if 0