psvita networking (Experimental)

This commit is contained in:
2026-08-04 07:04:38 +03:00
parent ce3e83039d
commit ea3621971f
22 changed files with 404 additions and 172 deletions
@@ -4,26 +4,23 @@
#include "..\..\Common\Network\PlatformNetworkManager.h"
#include "..\..\..\Minecraft.World\Socket.h"
#if defined _WINDOWS64 || defined _XBOX
SOCKET NetworkSocketLayer::s_listenSocket = INVALID_SOCKET;
SOCKET NetworkSocketLayer::s_hostConnectionSocket = INVALID_SOCKET;
SOCKET NetworkSocketLayer::s_advertiseSock = INVALID_SOCKET;
SOCKET NetworkSocketLayer::s_discoverySock = INVALID_SOCKET;
#elif defined __PS3__ || defined __ORBIS__
SOCKET NetworkSocketLayer::s_listenSocket = -1;
SOCKET NetworkSocketLayer::s_hostConnectionSocket = -1;
SOCKET NetworkSocketLayer::s_advertiseSock = -1;
SOCKET NetworkSocketLayer::s_discoverySock = -1;
#if defined __PS3__
int closesocket(int s) { return socketclose(s); };
#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
void WSACleanup() {};
#endif
#ifdef __PS3__
void terminate_networking() { cellNetCtlTerm(); sys_net_finalize_network(); };
#elif defined __ORBIS__
int closesocket(int s) { return sceNetSocketClose(s); };
int socketclose(int s) { return sceNetSocketClose(s); };
#else
void terminate_networking() {};
#endif
void WSACleanup() {};
#if defined __PSVITA__
int socket(int family, int type, int protocol) { return sceNetSocket(NULL, family, type, protocol); };
#endif
C4JThread* NetworkSocketLayer::s_acceptThread = NULL;
@@ -89,6 +86,19 @@ bool NetworkSocketLayer::Initialize()
sys_net_finalize_network();
return false;
}
#elif defined __PSVITA__
SceNetInitParam param;
static char memory[16 * 1024];
param.memory = memory;
param.size = sizeof(memory);
param.flags = 0;
int result = sceNetInit(&param);
if (result < 0) {
app.DebugPrintf("sceNetInit failed: %d\n", result);
return false;
}
#endif
InitializeCriticalSection(&s_sendLock);
@@ -125,7 +135,7 @@ void NetworkSocketLayer::Shutdown()
closesocket(s_hostConnectionSocket);
s_hostConnectionSocket = INVALID_SOCKET;
}
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
if (s_listenSocket >= 0)
{
socketclose(s_listenSocket);
@@ -146,7 +156,7 @@ void NetworkSocketLayer::Shutdown()
s_connections[i].active = false;
#if defined _WINDOWS64 || defined _XBOX
if (s_connections[i].tcpSocket != INVALID_SOCKET)
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
if (s_connections[i].tcpSocket >= 0)
#endif
{
@@ -238,8 +248,12 @@ bool NetworkSocketLayer::HostGame(int port)
app.DebugPrintf("socket() failed: %d\n", WSAGetLastError());
return false;
}
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
#ifdef __PSVITA__
SceNetSockaddrIn addr = {};
#else
struct sockaddr_in addr = {};
#endif
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons((uint16_t)port);
@@ -292,8 +306,12 @@ bool NetworkSocketLayer::HostGame(int port)
s_listenSocket = INVALID_SOCKET;
return false;
}
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
#ifdef __PSVITA__
iResult = ::bind(s_listenSocket, (const sockaddr*)&addr, sizeof(addr));
#else
iResult = ::bind(s_listenSocket, (struct sockaddr*)&addr, sizeof(addr));
#endif
if (iResult < 0)
{
app.DebugPrintf("bind() failed: %d\n", iResult);
@@ -546,14 +564,18 @@ bool NetworkSocketLayer::JoinGame(const char *ip, int port)
connected = true;
break;
}
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
if (s_hostConnectionSocket != -1)
{
socketclose(s_hostConnectionSocket);
s_hostConnectionSocket = -1;
}
#ifdef __PSVITA__
SceNetSockaddrIn addr = {};
#else
struct sockaddr_in addr = {};
#endif
addr.sin_family = AF_INET;
addr.sin_port = htons((uint16_t)port);
@@ -590,40 +612,47 @@ bool NetworkSocketLayer::JoinGame(const char *ip, int port)
setsockopt(s_hostConnectionSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay));
int nonBlocking = 1;
#ifdef __PS3__
setsockopt(s_hostConnectionSocket, SOL_SOCKET, SO_NBIO, &nonBlocking, sizeof(nonBlocking));
#elif defined(__ORBIS__)
setsockopt(s_hostConnectionSocket, SOL_SOCKET, SCE_NET_SO_NBIO, &nonBlocking, sizeof(nonBlocking));
#endif
#ifdef __PSVITA__
iResult = connect(s_hostConnectionSocket, (const SceNetSockaddr*)&addr, sizeof(addr));
#else
iResult = connect(s_hostConnectionSocket, (struct sockaddr*)&addr, sizeof(addr));
#endif
if (iResult < 0)
{
#if defined(__PS3__)
int err = sys_net_errno;
if (err == SYS_NET_EINPROGRESS)
{
#elif defined(__ORBIS__)
int err = sce_net_errno;
if (err == SCE_NET_EINPROGRESS)
{
#endif
#ifndef __PSVITA__
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;
#if defined(__PS3__)
int selectResult = socketselect(s_hostConnectionSocket + 1, NULL, &writeFds, &exceptFds, &tv);
#elif defined(__ORBIS__)
int selectResult = select(s_hostConnectionSocket + 1, NULL, &writeFds, &exceptFds, &tv);
#else
SceNetId eid = sceNetEpollCreate(NULL, 0);
SceNetEpollEvent ev = {};
ev.events = SCE_NET_EPOLLOUT;
ev.data.fd = s_hostConnectionSocket;
sceNetEpollControl(eid, SCE_NET_EPOLL_CTL_ADD, s_hostConnectionSocket, &ev);
int timeoutUsec = connectTimeoutMs * 1000;
SceNetEpollEvent outEvents[1];
int selectResult = sceNetEpollWait(eid, outEvents, 1, timeoutUsec);
sceNetEpollControl(eid, SCE_NET_EPOLL_CTL_DEL, s_hostConnectionSocket, NULL);
sceNetEpollDestroy(eid);
#endif
#ifndef __PSVITA__
int selectResult = socketselect(s_hostConnectionSocket + 1, NULL, &writeFds, &exceptFds, &tv);
if (selectResult <= 0 || FD_ISSET(s_hostConnectionSocket, &exceptFds))
#else
if (selectResult <= 0 || (selectResult > 0) &&
(outEvents[0].events & (SCE_NET_EPOLLERR | SCE_NET_EPOLLHUP)))
#endif
{
app.DebugPrintf("connect() to %s:%d timed out or failed (attempt %d/%d)\n", ip, port, attempt + 1, maxAttempts);
closesocket(s_hostConnectionSocket);
@@ -654,7 +683,7 @@ bool NetworkSocketLayer::JoinGame(const char *ip, int port)
int blocking = 0;
#ifdef __PS3__
setsockopt(s_hostConnectionSocket, SOL_SOCKET, SO_NBIO, &blocking, sizeof(blocking));
#elif defined(__ORBIS__)
#elif defined(__ORBIS__) || defined __PSVITA__
setsockopt(s_hostConnectionSocket, SOL_SOCKET, SCE_NET_SO_NBIO, &blocking, sizeof(blocking));
#endif
@@ -708,7 +737,7 @@ bool NetworkSocketLayer::SendOnSocket(SOCKET sock, const void *data, int dataSiz
{
#if defined _WINDOWS64 || defined _XBOX
if (sock == INVALID_SOCKET || dataSize <= 0) return false;
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
if (sock < 0 || dataSize <= 0) return false;
#endif
@@ -727,7 +756,7 @@ bool NetworkSocketLayer::SendOnSocket(SOCKET sock, const void *data, int dataSiz
int sent = send(sock, (const char *)header + totalSent, toSend - totalSent, 0);
#if defined _WINDOWS64 || defined _XBOX
if (sent == SOCKET_ERROR || sent == 0)
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
if (sent < 0 || sent == 0)
#endif
{
@@ -744,7 +773,7 @@ bool NetworkSocketLayer::SendOnSocket(SOCKET sock, const void *data, int dataSiz
#if defined _WINDOWS64 || defined _XBOX
if (sent == SOCKET_ERROR || sent == 0)
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
if (sent < 0 || sent == 0)
#endif
{
@@ -767,7 +796,7 @@ bool NetworkSocketLayer::SendToSmallId(BYTE targetSmallId, const void *data, int
SOCKET sock = GetSocketForSmallId(targetSmallId);
#if defined _WINDOWS64 || defined _XBOX
if (sock == INVALID_SOCKET) return false;
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
if (sock < 0) return false;
#endif
return SendOnSocket(sock, data, dataSize);
@@ -793,7 +822,7 @@ SOCKET NetworkSocketLayer::GetSocketForSmallId(BYTE smallId)
LeaveCriticalSection(&s_connectionsLock);
#if defined _WINDOWS64 || defined _XBOX
return INVALID_SOCKET;
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
return -1;
#endif
}
@@ -835,7 +864,11 @@ int NetworkSocketLayer::AcceptThreadProc(LPVOID param)
{
while (s_active)
{
#ifdef __PSVITA__
SOCKET clientSocket = accept(s_listenSocket, (SceNetSockaddr *)NULL, NULL);
#else
SOCKET clientSocket = accept(s_listenSocket, NULL, NULL);
#endif
#if defined _WINDOWS64 || defined _XBOX
if (clientSocket == INVALID_SOCKET)
{
@@ -843,7 +876,7 @@ int NetworkSocketLayer::AcceptThreadProc(LPVOID param)
app.DebugPrintf("accept() failed: %d\n", WSAGetLastError());
break;
}
#elif __PS3__ || defined __ORBIS__
#elif __PS3__ || defined __ORBIS__ || defined __PSVITA__
if (clientSocket < 0)
{
if (s_active)
@@ -1050,7 +1083,7 @@ int NetworkSocketLayer::ClientRecvThreadProc(LPVOID param)
#if defined _WINDOWS64 || defined _XBOX
while (s_active && s_hostConnectionSocket != INVALID_SOCKET)
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
while (s_active && s_hostConnectionSocket >= 0)
#endif
{
@@ -1115,7 +1148,7 @@ bool NetworkSocketLayer::StartAdvertising(int gamePort, const wchar_t *hostName,
app.DebugPrintf("Win64 LAN: Failed to create advertise socket: %d\n", WSAGetLastError());
return false;
}
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
if (s_advertiseSock < 0)
{
app.DebugPrintf("PS3 LAN: Failed to create advertise socket: %d\n", s_advertiseSock);
@@ -1143,7 +1176,7 @@ void NetworkSocketLayer::StopAdvertising()
closesocket(s_advertiseSock);
s_advertiseSock = INVALID_SOCKET;
}
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
if (s_advertiseSock >= 0)
{
closesocket(s_advertiseSock);
@@ -1187,7 +1220,11 @@ void NetworkSocketLayer::UpdateAdvertiseJoinable(bool joinable)
int NetworkSocketLayer::AdvertiseThreadProc(LPVOID param)
{
#ifdef __PSVITA__
SceNetSockaddrIn broadcastAddr;
#else
struct sockaddr_in broadcastAddr;
#endif
memset(&broadcastAddr, 0, sizeof(broadcastAddr));
broadcastAddr.sin_family = AF_INET;
broadcastAddr.sin_port = htons(NETWORK_LAN_DISCOVERY_PORT);
@@ -1205,15 +1242,20 @@ int NetworkSocketLayer::AdvertiseThreadProc(LPVOID param)
data.gameHostSettings = htonl(data.gameHostSettings);
data.texturePackParentId = htonl(data.texturePackParentId);
#ifdef __PSVITA__
int sent = sendto(s_advertiseSock, (const char *)&data, sizeof(data), 0,
(const sockaddr *)&broadcastAddr, sizeof(broadcastAddr));
#else
int 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)
{
app.DebugPrintf("Win64 LAN: Broadcast sendto failed: %d\n", WSAGetLastError());
}
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
if (sent < 0 && s_advertising)
{
app.DebugPrintf("PS3 LAN: Broadcast sendto failed: %d\n", sent);
@@ -1238,7 +1280,7 @@ bool NetworkSocketLayer::StartDiscovery()
app.DebugPrintf("Win64 LAN: Failed to create discovery socket: %d\n", WSAGetLastError());
return false;
}
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
app.DebugPrintf("Discovery socket: %d\n", s_discoverySock);
if (s_discoverySock < 0)
{
@@ -1250,8 +1292,12 @@ bool NetworkSocketLayer::StartDiscovery()
BOOL reuseAddr = TRUE;
setsockopt(s_discoverySock, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuseAddr, sizeof(reuseAddr));
#ifdef __PSVITA__
SceNetSockaddrIn bindAddr;
#else
struct sockaddr_in bindAddr;
#endif
memset(&bindAddr, 0, sizeof(bindAddr));
bindAddr.sin_family = AF_INET;
bindAddr.sin_port = htons(NETWORK_LAN_DISCOVERY_PORT);
@@ -1265,14 +1311,15 @@ bool NetworkSocketLayer::StartDiscovery()
s_discoverySock = INVALID_SOCKET;
return false;
}
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
#ifdef __PSVITA__
if (::bind(s_discoverySock, (const sockaddr *)&bindAddr, sizeof(bindAddr)) < 0)
{
#else
if (::bind(s_discoverySock, (struct sockaddr *)&bindAddr, sizeof(bindAddr)) < 0)
{
#if defined(__PS3__)
app.DebugPrintf("PS3 LAN: Discovery bind failed: %d\n", sys_net_errno);
#elif defined(__ORBIS__)
app.DebugPrintf("PS3 LAN: Discovery bind failed: %d\n", sce_net_errno);
#endif
app.DebugPrintf("PS3 LAN: Discovery bind failed: %d\n", sys_net_errno);
socketclose(s_discoverySock);
s_discoverySock = -1;
return false;
@@ -1299,7 +1346,7 @@ void NetworkSocketLayer::StopDiscovery()
closesocket(s_discoverySock);
s_discoverySock = INVALID_SOCKET;
}
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
if (s_discoverySock >= 0)
{
socketclose(s_discoverySock);
@@ -1337,22 +1384,31 @@ int NetworkSocketLayer::DiscoveryThreadProc(LPVOID param)
while (s_discovering)
{
#ifdef __PSVITA__
SceNetSockaddrIn senderAddr;
#else
struct sockaddr_in senderAddr;
#endif
#if defined _WINDOWS64 || defined _XBOX
int senderLen = sizeof(senderAddr);
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
socklen_t senderLen = sizeof(senderAddr);
#endif
#ifdef __PSVITA__
int recvLen = recvfrom(s_discoverySock, recvBuf, sizeof(recvBuf), 0,
(sockaddr *)&senderAddr, &senderLen);
#else
int recvLen = recvfrom(s_discoverySock, recvBuf, sizeof(recvBuf), 0,
(struct sockaddr *)&senderAddr, &senderLen);
#endif
#ifdef _WINDOWS64
if (recvLen == SOCKET_ERROR)
{
continue;
}
#elif defined __PS3__ || defined __ORBIS__
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
if (recvLen < 0)
{
continue;