From: Pasi Kallinen Date: Sat, 5 Apr 2008 13:29:19 +0000 (+0000) Subject: Admin-defineable menu structures. X-Git-Tag: v1.6.1-roc-dev~276 X-Git-Url: https://skyeroc.xyz/gitweb/?a=commitdiff_plain;h=9612c57b942029fa977f8d9348429b01791ee7d1;p=dgamelaunch Admin-defineable menu structures. git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@432 db0b04b0-f4d1-0310-9a6d-de3e77497b0e --- diff --git a/config.l b/config.l index 7c77b81..d688637 100644 --- a/config.l +++ b/config.l @@ -56,6 +56,8 @@ WHITE [\t ]* "]" { return ']'; } "{" { return '{'; } "}" { return '}'; } +"(" { return '('; } +")" { return ')'; } "shed_user" { return TYPE_SUSER; } "shed_group" { return TYPE_SGROUP; } "shed_uid" { return TYPE_SUID; } @@ -65,6 +67,9 @@ WHITE [\t ]* "allow_new_nicks" { return TYPE_ALLOW_REGISTRATION; } +menu { return TYPE_DEFINE_MENU; } +bannerfile { return TYPE_BANNER_FILE; } +cursor { return TYPE_CURSOR; } "chroot_path" { return TYPE_PATH_CHROOT; } "game_name" { return TYPE_NAME_GAME; } "short_name" { return TYPE_GAME_SHORT_NAME; } @@ -98,6 +103,10 @@ watch_menu { yylval.i = DGLCMD_WATCH_MENU; return TYPE_DGLCMD0; } ask_login { yylval.i = DGLCMD_LOGIN; return TYPE_DGLCMD0; } ask_register { yylval.i = DGLCMD_REGISTER; return TYPE_DGLCMD0; } quit { yylval.i = DGLCMD_QUIT; return TYPE_DGLCMD0; } +edit_options { yylval.i = DGLCMD_EDITOPTIONS; return TYPE_DGLCMD1; } +play_game { yylval.i = DGLCMD_PLAYGAME; return TYPE_DGLCMD1; } +submenu { yylval.i = DGLCMD_SUBMENU; return TYPE_DGLCMD1; } +return { yylval.i = DGLCMD_RETURN; return TYPE_DGLCMD0; } DEFINE { return TYPE_DEFINE_GAME; } diff --git a/config.y b/config.y index 8a63bd3..3f272fa 100644 --- a/config.y +++ b/config.y @@ -19,7 +19,8 @@ extern unsigned int line, col; extern int num_games; int ncnf = 0; -struct dg_cmdpart *curr_cmdqueue; +struct dg_cmdpart *curr_cmdqueue = NULL; +struct dg_menu *curr_menu = NULL; int cmdqueue_num = -1; static const char* lookup_token (int t); @@ -39,7 +40,7 @@ static const char* lookup_token (int t); %token TYPE_PATH_BANNER TYPE_PATH_CANNED TYPE_PATH_CHROOT %token TYPE_PATH_PASSWD TYPE_PATH_LOCKFILE %token TYPE_MALSTRING TYPE_PATH_INPROGRESS TYPE_GAME_ARGS TYPE_RC_FMT -%token TYPE_CMDQUEUE +%token TYPE_CMDQUEUE TYPE_DEFINE_MENU TYPE_BANNER_FILE TYPE_CURSOR %token TYPE_VALUE %token TYPE_NUMBER TYPE_CMDQUEUENAME %type KeyType @@ -80,6 +81,10 @@ KeyPair: TYPE_CMDQUEUE '[' TYPE_CMDQUEUENAME ']' globalconfig.cmdqueue[cmdqueue_num] = curr_cmdqueue; curr_cmdqueue = NULL; } + | definemenu + { + /* nothing */ + } | definegame { /* nothing */ @@ -238,6 +243,86 @@ KeyPair: TYPE_CMDQUEUE '[' TYPE_CMDQUEUENAME ']' } }; + + + +menu_definition : TYPE_BANNER_FILE '=' TYPE_VALUE + { + if (curr_menu->banner_fn) { + fprintf(stderr, "%s:%d: banner file already defined.\n", config, line); + exit(1); + } + curr_menu->banner_fn = strdup( $3 ); + } + | TYPE_CURSOR '=' '(' TYPE_NUMBER ',' TYPE_NUMBER ')' + { + if (curr_menu->cursor_x != -1) { + fprintf(stderr, "%s:%d: cursor position already defined.\n", config, line); + exit(1); + } + curr_menu->cursor_x = $4; + curr_menu->cursor_y = $6; + } + | TYPE_CMDQUEUE '[' TYPE_VALUE ']' + { + struct dg_menuoption *tmp; + struct dg_menuoption *tmpmenuopt; + if (curr_cmdqueue) { + fprintf(stderr, "%s:%d: command queue already in use?\n", config, line); + exit(1); + } + tmp = malloc(sizeof(struct dg_menuoption)); + tmp->keys = strdup( $3 ); + tmp->cmdqueue = NULL; + tmp->next = curr_menu->options; + curr_menu->options = tmp; + } + '=' cmdlist + { + curr_menu->options->cmdqueue = curr_cmdqueue; + curr_cmdqueue = NULL; + } + ; + + +menu_definitions : menu_definition + | menu_definition menu_definitions + ; + + +definemenu : TYPE_DEFINE_MENU '[' TYPE_VALUE ']' + { + struct dg_menulist *tmp_menulist = globalconfig.menulist; + + while (tmp_menulist) { + if (!strcmp(tmp_menulist->menuname, $3 )) { + fprintf(stderr, "%s:%d: menu \"%s\" already defined.\n", config, line, $3 ); + exit(1); + } + tmp_menulist = tmp_menulist->next; + } + + tmp_menulist = malloc(sizeof(struct dg_menulist)); + tmp_menulist->menuname = strdup( $3 ); + tmp_menulist->next = globalconfig.menulist; + + globalconfig.menulist = tmp_menulist; + + tmp_menulist->menu = malloc(sizeof(struct dg_menu)); + curr_menu = tmp_menulist->menu; + + curr_menu->options = NULL; + curr_menu->cursor_x = curr_menu->cursor_y = -1; + curr_menu->banner_fn = NULL; + } + '{' menu_definitions '}' + { + curr_menu = NULL; + } + ; + + + game_definition : TYPE_CMDQUEUE { if (myconfig[ncnf]->cmdqueue) { diff --git a/dgamelaunch.c b/dgamelaunch.c index d8d7b26..9bf13be 100644 --- a/dgamelaunch.c +++ b/dgamelaunch.c @@ -250,15 +250,49 @@ catch_sighup (int signum) /* ************************************************************* */ +char * +bannerstrmangle(char *buf, char *fromstr, char *tostr) +{ + static char bufnew[81]; + char *loc; + char *b = buf; + + memset (bufnew, 0, 80); + + if (strstr(b, fromstr)) { + int i = 0; + while ((loc = strstr (b, fromstr)) != NULL) { + for (; i < 80; i++) { + if (loc != b) + bufnew[i] = *(b++); + else { + strlcat (bufnew, tostr, 80); + b += strlen(fromstr); + i += strlen(tostr); + break; + } + + if (strlen (b) == 0) + break; + } + } + + if (*b) + strlcat(bufnew, b, 80); + } else strncpy(bufnew, buf, 80); + + return bufnew; +} + void -loadbanner (int game, struct dg_banner *ban) +loadbanner (char *fname, struct dg_banner *ban) { FILE *bannerfile; char buf[80]; memset (buf, 0, 80); - bannerfile = fopen (globalconfig.banner, "r"); + bannerfile = fopen (fname, "r"); if (!bannerfile) { @@ -268,9 +302,9 @@ loadbanner (int game, struct dg_banner *ban) ban->lines[0] = strdup ("### dgamelaunch " PACKAGE_VERSION " - network console game launcher"); - len = strlen(globalconfig.banner) + ARRAY_SIZE("### NOTE: administrator has not installed a file"); + len = strlen(fname) + ARRAY_SIZE("### NOTE: administrator has not installed a file"); ban->lines[1] = malloc(len); - snprintf(ban->lines[1], len, "### NOTE: administrator has not installed a %s file", globalconfig.banner); + snprintf(ban->lines[1], len, "### NOTE: administrator has not installed a %s file", fname); return; } @@ -278,70 +312,41 @@ loadbanner (int game, struct dg_banner *ban) while (fgets (buf, 80, bannerfile) != NULL) { - char *loc, *b = buf; char bufnew[80]; - + memset (bufnew, 0, 80); ban->len++; ban->lines = realloc (ban->lines, sizeof (char *) * ban->len); - if (strstr(b, "$VERSION")) - { - int i = 0; - while ((loc = strstr (b, "$VERSION")) != NULL) - { - for (; i < 80; i++) - { - if (loc != b) - bufnew[i] = *(b++); - else - { - strlcat (bufnew, PACKAGE_VERSION, 80); - b += 8; /* skip the whole $PACKAGE_VERSION string */ - i += ARRAY_SIZE (PACKAGE_VERSION) - 1; - break; - } - - if (strlen (b) == 0) - break; - } - } - - if (*b) - strlcat(bufnew, b, 80); - - ban->lines[ban->len - 1] = strdup (bufnew); + strncpy(bufnew, buf, 80); + strncpy(bufnew, bannerstrmangle(bufnew, "$VERSION", PACKAGE_STRING), 80); + if (me && loggedin) { + strncpy(bufnew, bannerstrmangle(bufnew, "$USERNAME", me->username), 80); } - else - ban->lines[ban->len - 1] = strdup (buf); + ban->lines[ban->len - 1] = strdup(bufnew); memset (buf, 0, 80); - if (ban->len == 11) /* menu itself needs 13 lines, 24 - 11 */ - break; + if (ban->len == 24) + break; } fclose (bannerfile); } void -drawbanner (unsigned int start_line, unsigned int howmany) +drawbanner (struct dg_banner *ban, unsigned int start_line, unsigned int howmany) { - static short loaded_banner = 0; unsigned int i; - if (!loaded_banner) - { - loadbanner (0, &banner); - loaded_banner = 1; - } + if (!ban) return; - if (howmany > banner.len || howmany == 0) - howmany = banner.len; + if (howmany > ban->len || howmany == 0) + howmany = ban->len; for (i = 0; i < howmany; i++) - mvaddstr (start_line + i, 1, banner.lines[i]); + mvaddstr (start_line + i, 1, ban->lines[i]); } void @@ -369,7 +374,7 @@ inprogressmenu (int gameid) } erase (); - drawbanner (1, 1); + drawbanner (&banner, 1, 1); mvprintw (3, 1, "During playback, hit 'q' to return here, 'm' to send mail (requires login),"); mvaddstr (4, 1, @@ -552,7 +557,7 @@ change_email () for (;;) { - drawbanner(1,1); + drawbanner(&banner, 1,1); mvprintw(3, 1, "Your current email is: %s", me->email); mvaddstr(4, 1, "Please enter a new one (max 80 chars; blank line aborts)"); @@ -610,7 +615,7 @@ changepw (int dowrite) char repeatbuf[21]; clear (); - drawbanner (1, 1); + drawbanner (&banner, 1, 1); mvprintw (5, 1, "Please enter a%s password. Remember that this is sent over the net", @@ -691,7 +696,7 @@ domailuser (char *username) /* print the enter your message line */ clear (); - drawbanner (1, 1); + drawbanner (&banner, 1, 1); mvaddstr (5, 1, "Enter your message here. It is to be one line only and 80 characters or less."); mvaddstr (7, 1, "=> "); @@ -760,6 +765,7 @@ domailuser (char *username) return; } +/* void drawgamemenu(int game) { @@ -767,7 +773,7 @@ drawgamemenu(int game) clear(); - drawbanner(1,0); + drawbanner(&banner, 1,0); mvprintw(banner.len + 2, 1, "Logged in as: %s", me->username); @@ -789,6 +795,7 @@ drawgamemenu(int game) } } +*/ void drawmenu () @@ -797,7 +804,7 @@ drawmenu () clear (); - drawbanner (1, 0); + drawbanner (&banner, 1, 0); if (loggedin) { @@ -908,7 +915,7 @@ loginprompt (int from_ttyplay) { clear (); - drawbanner (1, 1); + drawbanner (&banner, 1, 1); if (from_ttyplay == 1) mvaddstr (4, 1, "This operation requires you to be logged in."); @@ -945,7 +952,7 @@ loginprompt (int from_ttyplay) clear (); - drawbanner (1, 1); + drawbanner (&banner, 1, 1); mvaddstr (5, 1, "Please enter your password."); mvaddstr (7, 1, "=> "); @@ -992,7 +999,7 @@ newuser () { clear (); - drawbanner (1, 1); + drawbanner (&banner, 1, 1); mvaddstr (5, 1, "Sorry, too many users have registered now."); mvaddstr (6, 1, "You might email the server administrator."); @@ -1014,7 +1021,7 @@ newuser () sprintf(buf, "%i character max.", globalconfig.max_newnick_len); - drawbanner (1, 1); + drawbanner (&banner, 1, 1); mvaddstr (5, 1, "Welcome new user. Please enter a username."); mvaddstr (6, 1, @@ -1082,7 +1089,7 @@ newuser () { clear (); - drawbanner (1, 1); + drawbanner (&banner, 1, 1); mvaddstr (5, 1, "Please enter your email address."); mvaddstr (6, 1, "This is sent _nowhere_ but will be used if you ask" @@ -1655,7 +1662,7 @@ purge_stale_locks (int game) if (firsttime) { clear (); - drawbanner (1, 1); + drawbanner (&banner, 1, 1); #define HUP_WAIT 10 /* seconds before HUPPING */ mvprintw (3, 1, @@ -1728,6 +1735,7 @@ purge_stale_locks (int game) return 1; } +/* int gamemenuloop(int game) { @@ -1767,66 +1775,49 @@ gamemenuloop(int game) newuser (); break; case 'l': - if (!loggedin) /* not visible to loggedin */ + if (!loggedin) loginprompt (0); } } return 0; } +*/ -int -menuloop (void) +void +runmenuloop(struct dg_menu *menu) { - int userchoice = 0; - while (1) - { - drawmenu (); - userchoice = getch (); + struct dg_banner ban; + struct dg_menuoption *tmpopt; + int userchoice = 0; + + if (!menu) return; + + ban.lines = NULL; + ban.len = 0; + + loadbanner(menu->banner_fn, &ban); + while (1) { + clear(); + drawbanner(&ban, 1, 0); + mvprintw(menu->cursor_y, menu->cursor_x, ""); + refresh(); + userchoice = getch(); + if (userchoice == ERR) return; + tmpopt = menu->options; + while (tmpopt) { + if (strchr(tmpopt->keys, userchoice)) { + dgl_exec_cmdqueue(tmpopt->cmdqueue, selected_game, me); + break; + } else { + tmpopt = tmpopt->next; + } + } - if ((num_games >= 1) && loggedin && (userchoice >= '1') && (userchoice <= ('1'+num_games))) { - int game = userchoice - '1'; - if (myconfig[game] && myconfig[game]->game_name) { - if (gamemenuloop(game)) return game; - } - } else { - switch (tolower (userchoice)) - { - default: - break; - case 'c': - if (loggedin) - changepw (1); - break; - case 'e': - if (loggedin) - change_email(); - break; - case 'w': - inprogressmenu (-1); - break; - case 'o': - if (loggedin && (num_games == 0) && myconfig[0]->rcfile) - editoptions(0); - break; - case 'p': - if (loggedin && (num_games == 0)) - return 0; - break; - case ERR: - case 'q': - graceful_exit(0); - /* break; */ - case 'r': - if (!loggedin && globalconfig.allow_registration) - newuser (); - break; - case 'l': - if (!loggedin) /* not visible to loggedin */ - loginprompt (0); - } - } + if (return_from_submenu) { + return_from_submenu = 0; + return; + } } - return -1; } @@ -1890,7 +1881,7 @@ int main (int argc, char** argv) { /* for chroot and program execution */ - char atrcfilename[81], /**spool,*/ *p, *auth = NULL; + char atrcfilename[81], *p, *auth = NULL; unsigned int len; int c, i; int nhext = 0, nhauth = 0; @@ -2011,6 +2002,8 @@ main (int argc, char** argv) } } + loadbanner(globalconfig.banner, &banner); + dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_DGLSTART], 0, NULL); if (nhext) @@ -2052,50 +2045,10 @@ main (int argc, char** argv) } } - while (1) { - initcurses (); - - userchoice = menuloop(); + initcurses (); - assert (loggedin); - - if ((userchoice >= 0) && (userchoice <= num_games)) { - while (!purge_stale_locks(userchoice)) { - userchoice = gamemenuloop(userchoice); - } - if (!((userchoice >= 0) && (userchoice <= num_games))) - graceful_exit (1); - } else { - graceful_exit (1); - } - - if (myconfig[userchoice]->rcfile) { - if (access (dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt), R_OK) == -1) - write_canned_rcfile (userchoice, dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt)); - } - - setproctitle("%s [playing %s]", me->username, myconfig[userchoice]->shortname); - - endwin (); - signal(SIGWINCH, SIG_DFL); - - /* first run the generic "do these when a game is started" commands */ - dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_GAMESTART], userchoice, me); - /* then run the game-specific commands */ - dgl_exec_cmdqueue(myconfig[userchoice]->cmdqueue, userchoice, me); - - /* fix the variables in the arguments */ - for (i = 0; i < myconfig[userchoice]->num_args; i++) { - tmp = strdup(dgl_format_str(userchoice, me, myconfig[userchoice]->bin_args[i])); - free(myconfig[userchoice]->bin_args[i]); - myconfig[userchoice]->bin_args[i] = tmp; - } - - /* launch program */ - ttyrec_main (userchoice, me->username, gen_ttyrec_filename()); - check_retard(1); /* reset retard counter */ - - setproctitle ("%s", me->username); + while (1) { + runmenuloop(dgl_find_menu(loggedin ? "mainmenu_user" : "mainmenu_anon")); } /* NOW we can safely kill this */ diff --git a/dgamelaunch.h b/dgamelaunch.h index 611fc80..3951bc3 100644 --- a/dgamelaunch.h +++ b/dgamelaunch.h @@ -52,6 +52,28 @@ struct dg_banner unsigned int len; }; +struct dg_menuoption +{ + char *keys; + struct dg_cmdpart *cmdqueue; + struct dg_menuoption *next; +}; + +struct dg_menu +{ + char *banner_fn; + struct dg_banner banner; + int cursor_x, cursor_y; + struct dg_menuoption *options; +}; + +struct dg_menulist +{ + char *menuname; + struct dg_menu *menu; + struct dg_menulist *next; +}; + struct dg_game { char *ttyrec_fn; @@ -93,6 +115,8 @@ struct dg_globalconfig int allow_registration; /* allow registering new nicks */ struct dg_cmdpart *cmdqueue[NUM_DGLTIMES]; + + struct dg_menulist *menulist; }; typedef enum @@ -110,7 +134,11 @@ typedef enum DGLCMD_REGISTER, /* ask_register */ DGLCMD_QUIT, /* quit */ DGLCMD_CHMAIL, /* chmail */ - DGLCMD_CHPASSWD /* chpasswd */ + DGLCMD_CHPASSWD, /* chpasswd */ + DGLCMD_EDITOPTIONS, /* edit_options "foo" */ + DGLCMD_PLAYGAME, /* play_game "foo" */ + DGLCMD_SUBMENU, /* submenu "foo" */ + DGLCMD_RETURN /* return */ } dglcmd_actions; typedef enum @@ -137,6 +165,9 @@ extern int loggedin; extern int silent; extern int set_max; +extern int selected_game; +extern int return_from_submenu; + extern struct dg_globalconfig globalconfig; extern int num_games; @@ -149,17 +180,21 @@ extern void ttyrec_getmaster(void); extern char *gen_ttyrec_filename(void); extern char *gen_inprogress_lock(int game, pid_t pid, char *ttyrec_filename); extern void catch_sighup(int signum); -extern void loadbanner(int game, struct dg_banner *ban); -extern void drawbanner(unsigned int start_line, unsigned int howmany); +extern void loadbanner(char *fname, struct dg_banner *ban); +extern void drawbanner(struct dg_banner *ban, unsigned int start_line, unsigned int howmany); extern int check_retard(int reset); extern char *dgl_format_str(int game, struct dg_user *me, char *str); +extern struct dg_menu *dgl_find_menu(char *menuname); + extern int dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me); extern struct dg_game **populate_games(int game, int *l); extern struct dg_game **sort_games(struct dg_game **games, int len, dg_sortmode sortmode); +void runmenuloop(struct dg_menu *menu); + extern void inprogressmenu(int gameid); extern void change_email(void); extern int changepw(int dowrite); @@ -178,7 +213,7 @@ extern void editoptions(int game); extern void writefile(int requirenew); extern void graceful_exit(int status); extern int purge_stale_locks(int game); -extern int menuloop(void); +/*extern int menuloop(void);*/ extern void ttyrec_getpty(void); #if !defined(BSD) && !defined(__linux__) extern int mysetenv (const char* name, const char* value, int overwrite); diff --git a/dgl-common.c b/dgl-common.c index 522e5aa..0f8f4d5 100644 --- a/dgl-common.c +++ b/dgl-common.c @@ -1,6 +1,7 @@ /* Functions common to both dgamelaunch itself and dgl-wall. */ #include "dgamelaunch.h" +#include "ttyrec.h" #include #include #include @@ -52,6 +53,9 @@ int loggedin = 0; char *chosen_name; int num_games = 0; +int selected_game = 0; +int return_from_submenu = 0; + mode_t default_fmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; struct dg_globalconfig globalconfig; @@ -66,6 +70,19 @@ check_retard(int reset) return ((retardation > 20) ? 1 : 0); } + +struct dg_menu * +dgl_find_menu(char *menuname) +{ + struct dg_menulist *tmp = globalconfig.menulist; + + while (tmp) { + if (!strcmp(tmp->menuname, menuname)) return tmp->menu; + tmp = tmp->next; + } + return NULL; +} + /* * replace following codes with variables: * %u == shed_uid (number) @@ -136,14 +153,21 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me) { int i; struct dg_cmdpart *tmp = queue; + char *p1; + char *p2; if (!queue) return 1; - while (tmp) { - char *p1 = NULL; /* FIXME: should probably use fixed-size buffers instead of doing strdup() every time */ - char *p2 = NULL; - if (tmp->param1) p1 = strdup(dgl_format_str(game, me, tmp->param1)); - if (tmp->param2) p2 = strdup(dgl_format_str(game, me, tmp->param2)); + p1 = (char *)malloc(1024); + p2 = (char *)malloc(1024); + + if (!p1 || !p2) return 1; + + return_from_submenu = 0; + + while (tmp && !return_from_submenu) { + if (tmp->param1) strcpy(p1, dgl_format_str(game, me, tmp->param1)); + if (tmp->param2) strcpy(p2, dgl_format_str(game, me, tmp->param2)); switch (tmp->cmd) { default: break; @@ -221,6 +245,7 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me) break; case DGLCMD_LOGIN: if (!loggedin) loginprompt(0); + if (loggedin) runmenuloop(dgl_find_menu("mainmenu_user")); break; case DGLCMD_REGISTER: if (!loggedin && globalconfig.allow_registration) newuser(); @@ -228,12 +253,73 @@ dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me) case DGLCMD_QUIT: graceful_exit(0); /* break; */ + case DGLCMD_SUBMENU: + if (p1) + runmenuloop(dgl_find_menu(p1)); + break; + case DGLCMD_RETURN: + return_from_submenu = 1; + break; + case DGLCMD_EDITOPTIONS: + if (loggedin && p1) { + int i; + for (i = 0; i < num_games; i++) { + if ((!strcmp(myconfig[i]->game_name, p1) || !strcmp(myconfig[i]->shortname, p1)) && myconfig[i]->rcfile) { + editoptions(i); + break; + } + } + } + break; + case DGLCMD_PLAYGAME: + if (loggedin && me && p1) { + int userchoice, i; + char *tmpstr; + for (userchoice = 0; userchoice < num_games; userchoice++) { + if (!strcmp(myconfig[userchoice]->game_name, p1) || !strcmp(myconfig[userchoice]->shortname, p1)) { + if (purge_stale_locks(userchoice)) { + if (myconfig[userchoice]->rcfile) { + if (access (dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt), R_OK) == -1) + write_canned_rcfile (userchoice, dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt)); + } + + setproctitle("%s [playing %s]", me->username, myconfig[userchoice]->shortname); + + endwin (); + signal(SIGWINCH, SIG_DFL); + + /* first run the generic "do these when a game is started" commands */ + dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_GAMESTART], userchoice, me); + /* then run the game-specific commands */ + dgl_exec_cmdqueue(myconfig[userchoice]->cmdqueue, userchoice, me); + + /* fix the variables in the arguments */ + for (i = 0; i < myconfig[userchoice]->num_args; i++) { + tmpstr = strdup(dgl_format_str(userchoice, me, myconfig[userchoice]->bin_args[i])); + free(myconfig[userchoice]->bin_args[i]); + myconfig[userchoice]->bin_args[i] = tmpstr; + } + + /* launch program */ + ttyrec_main (userchoice, me->username, gen_ttyrec_filename()); + check_retard(1); /* reset retard counter */ + + setproctitle ("%s", me->username); + + initcurses (); + } + break; + } + } + } + break; } - free(p1); - free(p2); - tmp = tmp->next; } + + free(p1); + free(p2); + return 0; } @@ -436,6 +522,7 @@ create_config () int tmp; if (!globalconfig.allow_registration) globalconfig.allow_registration = 1; + globalconfig.menulist = NULL; if (config) { diff --git a/examples/dgamelaunch.conf b/examples/dgamelaunch.conf index d20e5ea..62fa1df 100644 --- a/examples/dgamelaunch.conf +++ b/examples/dgamelaunch.conf @@ -25,10 +25,9 @@ chroot_path = "/var/lib/dgamelaunch/" # From inside the jail, dgamelaunch's working directory for rcfiles/ttyrec/etc dglroot = "/dgldir/" -# From inside the jail, location of a banner file that contains no more than -# 14 lines of 80-column width text. Any more will be truncated. -# The topmost line will be shown even in submenus. -# string $VERSION will be replaced with dgl version number. +# From inside the jail, location of a banner file, the topmost line will be +# shown in submenus that cannot be defined separately. +# string $VERSION will be replaced with "dgamelaunch v" + dgl version number. banner = "/dgl-banner" # The following two options are fairly insecure. They will force us to @@ -82,6 +81,12 @@ lockfile = "/dgl-lock" # ask_login = do the login prompting, if not logged in # ask_register = do register new user prompting, if not logged in and # registration of new nicks is allowed. +# edit_options "foo" = edit options for game which has the short name "foo" +# (user must be logged in) +# play_game "foo" = start game which has the short name "foo" +# (user must be logged in) +# submenu "foo" = go to submenu "foo" +# return = return from submenu # # The commands will be done inside the chroot and with the uid and gid # defined above. @@ -99,6 +104,40 @@ commands[register] = mkdir "%rttyrec/%n" +# define the main menus. you _must_ define "mainmenu_anon" +# and "mainmenu_user". +# $VERSION will be replaced with dgl version string, as +# in the bannerfile above. +# first, the menu shown to anonymous user: +menu["mainmenu_anon"] { + bannerfile = "dgl_menu_main_anon.txt" + cursor = (5,18) + commands["l"] = ask_login + commands["r"] = ask_register + commands["w"] = watch_menu + commands["q"] = quit +} + +# then the menu shown when the user has logged in: +# $USERNAME in here will be replaced with the user name. +menu["mainmenu_user"] { +# contents of this file are written to screen. +# the file must be inside the chroot. + bannerfile = "dgl_menu_main_user.txt" +# after which cursor is moved to this location + cursor = (5,18) +# keys we accept. format is +# commands["string_of_keys"] = +# for example, you could use commands["qQ"] = quit + commands["c"] = chpasswd + commands["e"] = chmail + commands["w"] = watch_menu + commands["o"] = edit_options "NH343" + commands["p"] = play_game "NH343" + commands["q"] = quit +} + + # Next, we'll define one game's data: