From aa8dd16dadc704e1b445453b8dfb464da53487aa Mon Sep 17 00:00:00 2001 From: Shpoike Date: Wed, 17 Oct 2018 01:46:09 +0100 Subject: [PATCH] Display multiple local addresses on the create-game multiplayer menu. Hopefully this wll be slightly more useful on multi-homed machines. --- Quake/menu.c | 90 ++++++++++++++++++++++++++++++++++-------------- Quake/net.h | 5 +++ Quake/net_bsd.c | 4 +++ Quake/net_defs.h | 2 ++ Quake/net_dgrm.c | 17 +++++++++ Quake/net_dgrm.h | 1 + Quake/net_loop.h | 1 + Quake/net_main.c | 16 +++++++++ Quake/net_win.c | 5 +++ Quake/net_wins.c | 67 +++++++++++++++++++++++++++++++++-- Quake/net_wins.h | 2 ++ Quake/net_wipx.c | 8 +++++ Quake/net_wipx.h | 1 + Quake/pr_ext.c | 8 ++--- 14 files changed, 196 insertions(+), 31 deletions(-) diff --git a/Quake/menu.c b/Quake/menu.c index 8d046ae5..9d968ddb 100644 --- a/Quake/menu.c +++ b/Quake/menu.c @@ -1826,7 +1826,6 @@ void M_Quit_Draw (void) //johnfitz -- modified for new quit message /* LAN CONFIG MENU */ int lanConfig_cursor = -1; -int lanConfig_cursor_table [] = {72, 92, 100, 132}; #define NUM_LANCONFIG_CMDS 4 int lanConfig_port; @@ -1860,6 +1859,9 @@ void M_LanConfig_Draw (void) { qpic_t *p; int basex; + int y; + int numaddresses, i; + qhostaddr_t addresses[16]; const char *startJoin; const char *protocol; @@ -1879,51 +1881,89 @@ void M_LanConfig_Draw (void) M_Print (basex, 32, va ("%s - %s", startJoin, protocol)); basex += 8; - M_Print (basex, 52, "Address:"); + y = 52; + M_Print (basex, y, "Address:"); +#if 1 + numaddresses = NET_ListAddresses(addresses, sizeof(addresses)/sizeof(addresses[0])); + if (!numaddresses) + { + M_Print (basex+9*8, y, "NONE KNOWN"); + y += 8; + } + else for (i = 0; i < numaddresses; i++) + { + M_Print (basex+9*8, y, addresses[i]); + y += 8; + } +#else if (IPXConfig) - M_Print (basex+9*8, 52, my_ipx_address); + { + M_Print (basex+9*8, y, my_ipx_address); + y+=8; + } else { if (ipv4Available && ipv6Available) { - M_Print (basex+9*8, 52-4, my_ipv4_address); - M_Print (basex+9*8, 52+4, my_ipv6_address); + M_Print (basex+9*8, y, my_ipv4_address); + y+=8; + M_Print (basex+9*8, y, my_ipv6_address); + y+=8; } else { if (ipv4Available) - M_Print (basex+9*8, 52, my_ipv4_address); + M_Print (basex+9*8, y, my_ipv4_address); if (ipv6Available) - M_Print (basex+9*8, 52, my_ipv6_address); + M_Print (basex+9*8, y, my_ipv6_address); + y+=8; } } +#endif - M_Print (basex, lanConfig_cursor_table[0], "Port"); - M_DrawTextBox (basex+8*8, lanConfig_cursor_table[0]-8, 6, 1); - M_Print (basex+9*8, lanConfig_cursor_table[0], lanConfig_portname); + y+=8; //for the port's box + M_Print (basex, y, "Port"); + M_DrawTextBox (basex+8*8, y-8, 6, 1); + M_Print (basex+9*8, y, lanConfig_portname); + if (lanConfig_cursor == 0) + { + M_DrawCharacter (basex+9*8 + 8*strlen(lanConfig_portname), y, 10+((int)(realtime*4)&1)); + M_DrawCharacter (basex-8, y, 12+((int)(realtime*4)&1)); + } + y += 20; if (JoiningGame) { - M_Print (basex, lanConfig_cursor_table[1], "Search for local games..."); - M_Print (basex, lanConfig_cursor_table[2], "Search for public games..."); - M_Print (basex, 108, "Join game at:"); - M_DrawTextBox (basex+8, lanConfig_cursor_table[3]-8, 22, 1); - M_Print (basex+16, lanConfig_cursor_table[3], lanConfig_joinname); + M_Print (basex, y, "Search for local games..."); + if (lanConfig_cursor == 1) + M_DrawCharacter (basex-8, y, 12+((int)(realtime*4)&1)); + y+=8; + + M_Print (basex, y, "Search for public games..."); + if (lanConfig_cursor == 2) + M_DrawCharacter (basex-8, y, 12+((int)(realtime*4)&1)); + y+=8; + + M_Print (basex, y, "Join game at:"); + y+=24; + M_DrawTextBox (basex+8, y-8, 22, 1); + M_Print (basex+16, y, lanConfig_joinname); + if (lanConfig_cursor == 3) + { + M_DrawCharacter (basex+16 + 8*strlen(lanConfig_joinname), y, 10+((int)(realtime*4)&1)); + M_DrawCharacter (basex-8, y, 12+((int)(realtime*4)&1)); + } + y += 16; } else { - M_DrawTextBox (basex, lanConfig_cursor_table[1]-8, 2, 1); - M_Print (basex+8, lanConfig_cursor_table[1], "OK"); + M_DrawTextBox (basex, y-8, 2, 1); + M_Print (basex+8, y, "OK"); + if (lanConfig_cursor == 1) + M_DrawCharacter (basex-8, y, 12+((int)(realtime*4)&1)); + y += 16; } - M_DrawCharacter (basex-8, lanConfig_cursor_table [lanConfig_cursor], 12+((int)(realtime*4)&1)); - - if (lanConfig_cursor == 0) - M_DrawCharacter (basex+9*8 + 8*strlen(lanConfig_portname), lanConfig_cursor_table [0], 10+((int)(realtime*4)&1)); - - if (lanConfig_cursor == 3) - M_DrawCharacter (basex+16 + 8*strlen(lanConfig_joinname), lanConfig_cursor_table [3], 10+((int)(realtime*4)&1)); - if (*m_return_reason) M_PrintWhite (basex, 148, m_return_reason); } diff --git a/Quake/net.h b/Quake/net.h index ff2061f9..d73be4cb 100644 --- a/Quake/net.h +++ b/Quake/net.h @@ -45,6 +45,8 @@ extern double net_time; extern sizebuf_t net_message; extern int net_activeconnections; +typedef char qhostaddr_t[NET_NAMELEN]; + void NET_Init (void); void NET_Shutdown (void); @@ -70,6 +72,9 @@ qboolean NET_CanSendMessage (struct qsocket_s *sock); struct qsocket_s *NET_GetServerMessage(void); //returns data in net_message, qsocket says which client its from +int NET_ListAddresses(qhostaddr_t *addresses, int maxaddresses); +//gets a list of public addresses. + int NET_GetMessage (struct qsocket_s *sock); // returns data in net_message sizebuf // returns 0 if no data is waiting diff --git a/Quake/net_bsd.c b/Quake/net_bsd.c index a0b7c37a..09810ae0 100644 --- a/Quake/net_bsd.c +++ b/Quake/net_bsd.c @@ -34,6 +34,7 @@ net_driver_t net_drivers[] = false, Loop_Init, Loop_Listen, + Loop_QueryAddresses, Loop_SearchForHosts, Loop_Connect, Loop_CheckNewConnections, @@ -51,6 +52,7 @@ net_driver_t net_drivers[] = false, Datagram_Init, Datagram_Listen, + Datagram_QueryAddresses, Datagram_SearchForHosts, Datagram_Connect, Datagram_CheckNewConnections, @@ -77,6 +79,7 @@ net_landriver_t net_landrivers[] = UDP4_Init, UDP4_Shutdown, UDP4_Listen, + UDP4_GetAddresses, UDP4_OpenSocket, UDP_CloseSocket, UDP_Connect, @@ -99,6 +102,7 @@ net_landriver_t net_landrivers[] = UDP6_Init, UDP6_Shutdown, UDP6_Listen, + UDP6_GetAddresses, UDP6_OpenSocket, UDP_CloseSocket, UDP_Connect, diff --git a/Quake/net_defs.h b/Quake/net_defs.h index d18e97b0..30d53e87 100644 --- a/Quake/net_defs.h +++ b/Quake/net_defs.h @@ -178,6 +178,7 @@ typedef struct sys_socket_t (*Init) (void); void (*Shutdown) (void); sys_socket_t (*Listen) (qboolean state); + int (*QueryAddresses) (qhostaddr_t *addresses, int maxaddresses); sys_socket_t (*Open_Socket) (int port); int (*Close_Socket) (sys_socket_t socketid); int (*Connect) (sys_socket_t socketid, struct qsockaddr *addr); @@ -207,6 +208,7 @@ typedef struct qboolean initialized; int (*Init) (void); void (*Listen) (qboolean state); + int (*QueryAddresses) (qhostaddr_t *addresses, int maxaddresses); qboolean (*SearchForHosts) (qboolean xmit); qsocket_t *(*Connect) (const char *host); qsocket_t *(*CheckNewConnections) (void); diff --git a/Quake/net_dgrm.c b/Quake/net_dgrm.c index f18188e3..c39bbe23 100644 --- a/Quake/net_dgrm.c +++ b/Quake/net_dgrm.c @@ -2279,3 +2279,20 @@ qsocket_t *Datagram_Connect (const char *host) return ret; } +/* +Spike: added this to list more than one ipv4 address (many people are still multi-homed) +*/ +int Datagram_QueryAddresses(qhostaddr_t *addresses, int maxaddresses) +{ + int result = 0; + for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) + { + if (!net_landrivers[net_landriverlevel].initialized) + continue; + if (result == maxaddresses) + break; + if (net_landrivers[net_landriverlevel].QueryAddresses) + result += net_landrivers[net_landriverlevel].QueryAddresses(addresses+result, maxaddresses-result); + } + return result; +} diff --git a/Quake/net_dgrm.h b/Quake/net_dgrm.h index e9cd4c88..3578fe43 100644 --- a/Quake/net_dgrm.h +++ b/Quake/net_dgrm.h @@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. int Datagram_Init (void); void Datagram_Listen (qboolean state); +int Datagram_QueryAddresses(qhostaddr_t *addresses, int maxaddresses); qboolean Datagram_SearchForHosts (qboolean xmit); qsocket_t *Datagram_Connect (const char *host); qsocket_t *Datagram_CheckNewConnections (void); diff --git a/Quake/net_loop.h b/Quake/net_loop.h index ea18eef9..ab82b6db 100644 --- a/Quake/net_loop.h +++ b/Quake/net_loop.h @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // net_loop.h int Loop_Init (void); void Loop_Listen (qboolean state); +#define Loop_QueryAddresses NULL qboolean Loop_SearchForHosts (qboolean xmit); qsocket_t *Loop_Connect (const char *host); qsocket_t *Loop_CheckNewConnections (void); diff --git a/Quake/net_main.c b/Quake/net_main.c index c5aa666a..4224d5c9 100644 --- a/Quake/net_main.c +++ b/Quake/net_main.c @@ -649,6 +649,22 @@ qsocket_t *NET_GetServerMessage(void) return NULL; } +/* +Spike: This function is for the menus+status command +Just queries each driver's public addresses (which often requires system-specific calls) +*/ +int NET_ListAddresses(qhostaddr_t *addresses, int maxaddresses) +{ + int result = 0; + for (net_driverlevel = 0; net_driverlevel < net_numdrivers; net_driverlevel++) + { + if (!net_drivers[net_driverlevel].initialized) + continue; + if (net_drivers[net_driverlevel].QueryAddresses) + result += net_drivers[net_driverlevel].QueryAddresses(addresses+result, maxaddresses-result); + } + return result; +} /* ================== diff --git a/Quake/net_win.c b/Quake/net_win.c index bef01920..a6314037 100644 --- a/Quake/net_win.c +++ b/Quake/net_win.c @@ -34,6 +34,7 @@ net_driver_t net_drivers[] = false, Loop_Init, Loop_Listen, + Loop_QueryAddresses, Loop_SearchForHosts, Loop_Connect, Loop_CheckNewConnections, @@ -51,6 +52,7 @@ net_driver_t net_drivers[] = false, Datagram_Init, Datagram_Listen, + Datagram_QueryAddresses, Datagram_SearchForHosts, Datagram_Connect, Datagram_CheckNewConnections, @@ -79,6 +81,7 @@ net_landriver_t net_landrivers[] = WINIPv4_Init, WINIPv4_Shutdown, WINIPv4_Listen, + WINIPv4_GetAddresses, WINIPv4_OpenSocket, WINS_CloseSocket, WINS_Connect, @@ -102,6 +105,7 @@ net_landriver_t net_landrivers[] = WINIPv6_Init, WINIPv6_Shutdown, WINIPv6_Listen, + WINIPv6_GetAddresses, WINIPv6_OpenSocket, WINS_CloseSocket, WINS_Connect, @@ -125,6 +129,7 @@ net_landriver_t net_landrivers[] = WIPX_Init, WIPX_Shutdown, WIPX_Listen, + WIPX_GetAddresses, WIPX_OpenSocket, WIPX_CloseSocket, WIPX_Connect, diff --git a/Quake/net_wins.c b/Quake/net_wins.c index e8347608..048eb605 100644 --- a/Quake/net_wins.c +++ b/Quake/net_wins.c @@ -47,6 +47,7 @@ static in_addr6_t myAddrv6, bindAddrv6; //we don't use hybrid sockets, so things are a little easier when it comes to xp vs vista. //we don't detect the win2k ipv6 tech preview thing. it has different sized addresses, so lets hope microsoft's code handles that if it ever comes up. int (WSAAPI *qgetaddrinfo)(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res); +void (WSAAPI *qfreeaddrinfo)(const struct addrinfo *ai); #include "net_wins.h" @@ -580,6 +581,65 @@ int WINIPv4_GetNameFromAddr (struct qsockaddr *addr, char *name) return 0; } +int WINIPv4_GetAddresses (qhostaddr_t *addresses, int maxaddresses) +{ + int result = 0, b; + struct hostent *h; + + if (bindAddrv4 == INADDR_ANY) + { + //on windows, we can just do a dns lookup on our own hostname and expect an ipv4 result + char hostname[64]; + u_long addr; + gethostname(hostname, sizeof(hostname)); + + h = gethostbyname(hostname); + if(h && h->h_addrtype == AF_INET) + { + for (b = 0; h->h_addr_list[b] && result < maxaddresses; b++) + { + addr = ntohl(*(in_addr_t *)h->h_addr_list[b]); + q_snprintf(addresses[result++], sizeof(addresses[0]), "%ld.%ld.%ld.%ld", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); + } + } + } + + if (!result) + q_strlcpy(addresses[result++], my_ipv4_address, sizeof(addresses[0])); + return result; +} +int WINIPv6_GetAddresses (qhostaddr_t *addresses, int maxaddresses) +{ + int result = 0; + +// if (bindAddrv6 == IN6ADDR_ANY_INIT) + { + //on windows, we can just do a dns lookup on our own hostname and expect an ipv4 result + struct addrinfo hints, *addrlist, *itr; + char hostname[64]; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_INET6; /* Allow IPv4 or IPv6 */ + hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ + hints.ai_flags = 0; + hints.ai_protocol = 0; /* Any protocol */ + + gethostname(hostname, sizeof(hostname)); + if (qgetaddrinfo(hostname, NULL, &hints, &addrlist) == 0) + { + for (itr = addrlist; itr && result < maxaddresses; itr = itr->ai_next) + { + if (itr->ai_addr->sa_family == AF_INET6) + q_strlcpy(addresses[result++], WINS_AddrToString((struct qsockaddr*)itr->ai_addr, false), sizeof(addresses[0])); + } + freeaddrinfo(addrlist); + } + } + + if (!result) + q_strlcpy(addresses[result++], my_ipv6_address, sizeof(addresses[0])); + return result; +} + //============================================================================= int WINIPv4_GetAddrFromName (const char *name, struct qsockaddr *addr) @@ -718,7 +778,7 @@ static void WINIPv6_GetLocalAddress (void) l = strlen(my_ipv6_address); if (l > 2 && !strcmp(my_ipv6_address+l-2, ":0")) my_ipv6_address[l-2] = 0; - freeaddrinfo(local); + qfreeaddrinfo(local); } err = WSAGetLastError(); #ifndef _USE_WINSOCK2 @@ -742,8 +802,11 @@ sys_socket_t WINIPv6_Init (void) return -1; qgetaddrinfo = (void*)GetProcAddress(GetModuleHandle("ws2_32.dll"), "getaddrinfo"); - if (!qgetaddrinfo) + qfreeaddrinfo = (void*)GetProcAddress(GetModuleHandle("ws2_32.dll"), "freeaddrinfo"); + if (!qgetaddrinfo || !qfreeaddrinfo) { + qgetaddrinfo = NULL; + qfreeaddrinfo = NULL; Con_SafePrintf("Winsock lacks getaddrinfo, ipv6 support is unavailable.\n"); return INVALID_SOCKET; } diff --git a/Quake/net_wins.h b/Quake/net_wins.h index 81b92195..82172124 100644 --- a/Quake/net_wins.h +++ b/Quake/net_wins.h @@ -35,6 +35,7 @@ int WINS_SetSocketPort (struct qsockaddr *addr, int port); sys_socket_t WINIPv4_Init (void); void WINIPv4_Shutdown (void); sys_socket_t WINIPv4_Listen (qboolean state); +int WINIPv4_GetAddresses (qhostaddr_t *addresses, int maxaddresses); sys_socket_t WINIPv4_OpenSocket (int port); sys_socket_t WINIPv4_CheckNewConnections (void); int WINIPv4_Broadcast (sys_socket_t socketid, byte *buf, int len); @@ -47,6 +48,7 @@ int WINIPv4_GetAddrFromName (const char *name, struct qsockaddr *addr); sys_socket_t WINIPv6_Init (void); void WINIPv6_Shutdown (void); sys_socket_t WINIPv6_Listen (qboolean state); +int WINIPv6_GetAddresses (qhostaddr_t *addresses, int maxaddresses); sys_socket_t WINIPv6_OpenSocket (int port); sys_socket_t WINIPv6_CheckNewConnections (void); int WINIPv6_Broadcast (sys_socket_t socketid, byte *buf, int len); diff --git a/Quake/net_wipx.c b/Quake/net_wipx.c index 64b5e985..356703e3 100644 --- a/Quake/net_wipx.c +++ b/Quake/net_wipx.c @@ -108,6 +108,14 @@ sys_socket_t WIPX_Init (void) return net_controlsocket; } +int WIPX_GetAddresses (qhostaddr_t *addresses, int maxaddresses) +{ + int result = 0; + if (ipxAvailable) + q_strlcpy(addresses[result++], my_ipx_address, sizeof(addresses[0])); + return result; +} + //============================================================================= void WIPX_Shutdown (void) diff --git a/Quake/net_wipx.h b/Quake/net_wipx.h index 804b0e4d..0e66318b 100644 --- a/Quake/net_wipx.h +++ b/Quake/net_wipx.h @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. sys_socket_t WIPX_Init (void); void WIPX_Shutdown (void); sys_socket_t WIPX_Listen (qboolean state); +int WIPX_GetAddresses (qhostaddr_t *addresses, int maxaddresses); sys_socket_t WIPX_OpenSocket (int port); int WIPX_CloseSocket (sys_socket_t socketid); int WIPX_Connect (sys_socket_t socketid, struct qsockaddr *addr); diff --git a/Quake/pr_ext.c b/Quake/pr_ext.c index fb594b4a..e24993b0 100644 --- a/Quake/pr_ext.c +++ b/Quake/pr_ext.c @@ -4843,10 +4843,10 @@ static void PF_R_PolygonVertex(void) v->rgba[3] = G_FLOAT(OFS_PARM3); } static void PF_R_PolygonEnd(void) -{ - if (polygon_pic) - Draw_PicPolygon(polygon_pic, polygon_numverts, polygon_verts); - polygon_numverts = 0; +{ + if (polygon_pic) + Draw_PicPolygon(polygon_pic, polygon_numverts, polygon_verts); + polygon_numverts = 0; } static void PF_cl_cprint(void)