static menuSound_t PingSelected(void) { serverslot_t *slot; netadr_t address; char *hostname; if (!m_servers.list.numItems) return QMS_BEEP; if (m_servers.list.curvalue < 0) return QMS_BEEP; slot = m_servers.list.items[m_servers.list.curvalue]; address = slot->address; hostname = slot->hostname; FreeSlot(slot); slot = UI_FormatColumns(SLOT_EXTRASIZE, hostname, "???", "???", "?/?", "???", NULL); slot->status = SLOT_PENDING; slot->address = address; slot->hostname = hostname; slot->color = U32_WHITE; slot->numRules = 0; slot->numPlayers = 0; slot->timestamp = com_eventTime; m_servers.list.items[m_servers.list.curvalue] = slot; UpdateStatus(); UpdateSelection(); CL_SendStatusRequest(&slot->address); return QMS_SILENT; }
static void BuildDir( const char *name, int type ) { demoEntry_t *e = UI_FormatColumns( DEMO_EXTRASIZE, name, "-", DEMO_DIR_SIZE, "-", "-", NULL ); e->type = type; e->size = 0; e->mtime = 0; m_demos.list.items[m_demos.list.numItems++] = e; }
static void AddServer(const netadr_t *address, const char *hostname) { netadr_t tmp; serverslot_t *slot; if (m_servers.list.numItems >= MAX_STATUS_SERVERS) return; if (!address) { // either address or hostname can be NULL, but not both if (!hostname) return; if (!NET_StringToAdr(hostname, &tmp, PORT_SERVER)) { Com_Printf("Bad server address: %s\n", hostname); return; } address = &tmp; } // ignore if already listed if (FindSlot(address, NULL)) return; if (!hostname) hostname = NET_AdrToString(address); // privileged ports are not allowed if (BigShort(address->port) < 1024) { Com_Printf("Bad server port: %s\n", hostname); return; } slot = UI_FormatColumns(SLOT_EXTRASIZE, hostname, "???", "???", "?/?", "???", NULL); slot->status = SLOT_IDLE; slot->address = *address; slot->hostname = UI_CopyString(hostname); slot->color = U32_WHITE; slot->numRules = 0; slot->numPlayers = 0; slot->timestamp = com_eventTime; m_servers.list.items[m_servers.list.numItems++] = slot; }
/* ================= UI_ErrorEvent An ICMP destination-unreachable error has been received. ================= */ void UI_ErrorEvent(netadr_t *from) { serverslot_t *slot; netadr_t address; char *hostname; unsigned timestamp, ping; int i; // ignore unless menu is up if (!m_servers.args) return; slot = FindSlot(from, &i); if (!slot) return; // only mark unreplied slots as invalid if (slot->status != SLOT_PENDING) return; address = slot->address; hostname = slot->hostname; timestamp = slot->timestamp; FreeSlot(slot); if (timestamp > com_eventTime) timestamp = com_eventTime; ping = com_eventTime - timestamp; if (ping > 999) ping = 999; slot = UI_FormatColumns(SLOT_EXTRASIZE, hostname, "???", "???", "down", va("%u", ping), NULL); slot->status = SLOT_ERROR; slot->address = address; slot->hostname = hostname; slot->color = U32_WHITE; slot->numRules = 0; slot->numPlayers = 0; slot->timestamp = timestamp; m_servers.list.items[i] = slot; }
/* ================= UI_StatusEvent A server status response has been received, validated and parsed. ================= */ void UI_StatusEvent(const serverStatus_t *status) { serverslot_t *slot; char *hostname, *host, *mod, *map, *maxclients; unsigned timestamp, ping; const char *info = status->infostring; char key[MAX_INFO_STRING]; char value[MAX_INFO_STRING]; int i; // ignore unless menu is up if (!m_servers.args) { return; } // see if already added slot = FindSlot(&net_from, &i); if (!slot) { // reply to broadcast, create new slot if (m_servers.list.numItems >= MAX_STATUS_SERVERS) { return; } m_servers.list.numItems++; hostname = UI_CopyString(NET_AdrToString(&net_from)); timestamp = m_servers.timestamp; } else { // free previous data hostname = slot->hostname; timestamp = slot->timestamp; FreeSlot(slot); } host = Info_ValueForKey(info, "hostname"); if (COM_IsWhite(host)) { host = hostname; } mod = Info_ValueForKey(info, "game"); if (COM_IsWhite(mod)) { mod = "baseq2"; } map = Info_ValueForKey(info, "mapname"); if (COM_IsWhite(map)) { map = "???"; } maxclients = Info_ValueForKey(info, "maxclients"); if (!COM_IsUint(maxclients)) { maxclients = "?"; } if (timestamp > com_eventTime) timestamp = com_eventTime; ping = com_eventTime - timestamp; if (ping > 999) ping = 999; slot = UI_FormatColumns(SLOT_EXTRASIZE, host, mod, map, va("%d/%s", status->numPlayers, maxclients), va("%u", ping), NULL); slot->status = SLOT_VALID; slot->address = net_from; slot->hostname = hostname; slot->color = ColorForStatus(status, ping); m_servers.list.items[i] = slot; slot->numRules = 0; while (slot->numRules < MAX_STATUS_RULES) { Info_NextPair(&info, key, value); if (!info) break; if (!key[0]) strcpy(key, "<MISSING KEY>"); if (!value[0]) strcpy(value, "<MISSING VALUE>"); slot->rules[slot->numRules++] = UI_FormatColumns(0, key, value, NULL); } slot->numPlayers = status->numPlayers; for (i = 0; i < status->numPlayers; i++) { slot->players[i] = UI_FormatColumns(0, va("%d", status->players[i].score), va("%d", status->players[i].ping), status->players[i].name, NULL); } slot->timestamp = timestamp; // don't sort when manually refreshing if (m_servers.pingstage) m_servers.list.sort(&m_servers.list); UpdateStatus(); UpdateSelection(); }
static void BuildName( const file_info_t *info, char **cache ) { char buffer[MAX_OSPATH]; char date[MAX_QPATH]; demoInfo_t demo; demoEntry_t *e; struct tm *tm; size_t len; memset( &demo, 0, sizeof( demo ) ); strcpy( demo.map, "???" ); strcpy( demo.pov, "???" ); if( cache ) { char *s = *cache; char *p = strchr( s, '\\' ); if( p ) { *p = 0; Q_strlcpy( demo.map, s, sizeof( demo.map ) ); s = p + 1; p = strchr( s, '\\' ); if( p ) { *p = 0; Q_strlcpy( demo.pov, s, sizeof( demo.pov ) ); s = p + 1; } } *cache = s; } else { Q_concat( buffer, sizeof( buffer ), m_demos.browse, "/", info->name, NULL ); CL_GetDemoInfo( buffer, &demo ); if( demo.mvd ) { strcpy( demo.pov, DEMO_MVD_POV ); } } // resize columns len = strlen( demo.map ); if( len > 8 ) { len = 8; } if( len > m_demos.widest_map ) { m_demos.widest_map = len; } len = strlen( demo.pov ); if( len > m_demos.widest_pov ) { m_demos.widest_pov = len; } // format date if( ( tm = localtime( &info->mtime ) ) != NULL ) { if( tm->tm_year == m_demos.year ) { strftime( date, sizeof( date ), "%b %d %H:%M", tm ); } else { strftime( date, sizeof( date ), "%b %d %Y", tm ); } } else { strcpy( date, "???" ); } Com_FormatSize( buffer, sizeof( buffer ), info->size ); e = UI_FormatColumns( DEMO_EXTRASIZE, info->name, date, buffer, demo.map, demo.pov, NULL ); e->type = ENTRY_DEMO; e->size = info->size; e->mtime = info->mtime; m_demos.total_bytes += info->size; m_demos.list.items[m_demos.list.numItems++] = e; }