mirror of
https://git.code.sf.net/p/quake/newtree
synced 2025-01-22 16:01:25 +00:00
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:
parent
e537c27a70
commit
0210465303
4 changed files with 221 additions and 30 deletions
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -1066,7 +1106,11 @@ CL_ReadPackets (void)
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
p = swap1->server;
|
||||
swap1->server = swap2->server;
|
||||
swap2->server = p;
|
||||
p = swap1->desc;
|
||||
swap1->desc = swap2->desc;
|
||||
swap2->desc = p;
|
||||
next1 = swap1->next;
|
||||
next2 = swap2->next;
|
||||
prev1 = swap1->prev;
|
||||
prev2 = swap2->prev;
|
||||
|
||||
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;
|
||||
}
|
151
source/menu.c
151
source/menu.c
|
@ -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),
|
||||
|
|
Loading…
Reference in a new issue