]> skyeroc.xyz Git - dgamelaunch/commitdiff
Add extra_info_file support. (Darshan Shaligram <scintilla@gmail.com>)
authorPasi Kallinen <paxed@alt.org>
Mon, 3 Oct 2011 15:00:14 +0000 (15:00 +0000)
committerPasi Kallinen <paxed@alt.org>
Mon, 3 Oct 2011 15:00:14 +0000 (15:00 +0000)
git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@595 db0b04b0-f4d1-0310-9a6d-de3e77497b0e

config.l
config.y
dgamelaunch.c
dgamelaunch.h
dgl-common.c
examples/dgamelaunch.conf

index afcc8a6691d5d718531b71bb4cd90faea54b68ea..e60493c76ace491ea6a690e9acde02fb6722ffb3 100644 (file)
--- a/config.l
+++ b/config.l
@@ -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; }
index 935e796edb7d645517f81752e8b49cdc8ef93949..4474b0c7e54c909e8512e67df8359bc83b4baaf5 100644 (file)
--- a/config.y
+++ b/config.y
@@ -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;
index 8575dc6ff5ba9e73b096bce161002e3e39dc9499..905ac4127ac0af626c7fa17c8f8fc1480ab80c00 100644 (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) {
index fdfe57925c9e5bed941ed821b660e44b106156bb..7be7b3a76e9538d9ecb06cf8348b908d8c0eb5b1 100644 (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 {
index dd6221d26fc32064f5498fbcd5e963c3512f6beb..6c93e744d5884e37ccb1ae536b550fb96c0e3a50 100644 (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++;
             }
         }
index d7bb306e3118c4420ffebadd2b5e0003a2f4a705..21c5ab1c90d65835d15c946fd31009066e7aa2db 100644 (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/"