From 8c5feb3cac6ee8fe2e160f7073450ed49235ea11 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 18 May 2026 22:34:25 -0700
Subject: [PATCH] Updated to SDL_net 3.1.0 prerelease
---
external/SDL_net | 2 +-
game/lobby.cpp | 189 +----------------------------------------------
game/netplay.cpp | 8 +-
3 files changed, 8 insertions(+), 191 deletions(-)
diff --git a/external/SDL_net b/external/SDL_net
index 5af3b068..27dc45ae 160000
--- a/external/SDL_net
+++ b/external/SDL_net
@@ -1 +1 @@
-Subproject commit 5af3b068ea13f888be954801c0b8c17993811850
+Subproject commit 27dc45ae6e1f938bd31a76d23489c4f96f15ae28
diff --git a/game/lobby.cpp b/game/lobby.cpp
index 656a9e38..d04d2721 100644
--- a/game/lobby.cpp
+++ b/game/lobby.cpp
@@ -618,193 +618,6 @@ LobbyDialogDelegate::CheckPings()
}
}
-#ifdef HAVE_GETIFADDRS
-static Uint32 SockAddrToUint32(struct sockaddr* a)
-{
- return ((a) && (a->sa_family == AF_INET)) ? SDL_Swap32BE(((struct sockaddr_in*)a)->sin_addr.s_addr) : 0;
-}
-#endif
-
-#if defined(SDL_PLATFORM_WIN32) || defined(HAVE_GETIFADDRS)
-// convert a numeric IP address into its string representation
-static void Inet_NtoA(Uint32 addr, char *ipbuf, size_t maxlen)
-{
- SDL_snprintf(ipbuf, maxlen, "%u.%u.%u.%u", (addr >> 24) & 0xFF, (addr >> 16) & 0xFF, (addr >> 8) & 0xFF, (addr >> 0) & 0xFF);
-}
-
-// convert a string representation of an IP address into its numeric equivalent
-static Uint32 Inet_AtoN(const char* buf)
-{
- // net_server inexplicably doesn't have this function; so I'll just fake it
- Uint32 ret = 0;
- int shift = 24; // fill out the MSB first
- bool startQuad = true;
- while ((shift >= 0) && (*buf))
- {
- if (startQuad)
- {
- unsigned char quad = (unsigned char)atoi(buf);
- ret |= (((Uint32)quad) << shift);
- shift -= 8;
- }
- startQuad = (*buf == '.');
- buf++;
- }
- return ret;
-}
-#endif // SDL_PLATFORM_WIN32 || HAVE_GETIFADDRS
-
-static bool NET_SendDatagramBroadcast(NET_DatagramSocket *sock, Uint16 port, const void* buf, int buflen)
-{
-#ifdef SDL_PLATFORM_WIN32
- // Windows XP style implementation
- HMODULE hiphlpapi = LoadLibraryA("Iphlpapi.dll");
- typedef DWORD (WINAPI *GetIpAddrTable_t)(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL bOrder);
- GetIpAddrTable_t GetIpAddrTableFunc = (GetIpAddrTable_t)GetProcAddress(hiphlpapi, "GetIpAddrTable");
- typedef ULONG (WINAPI *GetAdaptersInfo_t)(PIP_ADAPTER_INFO AdapterInfo, PULONG SizePointer);
- GetAdaptersInfo_t GetAdaptersInfoFunc = (GetAdaptersInfo_t)GetProcAddress(hiphlpapi, "GetAdaptersInfo");
-
- // Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx
- // Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable()
- // multiple times in order to deal with potential race conditions properly.
- MIB_IPADDRTABLE* ipTable = NULL;
- {
- ULONG iptablelen = 0;
- for (int i = 0; i < 5; i++)
- {
- DWORD ipRet = GetIpAddrTableFunc(ipTable, &iptablelen, false);
- if (ipRet == ERROR_INSUFFICIENT_BUFFER)
- {
- free(ipTable); // in case we had previously allocated it
- ipTable = (MIB_IPADDRTABLE*)malloc(iptablelen);
- }
- else if (ipRet == NO_ERROR) break;
- else
- {
- free(ipTable);
- ipTable = NULL;
- break;
- }
- }
- }
-
- if (ipTable)
- {
- // Try to get the Adapters-info table, so we can given useful names to the IP
- // addresses we are returning. Gotta call GetAdaptersInfo() up to 5 times to handle
- // the potential race condition between the size-query call and the get-data call.
- // I love a well-designed API :^P
- IP_ADAPTER_INFO* pAdapterInfo = NULL;
- {
- ULONG bufLen = 0;
- for (int i = 0; i < 5; i++)
- {
- DWORD apRet = GetAdaptersInfoFunc(pAdapterInfo, &bufLen);
- if (apRet == ERROR_BUFFER_OVERFLOW)
- {
- free(pAdapterInfo); // in case we had previously allocated it
- pAdapterInfo = (IP_ADAPTER_INFO*)malloc(bufLen);
- }
- else if (apRet == ERROR_SUCCESS) break;
- else
- {
- free(pAdapterInfo);
- pAdapterInfo = NULL;
- break;
- }
- }
- }
-
- for (DWORD i = 0; i < ipTable->dwNumEntries; i++)
- {
- const MIB_IPADDRROW& row = ipTable->table[i];
-
- // Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it
- const char* name = NULL;
- const char* desc = NULL;
- if (pAdapterInfo)
- {
- IP_ADAPTER_INFO* next = pAdapterInfo;
- while ((next) && (name == NULL))
- {
- IP_ADDR_STRING* ipAddr = &next->IpAddressList;
- while (ipAddr)
- {
- if (Inet_AtoN(ipAddr->IpAddress.String) == SDL_Swap32BE(row.dwAddr))
- {
- name = next->AdapterName;
- desc = next->Description;
- break;
- }
- ipAddr = ipAddr->Next;
- }
- next = next->Next;
- }
- }
- char namebuf[128];
- if (name == NULL)
- {
- SDL_snprintf(namebuf, sizeof(namebuf), "unnamed-%i", i);
- name = namebuf;
- }
-
- Uint32 ipAddr = SDL_Swap32BE(row.dwAddr);
- Uint32 netmask = SDL_Swap32BE(row.dwMask);
- Uint32 baddr = ipAddr & netmask;
- if (row.dwBCastAddr) baddr |= ~netmask;
-
- char ifaAddrStr[32]; Inet_NtoA(ipAddr, ifaAddrStr, sizeof(ifaAddrStr));
- char maskAddrStr[32]; Inet_NtoA(netmask, maskAddrStr, sizeof(maskAddrStr));
- char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr, sizeof(dstAddrStr));
- //SDL_Log(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", name, desc ? desc : "unavailable", ifaAddrStr, maskAddrStr, dstAddrStr);
-
- NET_Address *address = NET_ResolveHostname(dstAddrStr);
- NET_WaitUntilResolved(address, -1);
- NET_SendDatagram(sock, address, port, buf, buflen);
- NET_UnrefAddress(address);
- }
-
- free(pAdapterInfo);
- free(ipTable);
- }
- return true;
-#elif defined(HAVE_GETIFADDRS)
- // BSD-style implementation
- struct ifaddrs* ifap;
- if (getifaddrs(&ifap) == 0)
- {
- struct ifaddrs* p = ifap;
- while (p)
- {
- Uint32 ifaAddr = SockAddrToUint32(p->ifa_addr);
- Uint32 maskAddr = SockAddrToUint32(p->ifa_netmask);
- Uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr);
- if (ifaAddr > 0)
- {
- char ifaAddrStr[32]; Inet_NtoA(ifaAddr, ifaAddrStr, sizeof(ifaAddrStr));
- char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr, sizeof(maskAddrStr));
- char dstAddrStr[32]; Inet_NtoA(dstAddr, dstAddrStr, sizeof(dstAddrStr));
- //SDL_Log(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", p->ifa_name, "unavailable", ifaAddrStr, maskAddrStr, dstAddrStr);
-
- NET_Address* address = NET_ResolveHostname(dstAddrStr);
- NET_WaitUntilResolved(address, -1);
- NET_SendDatagram(sock, address, port, buf, buflen);
- NET_UnrefAddress(address);
- }
- p = p->ifa_next;
- }
- freeifaddrs(ifap);
- }
- return true;
-#else
- NET_Address *address = NET_ResolveHostname("255.255.255.255");
- NET_WaitUntilResolved(address, -1);
- bool result = NET_SendDatagram(sock, address, port, buf, buflen);
- NET_UnrefAddress(address);
- return result;
-#endif
-}
-
void
LobbyDialogDelegate::GetGameList()
{
@@ -812,7 +625,7 @@ LobbyDialogDelegate::GetGameList()
m_packet.StartLobbyMessage(LOBBY_REQUEST_GAME_INFO);
m_packet.Write((Uint32)SDL_GetTicks());
- NET_SendDatagramBroadcast(gSocket, NETPLAY_PORT, m_packet.data, m_packet.len);
+ NET_SendDatagram(gSocket, NULL, NETPLAY_PORT, m_packet.data, m_packet.len);
}
void
diff --git a/game/netplay.cpp b/game/netplay.cpp
index 612d413a..7abb466f 100644
--- a/game/netplay.cpp
+++ b/game/netplay.cpp
@@ -70,8 +70,12 @@ int CreateSocket(bool hosting)
} else {
port = 0;
}
- gSocket = NET_CreateDatagramSocket(NULL, port);
- if ( gSocket == NULL ) {
+
+ SDL_PropertiesID props = SDL_CreateProperties();
+ SDL_SetBooleanProperty(props, NET_PROP_DATAGRAM_SOCKET_ALLOW_BROADCAST_BOOLEAN, true);
+ gSocket = NET_CreateDatagramSocket(NULL, port, props);
+ SDL_DestroyProperties(props);
+ if (!gSocket) {
error("Couldn't create socket bound to port %d: %s\n", port, SDL_GetError());
return(-1);
}