diff options
author | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-03-07 23:13:44 +0800 |
---|---|---|
committer | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-03-07 23:13:44 +0800 |
commit | ae31e19f92e717919ac8e3db9039eb38d2b89aae (patch) | |
tree | c70164d6a1852344f44b04a653ae2815043512af /mbbsd/chat.c | |
download | pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.gz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.bz2 pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.lz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.xz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.zst pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.zip |
Initial revision
git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@1 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/chat.c')
-rw-r--r-- | mbbsd/chat.c | 623 |
1 files changed, 623 insertions, 0 deletions
diff --git a/mbbsd/chat.c b/mbbsd/chat.c new file mode 100644 index 00000000..f75383a8 --- /dev/null +++ b/mbbsd/chat.c @@ -0,0 +1,623 @@ +/* $Id: chat.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <ctype.h> +#include <netdb.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "config.h" +#include "pttstruct.h" +#include "perm.h" +#include "common.h" +#include "modes.h" +#include "proto.h" + +extern userinfo_t *currutmp; +static int chatline; +static int stop_line; /* next line of bottom of message window area */ +static FILE *flog; + +static void printchatline(char *str) { + move(chatline, 0); + if(*str == '>' && !PERM_HIDE(currutmp)) + return; + else if(chatline < stop_line - 1) + chatline++; + else { + region_scroll_up(2, stop_line - 2); + move(stop_line - 2, 0); + } + outs(str); + outc('\n'); + outs("→"); + + if(flog) + fprintf(flog, "%s\n", str); +} + +extern int b_lines; /* Screen bottom line number: t_lines-1 */ + +static void chat_clear() { + for(chatline = 2; chatline < stop_line; chatline++) { + move(chatline, 0); + clrtoeol(); + } + move(b_lines, 0); + clrtoeol(); + move(chatline = 2, 0); + outs("→"); +} + +static void print_chatid(char *chatid) { + move(b_lines - 1, 0); + clrtoeol(); + outs(chatid); + outc(':'); +} + +static int chat_send(int fd, char *buf) { + int len; + char genbuf[200]; + + sprintf(genbuf, "%s\n", buf); + len = strlen(genbuf); + return (send(fd, genbuf, len, 0) == len); +} + +static char chatroom[IDLEN]; /* Chat-Room Name */ + +static int chat_recv(int fd, char *chatid) { + static char buf[512]; + static int bufstart = 0; + char genbuf[200]; + int c, len; + char *bptr; + + len = sizeof(buf) - bufstart - 1; + if((c = recv(fd, buf + bufstart, len, 0)) <= 0) + return -1; + c += bufstart; + + bptr = buf; + while(c > 0) { + len = strlen(bptr) + 1; + if(len > c && len < (sizeof buf / 2)) + break; + + if(*bptr == '/') { + switch(bptr[1]) { + case 'c': + chat_clear(); + break; + case 'n': + strncpy(chatid, bptr + 2, 8); + print_chatid(chatid); + clrtoeol(); + break; + case 'r': + strncpy(chatroom, bptr + 2, IDLEN - 1); + break; + case 't': + move(0, 0); + clrtoeol(); + sprintf(genbuf, "談天室 [%s]", chatroom); + prints("\033[1;37;46m %-21s \033[45m 話題:%-48s\033[m", + genbuf, bptr + 2); + } + } else + printchatline(bptr); + + c -= len; + bptr += len; + } + + if(c > 0) { + strcpy(genbuf, bptr); + strcpy(buf, genbuf); + bufstart = len - 1; + } else + bufstart = 0; + return 0; +} + +extern userec_t cuser; + +static int printuserent(userinfo_t *uentp) { + static char uline[80]; + static int cnt; + char pline[30]; + + if(!uentp) { + if(cnt) + printchatline(uline); + bzero(uline, 80); + cnt = 0; + return 0; + } + if(!HAS_PERM(PERM_SYSOP) && !HAS_PERM(PERM_SEECLOAK) && uentp->invisible) + return 0; + + sprintf(pline, "%-13s%c%-10s ", uentp->userid, + uentp->invisible ? '#' : ' ', + modestring(uentp, 1)); + if(cnt < 2) + strcat(pline, "│"); + strcat(uline, pline); + if(++cnt == 3) { + printchatline(uline); + memset(uline, 0, 80); + cnt = 0; + } + return 0; +} + +static void chathelp(char *cmd, char *desc) { + char buf[STRLEN]; + + sprintf(buf, " %-20s- %s", cmd, desc); + printchatline(buf); +} + +static void chat_help(char *arg) { + if(strstr(arg, " op")) { + printchatline("談天室管理員專用指令"); + chathelp("[/f]lag [+-][ls]", "設定鎖定、秘密狀態"); + chathelp("[/i]nvite <id>", "邀請 <id> 加入談天室"); + chathelp("[/k]ick <id>", "將 <id> 踢出談天室"); + chathelp("[/o]p <id>", "將 Op 的權力轉移給 <id>"); + chathelp("[/t]opic <text>", "換個話題"); + chathelp("[/w]all", "廣播 (站長專用)"); + } else { + chathelp("[//]help", "MUD-like 社交動詞"); + chathelp("[/.]help", "chicken 鬥雞用指令"); + chathelp("[/h]elp op", "談天室管理員專用指令"); + chathelp("[/a]ct <msg>", "做一個動作"); + chathelp("[/b]ye [msg]", "道別"); + chathelp("[/c]lear", "清除螢幕"); + chathelp("[/j]oin <room>", "建立或加入談天室"); + chathelp("[/l]ist [room]", "列出談天室使用者"); + chathelp("[/m]sg <id> <msg>", "跟 <id> 說悄悄話"); + chathelp("[/n]ick <id>", "將談天代號換成 <id>"); + chathelp("[/p]ager", "切換呼叫器"); + chathelp("[/q]uery", "查詢網友"); + chathelp("[/r]oom", "列出一般談天室"); + chathelp("[/u]sers", "列出站上使用者"); + chathelp("[/w]ho", "列出本談天室使用者"); + chathelp("[/w]hoin <room>", "列出談天室<room> 的使用者"); + } +} + +static void chat_date() { + time_t thetime; + char genbuf[200]; + + time(&thetime); + sprintf(genbuf, "◆ " BBSNAME "標準時間: %s", Cdate(&thetime)); + printchatline(genbuf); +} + +static void chat_pager() { + char genbuf[200]; + + char *msgs[] = {"關閉", "打開", "拔掉", "防水","好友"}; + sprintf(genbuf, "◆ 您的呼叫器:[%s]", + msgs[currutmp->pager = (currutmp->pager+1)%5]); + printchatline(genbuf); +} + +extern char *str_space; +extern userec_t xuser; +extern char *fn_plans; +extern char *err_uid; + +static void chat_query(char *arg) { + char *uid; + int tuid; + + printchatline(""); + strtok(arg, str_space); + if((uid = strtok(NULL, str_space)) && (tuid = getuser(uid))) { + char buf[128], *ptr; + FILE *fp; + + sprintf(buf, "%s(%s) 共上站 %d 次,發表過 %d 篇文章", + xuser.userid, xuser.username, xuser.numlogins, xuser.numposts); + printchatline(buf); + + sprintf(buf, "最近(%s)從[%s]上站", Cdate(&xuser.lastlogin), + (xuser.lasthost[0] ? xuser.lasthost : "(不詳)")); + printchatline(buf); + + sethomefile(buf, xuser.userid, fn_plans); + if((fp = fopen(buf, "r"))) { + tuid = 0; + while(tuid++ < MAX_QUERYLINES && fgets(buf, 128, fp)) { + if((ptr = strchr(buf, '\n'))) + ptr[0] = '\0'; + printchatline(buf); + } + fclose(fp); + } + } else + printchatline(err_uid); +} + +extern char *msg_shortulist; + +static void chat_users() { + printchatline(""); + printchatline("【 " BBSNAME "的遊客列表 】"); + printchatline(msg_shortulist); + + if(apply_ulist(printuserent) == -1) + printchatline("空無一人"); + printuserent(NULL); +} + +typedef struct chat_command_t { + char *cmdname; /* Chatroom command length */ + void (*cmdfunc) (); /* Pointer to function */ +} chat_command_t; + +static chat_command_t chat_cmdtbl[] = { + {"help", chat_help}, + {"clear", chat_clear}, + {"date", chat_date}, + {"pager", chat_pager}, + {"query", chat_query}, + {"users", chat_users}, + {NULL, NULL} +}; + +static int chat_cmd_match(char *buf, char *str) { + while(*str && *buf && !isspace(*buf)) + if(tolower(*buf++) != *str++) + return 0; + return 1; +} + +static int chat_cmd(char *buf, int fd) { + int i; + + if(*buf++ != '/') + return 0; + + for(i = 0; chat_cmdtbl[i].cmdname; i++) { + if(chat_cmd_match(buf, chat_cmdtbl[i].cmdname)) { + chat_cmdtbl[i].cmdfunc(buf); + return 1; + } + } + return 0; +} + +extern char trans_buffer[256]; /* 一般傳遞變數 add by Ptt */ + +#if 0 +static char *select_address() { + int c; + FILE *fp; + char nametab[25][90]; + char iptab[25][18], buf[80]; + + move(1, 0); + clrtobot(); + outs("\n \033[36m【找個地方抬抬槓吧!】\033[m " + "◎ 【以下為本站登記有案的茶樓】 \n"); + trans_buffer[0]=0; + if((fp = fopen("etc/teashop", "r"))) { + for(c = 0; fscanf(fp, "%s%s", iptab[c], nametab[c]) != EOF; c++) { + sprintf(buf,"\n (\033[36m%d\033[0m) %-30s [%s]", + c + 1, nametab[c], iptab[c]); + outs(buf); + } + getdata(20, 10, "★\033[32m 請選擇,[0]離開:\033[0m", buf, 3, + LCECHO); + if(buf[1]) + buf[0] = (buf[0] + 1) * 10 + (buf[1] - '1'); + else + buf[0] -= '1'; + if(buf[0] >= 0 && buf[0] < c) + strcpy(trans_buffer,iptab[(int)buf[0]]); + } else { + outs("本站沒有登記任何合格茶樓"); + pressanykey(); + } + return trans_buffer; +} +#endif + +extern int usernum; +extern int t_lines; +extern char *msg_seperator; +#define MAXLASTCMD 6 +static int chatid_len = 10; + +int t_chat() { + char inbuf[80], chatid[20], lastcmd[MAXLASTCMD][80], *ptr = ""; + struct sockaddr_in sin; + struct hostent *h; + int cfd, cmdpos, ch; + int currchar; + int newmail; + int chatting = YEA; + char fpath[80]; + char genbuf[200]; + char roomtype; + + if(inbuf[0] == 0) + return -1; + + outs(" 驅車前往 請梢候........ "); + if(!(h = gethostbyname("localhost"))) { + perror("gethostbyname"); + return -1; + } + memset(&sin, 0, sizeof sin); +#ifdef FreeBSD + sin.sin_len = sizeof(sin); +#endif + sin.sin_family = PF_INET; + memcpy(&sin.sin_addr, h->h_addr, h->h_length); + sin.sin_port = htons(NEW_CHATPORT); + cfd = socket(sin.sin_family, SOCK_STREAM, 0); + if(!(connect(cfd, (struct sockaddr *) & sin, sizeof sin))) + roomtype = 1; + else { + sin.sin_port = CHATPORT; + cfd = socket(sin.sin_family, SOCK_STREAM, 0); + if(!(connect(cfd, (struct sockaddr *) & sin, sizeof sin))) + roomtype = 2; + else { + outs("\n " + "哇! 沒人在那邊耶...要有那地方的人先去開門啦!..."); + system("bin/xchatd"); + pressanykey(); + return -1; + } + } + + while(1) { + getdata(b_lines - 1, 0, "請輸入聊天代號:", inbuf, 9, DOECHO); + sprintf(chatid, "%s", (inbuf[0] ? inbuf : cuser.userid)); + chatid[8] = '\0'; +/* + 舊格式: /! 使用者編號 使用者等級 UserID ChatID + 新格式: /! UserID ChatID Password +*/ + if(roomtype == 1) + sprintf(inbuf, "/! %s %s %s", + cuser.userid, chatid, cuser.passwd); + else + sprintf(inbuf, "/! %d %d %s %s", + usernum, cuser.userlevel, cuser.userid, chatid); + chat_send(cfd, inbuf); + if(recv(cfd, inbuf, 3, 0) != 3) + return 0; + if(!strcmp(inbuf, CHAT_LOGIN_OK)) + break; + else if(!strcmp(inbuf, CHAT_LOGIN_EXISTS)) + ptr = "這個代號已經有人用了"; + else if(!strcmp(inbuf, CHAT_LOGIN_INVALID)) + ptr = "這個代號是錯誤的"; + else if(!strcmp(inbuf, CHAT_LOGIN_BOGUS)) + ptr = "請勿派遣分身進入聊天室 !!"; + + move(b_lines - 2, 0); + outs(ptr); + clrtoeol(); + bell(); + } + + add_io(cfd, 0); + + newmail = currchar = 0; + cmdpos = -1; + memset(lastcmd, 0, MAXLASTCMD * 80); + + setutmpmode(CHATING); + currutmp->in_chat = YEA; + strcpy(currutmp->chatid, chatid); + + clear(); + chatline = 2; + strcpy(inbuf, chatid); + stop_line = t_lines - 3; + + move(stop_line, 0); + outs(msg_seperator); + move(1, 0); + outs(msg_seperator); + print_chatid(chatid); + memset(inbuf, 0, 80); + + sethomepath(fpath, cuser.userid); + strcpy(fpath, tempnam(fpath, "chat_")); + flog = fopen(fpath, "w"); + + while(chatting) { + move(b_lines - 1, currchar + chatid_len); + ch = igetkey(); + + switch(ch) { + case KEY_DOWN: + cmdpos += MAXLASTCMD - 2; + case KEY_UP: + cmdpos++; + cmdpos %= MAXLASTCMD; + strcpy(inbuf, lastcmd[cmdpos]); + move(b_lines - 1, chatid_len); + clrtoeol(); + outs(inbuf); + currchar = strlen(inbuf); + continue; + case KEY_LEFT: + if(currchar) + --currchar; + continue; + case KEY_RIGHT: + if(inbuf[currchar]) + ++currchar; + continue; + } + + if(!newmail && currutmp->mailalert ) { + newmail = 1; + printchatline("◆ 噹!郵差又來了..."); + } + + if(ch == I_OTHERDATA) { /* incoming */ + if(chat_recv(cfd, chatid) == -1) { + chatting = chat_send(cfd, "/b"); + break; + } + continue; + } + if(isprint2(ch)) { + if(currchar < 68) { + if(inbuf[currchar]) { /* insert */ + int i; + + for(i = currchar; inbuf[i] && i < 68; i++); + inbuf[i + 1 ] = '\0'; + for(; i > currchar; i--) + inbuf[i] = inbuf[i - 1]; + } else /* append */ + inbuf[currchar + 1] = '\0'; + inbuf[currchar] = ch; + move(b_lines - 1, currchar + chatid_len); + outs(&inbuf[currchar++]); + } + continue; + } + + if(ch == '\n' || ch == '\r') { + if(*inbuf) { + chatting = chat_cmd(inbuf, cfd); + if(chatting == 0) + chatting = chat_send(cfd, inbuf); + if(!strncmp(inbuf, "/b", 2)) + break; + + for(cmdpos = MAXLASTCMD - 1; cmdpos; cmdpos--) + strcpy(lastcmd[cmdpos], lastcmd[cmdpos - 1]); + strcpy(lastcmd[0], inbuf); + + inbuf[0] = '\0'; + currchar = 0; + cmdpos = -1; + } + print_chatid(chatid); + move(b_lines - 1, chatid_len); + continue; + } + + if(ch == Ctrl('H') || ch == '\177') { + if(currchar) { + currchar--; + inbuf[69] = '\0'; + memcpy(&inbuf[currchar], &inbuf[currchar + 1], 69 - currchar); + move(b_lines - 1, currchar + chatid_len); + clrtoeol(); + outs(&inbuf[currchar]); + } + continue; + } + if(ch == Ctrl('Z') || ch == Ctrl('Y')) { + inbuf[0] = '\0'; + currchar = 0; + print_chatid(chatid); + move(b_lines - 1, chatid_len); + continue; + } + + if(ch == Ctrl('C')) { + chat_send(cfd, "/b"); + break; + } + if(ch == Ctrl('D')) { + if(currchar < strlen(inbuf)) { + inbuf[69] = '\0'; + memcpy(&inbuf[currchar], &inbuf[currchar + 1], 69 - currchar); + move(b_lines - 1, currchar + chatid_len); + clrtoeol(); + outs(&inbuf[currchar]); + } + continue; + } + if(ch == Ctrl('K')) { + inbuf[currchar] = 0; + move(b_lines - 1, currchar + chatid_len); + clrtoeol(); + continue; + } + if(ch == Ctrl('A')) { + currchar = 0; + continue; + } + if(ch == Ctrl('E')) { + currchar = strlen(inbuf); + continue; + } + if(ch == Ctrl('I')) { + extern screenline_t *big_picture; + screenline_t *screen0 = calloc(t_lines, sizeof(screenline_t)); + + memcpy(screen0, big_picture, t_lines * sizeof(screenline_t)); + add_io(0, 0); + t_idle(); + memcpy(big_picture, screen0, t_lines * sizeof(screenline_t)); + free(screen0); + redoscr(); + add_io(cfd, 0); + continue; + } + if(ch == Ctrl('Q')) { + print_chatid(chatid); + move(b_lines - 1, chatid_len); + outs(inbuf); + continue; + } + } + + close(cfd); + add_io(0, 0); + currutmp->in_chat = currutmp->chatid[0] = 0; + + if(flog) { + char ans[4]; + + fclose(flog); + more(fpath, NA); + getdata(b_lines - 1, 0, "清除(C) 移至備忘錄(M) (C/M)?[C]", + ans, 4, LCECHO); + if (*ans == 'm') { + fileheader_t mymail; + char title[128]; + + sethomepath(genbuf, cuser.userid); + stampfile(genbuf, &mymail); + mymail.savemode = 'H'; /* hold-mail flag */ + mymail.filemode = FILE_READ; + strcpy(mymail.owner, "[備.忘.錄]"); + strcpy(mymail.title, "會議\033[1;33m記錄\033[m"); + sethomedir(title, cuser.userid); + append_record(title, &mymail, sizeof(mymail)); + Rename(fpath, genbuf); + } else + unlink(fpath); + } + + return 0; +} +/* -------------------------------------------------- */ +#if 0 + +extern char page_requestor[]; +extern userinfo_t *currutmp; + +#endif |