/* $Id$ */ #include "bbs.h" /* help & menu processring */ static int refscreen = NA; extern char *boardprefix; extern struct utmpfile_t *utmpshm; extern char *fn_board; extern char board_hidden_status; void showtitle(char *title, char *mid) { char buf[40], buf1[40], numreg[50]; #ifndef DEBUG int nreg; #endif int spc = 0, pad, bid; static char lastboard[16] = {0}; spc = strlen(mid); if (title[0] == 0) title++; #ifdef DEBUG else { snprintf(numreg, sizeof(numreg), "\033[41;5m current pid: %6d " TITLE_COLOR, getpid()); mid = numreg; spc = 22; } #else else if (currutmp->mailalert) { snprintf(buf1, sizeof(buf1), "%s"TITLE_COLOR, SHM->i18nstr[cuser.language][1380]); mid = buf1; spc = 22; } else if (HAS_PERM(PERM_SYSOP) && (nreg = dashs(fn_register) / 163) > 10) { snprintf(numreg, sizeof(numreg), SHM->i18nstr[cuser.language][1381], nreg, (int)dashs("register.new.tmp") / 163, TITLE_COLOR); mid = numreg; spc = 22; } #endif spc = 66 - strlen(title) - spc - strlen(currboard); if (spc < 0) spc = 0; pad = 1 - (spc & 1); memset(buf, ' ', spc >>= 1); buf[spc] = '\0'; clear(); prints(SHM->i18nstr[cuser.language][1382], TITLE_COLOR, title, buf, mid, buf, " " + pad, currmode & MODE_SELECT ? SHM->i18nstr[cuser.language][1383] : currmode & MODE_ETC ? SHM->i18nstr[cuser.language][1384] : currmode & MODE_DIGEST ? SHM->i18nstr[cuser.language][1385] : SHM->i18nstr[cuser.language][1386]); if (strcmp(currboard, lastboard)) { /* change board */ if (currboard[0] != 0 && (bid = getbnum(currboard)) > 0) { // XXX: bid starts from 1 board_hidden_status = ((bcache[bid - 1].brdattr & BRD_HIDE) && (bcache[bid - 1].brdattr & BRD_POSTMASK)); strncpy(lastboard, currboard, sizeof(lastboard)); } } if (board_hidden_status) prints("\033[32m%s", currboard); else prints("%s", currboard); prints(SHM->i18nstr[cuser.language][1387], currmode & MODE_SELECT ? 6 : currmode & MODE_ETC ? 5 : currmode & MODE_DIGEST ? 2 : 7); } /* 動畫處理 */ #define FILMROW 11 static unsigned char menu_row = 12; static unsigned char menu_column = 20; static void show_status(void) { int i; struct tm *ptime = localtime(&now); char mystatus[160]; char *myweek = SHM->i18nstr[cuser.language][1388]; const char *msgs[] = {SHM->i18nstr[cuser.language][1389], SHM->i18nstr[cuser.language][1390], SHM->i18nstr[cuser.language][1391], SHM->i18nstr[cuser.language][1392], SHM->i18nstr[cuser.language][1393]}; i = ptime->tm_wday << 1; snprintf(mystatus, sizeof(mystatus), SHM->i18nstr[cuser.language][1394], ptime->tm_mon + 1, ptime->tm_mday, myweek[i], myweek[i + 1], ptime->tm_hour, ptime->tm_min, currutmp->birth ? SHM->i18nstr[cuser.language][1395] : SHM->today_is, SHM->UTMPnumber, cuser.userid, msgs[currutmp->pager]); outmsg(mystatus); } static int u_movie() { cuser.uflag ^= MOVIE_FLAG; return 0; } void movie(int i) { static short history[MAX_HISTORY]; int j; if ((currstat != CLASS) && (cuser.uflag & MOVIE_FLAG) && !SHM->Pbusystate && SHM->max_film > 0) { if (currstat == PSALE) { i = PSALE; reload_money(); } else { do { if (!i) i = 1 + (int)(((float)SHM->max_film * rand()) / (RAND_MAX + 1.0)); for (j = SHM->max_history; j >= 0; j--) if (i == history[j]) { i = 0; break; } } while (i == 0); } memmove(history, &history[1], SHM->max_history * sizeof(short)); history[SHM->max_history] = j = i; if (i == 999) /* Goodbye my friend */ i = 0; move(1, 0); clrtoline(1 + FILMROW); /* 清掉上次的 */ out_lines(SHM->notes[i], 11); /* 只印11行就好 */ outs(reset_color); } show_status(); refresh(); } static int show_menu(commands_t * p) { register int n = 0; register char *s; char buf[80]; movie(currstat); move(menu_row, 0); while (p[n].desc > 0 && p[n].desc < MAX_STRING) { if (HAS_PERM(p[n].level)) { s = SHM->i18nstr[cuser.language][p[n].desc]; snprintf(buf, sizeof(buf), s + 2, SHM->i18nstr[cuser.language][1396 + cuser.proverb % 4]); prints("%*s (\033[1;36m%c\033[0m)%s\n", menu_column, "", s[1], buf); } n++; } return n - 1; } void domenu(int cmdmode, char *cmdtitle, int cmd, commands_t cmdtable[]) { int lastcmdptr; int n, pos, total, i; int err; static char cmd0[LOGIN]; /* XXX: 傳進來的 cmd 若權限不足, 則不知 cursor 在哪, 導致 crash */ if (cmd0[cmdmode]) cmd = cmd0[cmdmode]; setutmpmode(cmdmode); showtitle(cmdtitle, BBSName); total = show_menu(cmdtable); show_status(); lastcmdptr = pos = 0; do { i = -1; switch (cmd) { case Ctrl('I'): t_idle(); refscreen = YEA; i = lastcmdptr; break; case Ctrl('N'): New(); refscreen = YEA; i = lastcmdptr; break; case Ctrl('A'): if (mail_man() == FULLUPDATE) refscreen = YEA; i = lastcmdptr; break; case KEY_DOWN: i = lastcmdptr; case KEY_HOME: case KEY_PGUP: do { if (++i > total) i = 0; } while (!HAS_PERM(cmdtable[i].level)); break; case KEY_END: case KEY_PGDN: i = total; break; case KEY_UP: i = lastcmdptr; do { if (--i < 0) i = total; } while (!HAS_PERM(cmdtable[i].level)); break; case KEY_LEFT: case 'e': case 'E': if (cmdmode == MMENU) cmd = 'G'; else if ((cmdmode == MAIL) && chkmailbox()) cmd = 'R'; else return; default: if ((cmd == 's' || cmd == 'r') && (currstat == MMENU || currstat == TMENU || currstat == XMENU)) { if (cmd == 's') ReadSelect(); else Read(); refscreen = YEA; i = lastcmdptr; break; } if (cmd == '\n' || cmd == '\r' || cmd == KEY_RIGHT) { move(b_lines, 0); clrtoeol(); currstat = XMODE; if ((err = (*cmdtable[lastcmdptr].cmdfunc) ()) == QUIT) return; currutmp->mode = currstat = cmdmode; if (err == XEASY) { refresh(); safe_sleep(1); } else if (err != XEASY + 1 || err == FULLUPDATE) refscreen = YEA; if (err != -1) cmd = SHM->i18nstr[cuser.language][cmdtable[lastcmdptr].desc][0]; else cmd = SHM->i18nstr[cuser.language][cmdtable[lastcmdptr].desc][1]; cmd0[cmdmode] = SHM->i18nstr[cuser.language][cmdtable[lastcmdptr].desc][0]; } if (cmd >= 'a' && cmd <= 'z') cmd &= ~0x20; while (++i <= total) if (SHM->i18nstr[cuser.language][cmdtable[i].desc][1] == cmd) break; } if (i > total || !HAS_PERM(cmdtable[i].level)) continue; if (refscreen) { showtitle(cmdtitle, BBSName); show_menu(cmdtable); show_status(); refscreen = NA; } cursor_clear(menu_row + pos, menu_column); n = pos = -1; while (++n <= (lastcmdptr = i)) if (HAS_PERM(cmdtable[n].level)) pos++; cursor_show(menu_row + pos, menu_column); } while (((cmd = igetch()) != EOF) || refscreen); abort_bbs(0); } /* INDENT OFF */ /* administrator's maintain menu */ static commands_t adminlist[] = { {m_user, PERM_ACCOUNTS, 1399}, {search_user_bypwd, PERM_SYSOP, 1400}, {search_user_bybakpwd,PERM_SYSOP, 1401}, {m_board, PERM_SYSOP, 1402}, {m_register, PERM_SYSOP, 1403}, {cat_register, PERM_SYSOP, 1404}, {x_file, PERM_SYSOP|PERM_VIEWSYSOP, 1405}, {give_money, PERM_SYSOP|PERM_VIEWSYSOP, 1406}, {m_loginmsg, PERM_SYSOP, 1407}, #ifdef HAVE_MAILCLEAN {m_mclean, PERM_SYSOP, 1408}, #endif #ifdef HAVE_REPORT {m_trace, PERM_SYSOP, 1409}, #endif {NULL, 0, -1} }; /* mail menu */ static commands_t maillist[] = { {m_new, PERM_READMAIL, 1410}, {m_read, PERM_READMAIL, 1411}, {m_send, PERM_BASIC, 1412}, {x_love, PERM_LOGINOK, 1413}, {mail_list, PERM_BASIC, 1414}, {setforward, PERM_LOGINOK,1415}, {m_sysop, 0, 1416}, {m_internet, PERM_INTERNET, 1417}, {mail_mbox, PERM_INTERNET, 1418}, {built_mail_index, PERM_LOGINOK, 1419}, {mail_all, PERM_SYSOP, 1420}, {NULL, 0, -1} }; /* Talk menu */ static commands_t talklist[] = { {t_users, 0, 1421}, {t_pager, PERM_BASIC, 1422}, {t_idle, 0, 1423}, {t_query, 0, 1424}, {t_qchicken, 0, 1425}, {t_talk, PERM_PAGE, 1426}, {t_chat, PERM_CHAT, 1427}, {t_display, 0, 1428}, {NULL, 0, -1} }; /* name menu */ static int t_aloha() { friend_edit(FRIEND_ALOHA); return 0; } static int t_special() { friend_edit(FRIEND_SPECIAL); return 0; } static commands_t namelist[] = { {t_override, PERM_LOGINOK,1429}, {t_reject, PERM_LOGINOK, 1430}, {t_aloha,PERM_LOGINOK, 1431}, #ifdef POSTNOTIFY {t_post,PERM_LOGINOK, 1432}, #endif {t_special,PERM_LOGINOK, 1433}, {NULL, 0, -1} }; /* User menu */ static commands_t userlist[] = { {u_info, PERM_LOGINOK, 1434}, {calendar, PERM_LOGINOK, 1435}, {u_editcalendar, PERM_LOGINOK, 1436}, {u_loginview, PERM_LOGINOK, 1437}, {u_ansi, 0, 1438}, {u_movie, 0, 1439}, #ifdef HAVE_SUICIDE {u_kill, PERM_BASIC, 1440}, #endif {u_editplan, PERM_LOGINOK, 1441}, {u_editsig, PERM_LOGINOK, 1442}, #if HAVE_FREECLOAK {u_cloak, PERM_LOGINOK, 1443}, #else {u_cloak, PERM_CLOAK, 1444}, #endif {u_register, PERM_BASIC, 1445}, {u_list, PERM_SYSOP, 1446}, {NULL, 0, -1} }; /* XYZ tool menu */ static commands_t xyzlist[] = { #ifdef HAVE_LICENSE {x_gpl, 0, 1447}, #endif #ifdef HAVE_INFO {x_program, 0, 1448}, #endif {x_boardman,0, 1449}, // {x_boards,0, 1450}, {x_history, 0, 1451}, {x_note, 0, 1452}, {x_login,0, 1453}, {x_week, 0, 1454}, {x_issue, 0, 1455}, {x_today, 0, 1456}, {x_yesterday, 0, 1457}, {x_user100 ,0, 1458}, {x_birth, 0, 1459}, {p_sysinfo, 0, 1460}, {NULL, 0, -1} }; /* Ptt money menu */ static commands_t moneylist[] = { {p_give, 0, 1461}, {save_violatelaw, 0,1462}, #if !HAVE_FREECLOAK {p_cloak, 0, 1463}, #endif {p_from, 0, 1464}, {ordersong,0, 1465}, {p_exmail, 0, 1466}, {NULL, 0, -1} }; static int p_money() { domenu(PSALE, SHM->i18nstr[cuser.language][1467], '0', moneylist); return 0; }; #if 0 static commands_t jceelist[] = { {x_90,PERM_LOGINOK, 1468}, {x_89,PERM_LOGINOK, 1469}, {x_88,PERM_LOGINOK, 1470}, {x_87,PERM_LOGINOK, 1471}, {x_86,PERM_LOGINOK, 1472}, {NULL, 0, -1} }; static int m_jcee() { domenu(JCEE, SHM->i18nstr[cuser.language][1473], '0', jceelist); return 0; } #endif static int forsearch(); static int playground(); static int chessroom(); /* Ptt Play menu */ static commands_t playlist[] = { #if 0 #if HAVE_JCEE {m_jcee, PERM_LOGINOK, 1474}, #endif #endif {note, PERM_LOGINOK, 1475}, {x_weather,0 , 1476}, /* XXX 壞掉了 */ /* {x_stock,0 , "SStock 【 股市行情 】"},*/ {forsearch,PERM_LOGINOK, 1477}, {topsong,PERM_LOGINOK, 1478}, {p_money,PERM_LOGINOK, 1479}, {chicken_main,PERM_LOGINOK, 1480}, {playground,PERM_LOGINOK, 1481}, {chessroom, PERM_LOGINOK, 1482}, {NULL, 0, -1} }; static commands_t chesslist[] = { {chc_main, PERM_LOGINOK, 1483}, {chc_personal, PERM_LOGINOK, 1484}, {chc_watch, PERM_LOGINOK, 1485}, {NULL, 0, -1} }; static int chessroom() { domenu(CHC, SHM->i18nstr[cuser.language][1486], '1', chesslist); return 0; } static commands_t plist[] = { /* {p_ticket_main, PERM_LOGINOK,"00Pre 【 總統機 】"}, {alive, PERM_LOGINOK, "00Alive 【 訂票雞 】"}, */ {ticket_main, PERM_LOGINOK, 1487}, {guess_main, PERM_LOGINOK, 1488}, {othello_main, PERM_LOGINOK, 1489}, // {dice_main, PERM_LOGINOK, 1490}, {vice_main, PERM_LOGINOK, 1491}, {g_card_jack, PERM_LOGINOK, 1492}, {g_ten_helf, PERM_LOGINOK, 1493}, {card_99, PERM_LOGINOK, 1494}, {NULL, 0, -1} }; static int playground() { domenu(AMUSE, SHM->i18nstr[cuser.language][1495],'1',plist); return 0; } static commands_t slist[] = { {x_dict,0, 1496}, {x_mrtmap, 0, 1497}, {main_railway, PERM_LOGINOK, 1498}, {NULL, 0, -1} }; static int forsearch() { domenu(SREG, SHM->i18nstr[cuser.language][1499], '1', slist); return 0; } /* main menu */ int admin() { domenu(ADMIN, SHM->i18nstr[cuser.language][1500], 'X', adminlist); return 0; } int Mail() { domenu(MAIL, SHM->i18nstr[cuser.language][1501], 'R', maillist); return 0; } int Talk() { domenu(TMENU, SHM->i18nstr[cuser.language][1502], 'U', talklist); return 0; } int User() { domenu(UMENU, SHM->i18nstr[cuser.language][1503], 'A', userlist); return 0; } int Xyz() { domenu(XMENU, SHM->i18nstr[cuser.language][1504], 'M', xyzlist); return 0; } int Play_Play() { domenu(PMENU, SHM->i18nstr[cuser.language][1505], 'A', playlist); return 0; } int Name_Menu() { domenu(NMENU, SHM->i18nstr[cuser.language][1506], 'O', namelist); return 0; }