Fixed an issue where sometimes a player unable to join a host on Warriors Orochi 2 (should also fix similar issue on other games that use PDP/UDP on Windows)

This commit is contained in:
ANR2ME committed 2020-12-25 00:27:35 +07:00
1 parent a20567222a
commit b10797db95
3 files changed
+22 -1

No files matched your search

+13
View File
@@ -1982,6 +1982,19 @@ int setSockReuseAddrPort(int sock) {
return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt));
}
int setUDPConnReset(int udpsock, bool enabled) {
// On Windows: Connection Reset error on UDP could cause a strange behavior https://stackoverflow.com/questions/34242622/windows-udp-sockets-recvfrom-fails-with-error-10054
#if defined(_WIN32)
#if !defined(SIO_UDP_CONNRESET)
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR, 12)
#endif
BOOL bNewBehavior = enabled;
DWORD dwBytesReturned = 0;
return WSAIoctl(udpsock, SIO_UDP_CONNRESET, &bNewBehavior, sizeof bNewBehavior, NULL, 0, &dwBytesReturned, NULL, NULL);
#endif
return -1;
}
#if !defined(TCP_KEEPIDLE)
#define TCP_KEEPIDLE TCP_KEEPALIVE //TCP_KEEPIDLE on Linux is equivalent to TCP_KEEPALIVE on macOS
#endif
+5
View File
@@ -1317,6 +1317,11 @@ int setSockNoSIGPIPE(int sock, int flag);
*/
int setSockReuseAddrPort(int sock);
/*
* Set Socket Connection Reset on UDP (which could cause a strange behavior)
*/
int setUDPConnReset(int udpsock, bool enabled);
/*
* Set Socket KeepAlive (opt = SO_KEEPALIVE)
*/
+4 -1
View File
@@ -1240,6 +1240,9 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 f
// Enable Port Re-use, this will allow binding to an already used port, but only one of them can read the data (shared receive buffer?)
setSockReuseAddrPort(usocket);
// Disable Connection Reset error on UDP to avoid strange behavior https://stackoverflow.com/questions/34242622/windows-udp-sockets-recvfrom-fails-with-error-10054
setUDPConnReset(usocket, false);
// Binding Information for local Port
sockaddr_in addr;
addr.sin_family = AF_INET;
@@ -2923,7 +2926,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) {
// Valid Socket Entry
auto sock = adhocSockets[j];
if (sock != NULL && sock->type == SOCK_PDP) {
// Set available bytes to be received. With FIOREAD There might be lingering 1 byte in recv buffer when remote peer's socket got closed (ie. Warriors Orochi 2)
// Set available bytes to be received. With FIOREAD There might be ghosting 1 byte in recv buffer when remote peer's socket got closed (ie. Warriors Orochi 2) Attempting to recv this ghost 1 byte will result to socket error 10054 (may need to disable SIO_UDP_CONNRESET error)
sock->data.pdp.rcv_sb_cc = getAvailToRecv(sock->data.pdp.id);
// Copy Socket Data from Internal Memory