summaryrefslogtreecommitdiffstats
path: root/mbbsd
diff options
context:
space:
mode:
authorscw <scw@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2007-03-24 16:51:42 +0800
committerscw <scw@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2007-03-24 16:51:42 +0800
commit2bc657336cf51255ea6d0bf47c1792347d4bf8d3 (patch)
tree179338332df4d97e424093a1f75b39cf298c6afa /mbbsd
parent4ffc2cfeb67b922ac4885ac9443a45c9dc5ef17c (diff)
downloadpttbbs-2bc657336cf51255ea6d0bf47c1792347d4bf8d3.tar
pttbbs-2bc657336cf51255ea6d0bf47c1792347d4bf8d3.tar.gz
pttbbs-2bc657336cf51255ea6d0bf47c1792347d4bf8d3.tar.bz2
pttbbs-2bc657336cf51255ea6d0bf47c1792347d4bf8d3.tar.lz
pttbbs-2bc657336cf51255ea6d0bf47c1792347d4bf8d3.tar.xz
pttbbs-2bc657336cf51255ea6d0bf47c1792347d4bf8d3.tar.zst
pttbbs-2bc657336cf51255ea6d0bf47c1792347d4bf8d3.zip
Set timeout for confirmation when playing chess to avoid
wasting others' time. git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3491 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd')
-rw-r--r--mbbsd/chess.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/mbbsd/chess.c b/mbbsd/chess.c
index 04344d80..264b8553 100644
--- a/mbbsd/chess.c
+++ b/mbbsd/chess.c
@@ -1,6 +1,7 @@
/* $Id$ */
#include "bbs.h"
#include "chess.h"
+#include <setjmp.h>
#define assert_not_reached() assert(!"Should never be here!!!")
#define dim(x) (sizeof(x) / sizeof(x[0]))
@@ -25,6 +26,21 @@
#define CONNECT_PEER() add_io(info->sock, 0)
#define IGNORE_PEER() add_io(0, 0)
+#define DO_WITHOUT_PEER(TIMEOUT,ACT,ELSE) \
+ do { \
+ void (*orig_alarm_handler)(int) = \
+ Signal(SIGALRM, &SigjmpEnv); \
+ IGNORE_PEER(); \
+ if(sigsetjmp(sigjmpEnv, 1)) \
+ ELSE; \
+ else { \
+ alarm(TIMEOUT); \
+ ACT; \
+ } \
+ CONNECT_PEER(); \
+ Signal(SIGALRM, orig_alarm_handler); \
+ } while(0)
+
static const char * const ChessHintStr[] = {
" q 認輸離開",
" p 要求和棋",
@@ -44,12 +60,15 @@ static const struct {
};
static ChessInfo * CurrentPlayingGameInfo;
+static sigjmp_buf sigjmpEnv;
/* XXX: This is a BAD way to pass information.
* Fix this by handling chess request ourselves.
*/
static ChessTimeLimit * _current_time_limit;
+static void SigjmpEnv(int sig) { siglongjmp(sigjmpEnv, 1); }
+
#define CHESS_HISTORY_ENTRY(INFO,N) \
((INFO)->history.body + (N) * (INFO)->constants->step_entry_size)
static void
@@ -385,9 +404,9 @@ ChessAnswerRequest(ChessInfo* info, const char* req_name)
snprintf(msg, sizeof(msg),
"對方要求%s,是否接受?(y/N)", req_name);
- IGNORE_PEER();
- getdata(b_lines, 0, msg, buf, sizeof(buf), DOECHO);
- CONNECT_PEER();
+ DO_WITHOUT_PEER(30,
+ getdata(b_lines, 0, msg, buf, sizeof(buf), DOECHO),
+ buf[0] = 'n');
ChessDrawHelpLine(info);
info->warnmsg[0] = 0;
@@ -514,13 +533,14 @@ ChessPlayFuncMy(ChessInfo* info)
case 'q':
{
char buf[4];
- IGNORE_PEER();
+
+ DO_WITHOUT_PEER(30,
getdata(b_lines, 0,
info->mode == CHESS_MODE_PERSONAL ?
"是否真的要離開?(y/N)" :
"是否真的要認輸?(y/N)",
- buf, sizeof(buf), DOECHO);
- CONNECT_PEER();
+ buf, sizeof(buf), DOECHO),
+ buf[0] = 'n');
ChessDrawHelpLine(info);
if (buf[0] == 'y' || buf[0] == 'Y') {
@@ -541,10 +561,11 @@ ChessPlayFuncMy(ChessInfo* info)
endturn = 1;
} else if (info->mode != CHESS_MODE_PERSONAL) {
char buf[4];
- IGNORE_PEER();
+
+ DO_WITHOUT_PEER(30,
getdata(b_lines, 0, "是否真的要和棋?(y/N)",
- buf, sizeof(buf), DOECHO);
- CONNECT_PEER();
+ buf, sizeof(buf), DOECHO),
+ buf[0] = 'n');
ChessDrawHelpLine(info);
if (buf[0] == 'y' || buf[1] == 'Y') {
@@ -584,10 +605,10 @@ ChessPlayFuncMy(ChessInfo* info)
default:
if (info->actions->process_key) {
- IGNORE_PEER();
+ DO_WITHOUT_PEER(30,
endturn =
- info->actions->process_key(info, ch, &game_result);
- CONNECT_PEER();
+ info->actions->process_key(info, ch, &game_result),
+ );
}
}
}
@@ -625,10 +646,10 @@ ChessPlayFuncHis(ChessInfo* info)
case 'q':
{
char buf[4];
- IGNORE_PEER();
+ DO_WITHOUT_PEER(30,
getdata(b_lines, 0, "是否真的要認輸?(y/N)",
- buf, sizeof(buf), DOECHO);
- CONNECT_PEER();
+ buf, sizeof(buf), DOECHO),
+ buf[0] = 'n');
ChessDrawHelpLine(info);
if (buf[0] == 'y' || buf[0] == 'Y') {
@@ -708,10 +729,10 @@ ChessPlayFuncHis(ChessInfo* info)
default:
if (info->actions->process_key) {
- IGNORE_PEER();
+ DO_WITHOUT_PEER(30,
endturn =
- info->actions->process_key(info, ch, &game_result);
- CONNECT_PEER();
+ info->actions->process_key(info, ch, &game_result),
+ );
}
}
}