Display multiple local addresses on the create-game multiplayer menu.

Hopefully this wll be slightly more useful on multi-homed machines.
This commit is contained in:
Shpoike 2018-10-17 01:46:09 +01:00
parent 68ae3bfee7
commit aa8dd16dad
14 changed files with 196 additions and 31 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -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,

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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;
}
/*
==================

View file

@ -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,

View file

@ -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;
}

View file

@ -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);

View file

@ -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)

View file

@ -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);

View file

@ -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)