summaryrefslogtreecommitdiffstats
path: root/mbbsd/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'mbbsd/menu.c')
-rw-r--r--mbbsd/menu.c596
1 files changed, 596 insertions, 0 deletions
diff --git a/mbbsd/menu.c b/mbbsd/menu.c
new file mode 100644
index 00000000..d48670b3
--- /dev/null
+++ b/mbbsd/menu.c
@@ -0,0 +1,596 @@
+/* $Id: menu.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/types.h>
+#include <string.h>
+#include "config.h"
+#include "pttstruct.h"
+#include "common.h"
+#include "perm.h"
+#include "modes.h"
+#include "proto.h"
+extern int usernum;
+extern int talkrequest;
+extern char *fn_register;
+extern char currboard[]; /* name of currently selected board */
+extern int currmode;
+extern unsigned int currstat;
+extern char reset_color[];
+extern userinfo_t *currutmp;
+extern char *BBSName;
+extern int b_lines; /* Screen bottom line number: t_lines-1 */
+
+/* help & menu processring */
+static int refscreen = NA;
+extern char *boardprefix;
+extern struct utmpfile_t *utmpshm;
+
+int egetch() {
+ int rval;
+
+ while(1) {
+ rval = igetkey();
+ if(talkrequest) {
+ talkreply();
+ refscreen = YEA;
+ return rval;
+ }
+ if(rval != Ctrl('L'))
+ return rval;
+ redoscr();
+ }
+}
+
+extern userec_t cuser;
+extern char *fn_board;
+extern char board_hidden_status;
+
+void showtitle(char *title, char *mid) {
+ char buf[40], numreg[50];
+ int nreg, spc = 0, pad, bid;
+ boardheader_t bh;
+ static char lastboard[16] = {0};
+
+ spc = strlen(mid);
+ if(title[0] == 0)
+ title++;
+ else if(currutmp->mailalert) {
+ mid = "\033[41;5m 郵差來按鈴囉 " TITLE_COLOR;
+ spc = 22;
+ } else if(HAS_PERM(PERM_SYSOP) && (nreg = dashs(fn_register)/163) > 10) {
+ /* 超過十個人未審核 */
+ sprintf(numreg, "\033[41;5m 有%03d/%03d未審核 " TITLE_COLOR,
+ nreg,
+ (int)dashs("register.new.tmp") / 163);
+ mid = numreg;
+ spc = 22;
+ }
+ 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(TITLE_COLOR "【%s】%s\033[33m%s%s%s\033[3%s《",
+ title, buf, mid, buf, " " + pad,
+ currmode & MODE_SELECT ? "6m系列" : currmode & MODE_ETC ? "5m其他" :
+ currmode & MODE_DIGEST ? "2m文摘" : "7m看板");
+
+ if( strcmp(currboard, lastboard) ){ /* change board */
+ if( currboard[0] != 0 &&
+ (bid = getbnum(currboard)) > 0 &&
+ (get_record(fn_board, &bh, sizeof(bh), bid) != -1) ){
+ board_hidden_status = ((bh.brdattr & BRD_HIDE) &&
+ (bh.brdattr & BRD_POSTMASK));
+ strncpy(lastboard, currboard, sizeof(lastboard));
+ }
+ }
+
+ if( board_hidden_status )
+ prints("\033[32m%s", currboard);
+ else
+ prints("%s", currboard);
+ prints("\033[3%dm》\033[0m\n", 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 char mystatus[160];
+
+static int u_movie() {
+ cuser.uflag ^= MOVIE_FLAG;
+ return 0;
+}
+
+void movie(int i) {
+ extern struct pttcache_t *ptt;
+ static short history[MAX_HISTORY];
+ static char myweek[] = "天一二三四五六";
+ const char *msgs[] = {"關閉", "打開", "拔掉", "防水","好友"};
+ time_t now = time(NULL);
+ struct tm *ptime = localtime(&now);
+
+ if((currstat != CLASS) && (cuser.uflag & MOVIE_FLAG) &&
+ !ptt->busystate && ptt->max_film > 0) {
+ if(currstat == PSALE) {
+ i = PSALE;
+ reload_money();
+ } else {
+ do {
+ if(!i)
+ i = 1 + (int)(((float)ptt->max_film *
+ rand()) / (RAND_MAX + 1.0));
+
+ for(now = ptt->max_history; now >= 0; now--)
+ if(i == history[now]) {
+ i = 0;
+ break;
+ }
+ } while(i == 0);
+ }
+
+ memcpy(history, &history[1], ptt->max_history * sizeof(short));
+ history[ptt->max_history] = now = i;
+
+ if(i == 999) /* Goodbye my friend */
+ i = 0;
+
+ move(1, 0);
+ clrtoline(1 + FILMROW); /* 清掉上次的 */
+ Jaky_outs(ptt->notes[i], 11); /* 只印11行就好 */
+ outs(reset_color);
+ }
+ i = ptime->tm_wday << 1;
+ sprintf(mystatus, "\033[34;46m[%d/%d 星期%c%c %d:%02d]\033[1;33;45m%-14s"
+ "\033[30;47m 目前坊裡有 \033[31m%d\033[30m人, 我是\033[31m%-12s"
+ "\033[30m[扣機]\033[31m%s\033[0m",
+ ptime->tm_mon + 1, ptime->tm_mday, myweek[i], myweek[i + 1],
+ ptime->tm_hour, ptime->tm_min, currutmp->birth ?
+ "生日要請客唷" : ptt->today_is,
+ utmpshm->number, cuser.userid, msgs[currutmp->pager]);
+ outmsg(mystatus);
+ refresh();
+}
+
+static int show_menu(commands_t *p) {
+ register int n = 0;
+ register char *s;
+ const char *state[4]={"用功\型", "安逸型", "自定型", "SHUTUP"};
+ char buf[80];
+
+ movie(currstat);
+
+ move(menu_row, 0);
+ while((s = p[n].desc)) {
+ if(HAS_PERM(p[n].level)) {
+ sprintf(buf, s + 2, state[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;
+ int chkmailbox();
+ static char cmd0[LOGIN];
+
+ if(cmd0[cmdmode])
+ cmd = cmd0[cmdmode];
+
+ setutmpmode(cmdmode);
+
+ showtitle(cmdtitle, BBSName);
+
+ total = show_menu(cmdtable);
+
+ outmsg(mystatus);
+ lastcmdptr = pos = 0;
+
+ do {
+ i = -1;
+ switch(cmd) {
+ case Ctrl('C'):
+ cal();
+ i = lastcmdptr;
+ refscreen = YEA;
+ break;
+ 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 = cmdtable[lastcmdptr].desc[0];
+ else
+ cmd = cmdtable[lastcmdptr].desc[1];
+ cmd0[cmdmode] = cmdtable[lastcmdptr].desc[0];
+ }
+
+ if(cmd >= 'a' && cmd <= 'z')
+ cmd &= ~0x20;
+ while(++i <= total)
+ if(cmdtable[i].desc[1] == cmd)
+ break;
+ }
+
+ if(i > total || !HAS_PERM(cmdtable[i].level))
+ continue;
+
+ if(refscreen) {
+ showtitle(cmdtitle, BBSName);
+
+ show_menu(cmdtable);
+
+ outmsg(mystatus);
+ 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 = egetch()) != EOF) || refscreen);
+
+ abort_bbs(0);
+}
+/* INDENT OFF */
+
+/* administrator's maintain menu */
+static commands_t adminlist[] = {
+ {m_user, PERM_ACCOUNTS, "UUser 使用者資料"},
+ {search_user_bypwd, PERM_SYSOP, "SSearch User 特殊搜尋使用者"},
+ {search_user_bybakpwd,PERM_SYSOP, "OOld User data 查閱\備份使用者資料"},
+ {m_board, PERM_SYSOP, "BBoard 設定看板"},
+ {m_register, PERM_SYSOP, "RRegister 審核註冊表單"},
+ {cat_register, PERM_SYSOP, "CCatregister 無法審核時用的"},
+ {x_file, PERM_SYSOP|PERM_VIEWSYSOP, "XXfile 編輯系統檔案"},
+ {give_money, PERM_SYSOP|PERM_VIEWSYSOP, "GGivemoney 紅包雞"},
+#ifdef HAVE_MAILCLEAN
+ {m_mclean, PERM_SYSOP, "MMail Clean 清理使用者個人信箱"},
+#endif
+#ifdef HAVE_REPORT
+ {m_trace, PERM_SYSOP, "TTrace 設定是否記錄除錯資訊"},
+#endif
+ {NULL, 0, NULL}
+};
+
+/* mail menu */
+static commands_t maillist[] = {
+ {m_new, PERM_READMAIL, "RNew 閱\讀新進郵件"},
+ {m_read, PERM_READMAIL, "RRead 多功\能讀信選單"},
+ {m_send, PERM_BASIC, "RSend 站內寄信"},
+ {main_bbcall, PERM_LOGINOK, "BBBcall \033[1;31m電話秘書\033[m"},
+ {x_love, PERM_LOGINOK, "PPaper \033[1;32m情書產生器\033[m "},
+ {mail_list, PERM_BASIC, "RMail List 群組寄信"},
+ {setforward, PERM_LOGINOK,"FForward \033[32m設定信箱自動轉寄\033[m"},
+ {m_sysop, 0, "YYes, sir! 諂媚站長"},
+ {m_internet, PERM_INTERNET, "RInternet 寄信到 Internet"},
+ {mail_mbox, PERM_INTERNET, "RZip UserHome 把所有私人資料打包回去"},
+ {built_mail_index, PERM_LOGINOK, "SSavemail 把信件救回來"},
+ {mail_all, PERM_SYSOP, "RAll 寄信給所有使用者"},
+ {NULL, 0, NULL}
+};
+
+/* Talk menu */
+static commands_t talklist[] = {
+ {t_users, 0, "UUsers 完全聊天手冊"},
+ {t_pager, PERM_BASIC, "PPager 切換呼叫器"},
+ {t_idle, 0, "IIdle 發呆"},
+ {t_query, 0, "QQuery 查詢網友"},
+ {t_qchicken, 0, "WWatch Pet 查詢寵物"},
+ {t_talk, PERM_PAGE, "TTalk 找人聊聊"},
+ {t_chat, PERM_CHAT, "CChat 找家茶坊喫茶去"},
+#ifdef HAVE_MUD
+ {x_mud, 0, "VVrChat \033[1;32m虛擬實業聊天廣場\033[m"},
+#endif
+ {t_display, 0, "DDisplay 顯示上幾次熱訊"},
+ {NULL, 0, NULL}
+};
+
+/* 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,"OOverRide 好友名單"},
+ {t_reject, PERM_LOGINOK, "BBlack 壞人名單"},
+ {t_aloha,PERM_LOGINOK, "AALOHA 上站通知名單"},
+#ifdef POSTNOTIFY
+ {t_post,PERM_LOGINOK, "NNewPost 新文章通知名單"},
+#endif
+ {t_special,PERM_LOGINOK, "SSpecial 其他特別名單"},
+ {NULL, 0, NULL}
+};
+
+/* User menu */
+static commands_t userlist[] = {
+ {u_info, PERM_LOGINOK, "IInfo 設定個人資料與密碼"},
+ {calendar, PERM_LOGINOK, "CCalendar 個人行事曆"},
+ {u_editcalendar, PERM_LOGINOK, "CCalendarEdit 編輯個人行事曆"},
+ {u_loginview, PERM_LOGINOK, "LLogin View 選擇進站畫面"},
+ {u_ansi, 0, "AANSI 切換 ANSI \033[36m彩\033[35m色\033[37m/"
+ "\033[30;47m黑\033[1;37m白\033[m模示"},
+ {u_movie, 0, "MMovie 切換動畫模示"},
+#ifdef HAVE_SUICIDE
+ {u_kill, PERM_BASIC, "IKill 自殺!!"},
+#endif
+ {u_editplan, PERM_LOGINOK, "QQueryEdit 編輯名片檔"},
+ {u_editsig, PERM_LOGINOK, "SSignature 編輯簽名檔"},
+#if HAVE_FREECLOAK
+ {u_cloak, PERM_LOGINOK, "CCloak 隱身術"},
+#else
+ {u_cloak, PERM_CLOAK, "CCloak 隱身術"},
+#endif
+ {u_register, PERM_BASIC, "RRegister 填寫《註冊申請單》"},
+ {u_list, PERM_SYSOP, "UUsers 列出註冊名單"},
+ {NULL, 0, NULL}
+};
+
+/* XYZ tool menu */
+static commands_t xyzlist[] = {
+#ifdef HAVE_LICENSE
+ {x_gpl, 0, "LLicense GNU 使用執照"},
+#endif
+#ifdef HAVE_INFO
+ {x_program, 0, "PProgram 本程式之版本與版權宣告"},
+#endif
+ {x_boardman,0, "MMan Boards 《看版精華區排行榜》"},
+// {x_boards,0, "HHot Boards 《看版人氣排行榜》"},
+ {x_history, 0, "HHistory 《我們的成長》"},
+ {x_note, 0, "NNote 《酸甜苦辣流言版》"},
+ {x_login,0, "SSystem 《系統重要公告》"},
+ {x_week, 0, "WWeek 《本週五十大熱門話題》"},
+ {x_issue, 0, "IIssue 《今日十大熱門話題》"},
+ {x_today, 0, "TToday 《今日上線人次統計》"},
+ {x_yesterday, 0, "YYesterday 《昨日上線人次統計》"},
+ {x_user100 ,0, "UUsers 《使用者百大排行榜》"},
+ {x_birth, 0, "BBirthday 《今日壽星大觀》"},
+ {p_sysinfo, 0, "XXload 《查看系統負荷》"},
+ {NULL, 0, NULL}
+};
+
+/* Ptt money menu */
+static commands_t moneylist[] = {
+ {p_give, 0, "00Give 給其他人錢"},
+ {save_violatelaw, 0,"11ViolateLaw 繳罰單"},
+#if !HAVE_FREECLOAK
+ {p_cloak, 0, "22Cloak 切換 隱身/現身 $19 /次"},
+#endif
+ {p_from, 0, "33From 暫時修改故鄉 $49 /次"},
+ {ordersong,0, "44OSong 歐桑動態點歌機 $200 /次"},
+ {p_exmail, 0, "55Exmail 購買信箱 $1000/封"},
+ {NULL, 0, NULL}
+};
+
+static int p_money() {
+ domenu(PSALE, "Ptt量販店", '0', moneylist);
+ return 0;
+};
+
+static commands_t jceelist[] = {
+ {x_90,PERM_LOGINOK, "0090 JCEE 【90學年度大學聯招查榜系統】"},
+ {x_89,PERM_LOGINOK, "1189 JCEE 【89學年度大學聯招查榜系統】"},
+ {x_88,PERM_LOGINOK, "2288 JCEE 【88學年度大學聯招查榜系統】"},
+ {x_87,PERM_LOGINOK, "3387 JCEE 【87學年度大學聯招查榜系統】"},
+ {x_86,PERM_LOGINOK, "4486 JCEE 【86學年度大學聯招查榜系統】"},
+ {NULL, 0, NULL}
+};
+
+static int m_jcee() {
+ domenu(JCEE, "Ptt查榜系統", '0', jceelist);
+ return 0;
+}
+
+static int forsearch();
+static int playground();
+
+/* Ptt Play menu */
+static commands_t playlist[] = {
+#if HAVE_JCEE
+ {m_jcee, PERM_LOGINOK, "JJCEE 【 大學聯考查榜系統 】"},
+#endif
+ {note, PERM_LOGINOK, "NNote 【 刻刻流言版 】"},
+ {x_weather,0 , "WWeather 【 氣象預報 】"},
+ {x_stock,0 , "SStock 【 股市行情 】"},
+#ifdef HAVE_BIG2
+ {x_big2, 0, "BBig2 【 網路大老二 】"},
+#endif
+#ifdef HAVE_MJ
+ {x_mj, PERM_LOGINOK, "QQkmj 【 網路打麻將 】"},
+#endif
+#ifdef HAVE_BRIDGE
+ {x_bridge, PERM_LOGINOK, "OOkBridge 【 橋牌競技 】"},
+#endif
+#ifdef HAVE_GOPHER
+ {x_gopher, PERM_LOGINOK, "GGopher 【 地鼠資料庫 】"},
+#endif
+#ifdef HAVE_TIN
+ {x_tin, PERM_LOGINOK, "NNEWS 【 網際新聞 】"},
+#endif
+#ifdef BBSDOORS
+ {x_bbsnet, PERM_LOGINOK, "BBBSNet 【 其他 BBS站 】"},
+#endif
+#ifdef HAVE_WWW
+ {x_www, PERM_LOGINOK, "WWWW Browser 【 汪汪汪 】"},
+#endif
+ {forsearch,PERM_LOGINOK, "SSearchEngine【\033[1;35m Ptt搜尋器 \033[m】"},
+ {topsong,PERM_LOGINOK, "TTop Songs 【\033[1;32m歐桑點歌排行榜\033[m】"},
+ {p_money,PERM_LOGINOK, "PPay 【\033[1;31m Ptt量販店 \033[m】"},
+ {chicken_main,PERM_LOGINOK, "CChicken "
+ "【\033[1;34m Ptt養雞場 \033[m】"},
+ {playground,PERM_LOGINOK, "AAmusement 【\033[1;33m Ptt遊樂場 \033[m】"},
+ {NULL, 0, NULL}
+};
+
+static commands_t plist[] = {
+
+/* {p_ticket_main, PERM_LOGINOK,"00Pre 【 總統機 】"},
+ {alive, PERM_LOGINOK, "00Alive 【 訂票雞 】"},
+*/
+ {ticket_main, PERM_LOGINOK, "11Gamble 【 Ptt賭場 】"},
+ {guess_main, PERM_LOGINOK, "22Guess number【 猜數字 】"},
+ {othello_main, PERM_LOGINOK, "33Othello 【 黑白棋 】"},
+// {dice_main, PERM_LOGINOK, "44Dice 【 玩骰子 】"},
+ {vice_main, PERM_LOGINOK, "44Vice 【 發票對獎 】"},
+ {g_card_jack, PERM_LOGINOK, "55Jack 【 黑傑克 】"},
+ {g_ten_helf, PERM_LOGINOK, "66Tenhalf 【 十點半 】"},
+ {card_99, PERM_LOGINOK, "77Nine 【 九十九 】"},
+ {NULL, 0, NULL}
+};
+
+static int playground() {
+ domenu(AMUSE, "Ptt遊樂場",'1',plist);
+ return 0;
+}
+
+static commands_t slist[] = {
+ {x_dict,0, "11Dictionary "
+ "【\033[1;33m 趣味大字典 \033[m】"},
+ {main_railway, PERM_LOGINOK, "33Railway "
+ "【\033[1;32m 火車表查詢 \033[m】"},
+ {NULL, 0, NULL}
+};
+
+static int forsearch() {
+ domenu(SREG, "Ptt搜尋器", '1', slist);
+ return 0;
+}
+
+/* main menu */
+
+static int admin() {
+ domenu(ADMIN, "系統維護", 'X', adminlist);
+ return 0;
+}
+
+static int Mail() {
+ domenu(MAIL, "電子郵件", 'R', maillist);
+ return 0;
+}
+
+static int Talk() {
+ domenu(TMENU, "聊天說話", 'U', talklist);
+ return 0;
+}
+
+static int User() {
+ domenu(UMENU, "個人設定", 'A', userlist);
+ return 0;
+}
+
+static int Xyz() {
+ domenu(XMENU, "工具程式", 'M', xyzlist);
+ return 0;
+}
+
+static int Play_Play() {
+ domenu(PMENU, "網路遊樂場", 'A', playlist);
+ return 0;
+}
+
+static int Name_Menu() {
+ domenu(NMENU, "白色恐怖", 'O', namelist);
+ return 0;
+}
+
+commands_t cmdlist[] = {
+ {admin,PERM_SYSOP|PERM_VIEWSYSOP, "00Admin 【 系統維護區 】"},
+ {Announce, 0, "AAnnounce 【 精華公佈欄 】"},
+ {Boards, 0, "FFavorite 【 我 的 最愛 】"},
+ {root_board, 0, "CClass 【 分組討論區 】"},
+ {Mail, PERM_BASIC, "MMail 【 私人信件區 】"},
+ {Talk, 0, "TTalk 【 休閒聊天區 】"},
+ {User, 0, "UUser 【 個人設定區 】"},
+ {Xyz, 0, "XXyz 【 系統工具區 】"},
+ {Play_Play,0, "PPlay 【 遊樂場/大學查榜】"},
+ {Name_Menu,PERM_LOGINOK, "NNamelist 【 編特別名單 】"},
+ {Goodbye, 0, "GGoodbye 離開,再見……"},
+ {NULL, 0, NULL}
+};