mirror of
https://github.com/paxed/dgamelaunch.git
synced 2025-07-29 00:25:03 +02:00
Show the number of people watching each game in the watching-menu.
Also allow sorting by # of watchers. Requires dgamelaunch to be compiled with --enable-shmem git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@536 db0b04b0-f4d1-0310-9a6d-de3e77497b0e
This commit is contained in:
parent
6245e81b59
commit
113fc564ef
4
TODO
4
TODO
@ -9,8 +9,6 @@
|
|||||||
will no longer work, because the cursor won't be moved to the previous
|
will no longer work, because the cursor won't be moved to the previous
|
||||||
line again
|
line again
|
||||||
|
|
||||||
-change the watching-menu paging back to pre-1.5.0 behaviour
|
|
||||||
(don't backtrack in the gamelist to keep the last page full)
|
|
||||||
-when exiting from watching a player, move the cursor to the last line
|
-when exiting from watching a player, move the cursor to the last line
|
||||||
of the screen before enabling the ncurses mode; so when we exit dgl,
|
of the screen before enabling the ncurses mode; so when we exit dgl,
|
||||||
the watched player's game is all visible and the menu prompt doesn't
|
the watched player's game is all visible and the menu prompt doesn't
|
||||||
@ -118,8 +116,6 @@ or maybe add a new command '' set_charstrip "name" ''
|
|||||||
-public (no-password) accounts? (a per-user flag) what happens when someone
|
-public (no-password) accounts? (a per-user flag) what happens when someone
|
||||||
is playing on the account and someone else logins and we start playing?
|
is playing on the account and someone else logins and we start playing?
|
||||||
-allow users to run recover themselves
|
-allow users to run recover themselves
|
||||||
-make dgl show # of watchers. this would probably require adding a
|
|
||||||
shared memory block to keep track of who is watching who...
|
|
||||||
-configurable stuff: allowed chars in usernames,
|
-configurable stuff: allowed chars in usernames,
|
||||||
allow char stripping, ...
|
allow char stripping, ...
|
||||||
|
|
||||||
|
13
configure.ac
13
configure.ac
@ -144,6 +144,19 @@ if test "$enable_rlimit" = yes; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(shmem,
|
||||||
|
[AC_HELP_STRING([--enable-shmem], [Use a shared memory block to show number of watchers.])],
|
||||||
|
[enable_shmem=yes], [])
|
||||||
|
|
||||||
|
if test "$enable_shmem" = yes; then
|
||||||
|
AC_CHECK_HEADERS([semaphore.h], [], [AC_MSG_ERROR([semaphore.h not found.])], [])
|
||||||
|
AC_CHECK_HEADERS([sys/ipc.h], [], [AC_MSG_ERROR([sys/ipc.h not found.])], [])
|
||||||
|
AC_CHECK_HEADERS([sys/shm.h], [], [AC_MSG_ERROR([sys/shm.h not found.])], [])
|
||||||
|
AC_MSG_RESULT([Enabled showing number of watchers.])
|
||||||
|
AC_DEFINE(USE_SHMEM,1,[Use shared memory block])
|
||||||
|
LIBS="$LIBS -lrt"
|
||||||
|
# or -pthread?
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
AC_ARG_WITH(config-file,
|
AC_ARG_WITH(config-file,
|
||||||
|
240
dgamelaunch.c
240
dgamelaunch.c
@ -53,6 +53,12 @@
|
|||||||
#ifdef USE_RLIMIT
|
#ifdef USE_RLIMIT
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <curses.h>
|
#include <curses.h>
|
||||||
@ -408,18 +414,155 @@ drawbanner (struct dg_banner *ban, unsigned int start_line, unsigned int howmany
|
|||||||
mvaddstr (start_line + i, 1, ban->lines[i]);
|
mvaddstr (start_line + i, 1, ban->lines[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shm_sem_wait(struct dg_shm *shm_dg_data)
|
||||||
|
{
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
if (sem_wait(&(shm_dg_data->dg_sem)) == -1) {
|
||||||
|
debug_write("sem_wait");
|
||||||
|
graceful_exit(77);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shm_sem_post(struct dg_shm *shm_dg_data)
|
||||||
|
{
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
if (sem_post(&(shm_dg_data->dg_sem)) == -1) {
|
||||||
|
debug_write("sem_post");
|
||||||
|
graceful_exit(78);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shm_update(struct dg_shm *shm_dg_data, struct dg_game **games, int len)
|
||||||
|
{
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
int di, i;
|
||||||
|
struct dg_shm_game *shm_dg_game = (struct dg_shm_game *)(shm_dg_data + sizeof(struct dg_shm));
|
||||||
|
|
||||||
|
shm_sem_wait(shm_dg_data);
|
||||||
|
|
||||||
|
for (di = 0; di < shm_dg_data->max_n_games; di++)
|
||||||
|
if (shm_dg_game[di].in_use) {
|
||||||
|
int delgame = 1;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (!strcmp(games[i]->ttyrec_fn, shm_dg_game[di].ttyrec_fn)) {
|
||||||
|
delgame = 0;
|
||||||
|
games[i]->is_in_shm = 1;
|
||||||
|
games[i]->shm_idx = di;
|
||||||
|
games[i]->nwatchers = shm_dg_game[di].nwatchers;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (delgame) {
|
||||||
|
shm_dg_game[di].in_use = 0;
|
||||||
|
if (shm_dg_data->cur_n_games > 0) shm_dg_data->cur_n_games--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shm_dg_data->cur_n_games < shm_dg_data->max_n_games) {
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
if (!games[i]->is_in_shm) {
|
||||||
|
for (di = 0; di < shm_dg_data->max_n_games; di++)
|
||||||
|
if (!shm_dg_game[di].in_use) {
|
||||||
|
shm_dg_game[di].in_use = 1;
|
||||||
|
shm_dg_game[di].nwatchers = 0;
|
||||||
|
games[i]->nwatchers = 0;
|
||||||
|
games[i]->is_in_shm = 1;
|
||||||
|
games[i]->shm_idx = di;
|
||||||
|
shm_dg_data->cur_n_games++;
|
||||||
|
strncpy(shm_dg_game[di].ttyrec_fn, games[i]->ttyrec_fn, 150);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shm_sem_post(shm_dg_data);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shm_mk_keys(key_t *shm_key, key_t *shm_sem_key)
|
||||||
|
{
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
if ((*shm_key = ftok("dgamelaunch", 'R')) == -1) {
|
||||||
|
debug_write("ftok shm_key");
|
||||||
|
graceful_exit(71);
|
||||||
|
}
|
||||||
|
if ((*shm_sem_key = ftok("dgamelaunch", 'S')) == -1) {
|
||||||
|
debug_write("ftok shm_sem_key");
|
||||||
|
graceful_exit(72);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shm_init(struct dg_shm **shm_dg_data, struct dg_shm_game **shm_dg_game)
|
||||||
|
{
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
key_t shm_key;
|
||||||
|
key_t shm_sem_key;
|
||||||
|
int shm_id;
|
||||||
|
int shm_size;
|
||||||
|
void *shm_data = NULL;
|
||||||
|
int shm_data_existed = 0;
|
||||||
|
|
||||||
|
shm_mk_keys(&shm_key, &shm_sem_key);
|
||||||
|
|
||||||
|
/* max. shm_n_games simultaneous games recorded in the shared memory */
|
||||||
|
shm_size = sizeof(struct dg_shm) + shm_n_games * sizeof(struct dg_shm_game);
|
||||||
|
|
||||||
|
/* connect to (and possibly create) the segment */
|
||||||
|
if ((shm_id = shmget(shm_key, shm_size, 0644 | IPC_CREAT | IPC_EXCL)) == -1) {
|
||||||
|
/* creation failed, so it already exists. attach to it */
|
||||||
|
shm_data_existed = 1;
|
||||||
|
if ((shm_id = shmget(shm_key, shm_size, 0644)) == -1) {
|
||||||
|
debug_write("shmget");
|
||||||
|
graceful_exit(73);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* attach to the segment to get a pointer to it: */
|
||||||
|
shm_data = shmat(shm_id, (void *)0, 0);
|
||||||
|
if (shm_data == (char *)(-1)) {
|
||||||
|
debug_write("shmat");
|
||||||
|
graceful_exit(74);
|
||||||
|
}
|
||||||
|
if (!shm_data) {
|
||||||
|
debug_write("shm_data == null");
|
||||||
|
graceful_exit(75);
|
||||||
|
}
|
||||||
|
|
||||||
|
(*shm_dg_data) = (struct dg_shm *)shm_data;
|
||||||
|
(*shm_dg_game) = (struct dg_shm_game *)(shm_data + sizeof(struct dg_shm));
|
||||||
|
|
||||||
|
if (!shm_data_existed && shm_data) {
|
||||||
|
memset(*shm_dg_game, 0, shm_n_games*sizeof(struct dg_shm_game));
|
||||||
|
(*shm_dg_data)->max_n_games = shm_n_games;
|
||||||
|
(*shm_dg_data)->cur_n_games = 0;
|
||||||
|
if (sem_init(&((*shm_dg_data)->dg_sem), 1,1) == -1) {
|
||||||
|
debug_write("sem_init");
|
||||||
|
graceful_exit(76);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* USE_SHMEM */
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
inprogressmenu (int gameid)
|
inprogressmenu (int gameid)
|
||||||
{
|
{
|
||||||
const char *selectorchars = "abcdefghijklmnoprstuvwxyzABCDEFGHIJKLMNOPRSTUVWXYZ";
|
const char *selectorchars = "abcdefghijklmnoprstuvwxyzABCDEFGHIJKLMNOPRSTUVWXYZ";
|
||||||
int i, menuchoice, len = 20, offset = 0;
|
int i, menuchoice, len = 20, offset = 0;
|
||||||
static dg_sortmode sortmode = NUM_SORTMODES;
|
static dg_sortmode sortmode = NUM_SORTMODES;
|
||||||
time_t ctime;
|
|
||||||
struct dg_game **games = NULL;
|
struct dg_game **games = NULL;
|
||||||
char ttyrecname[130], gametype[10];
|
char ttyrecname[130], gametype[10], idletime[10];
|
||||||
int *is_nhext;
|
int *is_nhext;
|
||||||
sigset_t oldmask, toblock;
|
sigset_t oldmask, toblock;
|
||||||
int idx = -1;
|
int idx = -1;
|
||||||
|
int shm_idx = -1;
|
||||||
int max_height = -1;
|
int max_height = -1;
|
||||||
int selected = -1;
|
int selected = -1;
|
||||||
|
|
||||||
@ -438,6 +581,11 @@ inprogressmenu (int gameid)
|
|||||||
|
|
||||||
int require_enter = 0; /* TODO: make configurable */
|
int require_enter = 0; /* TODO: make configurable */
|
||||||
|
|
||||||
|
int di;
|
||||||
|
|
||||||
|
struct dg_shm *shm_dg_data = NULL;
|
||||||
|
struct dg_shm_game *shm_dg_game = NULL;
|
||||||
|
|
||||||
if (sortmode == NUM_SORTMODES)
|
if (sortmode == NUM_SORTMODES)
|
||||||
sortmode = globalconfig.sortmode;
|
sortmode = globalconfig.sortmode;
|
||||||
|
|
||||||
@ -449,7 +597,10 @@ inprogressmenu (int gameid)
|
|||||||
graceful_exit(70);
|
graceful_exit(70);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shm_init(&shm_dg_data, &shm_dg_game);
|
||||||
|
|
||||||
games = populate_games (gameid, &len, NULL); /* FIXME: should be 'me' instead of 'NULL' */
|
games = populate_games (gameid, &len, NULL); /* FIXME: should be 'me' instead of 'NULL' */
|
||||||
|
shm_update(shm_dg_data, games, len);
|
||||||
games = sort_games (games, len, sortmode);
|
games = sort_games (games, len, sortmode);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@ -492,10 +643,15 @@ inprogressmenu (int gameid)
|
|||||||
dgl_sortprintw(SORTMODE_WINDOWSIZE, 29, "Size")
|
dgl_sortprintw(SORTMODE_WINDOWSIZE, 29, "Size")
|
||||||
dgl_sortprintw(SORTMODE_STARTTIME, 37, "Start date & time")
|
dgl_sortprintw(SORTMODE_STARTTIME, 37, "Start date & time")
|
||||||
dgl_sortprintw(SORTMODE_IDLETIME, 58, "Idle time")
|
dgl_sortprintw(SORTMODE_IDLETIME, 58, "Idle time")
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
dgl_sortprintw(SORTMODE_WATCHERS, 70, "Watchers")
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef dgl_sortprintw
|
#undef dgl_sortprintw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shm_sem_wait(shm_dg_data);
|
||||||
|
|
||||||
for (i = 0; i < max_height; i++)
|
for (i = 0; i < max_height; i++)
|
||||||
{
|
{
|
||||||
if (i + offset >= len)
|
if (i + offset >= len)
|
||||||
@ -511,16 +667,40 @@ inprogressmenu (int gameid)
|
|||||||
snprintf (gametype, sizeof gametype, "%3dx%3d",
|
snprintf (gametype, sizeof gametype, "%3dx%3d",
|
||||||
games[i + offset]->ws_col, games[i + offset]->ws_row);
|
games[i + offset]->ws_col, games[i + offset]->ws_row);
|
||||||
|
|
||||||
mvprintw (top_banner_hei + 1 + i, 1, "%c) %-15s %-5s %s %s %s %ldm %lds",
|
#ifdef USE_SHMEM
|
||||||
|
# define WATCH_LINE_FORMAT "%c) %-15s %-5s %s %s %s %-10s %i"
|
||||||
|
#else
|
||||||
|
# define WATCH_LINE_FORMAT "%c) %-15s %-5s %s %s %s %-10s"
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
time_t ctime;
|
||||||
|
(void) time(&ctime);
|
||||||
|
long secs = (ctime - games[i + offset]->idle_time) % 60;
|
||||||
|
long mins = (ctime - games[i + offset]->idle_time) / 60;
|
||||||
|
long hours= (ctime - games[i + offset]->idle_time) / (60*60);
|
||||||
|
if (hours)
|
||||||
|
snprintf(idletime, 10, "%ldh %ldm", hours, mins);
|
||||||
|
else
|
||||||
|
snprintf(idletime, 10, "%ldm %lds", mins, secs);
|
||||||
|
}
|
||||||
|
|
||||||
|
mvprintw (top_banner_hei + 1 + i, 1, WATCH_LINE_FORMAT,
|
||||||
selectorchars[i], games[i + offset]->name, myconfig[games[i + offset]->gamenum]->shortname, gametype,
|
selectorchars[i], games[i + offset]->name, myconfig[games[i + offset]->gamenum]->shortname, gametype,
|
||||||
games[i + offset]->date, games[i + offset]->time,
|
games[i + offset]->date, games[i + offset]->time,
|
||||||
(time (&ctime) - games[i + offset]->idle_time) / 60,
|
idletime,
|
||||||
(time (&ctime) - games[i + offset]->idle_time) % 60);
|
#ifdef USE_SHMEM
|
||||||
|
(games[i+offset]->is_in_shm ? shm_dg_game[games[i+offset]->shm_idx].nwatchers : -1)
|
||||||
|
#else
|
||||||
|
0
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
if (i + offset == selected) attroff(selected_attr);
|
if (i + offset == selected) attroff(selected_attr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shm_sem_post(shm_dg_data);
|
||||||
|
|
||||||
btm = dgl_local_LINES-btm_banner_hei-top_banner_hei;
|
btm = dgl_local_LINES-btm_banner_hei-top_banner_hei;
|
||||||
if (btm > i) btm = i+1;
|
if (btm > i) btm = i+1;
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
@ -592,6 +772,9 @@ inprogressmenu (int gameid)
|
|||||||
case 'q': case 'Q':
|
case 'q': case 'Q':
|
||||||
if (is_nhext) free(is_nhext);
|
if (is_nhext) free(is_nhext);
|
||||||
free_populated_games(games, len);
|
free_populated_games(games, len);
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
shmdt(shm_dg_data);
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case '.':
|
case '.':
|
||||||
@ -643,7 +826,16 @@ watchgame:
|
|||||||
clear ();
|
clear ();
|
||||||
refresh ();
|
refresh ();
|
||||||
endwin ();
|
endwin ();
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
if (games[idx]->is_in_shm) {
|
||||||
|
shm_idx = games[idx]->shm_idx;
|
||||||
|
shm_sem_wait(shm_dg_data);
|
||||||
|
if (shm_dg_game[shm_idx].in_use &&
|
||||||
|
!strcmp(shm_dg_game[shm_idx].ttyrec_fn, games[idx]->ttyrec_fn))
|
||||||
|
shm_dg_game[shm_idx].nwatchers++;
|
||||||
|
shm_sem_post(shm_dg_data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
resizey = games[idx]->ws_row;
|
resizey = games[idx]->ws_row;
|
||||||
resizex = games[idx]->ws_col;
|
resizex = games[idx]->ws_col;
|
||||||
if (loggedin)
|
if (loggedin)
|
||||||
@ -655,6 +847,16 @@ watchgame:
|
|||||||
setproctitle("%s", me->username);
|
setproctitle("%s", me->username);
|
||||||
else
|
else
|
||||||
setproctitle("<Anonymous>");
|
setproctitle("<Anonymous>");
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
if (games[idx]->is_in_shm) {
|
||||||
|
shm_sem_wait(shm_dg_data);
|
||||||
|
if (shm_dg_game[shm_idx].in_use &&
|
||||||
|
!strcmp(shm_dg_game[shm_idx].ttyrec_fn, games[idx]->ttyrec_fn) &&
|
||||||
|
(shm_dg_game[shm_idx].nwatchers > 0))
|
||||||
|
shm_dg_game[shm_idx].nwatchers--;
|
||||||
|
shm_sem_post(shm_dg_data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
initcurses ();
|
initcurses ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -662,6 +864,7 @@ watchgame:
|
|||||||
if (selected >= 0 && selected < len)
|
if (selected >= 0 && selected < len)
|
||||||
selectedgame = strdup(games[selected]->name);
|
selectedgame = strdup(games[selected]->name);
|
||||||
games = populate_games (gameid, &len, NULL); /* FIXME: should be 'me' instead of 'NULL' */
|
games = populate_games (gameid, &len, NULL); /* FIXME: should be 'me' instead of 'NULL' */
|
||||||
|
shm_update(shm_dg_data, games, len);
|
||||||
games = sort_games (games, len, sortmode);
|
games = sort_games (games, len, sortmode);
|
||||||
if (selectedgame) {
|
if (selectedgame) {
|
||||||
selected = -1;
|
selected = -1;
|
||||||
@ -676,6 +879,9 @@ watchgame:
|
|||||||
}
|
}
|
||||||
if (is_nhext) free(is_nhext);
|
if (is_nhext) free(is_nhext);
|
||||||
free_populated_games(games, len);
|
free_populated_games(games, len);
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
shmdt(shm_dg_data);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************* */
|
/* ************************************************************* */
|
||||||
@ -2061,7 +2267,7 @@ main (int argc, char** argv)
|
|||||||
|
|
||||||
__progname = basename(strdup(argv[0]));
|
__progname = basename(strdup(argv[0]));
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "qh:pf:aeW:")) != -1)
|
while ((c = getopt(argc, argv, "qh:pf:aeW:S")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -2089,6 +2295,26 @@ main (int argc, char** argv)
|
|||||||
wall_email_str = strdup(optarg);
|
wall_email_str = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'S': /* Free the shared memory block */
|
||||||
|
{
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
key_t shm, sem;
|
||||||
|
int shm_id;
|
||||||
|
int shm_size = sizeof(struct dg_shm) + shm_n_games * sizeof(struct dg_shm_game);
|
||||||
|
shm_mk_keys(&shm, &sem);
|
||||||
|
if ((shm_id = shmget(shm, shm_size, 0644)) != -1) {
|
||||||
|
shmctl(shm_id, IPC_RMID, NULL);
|
||||||
|
if (!silent) fprintf(stderr, "shmem block freed.\n");
|
||||||
|
} else {
|
||||||
|
if (!silent) fprintf(stderr, "nonexistent shmem block.\n");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (!silent) fprintf(stderr, "warning: dgamelaunch was compiled without shmem.\n");
|
||||||
|
#endif
|
||||||
|
graceful_exit(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break; /*ignore */
|
break; /*ignore */
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
#include <semaphore.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef ARRAY_SIZE
|
#ifndef ARRAY_SIZE
|
||||||
# define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
# define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||||
#endif
|
#endif
|
||||||
@ -77,6 +81,22 @@ struct dg_menulist
|
|||||||
struct dg_menulist *next;
|
struct dg_menulist *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dg_shm
|
||||||
|
{
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
sem_t dg_sem;
|
||||||
|
#endif
|
||||||
|
int max_n_games;
|
||||||
|
int cur_n_games;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dg_shm_game
|
||||||
|
{
|
||||||
|
int in_use;
|
||||||
|
int nwatchers;
|
||||||
|
char ttyrec_fn[150];
|
||||||
|
};
|
||||||
|
|
||||||
struct dg_game
|
struct dg_game
|
||||||
{
|
{
|
||||||
char *ttyrec_fn;
|
char *ttyrec_fn;
|
||||||
@ -86,6 +106,9 @@ struct dg_game
|
|||||||
time_t idle_time;
|
time_t idle_time;
|
||||||
int ws_row, ws_col; /* Window size */
|
int ws_row, ws_col; /* Window size */
|
||||||
int gamenum;
|
int gamenum;
|
||||||
|
int is_in_shm;
|
||||||
|
int shm_idx;
|
||||||
|
int nwatchers;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dg_config
|
struct dg_config
|
||||||
@ -157,6 +180,9 @@ typedef enum
|
|||||||
SORTMODE_WINDOWSIZE,
|
SORTMODE_WINDOWSIZE,
|
||||||
SORTMODE_STARTTIME,
|
SORTMODE_STARTTIME,
|
||||||
SORTMODE_IDLETIME,
|
SORTMODE_IDLETIME,
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
SORTMODE_WATCHERS,
|
||||||
|
#endif
|
||||||
NUM_SORTMODES
|
NUM_SORTMODES
|
||||||
} dg_sortmode;
|
} dg_sortmode;
|
||||||
|
|
||||||
@ -166,11 +192,16 @@ static const char *SORTMODE_NAME[NUM_SORTMODES] = {
|
|||||||
"Game",
|
"Game",
|
||||||
"Windowsize",
|
"Windowsize",
|
||||||
"Starttime",
|
"Starttime",
|
||||||
"Idletime"
|
"Idletime",
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
"Watchers",
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
|
extern int shm_n_games; /* TODO: make configurable */
|
||||||
|
|
||||||
extern char* config; /* file path */
|
extern char* config; /* file path */
|
||||||
extern struct dg_config **myconfig;
|
extern struct dg_config **myconfig;
|
||||||
extern char *chosen_name;
|
extern char *chosen_name;
|
||||||
|
21
dgl-common.c
21
dgl-common.c
@ -55,6 +55,8 @@ int loggedin = 0;
|
|||||||
char *chosen_name;
|
char *chosen_name;
|
||||||
int num_games = 0;
|
int num_games = 0;
|
||||||
|
|
||||||
|
int shm_n_games = 200;
|
||||||
|
|
||||||
int dgl_local_COLS = -1, dgl_local_LINES = -1;
|
int dgl_local_COLS = -1, dgl_local_LINES = -1;
|
||||||
int curses_resize = 0;
|
int curses_resize = 0;
|
||||||
|
|
||||||
@ -432,6 +434,19 @@ sort_game_starttime(const void *g1, const void *g2)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sort_game_watchers(const void *g1, const void *g2)
|
||||||
|
{
|
||||||
|
const struct dg_game *game1 = *(const struct dg_game **)g1;
|
||||||
|
const struct dg_game *game2 = *(const struct dg_game **)g2;
|
||||||
|
int i = dglsign(game1->nwatchers - game2->nwatchers);
|
||||||
|
if (!i)
|
||||||
|
i = strcmp(game1->time, game2->time);
|
||||||
|
if (!i)
|
||||||
|
return strcasecmp(game1->name, game2->name);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
struct dg_game **
|
struct dg_game **
|
||||||
sort_games (struct dg_game **games, int len, dg_sortmode sortmode)
|
sort_games (struct dg_game **games, int len, dg_sortmode sortmode)
|
||||||
{
|
{
|
||||||
@ -441,6 +456,9 @@ sort_games (struct dg_game **games, int len, dg_sortmode sortmode)
|
|||||||
case SORTMODE_WINDOWSIZE: qsort(games, len, sizeof(struct dg_game *), sort_game_windowsize); break;
|
case SORTMODE_WINDOWSIZE: qsort(games, len, sizeof(struct dg_game *), sort_game_windowsize); break;
|
||||||
case SORTMODE_IDLETIME: qsort(games, len, sizeof(struct dg_game *), sort_game_idletime); break;
|
case SORTMODE_IDLETIME: 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_STARTTIME: qsort(games, len, sizeof(struct dg_game *), sort_game_starttime); break;
|
||||||
|
#ifdef USE_SHMEM
|
||||||
|
case SORTMODE_WATCHERS: qsort(games, len, sizeof(struct dg_game *), sort_game_watchers); break;
|
||||||
|
#endif
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
return games;
|
return games;
|
||||||
@ -573,6 +591,9 @@ populate_games (int xgame, int *l, struct dg_user *me)
|
|||||||
games[len]->idle_time = pstat.st_mtime;
|
games[len]->idle_time = pstat.st_mtime;
|
||||||
|
|
||||||
games[len]->gamenum = game;
|
games[len]->gamenum = game;
|
||||||
|
games[len]->is_in_shm = 0;
|
||||||
|
games[len]->nwatchers = 0;
|
||||||
|
games[len]->shm_idx = -1;
|
||||||
|
|
||||||
n = read(fd, pidws, sizeof(pidws) - 1);
|
n = read(fd, pidws, sizeof(pidws) - 1);
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user