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 {
|
typedef struct server_entry_s {
|
||||||
char *server;
|
char *server;
|
||||||
char *desc;
|
char *desc;
|
||||||
|
char *status;
|
||||||
|
int waitstatus;
|
||||||
|
struct timeval pingsent;
|
||||||
|
struct timeval pongback;
|
||||||
struct server_entry_s *next;
|
struct server_entry_s *next;
|
||||||
struct server_entry_s *prev;
|
struct server_entry_s *prev;
|
||||||
} server_entry_t;
|
} server_entry_t;
|
||||||
|
@ -58,4 +62,5 @@ void SL_Shutdown(server_entry_t *start);
|
||||||
char *gettokstart(char *str, int req, char delim);
|
char *gettokstart(char *str, int req, char delim);
|
||||||
int gettoklen(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
|
#endif // _CL_SLIST_H
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "host.h"
|
#include "host.h"
|
||||||
#include "bothdefs.h"
|
#include "bothdefs.h"
|
||||||
|
@ -1002,9 +1004,30 @@ CL_ConnectionlessPacket (void)
|
||||||
}
|
}
|
||||||
// print command from somewhere
|
// print command from somewhere
|
||||||
if (c == A2C_PRINT) {
|
if (c == A2C_PRINT) {
|
||||||
Con_Printf ("print\n");
|
netadr_t addy;
|
||||||
|
server_entry_t *temp;
|
||||||
s = MSG_ReadString ();
|
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);
|
Con_Print (s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1048,6 +1071,23 @@ CL_ConnectionlessPacket (void)
|
||||||
Con_Printf ("unknown: %c\n", c);
|
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 ();
|
CL_ConnectionlessPacket ();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (*(char *) net_message.data == A2A_ACK)
|
||||||
|
{
|
||||||
|
CL_PingPacket ();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (net_message.cursize < 8) {
|
if (net_message.cursize < 8) {
|
||||||
Con_Printf ("%s: Runt packet\n", NET_AdrToString (net_from));
|
Con_Printf ("%s: Runt packet\n", NET_AdrToString (net_from));
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "cl_slist.h"
|
#include "cl_slist.h"
|
||||||
#include "bothdefs.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->server, ip);
|
||||||
strcpy (p->next->desc, desc);
|
strcpy (p->next->desc, desc);
|
||||||
p->next->next = 0;
|
|
||||||
|
|
||||||
return (start);
|
return (start);
|
||||||
}
|
}
|
||||||
|
@ -95,6 +96,8 @@ SL_Del (server_entry_t *start, server_entry_t *del)
|
||||||
|
|
||||||
free (del->server);
|
free (del->server);
|
||||||
free (del->desc);
|
free (del->desc);
|
||||||
|
if (del->status)
|
||||||
|
free (del->status);
|
||||||
if (del->prev)
|
if (del->prev)
|
||||||
del->prev->next = del->next;
|
del->prev->next = del->next;
|
||||||
if (del->next)
|
if (del->next)
|
||||||
|
@ -129,14 +132,25 @@ SL_InsB (server_entry_t *start, server_entry_t *place, char *ip, char *desc)
|
||||||
void
|
void
|
||||||
SL_Swap (server_entry_t *swap1, server_entry_t *swap2)
|
SL_Swap (server_entry_t *swap1, server_entry_t *swap2)
|
||||||
{
|
{
|
||||||
char *p;
|
server_entry_t *next1, *next2, *prev1, *prev2;
|
||||||
|
int i;
|
||||||
|
|
||||||
p = swap1->server;
|
next1 = swap1->next;
|
||||||
swap1->server = swap2->server;
|
next2 = swap2->next;
|
||||||
swap2->server = p;
|
prev1 = swap1->prev;
|
||||||
p = swap1->desc;
|
prev2 = swap2->prev;
|
||||||
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 *
|
server_entry_t *
|
||||||
|
@ -236,6 +250,8 @@ SL_Del_All (server_entry_t *start)
|
||||||
n = start->next;
|
n = start->next;
|
||||||
free (start->server);
|
free (start->server);
|
||||||
free (start->desc);
|
free (start->desc);
|
||||||
|
if (start->status)
|
||||||
|
free (start->status);
|
||||||
free (start);
|
free (start);
|
||||||
start = n;
|
start = n;
|
||||||
}
|
}
|
||||||
|
@ -287,3 +303,14 @@ gettoklen (char *str, int req, char delim)
|
||||||
}
|
}
|
||||||
return len;
|
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"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "host.h"
|
#include "host.h"
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -49,6 +52,8 @@
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
#include "cl_main.h"
|
#include "cl_main.h"
|
||||||
#include "cl_input.h"
|
#include "cl_input.h"
|
||||||
|
#include "net.h"
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
void (*vid_menudrawfn) (void);
|
void (*vid_menudrawfn) (void);
|
||||||
void (*vid_menukeyfn) (int key);
|
void (*vid_menukeyfn) (int key);
|
||||||
|
@ -1048,10 +1053,13 @@ M_SinglePlayer_Key (key)
|
||||||
#define STAT_X 50
|
#define STAT_X 50
|
||||||
#define STAT_Y 122
|
#define STAT_Y 122
|
||||||
|
|
||||||
int m_multip_cursor = 0;
|
static int m_multip_cursor = 0;
|
||||||
int m_multip_mins = 0;
|
static int m_multip_mins = 0;
|
||||||
int m_multip_maxs = 10;
|
static int m_multip_maxs = 10;
|
||||||
int m_multip_horiz;
|
static int m_multip_horiz;
|
||||||
|
|
||||||
|
static server_entry_t *pingupdate = 0;
|
||||||
|
static server_entry_t *statusupdate = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
M_Menu_MultiPlayer_f (void)
|
M_Menu_MultiPlayer_f (void)
|
||||||
|
@ -1070,7 +1078,9 @@ M_MultiPlayer_Draw (void)
|
||||||
server_entry_t *cp;
|
server_entry_t *cp;
|
||||||
qpic_t *p;
|
qpic_t *p;
|
||||||
|
|
||||||
// int f;
|
static double lastping = 0;
|
||||||
|
|
||||||
|
int f;
|
||||||
|
|
||||||
M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp"));
|
M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp"));
|
||||||
p = Draw_CachePic ("gfx/p_multi.lmp");
|
p = Draw_CachePic ("gfx/p_multi.lmp");
|
||||||
|
@ -1082,27 +1092,96 @@ M_MultiPlayer_Draw (void)
|
||||||
M_PrintWhite (140, 13 * 8, "found.");
|
M_PrintWhite (140, 13 * 8, "found.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
M_DrawTextBox (STAT_X, STAT_Y, 23, 4);
|
M_DrawTextBox (STAT_X, STAT_Y, 23, 7);
|
||||||
M_DrawTextBox (STAT_X, STAT_Y + 38, 23, 3);
|
//M_DrawTextBox (STAT_X, STAT_Y + 38, 23, 3);
|
||||||
M_DrawTextBox (MENU_X, MENU_Y, 23, (m_multip_maxs - m_multip_mins) + 1);
|
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);
|
for (serv = m_multip_mins; serv <= m_multip_maxs && serv < SL_Len (slist); serv++) {
|
||||||
serv++) {
|
|
||||||
cp = SL_Get_By_Num (slist, serv);
|
cp = SL_Get_By_Num (slist, serv);
|
||||||
M_Print (MENU_X + 18, line * 8 + MENU_Y,
|
M_Print (MENU_X + 18, line * 8 + MENU_Y,
|
||||||
va ("%1.21s",
|
va ("%1.22s",
|
||||||
strlen (cp->desc) <=
|
strlen (cp->desc) <=
|
||||||
m_multip_horiz ? "" : cp->desc + m_multip_horiz));
|
m_multip_horiz ? "" : cp->desc + m_multip_horiz));
|
||||||
line++;
|
line++;
|
||||||
}
|
}
|
||||||
cp = SL_Get_By_Num (slist, m_multip_cursor);
|
cp = SL_Get_By_Num (slist, m_multip_cursor);
|
||||||
M_PrintWhite (STAT_X + 18, STAT_Y + 16, "IP/Hostname:");
|
M_PrintWhite (STAT_X + 10, STAT_Y + 8, "IP/Hostname:");
|
||||||
M_Print (STAT_X + 18, STAT_Y + 24, cp->server);
|
M_Print (STAT_X + 10, STAT_Y + 16, cp->server);
|
||||||
M_DrawCharacter (MENU_X + 8,
|
if (pingupdate && realtime - lastping >= .25)
|
||||||
(m_multip_cursor - m_multip_mins + 1) * 8 + MENU_Y,
|
{
|
||||||
12 + ((int) (realtime * 4) & 1));
|
netadr_t addy;
|
||||||
// f = (int)(realtime * 10) % 6;
|
char data[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)));
|
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
|
void
|
||||||
|
@ -1161,7 +1240,37 @@ M_MultiPlayer_Key (key)
|
||||||
case 'E':
|
case 'E':
|
||||||
M_Menu_SEdit_f ();
|
M_Menu_SEdit_f ();
|
||||||
break;
|
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:
|
case K_INS:
|
||||||
|
if (pingupdate || statusupdate)
|
||||||
|
break;
|
||||||
S_LocalSound ("misc/menu2.wav");
|
S_LocalSound ("misc/menu2.wav");
|
||||||
if (!slist) {
|
if (!slist) {
|
||||||
m_multip_cursor = 0;
|
m_multip_cursor = 0;
|
||||||
|
@ -1172,6 +1281,8 @@ M_MultiPlayer_Key (key)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case K_DEL:
|
case K_DEL:
|
||||||
|
if (pingupdate || statusupdate)
|
||||||
|
break;
|
||||||
S_LocalSound ("misc/menu2.wav");
|
S_LocalSound ("misc/menu2.wav");
|
||||||
if (SL_Len (slist) > 0) {
|
if (SL_Len (slist) > 0) {
|
||||||
slist = SL_Del (slist, SL_Get_By_Num (slist, m_multip_cursor));
|
slist = SL_Del (slist, SL_Get_By_Num (slist, m_multip_cursor));
|
||||||
|
@ -1181,6 +1292,8 @@ M_MultiPlayer_Key (key)
|
||||||
break;
|
break;
|
||||||
case ']':
|
case ']':
|
||||||
case '}':
|
case '}':
|
||||||
|
if (pingupdate || statusupdate)
|
||||||
|
break;
|
||||||
S_LocalSound ("misc/menu1.wav");
|
S_LocalSound ("misc/menu1.wav");
|
||||||
if (m_multip_cursor != SL_Len (slist) - 1) {
|
if (m_multip_cursor != SL_Len (slist) - 1) {
|
||||||
SL_Swap (SL_Get_By_Num (slist, m_multip_cursor),
|
SL_Swap (SL_Get_By_Num (slist, m_multip_cursor),
|
||||||
|
@ -1190,6 +1303,8 @@ M_MultiPlayer_Key (key)
|
||||||
break;
|
break;
|
||||||
case '[':
|
case '[':
|
||||||
case '{':
|
case '{':
|
||||||
|
if (pingupdate || statusupdate)
|
||||||
|
break;
|
||||||
S_LocalSound ("misc/menu1.wav");
|
S_LocalSound ("misc/menu1.wav");
|
||||||
if (m_multip_cursor) {
|
if (m_multip_cursor) {
|
||||||
SL_Swap (SL_Get_By_Num (slist, m_multip_cursor),
|
SL_Swap (SL_Get_By_Num (slist, m_multip_cursor),
|
||||||
|
|
Loading…
Reference in a new issue