Add extra_info_file support. (Darshan Shaligram <scintilla@gmail.com>)

git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@595 db0b04b0-f4d1-0310-9a6d-de3e77497b0e
This commit is contained in:
Pasi Kallinen 2011-10-03 15:00:14 +00:00
parent e2af2199f4
commit 514e8808a9
6 changed files with 167 additions and 40 deletions

View File

@ -83,6 +83,7 @@ cursor { return TYPE_CURSOR; }
"lockfile" { return TYPE_PATH_LOCKFILE; }
"inprogressdir" { return TYPE_PATH_INPROGRESS; }
"game_args" { return TYPE_GAME_ARGS; }
extra_info_file { return TYPE_EXTRA_INFO_FILE; }
"max_idle_time" { return TYPE_MAX_IDLE_TIME; }
"rc_fmt" { return TYPE_RC_FMT; }
"ttyrecdir" { return TYPE_PATH_TTYREC; }

View File

@ -57,7 +57,7 @@ static int sortmode_number(const char *sortmode_name) {
%token TYPE_MALSTRING TYPE_PATH_INPROGRESS TYPE_GAME_ARGS TYPE_RC_FMT
%token TYPE_CMDQUEUE TYPE_DEFINE_MENU TYPE_BANNER_FILE TYPE_CURSOR
%token TYPE_POSTCMDQUEUE
%token TYPE_MAX_IDLE_TIME TYPE_MENU_MAX_IDLE_TIME
%token TYPE_MAX_IDLE_TIME TYPE_MENU_MAX_IDLE_TIME TYPE_EXTRA_INFO_FILE
%token <s> TYPE_VALUE
%token <i> TYPE_NUMBER TYPE_CMDQUEUENAME
%type <kt> KeyType
@ -422,6 +422,10 @@ game_definition : TYPE_CMDQUEUE
{
/* nothing */
}
| TYPE_EXTRA_INFO_FILE '=' TYPE_VALUE
{
myconfig[ncnf]->extra_info_file = strdup($3);
}
| TYPE_MAX_IDLE_TIME '=' TYPE_NUMBER
{
myconfig[ncnf]->max_idle_time = $3;

View File

@ -756,6 +756,78 @@ sortmode_increment(struct dg_watchcols **watchcols,
*sortmode = old_sortmode;
}
static
void
game_get_column_data(struct dg_game *game,
char selectorchar,
time_t ctime, struct dg_shm_game *shm_dg_game,
char *data, int bufsz, int *hilite,
dg_sortmode which_data)
{
*data = 0;
switch (which_data) {
default: break;
case SORTMODE_NONE:
data[0] = selectorchar; data[1] = '\0';
break;
case SORTMODE_USERNAME:
snprintf(data, bufsz, "%s", game->name);
break;
case SORTMODE_GAMENUM:
snprintf(data, bufsz, "%s",
myconfig[game->gamenum]->shortname);
break;
case SORTMODE_WINDOWSIZE:
snprintf(data, bufsz, "%3dx%3d", game->ws_col, game->ws_row);
if ((game->ws_col > COLS || game->ws_row > LINES))
*hilite = CLR_RED;
break;
case SORTMODE_STARTTIME:
snprintf(data, bufsz, "%s %s", game->date,
game->time);
break;
case SORTMODE_IDLETIME:
{
long secs, mins, hours;
secs = (ctime - game->idle_time);
hours = (secs / 3600);
secs -= (hours * 3600);
mins = (secs / 60) % 60;
secs -= (mins*60);
if (hours)
snprintf(data, 10, "%ldh %ldm", hours, mins);
else if (mins)
snprintf(data, 10, "%ldm %lds", mins, secs);
else if (secs > 4)
snprintf(data, 10, "%lds", secs);
else
snprintf(data, 10, " ");
break;
}
case SORTMODE_EXTRA_INFO:
if (game->extra_info)
strlcpy(data, game->extra_info, bufsz);
break;
#ifdef USE_SHMEM
case SORTMODE_WATCHERS:
snprintf(data, bufsz, "%li",
(game->is_in_shm ?
shm_dg_game[game->shm_idx].nwatchers : -1));
break;
#endif
}
data[bufsz - 1] = '\0';
}
void
inprogressmenu (int gameid)
{
@ -847,48 +919,15 @@ inprogressmenu (int gameid)
if (i + offset == selected) attron(selected_attr);
snprintf (gametype, sizeof gametype, "%3dx%3d",
games[i + offset]->ws_col, games[i + offset]->ws_row);
{
long secs, mins, hours;
secs = (ctime - games[i + offset]->idle_time);
hours = (secs / 3600);
secs -= (hours * 3600);
mins = (secs / 60) % 60;
secs -= (mins*60);
if (hours)
snprintf(idletime, 10, "%ldh %ldm", hours, mins);
else if (mins)
snprintf(idletime, 10, "%ldm %lds", mins, secs);
else if (secs > 4)
snprintf(idletime, 10, "%lds", secs);
else
snprintf(idletime, 10, " ");
}
for (curr_watchcol = watchcols; *curr_watchcol; ++curr_watchcol) {
struct dg_watchcols *col = *curr_watchcol;
char tmpbuf[80];
int hilite = 0;
switch (col->dat) {
default: break;
case 0: tmpbuf[0] = selectorchars[i]; tmpbuf[1] = '\0'; break;
case 1: snprintf(tmpbuf, 80, "%s", games[i + offset]->name); break;
case 2: snprintf(tmpbuf, 80, "%s", myconfig[games[i + offset]->gamenum]->shortname); break;
case 3:
snprintf(tmpbuf, 80, "%s", gametype);
if ((games[i+offset]->ws_col > COLS || games[i+offset]->ws_row > LINES))
hilite = CLR_RED;
break;
case 4: snprintf(tmpbuf, 80, "%s %s", games[i + offset]->date, games[i + offset]->time); break;
case 5: snprintf(tmpbuf, 80, "%s", idletime); break;
#ifdef USE_SHMEM
case 6: snprintf(tmpbuf, 80, "%li", (games[i+offset]->is_in_shm ? shm_dg_game[games[i+offset]->shm_idx].nwatchers : -1)); break;
#endif
}
tmpbuf[79] = '\0';
game_get_column_data(games[i + offset],
selectorchars[i],
ctime, shm_dg_game,
tmpbuf, sizeof tmpbuf, &hilite,
(dg_sortmode)col->dat);
if (hilite) attron(hilite);
mvprintw(top_banner_hei + 1 + i, col->x, col->fmt, tmpbuf);
if (hilite) {

View File

@ -81,6 +81,7 @@ typedef enum
SORTMODE_WINDOWSIZE,
SORTMODE_STARTTIME,
SORTMODE_IDLETIME,
SORTMODE_EXTRA_INFO,
#ifdef USE_SHMEM
SORTMODE_WATCHERS,
#endif
@ -94,6 +95,7 @@ static const char *SORTMODE_NAME[NUM_SORTMODES] = {
"Windowsize",
"Starttime",
"Idletime",
"Extrainfo",
#ifdef USE_SHMEM
"Watchers",
#endif
@ -175,6 +177,9 @@ struct dg_game
int is_in_shm;
int shm_idx;
int nwatchers;
char *extra_info;
int extra_info_weight;
};
struct dg_config
@ -192,6 +197,7 @@ struct dg_config
struct dg_cmdpart *cmdqueue;
struct dg_cmdpart *postcmdqueue;
int max_idle_time;
char *extra_info_file;
};
struct dg_watchcols {

View File

@ -47,7 +47,8 @@ struct dg_config defconfig = {
/* rc_fmt = */ "%rrcfiles/%n.nethackrc", /* [dglroot]rcfiles/[username].nethackrc */
/* cmdqueue = */ NULL,
/* postcmdqueue = */ NULL,
/* max_idle_time = */ 0
/* max_idle_time = */ 0,
/* extra_info_file = */ NULL
};
char* config = NULL;
@ -414,6 +415,16 @@ sort_game_idletime(const void *g1, const void *g2)
return strcasecmp(game1->name, game2->name);
}
static int
sort_game_extrainfo(const void *g1, const void *g2)
{
const int extra_weight1 =
(*(const struct dg_game **) g1)->extra_info_weight;
const int extra_weight2 =
(*(const struct dg_game **) g2)->extra_info_weight;
return dglsign(extra_weight2 - extra_weight1);
}
static int
sort_game_gamenum(const void *g1, const void *g2)
{
@ -477,6 +488,12 @@ sort_games (struct dg_game **games, int len, dg_sortmode sortmode)
qsort(games, len, sizeof(struct dg_game *), sort_game_idletime);
break;
case SORTMODE_STARTTIME: qsort(games, len, sizeof(struct dg_game *), sort_game_starttime); break;
case SORTMODE_EXTRA_INFO:
qsort(games, len, sizeof(struct dg_game *),
sort_game_extrainfo);
break;
#ifdef USE_SHMEM
case SORTMODE_WATCHERS:
(void) time(&sort_ctime);
@ -512,11 +529,50 @@ free_populated_games(struct dg_game **games, int len)
if (games[i]->name) free(games[i]->name);
if (games[i]->date) free(games[i]->date);
if (games[i]->time) free(games[i]->time);
if (games[i]->extra_info) free(games[i]->extra_info);
free(games[i]);
}
free(games);
}
static
void
game_read_extra_info(struct dg_game *game, const char *extra_info_file)
{
FILE *ei = NULL;
char *sep = NULL;
char buffer[120];
int buflen;
if (game->extra_info) {
free(game->extra_info);
game->extra_info = NULL;
}
game->extra_info_weight = 0;
if (!extra_info_file)
return;
if (!(ei = fopen(extra_info_file, "r")))
return;
*buffer = 0;
fgets(buffer, sizeof buffer, ei);
fclose(ei);
buflen = strlen(buffer);
if (buflen && buffer[buflen - 1] == '\n')
buffer[buflen - 1] = 0;
/* The extra info file format is <sort-weight>|<info> */
sep = strchr(buffer, '|');
game->extra_info = strdup(sep? sep + 1 : buffer);
if (sep) {
*sep = 0;
game->extra_info_weight = atoi(buffer);
}
}
struct dg_game **
populate_games (int xgame, int *l, struct dg_user *me)
{
@ -637,6 +693,17 @@ populate_games (int xgame, int *l, struct dg_user *me)
games[len]->ws_row = 24;
games[len]->ws_col = 80;
}
games[len]->extra_info = NULL;
games[len]->extra_info_weight = 0;
if (myconfig[game]->extra_info_file) {
char *extra_info_file =
dgl_format_str(game, NULL,
myconfig[game]->extra_info_file,
games[len]->name);
game_read_extra_info(games[len], extra_info_file);
}
len++;
}
}

View File

@ -221,6 +221,16 @@ menu["watchmenu_help"] {
# # receive a sighup. Default value is 0, which disables the idling timer.
# max_idle_time = 2000
#
# # Player-specific path to an extra information file written by the game
# # The game should write the extra information on one line in this format:
# # <numeric-weight>|extra-information
# # For example, the game might write: "100|Astral", "1|D:1", etc. to indicate
# # where the player is in the game world. The numeric weight is used when
# # a spectator sorts games by the extra information field: higher weights
# # will be sorted to appear before lower weights.
# #
# extra_info_file = "%rgamedir/%n.extrainfo"
#
# # Make sure the inprogress dir actually exists. default is "inprogress/"
# # Each game you define here must have it's own.
# inprogressdir = "%rinprogress-nethackstub/"