feat: add PS4 networking support

This commit is contained in:
NaN
2026-08-03 16:57:07 -04:00
parent ce3e83039d
commit 930a104e50
7 changed files with 174 additions and 46 deletions
@@ -16,9 +16,11 @@ SOCKET NetworkSocketLayer::s_advertiseSock = -1;
SOCKET NetworkSocketLayer::s_discoverySock = -1;
#if defined __PS3__
#define LCE_NET_ERRNO sys_net_errno
int closesocket(int s) { return socketclose(s); };
void terminate_networking() { cellNetCtlTerm(); sys_net_finalize_network(); };
#elif defined __ORBIS__
#define LCE_NET_ERRNO errno
int closesocket(int s) { return sceNetSocketClose(s); };
int socketclose(int s) { return sceNetSocketClose(s); };
void terminate_networking() {};
@@ -60,10 +62,52 @@ std::vector<BYTE> NetworkSocketLayer::s_disconnectedSmallIds;
CRITICAL_SECTION NetworkSocketLayer::s_freeSmallIdLock;
std::vector<BYTE> NetworkSocketLayer::s_freeSmallIds;
bool g_MultiplayerHost = false;
bool g_MultiplayerJoin = true;
int g_MultiplayerPort = NETWORK_LAN_DEFAULT_PORT;
char g_MultiplayerIP[256] = "127.0.0.1";
bool g_Win64MultiplayerHost = false;
#if defined __ORBIS__
// Orbis has direct lan networking so it can bypass psn account checks
bool g_Win64MultiplayerJoin = true;
int g_Win64MultiplayerPort = WIN64_NET_DEFAULT_PORT;
char g_Win64MultiplayerIP[256] = "";
#else
bool g_Win64MultiplayerJoin = false;
int g_Win64MultiplayerPort = WIN64_NET_DEFAULT_PORT;
char g_Win64MultiplayerIP[256] = "127.0.0.1";
#endif
#ifdef _WINDOWS64
static int GetLocalIPv4Interfaces(SOCKET socketHandle, struct in_addr *localAddresses,
struct in_addr *broadcastAddresses, int capacity)
{
INTERFACE_INFO interfaceList[32];
DWORD bytesReturned = 0;
if(WSAIoctl(socketHandle, SIO_GET_INTERFACE_LIST, NULL, 0, interfaceList,
sizeof(interfaceList), &bytesReturned, NULL, NULL) == SOCKET_ERROR)
{
return 0;
}
int interfaceCount = (int)(bytesReturned / sizeof(INTERFACE_INFO));
int resultCount = 0;
for(int i = 0; i < interfaceCount && resultCount < capacity; ++i)
{
struct sockaddr_in *address = (struct sockaddr_in *)&interfaceList[i].iiAddress;
struct sockaddr_in *netmask = (struct sockaddr_in *)&interfaceList[i].iiNetmask;
if(address->sin_family != AF_INET)
continue;
unsigned long hostAddress = ntohl(address->sin_addr.s_addr);
unsigned long hostNetmask = ntohl(netmask->sin_addr.s_addr);
if(hostAddress == 0 || (hostAddress & 0xff000000) == 0x7f000000 || hostNetmask == 0)
continue;
localAddresses[resultCount] = address->sin_addr;
broadcastAddresses[resultCount].s_addr = htonl(hostAddress | ~hostNetmask);
++resultCount;
}
return resultCount;
}
#endif
bool NetworkSocketLayer::Initialize()
{
@@ -555,6 +599,9 @@ bool NetworkSocketLayer::JoinGame(const char *ip, int port)
struct sockaddr_in addr = {};
#if defined(__ORBIS__)
addr.sin_len = sizeof(addr);
#endif
addr.sin_family = AF_INET;
addr.sin_port = htons((uint16_t)port);
@@ -597,15 +644,16 @@ bool NetworkSocketLayer::JoinGame(const char *ip, int port)
#endif
iResult = connect(s_hostConnectionSocket, (struct sockaddr*)&addr, sizeof(addr));
int connectError = iResult < 0 ? LCE_NET_ERRNO : 0;
if (iResult < 0)
{
#if defined(__PS3__)
int err = sys_net_errno;
int err = connectError;
if (err == SYS_NET_EINPROGRESS)
{
#elif defined(__ORBIS__)
int err = sce_net_errno;
if (err == SCE_NET_EINPROGRESS)
int err = connectError;
if (err == EINPROGRESS)
{
#endif
fd_set writeFds, exceptFds;
@@ -1205,8 +1253,31 @@ int NetworkSocketLayer::AdvertiseThreadProc(LPVOID param)
data.gameHostSettings = htonl(data.gameHostSettings);
data.texturePackParentId = htonl(data.texturePackParentId);
int sent = sendto(s_advertiseSock, (const char *)&data, sizeof(data), 0,
int sent = -1;
#ifdef _WINDOWS64
struct in_addr localAddresses[32];
struct in_addr broadcastAddresses[32];
int interfaceCount = GetLocalIPv4Interfaces(s_advertiseSock, localAddresses, broadcastAddresses, 32);
for(int i = 0; i < interfaceCount; ++i)
{
broadcastAddr.sin_addr = broadcastAddresses[i];
int interfaceSent = sendto(s_advertiseSock, (const char *)&data, sizeof(data), 0,
(struct sockaddr *)&broadcastAddr, sizeof(broadcastAddr));
if(interfaceSent != SOCKET_ERROR)
sent = interfaceSent;
}
if(interfaceCount == 0)
{
broadcastAddr.sin_addr.s_addr = INADDR_BROADCAST;
sent = sendto(s_advertiseSock, (const char *)&data, sizeof(data), 0,
(struct sockaddr *)&broadcastAddr, sizeof(broadcastAddr));
}
#else
sent = sendto(s_advertiseSock, (const char *)&data, sizeof(data), 0,
(struct sockaddr *)&broadcastAddr, sizeof(broadcastAddr));
#endif
#if defined _WINDOWS64 || defined _XBOX
if (sent == SOCKET_ERROR && s_advertising)