diff options
author | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2010-07-01 22:20:23 +0800 |
---|---|---|
committer | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2010-07-01 22:20:23 +0800 |
commit | d0a451a787e08350fcd77344c78196fc8f57fb78 (patch) | |
tree | 9d66f6ad56304d76f512e8941097a4953a3d7ae4 | |
parent | 2a03da9fa30df523bf1b11e66be5b6c1b51c08ee (diff) | |
download | pttbbs-d0a451a787e08350fcd77344c78196fc8f57fb78.tar pttbbs-d0a451a787e08350fcd77344c78196fc8f57fb78.tar.gz pttbbs-d0a451a787e08350fcd77344c78196fc8f57fb78.tar.bz2 pttbbs-d0a451a787e08350fcd77344c78196fc8f57fb78.tar.lz pttbbs-d0a451a787e08350fcd77344c78196fc8f57fb78.tar.xz pttbbs-d0a451a787e08350fcd77344c78196fc8f57fb78.tar.zst pttbbs-d0a451a787e08350fcd77344c78196fc8f57fb78.zip |
* link angel beats system to mbbsd
git-svn-id: http://opensvn.csie.org/pttbbs/trunk@5080 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r-- | pttbbs/daemon/angelbeats/angelbeats.c | 31 | ||||
-rw-r--r-- | pttbbs/include/daemons.h | 6 | ||||
-rw-r--r-- | pttbbs/include/proto.h | 6 | ||||
-rw-r--r-- | pttbbs/mbbsd/angel.c | 163 | ||||
-rw-r--r-- | pttbbs/mbbsd/menu.c | 21 |
5 files changed, 205 insertions, 22 deletions
diff --git a/pttbbs/daemon/angelbeats/angelbeats.c b/pttbbs/daemon/angelbeats/angelbeats.c index 9d308af8..164c6b1a 100644 --- a/pttbbs/daemon/angelbeats/angelbeats.c +++ b/pttbbs/daemon/angelbeats/angelbeats.c @@ -356,13 +356,18 @@ static struct event ev_listen, ev_sighup; static void sighup_cb(int signal, short event, void *arg) { + time4_t clk = time(0); + fprintf(stderr, "%s reload (HUP)\n", Cdatelite(&clk)); init_angel_list(); } static void client_cb(int fd, short event, void *arg) { int len; + char master_uid[IDLEN+1] = "", angel_uid[IDLEN+1] = ""; + char *uid; angel_beats_data data ={0}; + time4_t clk = time4(NULL); // ignore clients that timeout or sending invalid request if (event & EV_TIMEOUT) @@ -372,24 +377,45 @@ client_cb(int fd, short event, void *arg) { if (data.cb != sizeof(data)) goto end; + if (debug) { + fprintf(stderr, "%s request: op=%d, mid=%d, aid=%d\n", Cdatelite(&clk), + data.operation, data.master_uid, data.angel_uid); + } + // solve user ids + if (data.angel_uid && (uid = getuserid(data.angel_uid))) + strlcpy(angel_uid, uid, sizeof(angel_uid)); + if (data.master_uid && (uid = getuserid(data.master_uid))) + strlcpy(master_uid, uid, sizeof(master_uid)); + if (debug) printf("got request: %d\n", data.operation); switch(data.operation) { case ANGELBEATS_REQ_INVALID: + fprintf(stderr, "%s got invalid request [%s/%s]\n", + Cdatelite(&clk), master_uid, angel_uid); break; case ANGELBEATS_REQ_RELOAD: + fprintf(stderr, "%s reload\n", Cdatelite(&clk)); init_angel_list(); break; case ANGELBEATS_REQ_SUGGEST_AND_LINK: + fprintf(stderr, "%s request suggest&link from [%s], ", + Cdatelite(&clk), master_uid); data.angel_uid = suggest_online_angel(data.master_uid); if (data.angel_uid > 0) { inc_angel_master(data.angel_uid); + uid = getuserid(data.angel_uid); + strlcpy(angel_uid, uid, sizeof(angel_uid)); } - if(debug) printf("suggestion result: %d\n", data.angel_uid); + fprintf(stderr, "result: [%s]\n", data.angel_uid > 0 ? + angel_uid : "<none>"); break; case ANGELBEATS_REQ_REMOVE_LINK: + fprintf(stderr, "%s request remove link by master [%s] to angel [%s]\n", + Cdatelite(&clk), master_uid, angel_uid); dec_angel_master(data.angel_uid); break; case ANGELBEATS_REQ_REPORT: + fprintf(stderr, "%s report by [%s]\n", Cdatelite(&clk), master_uid); { if (debug) printf("ANGELBEATS_REQ_REPORT\n"); angel_beats_report rpt = {0}; @@ -427,7 +453,7 @@ int main(int argc, char *argv[]) { int i; AngelInfo *kanade; - int ch, sfd, go_daemon = 0; + int ch, sfd, go_daemon = 1; const char *iface_ip = ANGELBEATS_ADDR; // things to do: @@ -458,6 +484,7 @@ main(int argc, char *argv[]) { chdir(BBSHOME); attach_SHM(); + printf("initializing angel list...\n"); init_angel_list(); printf("found %zd angels. (cap=%zd)\n", g_angel_list_size, g_angel_list_capacity); diff --git a/pttbbs/include/daemons.h b/pttbbs/include/daemons.h index 40260f64..23f0162f 100644 --- a/pttbbs/include/daemons.h +++ b/pttbbs/include/daemons.h @@ -81,8 +81,10 @@ typedef struct { short total_angels; short total_online_angels; short total_active_angels; - short low_average_masters; - short high_average_masters; + short min_masters_of_online_angels; + short max_masters_of_online_angels; + short min_masters_of_active_angels; + short max_masters_of_active_angels; short my_active_masters; } angel_beats_report ; diff --git a/pttbbs/include/proto.h b/pttbbs/include/proto.h index 92e4a537..3315a3bc 100644 --- a/pttbbs/include/proto.h +++ b/pttbbs/include/proto.h @@ -30,8 +30,10 @@ int make_symbolic_link_interactively(int gid); void merge_dir(const char *dir1, const char *dir2, int isoutter); /* angel */ -int t_changeangel(void); -int t_angelmsg(void); +int a_changeangel(void); +int a_angelmsg(void); +int a_angelreport(void); +int a_angelreload(void); int angel_reject_me(userinfo_t * uin); void CallAngel(void); void angel_toggle_pause(); diff --git a/pttbbs/mbbsd/angel.c b/pttbbs/mbbsd/angel.c index dee19527..9f57c394 100644 --- a/pttbbs/mbbsd/angel.c +++ b/pttbbs/mbbsd/angel.c @@ -1,12 +1,48 @@ /* $Id$ */ #include "bbs.h" +#ifdef PLAY_ANGEL // PTT-BBS Angel System -#ifdef PLAY_ANGEL - +#include "daemons.h" #define FN_ANGELMSG "angelmsg" +///////////////////////////////////////////////////////////////////////////// +// Angel Beats! Client + +// this works for simple requests: (return 1/angel_uid for success, 0 for fail +static int +angel_beats_do_request(int op, int master_uid, int angel_uid) { + int fd; + int ret = 1; + angel_beats_data req = {0}; + + req.cb = sizeof(req); + req.operation = op; + req.master_uid = master_uid; + req.angel_uid = angel_uid; + assert(op != ANGELBEATS_REQ_INVALID); + + if ((fd = toconnect(ANGELBEATS_ADDR)) < 0) + return -1; + + assert(req.operation != ANGELBEATS_REQ_INVALID); + + if (towrite(fd, &req, sizeof(req)) < 1 || + toread (fd, &req, sizeof(req)) < 1 || + req.cb != sizeof(req)) { + ret = -2; + } else { + ret = (req.angel_uid > 0) ? req.angel_uid : 1; + } + + close(fd); + return ret; +} + +///////////////////////////////////////////////////////////////////////////// +// Local Angel Service + void angel_toggle_pause() { @@ -122,7 +158,7 @@ angel_get_nick() } int -t_changeangel(){ +a_changeangel(){ char buf[4]; /* cuser.myangel == "-" means banned for calling angel */ @@ -136,15 +172,17 @@ t_changeangel(){ snprintf(buf, sizeof(buf), "%s 小主人 %s 換掉 %s 小天使\n", Cdatelite(&now), cuser.userid, cuser.myangel); log_file(BBSHOME "/log/changeangel.log", LOG_CREAT, buf); - + if (cuser.myangel[0]) + angel_beats_do_request(ANGELBEATS_REQ_REMOVE_LINK, + usernum, searchuser(cuser.myangel, NULL)); pwcuSetMyAngel(""); - outs("小天使更新完成,下次呼叫時會選出新的小天使"); + vmsg("小天使更新完成,下次呼叫時會選出新的小天使"); } - return XEASY; + return 0; } int -t_angelmsg(){ +a_angelmsg(){ char msg[3][74] = { "", "", "" }; char nick[10] = ""; char buf[512]; @@ -213,6 +251,84 @@ t_angelmsg(){ return 0; } +int a_angelreport() { + angel_beats_report rpt = {0}; + angel_beats_data req = {0}; + int fd; + + vs_hdr2(" Angel Beats! 天使公會 ", " 天使狀態報告 "); + outs("\n"); + + if ((fd = toconnect(ANGELBEATS_ADDR)) < 0) { + outs("抱歉,無法連線至天使公會。\n" + "請至 " BN_BUGREPORT " 看板通知站方管理人員。\n"); + pressanykey(); + return 0; + } + + req.cb = sizeof(req); + req.operation = ANGELBEATS_REQ_REPORT; + req.master_uid = usernum; + + if (HasUserPerm(PERM_ANGEL)) + req.angel_uid = usernum; + + if (towrite(fd, &req, sizeof(req)) < 1 || + toread(fd, &rpt, sizeof(rpt)) < 1 || + rpt.cb != sizeof(rpt)) { + outs("抱歉,天使公會連線異常。\n" + "請至 " BN_BUGREPORT " 看板通知站方管理人員。\n"); + } else { + prints( + "\t 現在時間: %s\n\n" + "\n\t 系統內已登記的天使為 %d 位。\n" + "\n\t 目前有 %d 位天使在線上,其中 %d 位神諭呼叫器為設定開放;\n" + "\n\t 上線的天使中,擁有小主人數目最少為 %d 位,最多為 %d 位;\n" + "\n\t 上線且開放收小主人的天使中,小主人最少 %d 位,最多 %d 位。\n", + Cdatelite(&now), + rpt.total_angels, + rpt.total_online_angels, + rpt.total_active_angels, + rpt.min_masters_of_online_angels, + rpt.max_masters_of_online_angels, + rpt.min_masters_of_active_angels, + rpt.max_masters_of_active_angels); + if (HasUserPerm(PERM_ANGEL)) + prints("\n\t 您目前大約有 %d 位小主人。\n", rpt.my_active_masters); + } + close(fd); + pressanykey(); + return 0; +} + +int a_angelreload() { + vs_hdr2(" Angel Beats! 天使公會 ", " 重整天使資訊 "); + outs("\n" + "\t 由於重新統計天使小主人數目非常花時間,所以目前系統\n" + "\t 一般只會更新已知的天使。 若站方有新增或刪除天使時\n" + "\t 請在改完所有天使權限後利用此功\能來重整天使資訊。\n" + "\n" + "\t 另外由於重整時所有跟天使有關的功\能都會暫停 30 秒 ~ 一兩分鐘,\n" + "\t 請不要沒事就重整,而是真的有調整天使名單後才使用。\n"); + if (vans("請問確定要重整天使資訊了嗎? [y/N]: ") != 'y') { + vmsg("放棄。"); + return 0; + } + + move(1, 0); clrtobot(); + outs("\n連線中...\n"); refresh(); + + if (angel_beats_do_request(ANGELBEATS_REQ_RELOAD, usernum, 0) < 0) { + outs("抱歉,無法連線至天使公會。\n" + "請至 " BN_BUGREPORT " 看板通知站方管理人員。\n"); + } else { + outs("\n完成!\n"); + } + + pressanykey(); + return 0; +} + inline int angel_reject_me(userinfo_t * uin){ // TODO 超級好友怎麼辦? @@ -226,9 +342,8 @@ angel_reject_me(userinfo_t * uin){ return 0; } - static int -FindAngel(void){ +FindAngel_Old(void){ int nAngel; int i, j; int choose; @@ -273,6 +388,32 @@ FindAngel(void){ return 0; } +static int +FindAngel(void){ + + int angel_uid = 0; + userinfo_t *angel = NULL; + int retries = 2; + + do { + angel_uid = angel_beats_do_request(ANGELBEATS_REQ_SUGGEST_AND_LINK, + usernum, 0); + if (angel_uid < 0) // connection failure + break; + if (angel_uid > 0) + angel = search_ulist(angel_uid); + } while ((retries-- < 1) && !(angel && (angel->userlevel & PERM_ANGEL))); + + if (angel) { + // got new angel + pwcuSetMyAngel(angel->userid); + return 1; + } + + // not able to find angel beats? try traditional way. + return FindAngel_Old(); +} + static inline void GotoNewHand(){ char old_board[IDLEN + 1] = ""; @@ -456,13 +597,9 @@ CallAngel(){ if (!HasUserPerm(PERM_LOGINOK) || entered) return; entered = 1; - scr_dump(&old_screen); - TalkToAngel(); - scr_restore(&old_screen); - entered = 0; } diff --git a/pttbbs/mbbsd/menu.c b/pttbbs/mbbsd/menu.c index 58791b3e..40f07284 100644 --- a/pttbbs/mbbsd/menu.c +++ b/pttbbs/mbbsd/menu.c @@ -585,6 +585,20 @@ static const commands_t maillist[] = { {NULL, 0, NULL} }; +#ifdef PLAY_ANGEL +static const commands_t angelmenu[] = { + {a_angelmsg, PERM_ANGEL,"LLeave message 留言給小主人"}, + {a_angelreport, 0, "RReport 線上天使狀態報告"}, + {a_angelreload, PERM_SYSOP,"OOReload 重整天使資訊"}, + {NULL, 0, NULL} +}; + +static int menu_angelbeats() { + domenu(M_TMENU, "Angel Beats! 天使公會", 'L', angelmenu); + return 0; +} +#endif + /* Talk menu */ static const commands_t talklist[] = { {t_users, 0, "UUsers 線上使用者列表"}, @@ -599,9 +613,10 @@ static const commands_t talklist[] = { {t_idle, 0, "IIdle 發呆"}, {t_qchicken, 0, "WWatch Pet 查詢寵物"}, #ifdef PLAY_ANGEL - {t_changeangel, - PERM_LOGINOK, "UAChange Angel 更換小天使"}, - {t_angelmsg, PERM_ANGEL,"LLeave message 留言給小主人"}, + {a_changeangel, + PERM_LOGINOK, "AAChange Angel 更換小天使"}, + {menu_angelbeats, PERM_ANGEL|PERM_SYSOP, + "BBAngel Beats! 天使公會"}, #endif {t_display, 0, "DDisplay 顯示上幾次熱訊"}, {NULL, 0, NULL} |