This update changes the server list layout and adds server pinging and querying support. Use 'p' to update pings, 's' to update status information, and 'u' to do both at once. Feel free to abuse this and report any bugs that you find.

This commit is contained in:
Brian Koropoff 2000-12-25 02:36:36 +00:00
parent e537c27a70
commit 0210465303
4 changed files with 221 additions and 30 deletions

View file

@ -36,6 +36,10 @@
typedef struct server_entry_s {
char *server;
char *desc;
char *status;
int waitstatus;
struct timeval pingsent;
struct timeval pongback;
struct server_entry_s *next;
struct server_entry_s *prev;
} server_entry_t;
@ -58,4 +62,5 @@ void SL_Shutdown(server_entry_t *start);
char *gettokstart(char *str, int req, char delim);
int gettoklen(char *str, int req, char delim);
void timepassed (struct timeval *time1, struct timeval *time2);
#endif // _CL_SLIST_H

View file

@ -30,6 +30,8 @@
# include "config.h"
#endif
#include <ctype.h>
#include <sys/time.h>
#include <unistd.h>
#include "host.h"
#include "bothdefs.h"
@ -1002,9 +1004,30 @@ CL_ConnectionlessPacket (void)
}
// print command from somewhere
if (c == A2C_PRINT) {
Con_Printf ("print\n");
netadr_t addy;
server_entry_t *temp;
s = MSG_ReadString ();
for (temp = slist; temp; temp = temp->next)
if (temp->waitstatus)
{
NET_StringToAdr (temp->server, &addy);
if (NET_CompareBaseAdr (net_from, addy))
{
int i;
temp->status = realloc(temp->status, strlen(s) + 1);
strcpy(temp->status, s);
temp->waitstatus = 0;
for (i = 0; i < strlen(temp->status); i++)
if (temp->status[i] == '\n')
{
temp->status[i] = '\\';
break;
}
Con_Printf("status response\n");
return;
}
}
Con_Printf ("print\n");
Con_Print (s);
return;
}
@ -1048,6 +1071,23 @@ CL_ConnectionlessPacket (void)
Con_Printf ("unknown: %c\n", c);
}
void
CL_PingPacket (void)
{
server_entry_t *temp;
netadr_t addy;
MSG_ReadByte ();;
for (temp = slist; temp; temp = temp->next)
if ((temp->pingsent.tv_sec || temp->pingsent.tv_usec) && !temp->pongback.tv_sec && !temp->pongback.tv_usec)
{
NET_StringToAdr (temp->server, &addy);
if (NET_CompareBaseAdr (net_from, addy))
{
gettimeofday(&(temp->pongback), 0);
timepassed(&(temp->pingsent), &(temp->pongback));
}
}
}
/*
=================
@ -1061,12 +1101,16 @@ CL_ReadPackets (void)
while (CL_GetMessage ()) {
//
// remote command packet
//
//
if (*(int *) net_message.data == -1) {
CL_ConnectionlessPacket ();
continue;
}
if (*(char *) net_message.data == A2A_ACK)
{
CL_PingPacket ();
continue;
}
if (net_message.cursize < 8) {
Con_Printf ("%s: Runt packet\n", NET_AdrToString (net_from));
continue;

View file

@ -34,6 +34,8 @@
#endif
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include "cl_slist.h"
#include "bothdefs.h"
@ -73,7 +75,6 @@ SL_Add (server_entry_t *start, char *ip, char *desc)
strcpy (p->next->server, ip);
strcpy (p->next->desc, desc);
p->next->next = 0;
return (start);
}
@ -95,6 +96,8 @@ SL_Del (server_entry_t *start, server_entry_t *del)
free (del->server);
free (del->desc);
if (del->status)
free (del->status);
if (del->prev)
del->prev->next = del->next;
if (del->next)
@ -129,14 +132,25 @@ SL_InsB (server_entry_t *start, server_entry_t *place, char *ip, char *desc)
void
SL_Swap (server_entry_t *swap1, server_entry_t *swap2)
{
char *p;
server_entry_t *next1, *next2, *prev1, *prev2;
int i;
next1 = swap1->next;
next2 = swap2->next;
prev1 = swap1->prev;
prev2 = swap2->prev;
p = swap1->server;
swap1->server = swap2->server;
swap2->server = p;
p = swap1->desc;
swap1->desc = swap2->desc;
swap2->desc = p;
for (i = 0; i < sizeof(server_entry_t); i++)
{
((char *)swap1)[i] ^= ((char *)swap2)[i];
((char *)swap2)[i] ^= ((char *)swap1)[i];
((char *)swap1)[i] ^= ((char *)swap2)[i];
}
swap1->next = next1;
swap2->next = next2;
swap1->prev = prev1;
swap2->prev = prev2;
}
server_entry_t *
@ -236,6 +250,8 @@ SL_Del_All (server_entry_t *start)
n = start->next;
free (start->server);
free (start->desc);
if (start->status)
free (start->status);
free (start);
start = n;
}
@ -287,3 +303,14 @@ gettoklen (char *str, int req, char delim)
}
return len;
}
void timepassed (struct timeval *time1, struct timeval *time2)
{
if (time2->tv_usec < time1->tv_usec)
{
time2->tv_usec = time2->tv_usec + 1000000;
time2->tv_sec--;
}
time2->tv_sec -= time1->tv_sec;
time2->tv_usec -= time1->tv_usec;
}

View file

@ -30,6 +30,9 @@
# include "config.h"
#endif
#include <sys/time.h>
#include <unistd.h>
#include "host.h"
#include "sys.h"
#ifdef _WIN32
@ -49,6 +52,8 @@
#include "view.h"
#include "cl_main.h"
#include "cl_input.h"
#include "net.h"
#include <netinet/in.h>
void (*vid_menudrawfn) (void);
void (*vid_menukeyfn) (int key);
@ -1048,10 +1053,13 @@ M_SinglePlayer_Key (key)
#define STAT_X 50
#define STAT_Y 122
int m_multip_cursor = 0;
int m_multip_mins = 0;
int m_multip_maxs = 10;
int m_multip_horiz;
static int m_multip_cursor = 0;
static int m_multip_mins = 0;
static int m_multip_maxs = 10;
static int m_multip_horiz;
static server_entry_t *pingupdate = 0;
static server_entry_t *statusupdate = 0;
void
M_Menu_MultiPlayer_f (void)
@ -1070,7 +1078,9 @@ M_MultiPlayer_Draw (void)
server_entry_t *cp;
qpic_t *p;
// int f;
static double lastping = 0;
int f;
M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp"));
p = Draw_CachePic ("gfx/p_multi.lmp");
@ -1082,27 +1092,96 @@ M_MultiPlayer_Draw (void)
M_PrintWhite (140, 13 * 8, "found.");
return;
}
M_DrawTextBox (STAT_X, STAT_Y, 23, 4);
M_DrawTextBox (STAT_X, STAT_Y + 38, 23, 3);
M_DrawTextBox (STAT_X, STAT_Y, 23, 7);
//M_DrawTextBox (STAT_X, STAT_Y + 38, 23, 3);
M_DrawTextBox (MENU_X, MENU_Y, 23, (m_multip_maxs - m_multip_mins) + 1);
for (serv = m_multip_mins; serv <= m_multip_maxs && serv < SL_Len (slist);
serv++) {
for (serv = m_multip_mins; serv <= m_multip_maxs && serv < SL_Len (slist); serv++) {
cp = SL_Get_By_Num (slist, serv);
M_Print (MENU_X + 18, line * 8 + MENU_Y,
va ("%1.21s",
va ("%1.22s",
strlen (cp->desc) <=
m_multip_horiz ? "" : cp->desc + m_multip_horiz));
line++;
}
cp = SL_Get_By_Num (slist, m_multip_cursor);
M_PrintWhite (STAT_X + 18, STAT_Y + 16, "IP/Hostname:");
M_Print (STAT_X + 18, STAT_Y + 24, cp->server);
M_DrawCharacter (MENU_X + 8,
(m_multip_cursor - m_multip_mins + 1) * 8 + MENU_Y,
12 + ((int) (realtime * 4) & 1));
// f = (int)(realtime * 10) % 6;
// M_PrintWhite(STAT_X+118,STAT_Y+58,"uakeforge!");
// M_DrawTransPic(STAT_X+105,STAT_Y+48,Draw_CachePic(va("gfx/menudot%i.lmp",f+1)));
M_PrintWhite (STAT_X + 10, STAT_Y + 8, "IP/Hostname:");
M_Print (STAT_X + 10, STAT_Y + 16, cp->server);
if (pingupdate && realtime - lastping >= .25)
{
netadr_t addy;
char data[6];
data[0] = '\377';
data[1] = '\377';
data[2] = '\377';
data[3] = '\377';
data[4] = A2A_PING;
data[5] = 0;
NET_StringToAdr (pingupdate->server, &addy);
if (!addy.port)
addy.port = ntohs (27500);
gettimeofday(&(pingupdate->pingsent), 0);
pingupdate->pongback.tv_sec = 0;
pingupdate->pongback.tv_usec = 0;
NET_SendPacket (6, data, addy);
pingupdate = pingupdate->next;
lastping = realtime;
}
if (statusupdate && realtime - lastping >= .25)
{
netadr_t addy;
char data[] = "\377\377\377\377status";
NET_StringToAdr (statusupdate->server, &addy);
if (!addy.port)
addy.port = ntohs (27500);
NET_SendPacket (strlen(data) + 1, data, addy);
statusupdate->waitstatus = 1;
statusupdate = statusupdate->next;
lastping = realtime;
}
if (!pingupdate && !statusupdate)
{
int playercount = 0, i;
M_PrintWhite (STAT_X + 10, STAT_Y + 24, "Ping:");
M_PrintWhite (STAT_X + 10, STAT_Y + 32, "Game:");
M_PrintWhite (STAT_X + 10, STAT_Y + 40, "Map:");
M_PrintWhite (STAT_X + 10, STAT_Y + 48, "Players:");
if (cp->pongback.tv_usec || cp->pongback.tv_sec)
M_Print (STAT_X + 58, STAT_Y + 24, va("%i", (int)(cp->pongback.tv_sec * 1000 + cp->pongback.tv_usec / 1000)));
else
M_Print (STAT_X + 58, STAT_Y + 24, "N/A");
if (cp->status)
{
for (i = 0; i < strlen(cp->status); i++)
if (cp->status[i] == '\n')
playercount++;
M_Print (STAT_X + 58, STAT_Y + 32, Info_ValueForKey (cp->status, "*gamedir"));
M_Print (STAT_X + 50, STAT_Y + 40, Info_ValueForKey (cp->status, "map"));
M_Print (STAT_X + 82, STAT_Y + 48, va("%i/%s", playercount, Info_ValueForKey(cp->status, "maxclients")));
}
else
{
M_Print (STAT_X + 58, STAT_Y + 32, "N/A");
M_Print (STAT_X + 50, STAT_Y + 40, "N/A");
M_Print (STAT_X + 82, STAT_Y + 48, "N/A");
}
}
else
{
M_PrintWhite (STAT_X + 10, STAT_Y + 24, "Updating...");
f = (int)(realtime * 10) % 6;
M_PrintWhite(STAT_X+118,STAT_Y+48,"uakeforge!");
M_DrawTransPic(STAT_X+105,STAT_Y+38,Draw_CachePic(va("gfx/menudot%i.lmp",f+1)));
}
M_DrawCharacter (MENU_X + 8, (m_multip_cursor - m_multip_mins + 1) * 8 + MENU_Y, 12 + ((int) (realtime * 4) & 1));
}
void
@ -1161,7 +1240,37 @@ M_MultiPlayer_Key (key)
case 'E':
M_Menu_SEdit_f ();
break;
case 'p':
case 'P':
if (pingupdate || statusupdate)
break;
pingupdate = slist;
for (temp = slist; temp; temp = temp->next)
temp->pingsent.tv_sec = temp->pingsent.tv_usec = temp->pongback.tv_sec = temp->pongback.tv_usec = 0;
break;
case 's':
case 'S':
if (pingupdate || statusupdate)
break;
statusupdate = slist;
for (temp = slist; temp; temp = temp->next)
temp->waitstatus = 0;
break;
case 'u':
case 'U':
if (pingupdate || statusupdate)
break;
pingupdate = slist;
statusupdate = slist;
for (temp = slist; temp; temp = temp->next)
{
temp->pingsent.tv_sec = temp->pingsent.tv_usec = temp->pongback.tv_sec = temp->pongback.tv_usec = 0;
temp->waitstatus = 0;
}
break;
case K_INS:
if (pingupdate || statusupdate)
break;
S_LocalSound ("misc/menu2.wav");
if (!slist) {
m_multip_cursor = 0;
@ -1172,6 +1281,8 @@ M_MultiPlayer_Key (key)
}
break;
case K_DEL:
if (pingupdate || statusupdate)
break;
S_LocalSound ("misc/menu2.wav");
if (SL_Len (slist) > 0) {
slist = SL_Del (slist, SL_Get_By_Num (slist, m_multip_cursor));
@ -1181,6 +1292,8 @@ M_MultiPlayer_Key (key)
break;
case ']':
case '}':
if (pingupdate || statusupdate)
break;
S_LocalSound ("misc/menu1.wav");
if (m_multip_cursor != SL_Len (slist) - 1) {
SL_Swap (SL_Get_By_Num (slist, m_multip_cursor),
@ -1190,6 +1303,8 @@ M_MultiPlayer_Key (key)
break;
case '[':
case '{':
if (pingupdate || statusupdate)
break;
S_LocalSound ("misc/menu1.wav");
if (m_multip_cursor) {
SL_Swap (SL_Get_By_Num (slist, m_multip_cursor),