diff options
31 files changed, 547 insertions, 189 deletions
diff --git a/pttbbs/include/bbs.h b/pttbbs/include/bbs.h index 71a3332f..666d30c7 100644 --- a/pttbbs/include/bbs.h +++ b/pttbbs/include/bbs.h @@ -60,6 +60,7 @@ #include "common.h" #include "perm.h" #include "modes.h" +#include "chc.h" #include "proto.h" #include "gomo.h" diff --git a/pttbbs/include/chc.h b/pttbbs/include/chc.h new file mode 100644 index 00000000..66f1aacb --- /dev/null +++ b/pttbbs/include/chc.h @@ -0,0 +1,34 @@ +/* 象棋 */ +#define SIDE_ROW 7 +#define TURN_ROW 8 +#define STEP_ROW 9 +#define TIME_ROW 10 +#define WARN_ROW 12 +#define MYWIN_ROW 17 +#define HISWIN_ROW 18 + +#define CHC_VERSUS 1 /* 雙人 */ +#define CHC_WATCH 2 /* 觀棋 */ +#define CHC_PERSONAL 4 /* 打譜 */ +#define CHC_WATCH_PERSONAL 8 /* 觀人打譜 */ + +#define BLACK_COLOR "\033[1;36m" +#define RED_COLOR "\033[1;31m" +#define BLACK_REVERSE "\033[1;37;46m" +#define RED_REVERSE "\033[1;37;41m" +#define TURN_COLOR "\033[1;33m" + +typedef struct chcusr_t{ + char userid[IDLEN + 1]; + int win; + int lose; + int tie; +} chcusr_t; + +#define CHC_ACT_BOARD 0x1 /* set if transfered board to this sock */ + +typedef struct chc_act_list{ + int sock; + struct chc_act_list *next; +} chc_act_list; + diff --git a/pttbbs/include/modes.h b/pttbbs/include/modes.h index a70e7047..2ddf2b52 100644 --- a/pttbbs/include/modes.h +++ b/pttbbs/include/modes.h @@ -96,11 +96,7 @@ #define JCEE 78 #define REEDIT 79 #define BLOGGING 80 - -/* 象棋 */ -#define CHC_VERSUS 0 /* 雙人 */ -#define CHC_WATCH 1 /* 觀棋 */ -#define CHC_PERSONAL 2 /* 打譜 */ +#define CHESS_MENU 81 /* menu.c 中的模式 */ #define QUIT 0x666 /* Return value to abort recursive functions */ diff --git a/pttbbs/include/proto.h b/pttbbs/include/proto.h index d3b6058d..e11528a2 100644 --- a/pttbbs/include/proto.h +++ b/pttbbs/include/proto.h @@ -165,10 +165,18 @@ int card_99(); int t_chat(); /* chc_draw */ +char *getstep(board_t board, rc_t *from, rc_t *to); void chc_drawline(board_t board, chcusr_t *user1, chcusr_t *user2, int line); void chc_movecur(int r, int c); void chc_redraw(chcusr_t *user1, chcusr_t *user2, board_t board); +/* chc_log */ +int chc_log_open(chcusr_t *user1, chcusr_t *user2, char *file); +int chc_log(char *step); +void chc_log_close(void); +int chc_log_step(board_t board, rc_t *from, rc_t *to); +int chc_log_poem(void); + /* chc_net */ //void chc_sendmove(int s); //int chc_recvmove(int s); @@ -177,6 +185,9 @@ void chc_broadcast_send(chc_act_list *act_list, board_t board); /* chc_play */ void chc(int s, int mode); +int chc_main(void); +int chc_personal(void); +int chc_watch(void); /* chc_rule */ void chc_movechess(board_t board); @@ -260,6 +271,7 @@ int num_in_buf(); int ochar(int c); int rget(int x,char *prompt); char getans(char *prompt); +int timeout_read(int fd, void *pointer, int size, int sec); /* kaede */ int Rename(char* src, char* dst); @@ -308,6 +320,8 @@ void show_last_call_in(int save); int dosearchuser(char *userid); void u_exit(char *mode); void talk_request(int sig); +int reply_connection_request(userinfo_t *uip); +void my_talk(userinfo_t * uin, int fri_stat, char defact); /* menu */ void showtitle(char *title, char *mid); @@ -507,7 +521,7 @@ int login_friend_online(); int isvisible_uid(int tuid); int friend_stat(userinfo_t *me, userinfo_t * ui); int call_in(userinfo_t *uentp, int fri_stat); -void chc_watch_request(int signo); +int make_connection_to_somebody(userinfo_t *uin, int timeout); /* tmpjack */ int reg_barbq(); diff --git a/pttbbs/include/pttstruct.h b/pttbbs/include/pttstruct.h index a69ba30b..d598eab9 100644 --- a/pttbbs/include/pttstruct.h +++ b/pttbbs/include/pttstruct.h @@ -425,20 +425,4 @@ typedef struct int recno; } TagItem; -/* 象棋 */ -typedef struct chcusr_t{ - char userid[IDLEN + 1]; - int uid; - int win; - int lose; - int tie; -} chcusr_t; - -#define CHC_ACT_BOARD 0x1 /* set if transfered board to this sock */ - -typedef struct chc_act_list{ - int sock; - char flag; - struct chc_act_list *next; -} chc_act_list; #endif diff --git a/pttbbs/mbbsd/Makefile b/pttbbs/mbbsd/Makefile index b0c09c4a..1ac765f7 100644 --- a/pttbbs/mbbsd/Makefile +++ b/pttbbs/mbbsd/Makefile @@ -9,7 +9,8 @@ LDFLAGS+= -L/usr/local/lib/mysql -lmysqlclient PROG= mbbsd OBJS= admin.o announce.o args.o bbs.o board.o cache.o cal.o card.o\ - chat.o chc_draw.o chc_net.o chc_play.o chc_rule.o chicken.o dark.o\ + chat.o chicken.o dark.o\ + chc_draw.o chc_net.o chc_play.o chc_rule.o chc_log.o \ edit.o friend.o gamble.o gomo.o gomo1.o guess.o indict.o io.o\ kaede.o lovepaper.o mail.o mbbsd.o menu.o more.o name.o osdep.o\ othello.o page.o read.o record.o register.o screen.o stuff.o\ diff --git a/pttbbs/mbbsd/chc_draw.c b/pttbbs/mbbsd/chc_draw.c index 2cca2f19..2c687c77 100644 --- a/pttbbs/mbbsd/chc_draw.c +++ b/pttbbs/mbbsd/chc_draw.c @@ -1,14 +1,6 @@ /* $Id$ */ #include "bbs.h" -#define SIDE_ROW 10 -#define TURN_ROW 11 -#define STEP_ROW 12 -#define TIME_ROW 13 -#define WARN_ROW 15 -#define MYWIN_ROW 17 -#define HISWIN_ROW 18 - static char *turn_str[2] = {"黑的", "紅的"}; static char *num_str[10] = { @@ -57,39 +49,43 @@ chc_movecur(int r, int c) move(r * 2 + 3, c * 4 + 4); } -#define BLACK_COLOR "\033[1;36m" -#define RED_COLOR "\033[1;31m" -#define BLACK_REVERSE "\033[1;37;46m" -#define RED_REVERSE "\033[1;37;41m" -#define TURN_COLOR "\033[1;33m" - -static void -showstep(board_t board) +char * +getstep(board_t board, rc_t *from, rc_t *to) { - int turn, fc, tc, eatten; + int turn, fc, tc; char *dir; + static char buf[80]; - turn = CHE_O(board[chc_from.r][chc_from.c]); - fc = (turn == (chc_my ^ 1) ? chc_from.c + 1 : 9 - chc_from.c); - tc = (turn == (chc_my ^ 1) ? chc_to.c + 1 : 9 - chc_to.c); - if (chc_from.r == chc_to.r) + turn = CHE_O(board[from->r][from->c]); + fc = (turn == (chc_my ^ 1) ? from->c + 1 : 9 - from->c); + tc = (turn == (chc_my ^ 1) ? to->c + 1 : 9 - to->c); + if (from->r == to->r) dir = "平"; else { - if (chc_from.c == chc_to.c) - tc = chc_from.r - chc_to.r; + if (from->c == to->c) + tc = from->r - to->r; if (tc < 0) tc = -tc; - if ((turn == (chc_my ^ 1) && chc_to.r > chc_from.r) || - (turn == chc_my && chc_to.r < chc_from.r)) + if ((turn == (chc_my ^ 1) && to->r > from->r) || + (turn == chc_my && to->r < from->r)) dir = "進"; else dir = "退"; } - prints("%s%s%s%s%s", - turn == 0 ? BLACK_COLOR : RED_COLOR, - chess_str[turn][CHE_P(board[chc_from.r][chc_from.c])], + sprintf(buf, "%s%s%s%s", + chess_str[turn][CHE_P(board[from->r][from->c])], num_str[fc], dir, num_str[tc]); + return buf; +} + +static void +showstep(board_t board) +{ + int eatten; + + prints("%s%s", CHE_O(board[chc_from.r][chc_from.c]) == 0 ? BLACK_COLOR : RED_COLOR, getstep(board, &chc_from, &chc_to)); + eatten = board[chc_to.r][chc_to.c]; if (eatten) prints(": %s%s", @@ -106,8 +102,8 @@ chc_drawline(board_t board, chcusr_t *user1, chcusr_t *user2, int line) move(line, 0); clrtoeol(); if (line == 0) { - prints("\033[1;46m 象棋對戰 \033[45m%30s VS %-30s\033[m", - user1->userid, user2->userid); + prints("\033[1;46m 象棋對戰 \033[45m%30s VS %-20s%10s\033[m", + user1->userid, user2->userid, chc_mode & CHC_WATCH ? "[觀棋模式]" : ""); } else if (line >= 3 && line <= 21) { outs(" "); for (i = 0; i < 9; i++) { diff --git a/pttbbs/mbbsd/chc_log.c b/pttbbs/mbbsd/chc_log.c new file mode 100644 index 00000000..cb464322 --- /dev/null +++ b/pttbbs/mbbsd/chc_log.c @@ -0,0 +1,73 @@ +#include "bbs.h" + +extern char * chc_getstep(board_t board); + +static FILE *fp = NULL; + +int +chc_log_open(chcusr_t *user1, chcusr_t *user2, char *file) +{ + char buf[128]; + if ((fp = fopen(file, "w")) == NULL) + return -1; + sprintf(buf, "%s V.S. %s\n", user1->userid, user2->userid); + fputs(buf, fp); + return 0; +} + +void +chc_log_close(void) +{ + if (fp) + fclose(fp); +} + +int +chc_log(char *desc) +{ + if (fp) + return fputs(desc, fp); + return NULL; +} + +int +chc_log_step(board_t board, rc_t *from, rc_t *to) +{ + char buf[80]; + sprintf(buf, " %s%s\033[m\n", CHE_O(board[from->r][from->c]) == 0 ? BLACK_COLOR : RED_COLOR, getstep(board, from, to)); + return chc_log(buf); +} + +static int +chc_filter(struct dirent *dir) +{ + if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0 ) + return 0; + return strnstr(dir->d_name, ".poem", sizeof(dir->d_name)) != NULL; +} + +int +chc_log_poem(void) +{ + struct dirent **namelist; + int n; + + n = scandir(BBSHOME"/etc/chess", &namelist, chc_filter, alphasort); + if (n < 0) + perror("scandir"); + else { + char buf[80]; + FILE *fp; + sprintf(buf, BBSHOME"/etc/chess/%s", namelist[rand() % n]->d_name); + if ((fp = fopen(buf, "r")) == NULL) + return -1; + + while(fgets(buf, sizeof(buf), fp) != NULL) + chc_log(buf); + while(n--) + free(namelist[n]); + free(namelist); + fclose(fp); + } + return 0; +} diff --git a/pttbbs/mbbsd/chc_net.c b/pttbbs/mbbsd/chc_net.c index d82066e7..4a780336 100644 --- a/pttbbs/mbbsd/chc_net.c +++ b/pttbbs/mbbsd/chc_net.c @@ -27,19 +27,8 @@ chc_sendmove(int s) } static void -chc_send_status(int sock, board_t board){ - write(sock, &board, sizeof(board)); - /////// nessesery? correct? - write(sock, &chc_turn, sizeof(chc_turn)); -} - -static void chc_broadcast(chc_act_list *p, board_t board){ while(p){ - if (!(p->flag & CHC_ACT_BOARD)){ - chc_send_status(p->sock, board); - p->flag |= CHC_ACT_BOARD; - } if (chc_sendmove(p->sock) < 0) { if (p->next->next == NULL) p = NULL; diff --git a/pttbbs/mbbsd/chc_play.c b/pttbbs/mbbsd/chc_play.c index 7efbaaca..b3053ea3 100644 --- a/pttbbs/mbbsd/chc_play.c +++ b/pttbbs/mbbsd/chc_play.c @@ -2,16 +2,12 @@ #include "bbs.h" typedef int (*play_func_t) (int, chcusr_t *, chcusr_t *, board_t, board_t); -static int chc_ipass = 0, chc_hepass = 0; +static char chc_ipass = 0, chc_hepass = 0; -#define CHC_TIMEOUT 300 -#define SIDE_ROW 10 -#define TURN_ROW 11 -#define STEP_ROW 12 -#define TIME_ROW 13 -#define WARN_ROW 15 -#define MYWIN_ROW 17 -#define HISWIN_ROW 18 +extern userinfo_t *uip; + +#define CHC_TIMEOUT 300 +#define CHC_LOG "chc_log" static void chcusr_put(userec_t *userec, chcusr_t *user) @@ -72,14 +68,27 @@ hisplay(int s, chcusr_t *user1, chcusr_t *user2, board_t board, board_t tmpbrd) strlcpy(chc_warnmsg, "\033[1;33m要求和局!\033[m", sizeof(chc_warnmsg)); chc_drawline(board, user1, user2, WARN_ROW); } else { - chc_from.r = 9 - chc_from.r, chc_from.c = 8 - chc_from.c; - chc_to.r = 9 - chc_to.r, chc_to.c = 8 - chc_to.c; + /* 座標變換 + * (CHC_WATCH_PERSONAL 設定時 + * 表觀棋者看的棋局為單人打譜的棋局) + * 棋盤需倒置的清況才要轉換 + */ + if ( ((chc_mode & CHC_WATCH) && (chc_mode & CHC_WATCH_PERSONAL)) || /* 1.如果在觀棋 且棋局是別人在打譜 且輪到你 或*/ + (chc_mode & CHC_PERSONAL) || /* 2.自己在打譜 */ + ((chc_mode & CHC_WATCH) && !chc_turn) + ) + ; // do nothing + else { + chc_from.r = 9 - chc_from.r, chc_from.c = 8 - chc_from.c; + chc_to.r = 9 - chc_to.r, chc_to.c = 8 - chc_to.c; + } chc_cursor = chc_to; if (CHE_P(board[chc_to.r][chc_to.c]) == 1) endgame = 2; endturn = 1; chc_hepass = 0; chc_drawline(board, user1, user2, STEP_ROW); + chc_log_step(board, &chc_from, &chc_to); chc_movechess(board); chc_drawline(board, user1, user2, LTR(chc_from.r)); chc_drawline(board, user1, user2, LTR(chc_to.r)); @@ -170,6 +179,7 @@ myplay(int s, chcusr_t *user1, chcusr_t *user2, board_t board, board_t tmpbrd) } if (endgame || !chc_iskfk(tmpbrd)) { chc_drawline(board, user1, user2, STEP_ROW); + chc_log_step(board, &chc_from, &chc_to); chc_movechess(board); chc_broadcast_send(act_list, board); chc_selected = 0; @@ -198,15 +208,12 @@ static void mainloop(int s, chcusr_t *user1, chcusr_t *user2, board_t board, play_func_t play_func[2]) { int endgame; + char buf[80]; board_t tmpbrd; - play_func[chc_my] = myplay; - if(s != 0) - play_func[chc_my ^ 1] = hisplay; - else /* 跟自己下棋 */ - play_func[chc_my ^ 1] = myplay; - - for (chc_turn = 1, endgame = 0; !endgame; chc_turn ^= 1) { + if (!(chc_mode & CHC_WATCH)) + chc_turn = 1; + for (endgame = 0; !endgame; chc_turn ^= 1) { chc_firststep = 0; chc_drawline(board, user1, user2, TURN_ROW); if (chc_ischeck(board, chc_turn)) { @@ -218,7 +225,7 @@ mainloop(int s, chcusr_t *user1, chcusr_t *user2, board_t board, play_func_t pla endgame = play_func[chc_turn] (s, user1, user2, board, tmpbrd); } - if (s != 0) { + if (chc_mode & CHC_VERSUS) { if (endgame == 1) { strlcpy(chc_warnmsg, "對方認輸了!", sizeof(chc_warnmsg)); user1->win++; @@ -232,113 +239,258 @@ mainloop(int s, chcusr_t *user1, chcusr_t *user2, board_t board, play_func_t pla user1->tie++; currutmp->chc_tie++; } + user1->lose--; + chcusr_put(&cuser, user1); + passwd_update(usernum, &cuser); + } + else if (chc_mode & CHC_WATCH) { + strlcpy(chc_warnmsg, "結束觀棋", sizeof(chc_warnmsg)); } else { strlcpy(chc_warnmsg, "結束打譜", sizeof(chc_warnmsg)); } - user1->lose--; - // if not watching - chcusr_put(&cuser, user1); - passwd_update(usernum, &cuser); + chc_log("=> "); + if (endgame == 3) + chc_log("和局"); + else{ + sprintf(buf, "%s勝\n", chc_my && endgame == 1 ? "紅" : "黑"); + chc_log(buf); + } + chc_drawline(board, user1, user2, WARN_ROW); bell(); oflush(); } static void -chc_init(int s, chcusr_t *user1, chcusr_t *user2, board_t board) +chc_init_play_func(chcusr_t *user1, chcusr_t *user2, play_func_t play_func[2]) +{ + char userid[2][IDLEN + 1]; + + if (chc_mode & CHC_PERSONAL) { + strlcpy(userid[0], cuser.userid, sizeof(userid[0])); + strlcpy(userid[1], cuser.userid, sizeof(userid[1])); + play_func[0] = play_func[1] = myplay; + } + else if (chc_mode & CHC_WATCH) { + userinfo_t *uinfo = search_ulist_userid(currutmp->mateid); + strlcpy(userid[0], uinfo->userid, sizeof(userid[0])); + strlcpy(userid[1], uinfo->mateid, sizeof(userid[1])); + play_func[0] = play_func[1] = hisplay; + } + else { + strlcpy(userid[0], cuser.userid, sizeof(userid[0])); + strlcpy(userid[1], currutmp->mateid, sizeof(userid[1])); + play_func[chc_my] = myplay; + play_func[chc_my ^ 1] = hisplay; + } + + getuser(userid[0]); + chcusr_get(&xuser, user1); + getuser(userid[1]); + chcusr_get(&xuser, user2); +} + +static void +chc_watch_request(int signo) +{ + if (!(currstat & CHC)) + return; + chc_act_list *tmp; + for(tmp = act_list; tmp->next != NULL; tmp = tmp->next); + tmp->next = (chc_act_list *)malloc(sizeof(chc_act_list)); + tmp = tmp->next; + tmp->sock = reply_connection_request(uip); + if (tmp->sock < 0) + return; + tmp->next = NULL; + write(tmp->sock, chc_bp, sizeof(board_t)); + write(tmp->sock, &chc_my, sizeof(chc_my)); + write(tmp->sock, &chc_turn, sizeof(chc_turn)); + write(tmp->sock, &currutmp->turn, sizeof(currutmp->turn)); + write(tmp->sock, &chc_firststep, sizeof(chc_firststep)); + write(tmp->sock, &chc_mode, sizeof(chc_mode)); +} + +static void +chc_init(int s, chcusr_t *user1, chcusr_t *user2, board_t board, play_func_t play_func[2]) { userinfo_t *my = currutmp; setutmpmode(CHC); clear(); chc_warnmsg[0] = 0; - if(s != 0){ // XXX mateid -> user2 - chc_my = my->turn; - chc_mateid = my->mateid; + + /* 從不同來源初始化各個變數 */ + if (!(chc_mode & CHC_WATCH)) { + if (chc_mode & CHC_PERSONAL) + chc_my = 1; + else + chc_my = my->turn; + chc_firststep = 1; + chc_init_board(board); + chc_cursor.r = 9, chc_cursor.c = 0; } - else{ - chc_my = 1; - chc_mateid = cuser.userid; + else { + char mode; + read(s, board, sizeof(board_t)); + read(s, &chc_my, sizeof(chc_my)); + read(s, &chc_turn, sizeof(chc_turn)); + read(s, &my->turn, sizeof(my->turn)); + read(s, &chc_firststep, sizeof(chc_firststep)); + read(s, &mode, sizeof(mode)); + if (mode & CHC_PERSONAL) + chc_mode |= CHC_WATCH_PERSONAL; } - chc_firststep = 1; - chc_init_board(board); + + act_list = (chc_act_list *)malloc(sizeof(*act_list)); + act_list->sock = s; + act_list->next = 0; + + chc_init_play_func(user1, user2, play_func); + chc_redraw(user1, user2, board); - chc_cursor.r = 9, chc_cursor.c = 0; add_io(s, 0); - if (my->turn) + signal(SIGUSR1, chc_watch_request); + + if (my->turn && !(chc_mode & CHC_WATCH)) chc_broadcast_recv(act_list, board); user1->lose++; - // if not watching - passwd_query(usernum, &xuser); - chcusr_put(&xuser, user1); - passwd_update(usernum, &xuser); + + if (chc_mode & CHC_VERSUS) { + passwd_query(usernum, &xuser); + chcusr_put(&xuser, user1); + passwd_update(usernum, &xuser); + } if (!my->turn) { - chc_broadcast_send(act_list, board); - user2->lose++; + if (!(chc_mode & CHC_WATCH)) + chc_broadcast_send(act_list, board); + user2->lose++; } chc_redraw(user1, user2, board); } void -chc(int s, int type) +chc(int s, int mode) { - char userid[2][IDLEN + 1]; - board_t board; chcusr_t user1, user2; play_func_t play_func[2]; + board_t board; + char mode0 = currutmp->mode; + char file[80]; - signal(SIGUSR1, chc_watch_request); + signal(SIGUSR1, SIG_IGN); - if (type == CHC_PERSONAL) { - strlcpy(userid[0], cuser.userid, sizeof(userid[0])); - strlcpy(userid[1], cuser.userid, sizeof(userid[1])); - play_func[0] = play_func[1] = myplay; - } - else if (type == CHC_WATCH) { - userinfo_t *uinfo = search_ulist_userid(cuser.userid); - strlcpy(userid[0], uinfo->userid, sizeof(userid[0])); - strlcpy(userid[1], uinfo->mateid, sizeof(userid[1])); - play_func[0] = play_func[1] = hisplay; - timeout_read(s, 60); - read(s, &board, sizeof(board)); - /////// nessesery? correct? - read(s, &chc_turn, sizeof(chc_turn)); - } - else { - strlcpy(userid[0], cuser.userid, sizeof(userid[0])); - strlcpy(userid[1], currutmp->mateid, sizeof(userid[1])); - play_func[0] = myplay; - play_func[1] = hisplay; - } - - if (type != CHC_WATCH) { - act_list = (chc_act_list *)malloc(sizeof(*act_list)); - act_list->sock = s; - act_list->next = 0; - } + chc_mode = mode; + chc_bp = &board; - getuser(userid[0]); - chcusr_get(&xuser, &user1); - getuser(userid[1]); - chcusr_get(&xuser, &user2); - - chc_init(s, &user1, &user2, board); + chc_init(s, &user1, &user2, board, play_func); + + setuserfile(file, CHC_LOG); + if (chc_log_open(&user1, &user2, file) < 0) + vmsg("無法紀錄棋局"); + mainloop(s, &user1, &user2, board, play_func); - if (type == CHC_VERSUS) { - while(act_list){ - close(act_list->sock); - act_list = act_list->next; - } + /* close these fd */ + if (chc_mode & CHC_PERSONAL) + act_list = act_list->next; + while(act_list){ + close(act_list->sock); + act_list = act_list->next; } + add_io(0, 0); if (chc_my) pressanykey(); + currutmp->mode = mode0; + + if (getans("是否將棋譜寄回信箱?[N/y]") == 'y') { + char title[80]; + sprintf(title, "%s V.S. %s", user1.userid, user2.userid); + chc_log("\n--\n\n"); + chc_log_poem(); + chc_log_close(); + mail_id(cuser.userid, title, file, "[楚河漢界]"); + } + else + chc_log_close(); signal(SIGUSR1, talk_request); } + +static userinfo_t * +chc_init_utmp(void) +{ + char uident[16]; + userinfo_t *uin; + + stand_title("楚河漢界之爭"); + generalnamecomplete(msg_uid, uident, sizeof(uident), + SHM->UTMPnumber, + completeutmp_compar, + completeutmp_permission, + completeutmp_getname); + if (uident[0] == '\0') + return NULL; + + if ((uin = search_ulist_userid(uident)) == NULL) + return NULL; + + uin->sig = SIG_CHC; + return uin; +} + +int +chc_main(void) +{ + userinfo_t *uin; + + if ((uin = chc_init_utmp()) == NULL) + return -1; + uin->turn = 1; + currutmp->turn = 0; + strlcpy(uin->mateid, currutmp->userid, sizeof(uin->mateid)); + strlcpy(currutmp->mateid, uin->userid, sizeof(currutmp->mateid)); + + my_talk(uin, friend_stat(currutmp, uin), 'c'); + return 0; +} + +int +chc_personal(void) +{ + chc(0, CHC_PERSONAL); + return 0; +} + +int +chc_watch(void) +{ + int sock, msgsock; + userinfo_t *uin; + + if ((uin = chc_init_utmp()) == NULL) + return -1; + + if (uin->uid == currutmp->uid) + return -1; + + if ((sock = make_connection_to_somebody(uin, 10)) < 0) { + vmsg("無法建立連線"); + return -1; + } + msgsock = accept(sock, (struct sockaddr *) 0, (socklen_t *) 0); + close(sock); + if (msgsock < 0) + return -1; + + strlcpy(currutmp->mateid, uin->userid, sizeof(currutmp->mateid)); + chc(msgsock, CHC_WATCH); + close(msgsock); + return 0; +} diff --git a/pttbbs/mbbsd/mbbsd.c b/pttbbs/mbbsd/mbbsd.c index 2e0794dd..4fc5ac54 100644 --- a/pttbbs/mbbsd/mbbsd.c +++ b/pttbbs/mbbsd/mbbsd.c @@ -25,7 +25,7 @@ signal_restart(int signum, void (*handler) (int)) struct sigaction act; act.sa_handler = handler; memset(&(act.sa_mask), 0, sizeof(sigset_t)); - act.sa_flags = 0; + act.sa_flags = SA_NODEFER; sigaction(signum, &act, NULL); } diff --git a/pttbbs/mbbsd/menu.c b/pttbbs/mbbsd/menu.c index ca5b480f..ef978a94 100644 --- a/pttbbs/mbbsd/menu.c +++ b/pttbbs/mbbsd/menu.c @@ -467,6 +467,18 @@ static int m_jcee() { static int forsearch(); static int playground(); +static commands_t chesslist[] = { + {chc_main, PERM_LOGINOK, "11Play 【 邀棋 】"}, + {chc_personal, PERM_LOGINOK, "22Self-Play 【 打譜 】"}, + {chc_watch, PERM_LOGINOK, "33CHCWatch 【 觀棋 】"}, + {NULL, 0, NULL} +}; + +static int chessroom() { + domenu(CHESS_MENU, "Ptt棋奕館", '1', chesslist); + return 0; +} + /* Ptt Play menu */ static commands_t playlist[] = { #if 0 @@ -484,6 +496,7 @@ static commands_t playlist[] = { {chicken_main,PERM_LOGINOK, "CChicken " "【\033[1;34m Ptt養雞場 \033[m】"}, {playground,PERM_LOGINOK, "AAmusement 【\033[1;33m Ptt遊樂場 \033[m】"}, + {chessroom,PERM_LOGINOK, "BChessroom 【\033[1;34m Ptt棋奕館 \033[m】"}, {NULL, 0, NULL} }; diff --git a/pttbbs/mbbsd/talk.c b/pttbbs/mbbsd/talk.c index 72a51131..42cae53b 100644 --- a/pttbbs/mbbsd/talk.c +++ b/pttbbs/mbbsd/talk.c @@ -42,7 +42,8 @@ static char save_page_requestor[40]; static char page_requestor[40]; static char description[30]; static FILE *flog; -static userinfo_t *uip; + +userinfo_t *uip; int iswritable_stat(userinfo_t * uentp, int fri_stat) @@ -1155,6 +1156,8 @@ int make_connection_to_somebody(userinfo_t *uin, int timeout){ (!ch && (uin->chatid[0] == 1 || uin->chatid[0] == 3))) { add_io(0, 0); + if (ch == CHC) + break; close(sock); currutmp->sockactive = currutmp->destuid = 0; outmsg("人家在忙啦"); @@ -1197,8 +1200,8 @@ int make_connection_to_somebody(userinfo_t *uin, int timeout){ return sock; } -static void -my_talk(userinfo_t * uin, int fri_stat) +void +my_talk(userinfo_t * uin, int fri_stat, char defact) { int sock, msgsock, error = 0, ch; pid_t pid; @@ -1207,6 +1210,7 @@ my_talk(userinfo_t * uin, int fri_stat) unsigned char mode0 = currutmp->mode; + genbuf[0] = defact; ch = uin->mode; strlcpy(currauthor, uin->userid, sizeof(currauthor)); @@ -1215,12 +1219,16 @@ my_talk(userinfo_t * uin, int fri_stat) (!ch && (uin->chatid[0] == 1 || uin->chatid[0] == 3)) || uin->lockmode == M_FIVE || uin->lockmode == CHC) { if (ch == CHC) { - kill(uin->pid, SIGUSR1); - if ((sock = make_connection_to_somebody(uin, 20)) < 0) + if ((sock = make_connection_to_somebody(uin, 10)) < 0) vmsg("無法建立連線"); else { - strlcpy(currutmp->mateid, uin->userid, sizeof(currutmp->mateid)); - chc(sock, CHC_WATCH); + int msgsock = accept(sock, (struct sockaddr *) 0, (socklen_t *) 0); + close(sock); + if (msgsock >= 0) { + strlcpy(currutmp->mateid, uin->userid, sizeof(currutmp->mateid)); + chc(msgsock, CHC_WATCH); + close(msgsock); + } } } else @@ -1240,7 +1248,8 @@ my_talk(userinfo_t * uin, int fri_stat) outs(msg_usr_left); } else { showplans(uin->userid); - getdata(2, 0, "要和他(她) (T)談天(F)下五子棋(P)鬥寵物" + if (!genbuf[0]) + getdata(2, 0, "要和他(她) (T)談天(F)下五子棋(P)鬥寵物" "(C)下象棋(D)下暗棋(N)沒事找錯人了?[N] ", genbuf, 4, LCECHO); switch (*genbuf) { case 'y': @@ -1365,13 +1374,6 @@ my_talk(userinfo_t * uin, int fri_stat) pressanykey(); } -static void -self_play(userinfo_t * uin, int fri_stat) -{ - if (getans("[象棋] 你確定要打譜嗎?[N/y]") == 'y') - chc(0, CHC_PERSONAL); -} - /* 選單式聊天介面 */ #define US_PICKUP 1234 #define US_RESORT 1233 @@ -2222,17 +2224,14 @@ userlist(void) case 't': if (HAS_PERM(PERM_LOGINOK)) { - move(1, 0); - clrtobot(); - move(3, 0); if (uentp->pid != currpid && strcmp(uentp->userid, cuser.userid) != 0) { - my_talk(uentp, fri_stat); - } - else{ - self_play(uentp, fri_stat); + move(1, 0); + clrtobot(); + move(3, 0); + my_talk(uentp, fri_stat, 0); + redrawall = redraw = 1; } - redrawall = redraw = 1; } break; case 'K': @@ -2539,12 +2538,12 @@ t_talk() } if ((uentp = (userinfo_t *) search_ulistn(tuid, unum))) - my_talk(uentp, friend_stat(currutmp, uentp)); + my_talk(uentp, friend_stat(currutmp, uentp), 0); return 0; } -static int +int reply_connection_request(userinfo_t *uip) { int a; @@ -2554,7 +2553,7 @@ reply_connection_request(userinfo_t *uip) uip = &SHM->uinfo[currutmp->destuip]; - if (uip->mode != PAGE) { + if (uip->mode != PAGE && uip->mode != CHC) { snprintf(genbuf, sizeof(genbuf), "%s已停止呼叫,按Enter繼續...", page_requestor); getdata(0, 0, genbuf, buf, sizeof(buf), LCECHO); @@ -2572,7 +2571,6 @@ reply_connection_request(userinfo_t *uip) memcpy(&sin.sin_addr, h->h_addr, h->h_length); sin.sin_port = uip->sockaddr; a = socket(sin.sin_family, SOCK_STREAM, 0); - /////////////// if ((connect(a, (struct sockaddr *) & sin, sizeof(sin)))) { perror("connect err"); return -1; @@ -2580,19 +2578,6 @@ reply_connection_request(userinfo_t *uip) return a; } -void -chc_watch_request(int signo) -{ - if (!(currstat & CHC)) - return; - chc_act_list *tmp; - for(tmp = act_list; tmp->next != NULL; tmp = tmp->next); - tmp->next = (chc_act_list *)malloc(sizeof(chc_act_list)); - tmp = tmp->next; - tmp->sock = reply_connection_request(uip); - tmp->next = NULL; -} - /* 有人來串門子了,回應呼叫器 */ void talkreply(void) diff --git a/pttbbs/mbbsd/var.c b/pttbbs/mbbsd/var.c index 1d2eac31..aae2fd8c 100644 --- a/pttbbs/mbbsd/var.c +++ b/pttbbs/mbbsd/var.c @@ -389,8 +389,10 @@ char trans_buffer[256]; rc_t chc_from, chc_to, chc_select, chc_cursor; int chc_lefttime; int chc_my, chc_turn, chc_selected, chc_firststep; -char chc_warnmsg[64], *chc_mateid; +char chc_mode; +char chc_warnmsg[64]; chc_act_list *act_list = NULL; +board_t *chc_bp; /* screen.c */ screenline_t *big_picture = NULL; diff --git a/pttbbs/sample/etc/Makefile b/pttbbs/sample/etc/Makefile index 6a2755ef..2f2753eb 100644 --- a/pttbbs/sample/etc/Makefile +++ b/pttbbs/sample/etc/Makefile @@ -1,4 +1,4 @@ -SUBDIR=chickens +SUBDIR=chickens chess BBSHOME?=$(HOME) TARGET=$(BBSHOME)/etc/ FILES= @five Welcome register today_boring \ diff --git a/pttbbs/sample/etc/chess/1.poem b/pttbbs/sample/etc/chess/1.poem new file mode 100644 index 00000000..f50247ab --- /dev/null +++ b/pttbbs/sample/etc/chess/1.poem @@ -0,0 +1,10 @@ +象弈 南宋 劉克莊 + + 或遲如圍莒,或速如入蔡。 + + 遠炮勿虛發,冗卒要精汰。 + + 負非由寡少,勝豈繫強大? + + 昆陽以象奔,陳濤以車敗。 + diff --git a/pttbbs/sample/etc/chess/10.poem b/pttbbs/sample/etc/chess/10.poem new file mode 100644 index 00000000..b9dc2107 --- /dev/null +++ b/pttbbs/sample/etc/chess/10.poem @@ -0,0 +1,10 @@ +無題 明 明太子朱高熾 + + 二國爭強各用兵,擺成隊伍定輸贏。 + + 馬行曲路當先道,將守深宮戒遠征。 + + 乘險出車收敗卒,隔河飛炮下重城。 + + 等閒識得軍情事,一著功成見太平。 + diff --git a/pttbbs/sample/etc/chess/11.poem b/pttbbs/sample/etc/chess/11.poem new file mode 100644 index 00000000..01331372 --- /dev/null +++ b/pttbbs/sample/etc/chess/11.poem @@ -0,0 +1,6 @@ +無題 不明 + + 清風明月之夜,詩歌唱詠; + + 古松流水之間,敲棋品茗。 + diff --git a/pttbbs/sample/etc/chess/12.poem b/pttbbs/sample/etc/chess/12.poem new file mode 100644 index 00000000..53a68b72 --- /dev/null +++ b/pttbbs/sample/etc/chess/12.poem @@ -0,0 +1,6 @@ +諷宋薛昂處士負棋作詩 不明 + + 好笑當年薛乞兒,荊公座上賭新詩, + + 而今又向江東去,奉勸先生莫下棋。 + diff --git a/pttbbs/sample/etc/chess/13.poem b/pttbbs/sample/etc/chess/13.poem new file mode 100644 index 00000000..01331372 --- /dev/null +++ b/pttbbs/sample/etc/chess/13.poem @@ -0,0 +1,6 @@ +無題 不明 + + 清風明月之夜,詩歌唱詠; + + 古松流水之間,敲棋品茗。 + diff --git a/pttbbs/sample/etc/chess/14.poem b/pttbbs/sample/etc/chess/14.poem new file mode 100644 index 00000000..d41950e8 --- /dev/null +++ b/pttbbs/sample/etc/chess/14.poem @@ -0,0 +1,10 @@ +無題 明 明象棋高手李開先 村翁 + + 小有兼逢大有年,田家多穫即為賢。 + + 有時撒網為漁父,日常登床作睡仙。 + + 破局棋堆隨手應,無弦琴不用音傳。 + + 一身之外無所慕,下有青山上碧天。 + diff --git a/pttbbs/sample/etc/chess/15.poem b/pttbbs/sample/etc/chess/15.poem new file mode 100644 index 00000000..139597f9 --- /dev/null +++ b/pttbbs/sample/etc/chess/15.poem @@ -0,0 +1,2 @@ + + diff --git a/pttbbs/sample/etc/chess/16.poem b/pttbbs/sample/etc/chess/16.poem new file mode 100644 index 00000000..139597f9 --- /dev/null +++ b/pttbbs/sample/etc/chess/16.poem @@ -0,0 +1,2 @@ + + diff --git a/pttbbs/sample/etc/chess/2.poem b/pttbbs/sample/etc/chess/2.poem new file mode 100644 index 00000000..119e98ae --- /dev/null +++ b/pttbbs/sample/etc/chess/2.poem @@ -0,0 +1,10 @@ +棋詩 明 曾子棨 + + 兩軍對敵立雙營,坐運神機決死生。 + + 千里封疆馳鐵馬,一川波浪動金兵。 + + 虞姬歌舞悲垓下,反將旌旗逼楚城。 + + 興盡計窮征戰罷,松蔭花影滿棋秤。 + diff --git a/pttbbs/sample/etc/chess/3.poem b/pttbbs/sample/etc/chess/3.poem new file mode 100644 index 00000000..d69636b7 --- /dev/null +++ b/pttbbs/sample/etc/chess/3.poem @@ -0,0 +1,6 @@ +觀棋 清 袁枚 + + 攏袖觀棋有所思,分明楚漢兩軍峙。 + + 非常喜歡非常惱,不著棋人總不如。 + diff --git a/pttbbs/sample/etc/chess/4.poem b/pttbbs/sample/etc/chess/4.poem new file mode 100644 index 00000000..f86edc12 --- /dev/null +++ b/pttbbs/sample/etc/chess/4.poem @@ -0,0 +1,10 @@ +和春深 唐 白居易 + + 何處深為好,春到博弈家。 + + 一先爭破眼,六聚斗成花, + + 鼓應投壹馬,兵沖象戲車。 + + 評棋局上事,最妙是長斜。 + diff --git a/pttbbs/sample/etc/chess/5.poem b/pttbbs/sample/etc/chess/5.poem new file mode 100644 index 00000000..cffd55e1 --- /dev/null +++ b/pttbbs/sample/etc/chess/5.poem @@ -0,0 +1,8 @@ +無題 宋 王安石 + + 飄飄凌雲志,強御莫能懾; + + 忘情塞上馬,適志夢中蝶; + + 經論安所施,有寓聊自愜。 + diff --git a/pttbbs/sample/etc/chess/6.poem b/pttbbs/sample/etc/chess/6.poem new file mode 100644 index 00000000..00c4cff8 --- /dev/null +++ b/pttbbs/sample/etc/chess/6.poem @@ -0,0 +1,6 @@ +無題 呂洞賓 + + 教著殘局山月曉, + + 一聲長嘯海天秋。 + diff --git a/pttbbs/sample/etc/chess/7.poem b/pttbbs/sample/etc/chess/7.poem new file mode 100644 index 00000000..b525cba0 --- /dev/null +++ b/pttbbs/sample/etc/chess/7.poem @@ -0,0 +1,10 @@ +吊棋 明 錢鶴灘 + + 敲棋終日與偏幽,誰道今朝結父仇。 + + 兵足下河車不救,將軍落水士難留。 + + 馬行千里隨波去,象渡三江逐淚流。 + + 炮響一聲驚霹靂,臥龍投起碧雲浮。 + diff --git a/pttbbs/sample/etc/chess/8.poem b/pttbbs/sample/etc/chess/8.poem new file mode 100644 index 00000000..01360b29 --- /dev/null +++ b/pttbbs/sample/etc/chess/8.poem @@ -0,0 +1,10 @@ +詠象戲 北宋 程顥 + + 大都博弈皆戲劇,象戲翻能學用兵。 + + 車馬尚存周戰法,偏裨兼備漢官名。 + + 中軍八面將軍重,河外尖斜步卒輕。 + + 卻憑紋楸聊自笑,雄如劉項亦間爭。 + diff --git a/pttbbs/sample/etc/chess/9.poem b/pttbbs/sample/etc/chess/9.poem new file mode 100644 index 00000000..01331372 --- /dev/null +++ b/pttbbs/sample/etc/chess/9.poem @@ -0,0 +1,6 @@ +無題 不明 + + 清風明月之夜,詩歌唱詠; + + 古松流水之間,敲棋品茗。 + |