/* $Id: netsrvlist.c,v 1.18 2012/01/28 21:53:19 steffen Exp $ * netsrvlist.c - shows a list of possible servers.*/ #include "basic.h" #include "bomberclone.h" #include "basic.h" #include "bomberclone.h" #include "network.h" #include "menu.h" #include "ogcache-client.h" #include "broadcast.h" #define SRVLST_TIMEREBUILD 2000 _charlist srvlst_text[MAX_SRVLIST]; struct __srvlst_entry { char host[LEN_SERVERNAME]; char port[LEN_PORT]; char gamename[LEN_GAMENAME]; char version[LEN_VERSION]; int maxplayers; int curplayers; int ai_family; int ping; char comment[32]; } srvlst_dat[MAX_SRVLIST]; int srvlst_cnt = 0; /* will build up our srvlst list with * all servers we have in there */ void srvlist_rebuildlist () { int ogclst, i, j; char txt1[255]; char txt2[255]; char txt3[255]; /* delete the whole list */ for (i = 0; i < MAX_SRVLIST; i++) { srvlst_text[i].text[0] = 0; srvlst_text[i].next = NULL; srvlst_dat[i].host[0] = 0; srvlst_dat[i].port[0] = 0; srvlst_dat[i].version[0] = 0; srvlst_dat[i].gamename[0] = 0; srvlst_dat[i].comment[0] = 0; srvlst_dat[i].ping = -1; } srvlst_cnt = 0; /* add broadcasted list (j == LAN GAME) */ for (j = 1; j >= 0; j--) for (i = 0; i < BC_MAXENTRYS; i++) { if (broadcast_list[i].host[0] != 0 && broadcast_list[i].lan == j) { strncpy (srvlst_dat[srvlst_cnt].host, broadcast_list[i].host, LEN_SERVERNAME); strncpy (srvlst_dat[srvlst_cnt].port, broadcast_list[i].port, LEN_PORT); strncpy (srvlst_dat[srvlst_cnt].version, broadcast_list[i].version, LEN_VERSION); strncpy (srvlst_dat[srvlst_cnt].gamename, broadcast_list[i].gamename, LEN_GAMENAME); srvlst_dat[srvlst_cnt].ping = broadcast_list[i].ping; srvlst_dat[srvlst_cnt].curplayers = broadcast_list[i].curplayers; srvlst_dat[srvlst_cnt].maxplayers = broadcast_list[i].maxplayers; srvlst_dat[srvlst_cnt].ai_family = bman.net_ai_family; if (broadcast_list[i].lan) sprintf (srvlst_dat[srvlst_cnt].comment, "LAN"); else sprintf (srvlst_dat[srvlst_cnt].comment, "Inet"); srvlst_cnt++; } } /* add the OpenGameCache Entrys which are not in the broadcasted list */ if (bman.notifygamemaster) { for (ogclst = 0; (ogclst < MAX_OGC_ENTRYS && srvlst_cnt < MAX_SRVLIST); ogclst++) if ((ogc_array[ogclst].serial != -1) && (broadcast_find (ogc_array[ogclst].host, ogc_array[ogclst].port) == -1)) { srvlst_dat[srvlst_cnt].host[0] = 0; srvlst_dat[srvlst_cnt].port[0] = 0; srvlst_dat[srvlst_cnt].version[0] = 0; srvlst_dat[srvlst_cnt].gamename[0] = 0; srvlst_dat[srvlst_cnt].ping = -2; srvlst_dat[srvlst_cnt].ai_family = ogc_array[ogclst].ai_family; srvlst_dat[srvlst_cnt].curplayers = ogc_array[ogclst].curplayers; srvlst_dat[srvlst_cnt].maxplayers = ogc_array[ogclst].maxplayers; strncpy (srvlst_dat[srvlst_cnt].host,ogc_array[ogclst].host, LEN_SERVERNAME); strncpy (srvlst_dat[srvlst_cnt].port,ogc_array[ogclst].port, LEN_PORT); strncpy (srvlst_dat[srvlst_cnt].gamename,ogc_array[ogclst].gamename, LEN_GAMENAME); strncpy (srvlst_dat[srvlst_cnt].version,ogc_array[ogclst].version, LEN_VERSION); sprintf (srvlst_dat[srvlst_cnt].comment, "INet"); srvlst_cnt++; } } if (srvlst_cnt >= MAX_SRVLIST) d_fatal ("srvlist_rebuildlist : srvlst_cnt >= MAX_SRVLIST\n"); /* make the list viewable */ for (i = 0; i < srvlst_cnt; i++) { sprintf (txt3, "%d/%d",srvlst_dat[i].curplayers, srvlst_dat[i].maxplayers); if (srvlst_dat[i].ping == -2) txt2[0] = 0; else if (srvlst_dat[i].ping == -1) sprintf (txt2, "NoCon"); else sprintf (txt2, "%dms", srvlst_dat[i].ping); if (srvlst_dat[i].gamename[0] != 0) /* gamename is present */ sprintf (txt1, "%-15s %-5s %5s %-11s %-4s", srvlst_dat[i].gamename, txt3, txt2, srvlst_dat[i].version, srvlst_dat[i].comment); else { sprintf (txt1, "%s:%s", srvlst_dat[i].host, srvlst_dat[i].port); sprintf (txt1, "%-20s %5s %-11s %-4s", txt1,txt2, srvlst_dat[i].version, srvlst_dat[i].comment); } strncpy (srvlst_text[i].text, txt1, LEN_CHARENTRY); } if (srvlst_cnt == 0) strcpy (srvlst_text[0].text, "No Servers Found"); charlist_fillarraypointer (srvlst_text, srvlst_cnt); }; /* show a list of servers you can select */ void net_getserver () { int menuselect = 0, entry = 0, newentry = 0, eventstate, done, srvlst_lastrebuild = 0; _charlist *sel_entry = &srvlst_text[0]; _menu *menu; _menuitem *srvlst_listmenu; SDL_Event event; d_printf ("net_getserver\n"); broadcast_init (); if (bman.servername[0] != 0) return; // a server has already been selected if (bman.notifygamemaster) ogc_browsestart (); menu = menu_new ("Join a Game", 500, 400); srvlst_listmenu = menu_create_list (menu, "Host a Game", -1, 50, 475, 250, srvlst_text, &sel_entry, 1); menu_create_entry (menu, "IP :", -1, 320, 475, bman.servername, LEN_SERVERNAME+LEN_PORT + 2, MENU_entrytext, 2); menu_create_button (menu, "OK", -1, 350, 150, 0); menu_focus_id (menu, 1); menu->looprunning = 1; menu_draw (menu); while (menuselect != -1 && bman.state != GS_quit) { broadcast_loop (); if (bman.notifygamemaster) ogc_loop (); if ((timestamp - srvlst_lastrebuild) > SRVLST_TIMEREBUILD) { srvlist_rebuildlist (); srvlst_lastrebuild = timestamp; srvlst_listmenu->changed = 1; menu_draw (menu); } eventstate = s_fetchevent (&event); gfx_blitdraw (); done = menu_event_loop (menu, &event, eventstate); menuselect = menu->focus->id; newentry = sel_entry - &srvlst_text[0]; if ((newentry != entry || (bman.servername[0] == 0 && srvlst_dat[entry].host[0] != 0)) && menu->focus->id != 2) { entry = newentry; d_printf ("Selected Entry (%d) %s:%s Game:%s\n", entry, srvlst_dat[entry].host, srvlst_dat[entry].port, srvlst_dat[entry].gamename); if (srvlst_dat[entry].host[0] != 0 && srvlst_dat[entry].port[0] != 0 && srvlst_dat[entry].gamename[0] != 0) { /* test if there was a selection */ bman.net_ai_family = srvlst_dat[entry].ai_family; sprintf (bman.servername, "%s:%s", srvlst_dat[entry].host, srvlst_dat[entry].port); } srvlst_listmenu->changed = 1; menu_reload (menu); menu_draw (menu); } if (done) { switch (menuselect) { case (0): // Ok Join Selected Game menuselect = -1; break; case (1): // Join a Game entry = newentry; d_printf ("Selected Entry (%d) %s:%s Game:%s\n", entry, srvlst_dat[entry].host, srvlst_dat[entry].port, srvlst_dat[entry].gamename); if (srvlst_dat[entry].host[0] != 0 && srvlst_dat[entry].port[0] != 0 && srvlst_dat[entry].gamename[0] != 0) { /* test if there was a selection */ bman.net_ai_family = srvlst_dat[entry].ai_family; sprintf (bman.servername, "%s:%s", srvlst_dat[entry].host, srvlst_dat[entry].port); } srvlst_listmenu->changed = 1; menu_reload (menu); menu_draw (menu); menu_focus_id (menu, 0); break; } } if (done == -1) { menuselect = -1; bman.servername[0] = 0; } s_calctimesync (); } if (bman.notifygamemaster) ogc_browsestop (); menu_delete (menu); };