/** * @brief Request weapon stats data from mod */ void Tracker_requestWeaponStats(void) { int i; qboolean onlybots = qtrue; char *P; if (!maprunning) { return; } strcpy(infostring, Cvar_InfoString(CVAR_SERVERINFO | CVAR_SERVERINFO_NOUPDATE)); P = Info_ValueForKey(infostring, "P"); strcpy(expect, "ws"); for (i = 0; i < sv_maxclients->value; i++) { if (svs.clients[i].state == CS_ACTIVE) { if (svs.clients[i].netchan.remoteAddress.type != NA_BOT) { onlybots = qfalse; querycl = i; } expectnum++; } } if (expectnum > 0) { Tracker_Send("wsc %i", expectnum); for (i = 0; i < sv_maxclients->value; i++) { if (svs.clients[i].state == CS_ACTIVE) { // send basic data is client is spectator if (P[i] == '3' || (svs.clients[i].netchan.remoteAddress.type == NA_BOT && onlybots)) { Tracker_Send("ws %i 0 0 0\\%s", i, Tracker_createClientInfo(i)); } } } if (querycl >= 0) { SV_ExecuteClientCommand(&svs.clients[querycl], "statsall", qtrue, qfalse); } } }
/** * @brief Frame function */ void Tracker_Frame(int msec) { if (!(sv_advert->integer & SVA_TRACKER)) { return; } if (catchBot == TR_BOT_CONNECT) { Tracker_ClientConnect(&svs.clients[catchBotNum]); catchBot = TR_BOT_NONE; } if (!(time(0) - waittime > t)) { return; } Tracker_Send("p"); // send ping to tb to show that server is still alive expectnum = 0; // reset before next statsall Tracker_requestWeaponStats(); t = time(0); }
/** * @brief Send info when client disconnects * @param[in] cl Client */ void Tracker_ClientDisconnect(client_t *cl) { if (!(sv_advert->integer & SVA_TRACKER)) { return; } Tracker_Send("disconnect %i", (int)(cl - svs.clients)); }
/** * @brief Send info about new client connected * @param[in] cl Client */ void Tracker_ClientConnect(client_t *cl) { if (!(sv_advert->integer & SVA_TRACKER)) { return; } Tracker_Send("connect %i %s %s", (int)(cl - svs.clients), Tracker_getGUID(cl), cl->name); }
/** * @brief Send info about server shutdown */ void Tracker_ServerStop(void) { if (!(sv_advert->integer & SVA_TRACKER)) { return; } Tracker_Send("stop"); }
/** * @brief Send info when map restarts * * Allows counting time from 0 again on TB */ void Tracker_MapRestart(void) { if (!(sv_advert->integer & SVA_TRACKER)) { return; } Tracker_Send("maprestart"); maprunning = qtrue; }
/** * @brief Send info when map has changed * @param[in] mapname Current Map */ void Tracker_Map(char *mapname) { if (!(sv_advert->integer & SVA_TRACKER)) { return; } Tracker_Send("map %s", mapname); maprunning = qtrue; }
/** * @brief Send info when map has finished * * Sometimes intermission is very long, so TB can show appropriate info to players */ void Tracker_MapEnd(void) { if (!(sv_advert->integer & SVA_TRACKER)) { return; } Tracker_Send("mapend"); Tracker_requestWeaponStats(); maprunning = qfalse; }
/** * @brief Send info when player changes his name * @param[in] cl Client */ void Tracker_ClientName(client_t *cl) { if (!(sv_advert->integer & SVA_TRACKER)) { return; } if (!*cl->name) { return; } Tracker_Send("name %i %s %s", (int)(cl - svs.clients), Tracker_getGUID(cl), Info_ValueForKey(cl->userinfo, "name")); }
/** * @brief Catches server command * @param clientNum Client ID (from 0 to MAX_CLIENTS) * @param[in] msg Message sends by backend */ qboolean Tracker_catchServerCommand(int clientNum, char *msg) { int slot; if (!(sv_advert->integer & SVA_TRACKER)) { return qfalse; } if (clientNum != querycl) { return qfalse; } if (expectnum == 0) { return qfalse; } if (!(!strncmp(expect, msg, strlen(expect)))) { return qfalse; } if (msg[strlen(msg) - 1] == '\n') { msg[strlen(msg) - 1] = '\0'; } if (!Q_strncmp("ws", msg, 2)) { expectnum--; if (expectnum == 0) { strcpy(expect, ""); querycl = -1; } slot = 0; sscanf(msg, "ws %i", &slot); Tracker_Send("%s\\%s", msg, Tracker_createClientInfo(slot)); return qtrue; } return qfalse; }
/** * @brief Send info when player changes his team * @param[in] cl Client */ void Tracker_TeamSwitch(client_t *cl) { Tracker_Send("team %i", (int)(cl - svs.clients)); }