From d9da49c2a97e4e37dc0a9d8f8052636d14be2b2d Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Sun, 21 May 2000 20:14:09 +0000 Subject: [PATCH] The server address book now uses a linked list. I had some issues merging this with some of taniwha's changes, so it may not be perfect. Please test it. --- include/cl_slist.h | 38 ++++--- source/cl_main.c | 11 +- source/cl_slist.c | 275 +++++++++++++++++++++++++-------------------- source/menu.c | 91 ++++++++------- 4 files changed, 223 insertions(+), 192 deletions(-) diff --git a/include/cl_slist.h b/include/cl_slist.h index 939be47..bc515e3 100644 --- a/include/cl_slist.h +++ b/include/cl_slist.h @@ -30,24 +30,28 @@ $Id$ */ #include "quakeio.h" -#define MAX_SERVER_LIST 256 -typedef struct { - char *server; - char *description; - int ping; -} server_entry_t; +typedef struct server_entry_s { + char *server; + char *desc; + struct server_entry_s *next; + struct server_entry_s *prev; + } server_entry_t; + +extern server_entry_t *slist; + +server_entry_t *Server_List_Add(server_entry_t *start, char *ip, char *desc); +server_entry_t *Server_List_Del(server_entry_t *start, server_entry_t *del); +server_entry_t *Server_List_InsB(server_entry_t *start, server_entry_t *place, char *ip, char *desc); +void Server_List_Swap(server_entry_t *swap1, server_entry_t *swap2); +server_entry_t *Server_List_Get_By_Num(server_entry_t *start, int n); +int Server_List_Len(server_entry_t *start); -extern server_entry_t slist[MAX_SERVER_LIST]; +server_entry_t *Server_List_LoadF(QFile *f, server_entry_t *start); +void Server_List_SaveF(QFile *f, server_entry_t *start); -void Server_List_Init(void); -void Server_List_Shutdown(void); -int Server_List_Set(int i,char *addr,char *desc); -int Server_List_Reset_NoFree(int i); -int Server_List_Reset(int i); -void Server_List_Switch(int a,int b); -int Server_List_Len(void); -int Server_List_Load(QFile *f); -int Server_List_Save(QFile *f); -char *gettokstart (char *str, int req, char delim); +void Server_List_Del_All(server_entry_t *start); +void Server_List_Shutdown(server_entry_t *start); + +char *gettokstart(char *str, int req, char delim); int gettoklen(char *str, int req, char delim); diff --git a/source/cl_main.c b/source/cl_main.c index 47bc1d5..b7eac94 100644 --- a/source/cl_main.c +++ b/source/cl_main.c @@ -65,7 +65,7 @@ #else #include #endif -#include "cl_slist.h" +#include extern cvar_t *fs_basepath; extern cvar_t *fs_sharepath; @@ -1206,10 +1206,9 @@ void CL_Init (void) CL_InitPrediction (); CL_InitCam (); Pmove_Init (); - Server_List_Init (); //Init server list - - if ((servlist = Qopen("./servers.txt","r"))) { - Server_List_Load(servlist); + + if ((servlist = Qopen(va("%s/servers.txt",fs_basepath->string),"r"))) { + slist = Server_List_LoadF(servlist,slist); Qclose(servlist); } @@ -1808,7 +1807,7 @@ void Host_Shutdown(void) } isdown = true; - Server_List_Shutdown (); + Server_List_Shutdown (slist); Host_WriteConfiguration (); diff --git a/source/cl_slist.c b/source/cl_slist.c index 0867b50..e779368 100644 --- a/source/cl_slist.c +++ b/source/cl_slist.c @@ -36,109 +36,118 @@ #include "cl_slist.h" #include "bothdefs.h" #include "console.h" - -#include -#include +#include "commdef.h" +#include "zone.h" #include -//Better watch out for buffer overflows -server_entry_t slist[MAX_SERVER_LIST]; +extern cvar_t *fs_basepath; +server_entry_t *slist; + +server_entry_t *Server_List_Add (server_entry_t *start, char *ip, char *desc) { + server_entry_t *p; + p = start; + if (!start) { //Nothing at beginning of list, create it + start = Z_Malloc(sizeof(server_entry_t)); + start->prev = 0; + start->next = 0; + start->server = Z_Malloc(strlen(ip) + 1); + start->desc = Z_Malloc(strlen(desc) + 1); + strcpy(start->server,ip); + strcpy(start->desc,desc); + return (start); + } -void Server_List_Init(void) { // Do this or everything else will sig11 + for(p=start;p->next;p=p->next); //Get to end of list + + p->next = Z_Malloc(sizeof(server_entry_t)); + p->next->prev = p; + p->next->server = Z_Malloc(strlen(ip) + 1); + p->next->desc = Z_Malloc(strlen(desc) + 1); + + strcpy(p->next->server,ip); + strcpy(p->next->desc,desc); + p->next->next = 0; + + return (start); + } + +server_entry_t *Server_List_Del(server_entry_t *start, server_entry_t *del) { + server_entry_t *n; + if (del == start) { + Z_Free(start->server); + Z_Free(start->desc); + n = start->next; + if (n) + n->prev = 0; + Z_Free(start); + return (n); + } + + Z_Free(del->server); + Z_Free(del->desc); + if (del->prev) + del->prev->next = del->next; + if (del->next) + del->next->prev = del->prev; + Z_Free(del); + return (start); +} + +server_entry_t *Server_List_InsB (server_entry_t *start, server_entry_t *place, char *ip, char *desc) { + server_entry_t *new; + server_entry_t *other; + + new = Z_Malloc(sizeof(server_entry_t)); + new->server = Z_Malloc(strlen(ip) + 1); + new->desc = Z_Malloc(strlen(desc) + 1); + strcpy(new->server,ip); + strcpy(new->desc,desc); + other = place->prev; + if (other) + other->next = new; + place->prev = new; + new->next = place; + new->prev = other; + if (!other) + return new; + return start; +} + +void Server_List_Swap (server_entry_t *swap1, server_entry_t *swap2) { + char *p; + p = swap1->server; + swap1->server = swap2->server; + swap2->server = p; + p = swap1->desc; + swap1->desc = swap2->desc; + swap2->desc = p; +} + +server_entry_t *Server_List_Get_By_Num (server_entry_t *start, int n) { int i; - for(i=0;i < MAX_SERVER_LIST;i++) { - slist[i].server = '\0'; - slist[i].description = '\0'; - slist[i].ping = 0; - } + for (i=0;i < n;i++) + start = start->next; + if (!start) + return (0); + return (start); } - - -void Server_List_Shutdown(void) { // I am the liberator of memory. + +int Server_List_Len (server_entry_t *start) { int i; - QFile *f; - if (!(f = Qopen("./servers.txt","w"))) { - Con_Printf("Couldn't open servers.txt.\n"); - return; - } - Server_List_Save(f); - Qclose(f); - for(i=0;i < MAX_SERVER_LIST;i++) { - if (slist[i].server) - free(slist[i].server); - if (slist[i].description) - free(slist[i].description); - } -} - - -int Server_List_Set(int i,char *addr,char *desc) { - int len; - if (i < MAX_SERVER_LIST && i >= 0) { - if (slist[i].server) // (Re)allocate memory first - free(slist[i].server); - if (slist[i].description) - free(slist[i].description); - len = strlen(desc); - slist[i].server = malloc(strlen(addr) + 1); - slist[i].description = malloc(len + 1); - strcpy(slist[i].server,addr); - strcpy(slist[i].description,desc); - return 0; // Yay, we haven't segfaulted yet. - } - return 1; // Out of range -} -int Server_List_Reset_NoFree (int i) { //NEVER USE THIS UNLESS REALLY NEEDED - if (i < MAX_SERVER_LIST && i >= 0) { - slist[i].server = '\0'; - slist[i].description = '\0'; - slist[i].ping = 0; - return 0; - } - return 1; -} - -int Server_List_Reset (int i) { - if (i < MAX_SERVER_LIST && i >= 0) { - if (slist[i].server) - free(slist[i].server); - if (slist[i].description) - free(slist[i].description); - slist[i].server = '\0'; - slist[i].description = '\0'; - slist[i].ping = 0; - return 0; - } - return 1; -} - -void Server_List_Switch(int a,int b) { - server_entry_t temp; - memcpy(&temp,&slist[a],sizeof(temp)); - memcpy(&slist[a],&slist[b],sizeof(temp)); - memcpy(&slist[b],&temp,sizeof(temp)); -} - -int Server_List_Len (void) { - int i; - for (i = 0; i < MAX_SERVER_LIST && slist[i].server;i++) - ; + for (i=0;start;i++) + start=start->next; return i; -} - -int Server_List_Load (QFile *f) { // This could get messy - int serv = 0; - char line[256]; /* Long lines get truncated. */ - int c = ' '; /* int so it can be compared to EOF properly*/ - char *start; - int len; - int i; - char *addr; - - // Init again to clear the list -// Server_List_Shutdown(); -// Server_List_Init(); - while (serv < MAX_SERVER_LIST) { + } + +server_entry_t *Server_List_LoadF (QFile *f,server_entry_t *start) { // This could get messy + char line[256]; /* Long lines get truncated. */ + int c = ' '; /* int so it can be compared to EOF properly*/ + int len; + int i; + char *st; + char *addr; + + while (1) { //First, get a line i = 0; c = ' '; @@ -150,35 +159,55 @@ int Server_List_Load (QFile *f) { // This could get messy } } line[i - 1] = '\0'; // Now we can parse it - if ((start = gettokstart(line,1,' ')) != NULL) { - len = gettoklen(line,1,' '); - addr = malloc(len + 1); - strncpy(addr,&line[0],len); - addr[len] = '\0'; - if ((start = gettokstart(line,2,' '))) { - Server_List_Set(serv,addr,start); - } - else { - Server_List_Set(serv,addr,"Unknown"); - } - serv++; - } - if (c == EOF) // We're done - return 0; - } - return 0; + if ((st = gettokstart(line,1,' ')) != NULL) { + len = gettoklen(line,1,' '); + addr = Z_Malloc(len + 1); + strncpy(addr,&line[0],len); + addr[len] = '\0'; + if ((st = gettokstart(line,2,' '))) { + start = Server_List_Add(start,addr,st); + } + else { + start = Server_List_Add(start,addr,"Unknown"); + } + } + if (c == EOF) // We're done + return start; + } } -int Server_List_Save(QFile *f) { - int i; - for(i=0;i < MAX_SERVER_LIST;i++) { - if (slist[i].server) - Qprintf(f,"%s %s\n", - slist[i].server, - slist[i].description); - } - return 0; -} + void Server_List_SaveF (QFile *f,server_entry_t *start) { + do { + Qprintf(f,"%s %s\n",start->server,start->desc); + start = start->next; + + } while (start); + } + + void Server_List_Shutdown (server_entry_t *start) { + QFile *f; + if (start) { + if ((f = Qopen(va("%s/servers.txt",fs_basepath->string),"w"))) { + Server_List_SaveF(f,start); + Qclose(f); + } + Server_List_Del_All (start); + } + } + + void Server_List_Del_All (server_entry_t *start) { + server_entry_t *n; + while (start) { + n = start->next; + Z_Free(start->server); + Z_Free(start->desc); + Z_Free(start); + start = n; + } + } + + + char *gettokstart (char *str, int req, char delim) { char *start = str; diff --git a/source/menu.c b/source/menu.c index 6641e21..2e68f93 100644 --- a/source/menu.c +++ b/source/menu.c @@ -1164,6 +1164,7 @@ void M_Menu_MultiPlayer_f (void) { void M_MultiPlayer_Draw (void) { int serv; int line = 1; + server_entry_t *cp; qpic_t *p; //int f; @@ -1171,26 +1172,25 @@ void M_MultiPlayer_Draw (void) { p = Draw_CachePic("gfx/p_multi.lmp"); M_DrawPic((320-p->width)/2,4,p); - if (!(slist[0].server)) { + if (!slist) { M_DrawTextBox(60,80,23,4); M_PrintWhite(110,12*8,"No server list"); M_PrintWhite(140,13*8,"found."); return; } M_DrawTextBox(STAT_X,STAT_Y,23,4); - //M_DrawTextBox(STAT_X+96,STAT_Y+38,12,3); 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++) { - if (slist[serv].server) { - M_Print(MENU_X+18,line*8+MENU_Y, - va("%1.21s", - strlen(slist[serv].description) <= m_multip_horiz ? "" : slist[serv].description+m_multip_horiz)); - line++; - } + for (serv = m_multip_mins; serv <= m_multip_maxs && serv < Server_List_Len(slist); serv++) { + cp = Server_List_Get_By_Num(slist,serv); + M_Print(MENU_X+18,line*8+MENU_Y, + va("%1.21s", + strlen(cp->desc) <= m_multip_horiz ? "" : cp->desc+m_multip_horiz)); + line++; } + cp = Server_List_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,slist[m_multip_cursor].server); + 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; @@ -1199,8 +1199,8 @@ void M_MultiPlayer_Draw (void) { } void M_MultiPlayer_Key (key) { -// server_entry_t *pt; - if (!(slist[0].server) && key != K_ESCAPE && key != K_INS) + server_entry_t *temp; + if (!slist && key != K_ESCAPE && key != K_INS) return; switch(key) { case K_ESCAPE: @@ -1209,7 +1209,7 @@ void M_MultiPlayer_Key (key) { case KP_DOWNARROW: case K_DOWNARROW: S_LocalSound("misc/menu1.wav"); - if (m_multip_cursor < (MAX_SERVER_LIST-1) && slist[m_multip_cursor+1].server) { + if (Server_List_Get_By_Num(slist,m_multip_cursor+1)) { m_multip_cursor++; } break; @@ -1229,10 +1229,8 @@ void M_MultiPlayer_Key (key) { case K_PGDN: S_LocalSound("misc/menu1.wav"); m_multip_cursor += (m_multip_maxs - m_multip_mins); - if (m_multip_cursor >= MAX_SERVER_LIST) - m_multip_cursor = MAX_SERVER_LIST - 1; - while (!(slist[m_multip_cursor].server)) - m_multip_cursor--; + if (Server_List_Len(slist) - 1 < m_multip_cursor ) + m_multip_cursor = Server_List_Len(slist) - 1; break; case K_RIGHTARROW: S_LocalSound("misc/menu1.wav"); @@ -1248,7 +1246,7 @@ void M_MultiPlayer_Key (key) { m_state = m_main; M_ToggleMenu_f(); CL_Disconnect(); - strncpy(cls.servername,slist[m_multip_cursor].server,sizeof(cls.servername)-1); + strncpy(cls.servername,Server_List_Get_By_Num(slist,m_multip_cursor)->server,sizeof(cls.servername)-1); CL_BeginServerConnect(); break; case 'e': @@ -1257,37 +1255,28 @@ void M_MultiPlayer_Key (key) { break; case K_INS: S_LocalSound("misc/menu2.wav"); - if (Server_List_Len() < (MAX_SERVER_LIST-1)) { - memmove(&slist[m_multip_cursor+1], - &slist[m_multip_cursor], - (Server_List_Len() - m_multip_cursor)*sizeof(slist[0])); - Server_List_Reset_NoFree(m_multip_cursor); - Server_List_Set(m_multip_cursor,"127.0.0.1",""); + if (!slist) { + m_multip_cursor = 0; + slist = Server_List_Add(slist, "127.0.0.1",""); + } + else { + temp = Server_List_Get_By_Num(slist,m_multip_cursor); + slist = Server_List_InsB(slist, temp, "127.0.0.1",""); } break; case K_DEL: S_LocalSound("misc/menu2.wav"); - if (Server_List_Len() > 0) { - free(slist[m_multip_cursor].server); - free(slist[m_multip_cursor].description); - if (Server_List_Len()-1 == m_multip_cursor) { - Server_List_Reset_NoFree(m_multip_cursor); - m_multip_cursor = !m_multip_cursor ? 0 : m_multip_cursor-1; - - } - else { - memmove(&slist[m_multip_cursor], - &slist[m_multip_cursor+1], - (Server_List_Len()-m_multip_cursor-1) * sizeof(slist[0])); - Server_List_Reset_NoFree(Server_List_Len()-1); - } + if (Server_List_Len(slist) > 0) { + slist = Server_List_Del(slist, Server_List_Get_By_Num(slist,m_multip_cursor)); + if (Server_List_Len(slist) == m_multip_cursor && slist) + m_multip_cursor--; } break; case ']': case '}': S_LocalSound("misc/menu1.wav"); - if (m_multip_cursor != Server_List_Len() - 1) { - Server_List_Switch(m_multip_cursor,m_multip_cursor+1); + if (m_multip_cursor != Server_List_Len(slist) - 1) { + Server_List_Swap(Server_List_Get_By_Num(slist,m_multip_cursor),Server_List_Get_By_Num(slist,m_multip_cursor+1)); m_multip_cursor++; } break; @@ -1295,7 +1284,7 @@ void M_MultiPlayer_Key (key) { case '{': S_LocalSound("misc/menu1.wav"); if (m_multip_cursor) { - Server_List_Switch(m_multip_cursor,m_multip_cursor-1); + Server_List_Swap(Server_List_Get_By_Num(slist,m_multip_cursor),Server_List_Get_By_Num(slist,m_multip_cursor-1)); m_multip_cursor--; } break; @@ -1327,14 +1316,16 @@ int desc_min; int sedit_state; void M_Menu_SEdit_f (void) { + server_entry_t *c; key_dest = key_menu; m_entersound = true; m_state = m_sedit; sedit_state = 0; - strncpy(serv,slist[m_multip_cursor].server,255); - serv[strlen(slist[m_multip_cursor].server) + 1] = 0; - strncpy(desc,slist[m_multip_cursor].description,255); - desc[strlen(slist[m_multip_cursor].description) + 1] = 0; + c = Server_List_Get_By_Num(slist,m_multip_cursor); + strncpy(serv,c->server,255); + serv[strlen(c->server) + 1] = 0; + strncpy(desc,c->desc,255); + desc[strlen(c->desc) + 1] = 0; serv_max = strlen(serv) > SERV_L ? strlen(serv) : SERV_L; serv_min = serv_max - (SERV_L); desc_max = strlen(desc) > DESC_L ? strlen(desc) : DESC_L; @@ -1362,14 +1353,22 @@ void M_SEdit_Draw (void) { DESC_Y+8,10+((int)(realtime*4)&1)); } + void M_SEdit_Key (int key) { int l; + server_entry_t *c; switch (key) { case K_ESCAPE: M_Menu_MultiPlayer_f (); break; case K_ENTER: - Server_List_Set(m_multip_cursor,serv,desc); + c = Server_List_Get_By_Num(slist,m_multip_cursor); + free(c->server); + free(c->desc); + c->server = malloc(strlen(serv) + 1); + c->desc = malloc(strlen(desc) + 1); + strcpy(c->server,serv); + strcpy(c->desc,desc); M_Menu_MultiPlayer_f (); break; case K_UPARROW: