summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2010-07-01 22:20:23 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2010-07-01 22:20:23 +0800
commitd0a451a787e08350fcd77344c78196fc8f57fb78 (patch)
tree9d66f6ad56304d76f512e8941097a4953a3d7ae4
parent2a03da9fa30df523bf1b11e66be5b6c1b51c08ee (diff)
downloadpttbbs-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.c31
-rw-r--r--pttbbs/include/daemons.h6
-rw-r--r--pttbbs/include/proto.h6
-rw-r--r--pttbbs/mbbsd/angel.c163
-rw-r--r--pttbbs/mbbsd/menu.c21
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}