diff --git a/src/server.h b/src/server.h index 75d8a9da..70c8cd8f 100644 --- a/src/server.h +++ b/src/server.h @@ -1008,6 +1008,7 @@ int Dem_CountTeamPlayers (char *t); char *quote (char *str); void CleanName_Init (void); void SV_LastScores_f (void); +void SV_LastStats_f (void); void SV_DemoList_f (void); void SV_DemoListRegex_f (void); void SV_MVDRemove_f (void); diff --git a/src/sv_demo_misc.c b/src/sv_demo_misc.c index a64dcd4f..20fe1433 100644 --- a/src/sv_demo_misc.c +++ b/src/sv_demo_misc.c @@ -968,9 +968,7 @@ void SV_MVDInfo_f (void) #define MAXDEMOS_RD_PACKET 100 void SV_LastScores_f (void) { - int demos = MAXDEMOS; - int i; - int nChars; + int demos = MAXDEMOS, i; char buf[512]; FILE *f = NULL; char path[MAX_OSPATH]; @@ -980,71 +978,136 @@ void SV_LastScores_f (void) if (Cmd_Argc() > 2) { Con_Printf("usage: lastscores []\n = '0' for all demos\n = '' for last %i demos\n", MAXDEMOS); - return; } if (Cmd_Argc() == 2) - { if ((demos = Q_atoi(Cmd_Argv(1))) <= 0) - { demos = MAXDEMOS; - } - } - dir = Sys_listdir(va("%s/%s", fs_gamedir, sv_demoDir.string), sv_demoRegexp.string, - SORT_BY_DATE); + dir = Sys_listdir(va("%s/%s", fs_gamedir, sv_demoDir.string), + sv_demoRegexp.string, SORT_BY_DATE); if (!dir.numfiles) { Con_Printf("No demos.\n"); - return; } if (demos > dir.numfiles) - { demos = dir.numfiles; - } if (demos > MAXDEMOS && GameStarted()) - { Con_Printf(" was decreased to %i: match is in progress.\n", - demos = MAXDEMOS); - } + demos = MAXDEMOS); if (demos > MAXDEMOS_RD_PACKET && sv_redirected == RD_PACKET) - { Con_Printf(" was decreased to %i: command from connectionless packet.\n", demos = MAXDEMOS_RD_PACKET); - } Con_Printf("List of %d last demos:\n", demos); - for (i = dir.numfiles - demos; i < dir.numfiles; i++) + for (i = dir.numfiles - demos; i < dir.numfiles; ) { snprintf(path, MAX_OSPATH, "%s/%s/%s", fs_gamedir, sv_demoDir.string, SV_MVDName2Txt(dir.files[i].name)); + Con_Printf("%i. ", ++i); if ((f = fopen(path, "rt")) == NULL) - { Con_Printf("(empty)\n"); - } else { + if (!feof(f)) + { + char *nl; + + buf[fread (buf, 1, sizeof(buf) - 1, f)] = 0; + if ((nl = strchr(buf, '\n'))) + nl[0] = 0; + Con_Printf("%s\n", Q_yelltext((unsigned char*)buf)); + } + else + Con_Printf("(empty)\n"); + fclose(f); + } + } +} + +#define STATS_LIMIT_DEFAULT 10 +#define STATS_LIMIT_MAX 50 +void SV_LastStats_f (void) +{ + int limit = STATS_LIMIT_DEFAULT; + int i; + char buf[512]; + FILE *f = NULL; + char path[MAX_OSPATH]; + dir_t dir; + extern redirect_t sv_redirected; + + if (sv_redirected != RD_PACKET) + { + return; + } + + if (Cmd_Argc() > 2) + { + Con_Printf("usage: laststats []\n = '0' for last %i stats\n = 'n' for last n stats (max %i)\n = '' (empty) for last %i stats\n", STATS_LIMIT_MAX, STATS_LIMIT_MAX, STATS_LIMIT_DEFAULT); + return; + } + else if (Cmd_Argc() == 2) + { + limit = Q_atoi(Cmd_Argv(1)); + + if (limit <= 0 || limit > STATS_LIMIT_MAX) + { + limit = STATS_LIMIT_MAX; + } + } + + dir = Sys_listdir(va("%s/%s", fs_gamedir, sv_demoDir.string), sv_demoRegexp.string, + SORT_BY_DATE); + + if (!dir.numfiles) + { + Con_Printf("laststats 0:\n"); + Con_Printf("[]\n"); + return; + } + + if (limit > dir.numfiles) + { + limit = dir.numfiles; + } + + Con_Printf("laststats %i\n", limit); + Con_Printf("[\n"); + + for (i = dir.numfiles - limit; i < dir.numfiles; i++) + { + snprintf(path, MAX_OSPATH, "%s/%s/%s", fs_gamedir, sv_demoDir.string, + SV_MVDName2Txt(dir.files[i].name)); + + if ((f = fopen(path, "rt")) != NULL) + { + if (i != dir.numfiles - limit) + { + Con_Printf(",\n"); + } + while (fread(buf, 1, sizeof(buf)-1, f)) { Con_Printf("%s", (unsigned char*)buf); memset(buf, 0, sizeof(buf)); } - - Con_Printf("\n"); - fclose(f); } } + + Con_Printf("\n]\n"); } // easyrecord helpers + int Dem_CountPlayers (void) { int i, count; diff --git a/src/sv_main.c b/src/sv_main.c index c6a26842..9629d9dd 100644 --- a/src/sv_main.c +++ b/src/sv_main.c @@ -679,6 +679,22 @@ static void SVC_LastScores (void) SV_EndRedirect (); } +/* +=================== +SVC_LastStats +=================== +*/ +void SV_LastStats_f (void); +static void SVC_LastStats (void) +{ + if(!(int)sv_allowlastscores.value) + return; + + SV_BeginRedirect (RD_PACKET); + SV_LastStats_f (); + SV_EndRedirect (); +} + /* =================== SVC_DemoList @@ -1893,6 +1909,8 @@ static void SV_ConnectionlessPacket (void) SVC_GetChallenge (); else if (!strcmp(c,"lastscores")) SVC_LastScores (); + else if (!strcmp(c,"laststats")) + SVC_LastStats (); else if (!strcmp(c,"dlist")) SVC_DemoList (); else if (!strcmp(c,"dlistr"))