void call_query_ByChatid(chatcontext * pthis, const char *arg) { /* add by dong, 1998.9.12 */ char uident[32]; char tmpstr[40]; int res; if (!*arg) { printchatline(pthis, "*** 请输入要查询的chat ID ***"); return; } strncpy(uident, arg, 32); uident[31] = '\0'; /* get user id from the chat id */ sprintf(tmpstr, "/qc %s", uident); chat_send(pthis, tmpstr); res = chat_recv(pthis, tmpstr, 40); if (res <= 0) return; tmpstr[res] = '\0'; if (tmpstr[0] == '1') { sprintf(uident, "%s", tmpstr + 1); } else { sprintf(genbuf, "\033[32m这个chat ID不存在!\033[m"); printchatline(pthis, genbuf); return; } query_user(pthis, uident); }
int chat_status(struct user_info *uentp, chatcontext * pthis) { char tmpstr[31],buf[80],buf2[80]; char *lpTmp; if (strlen(genbuf)>t_columns) return QUIT; if (uentp->invisible == 1) { if (HAS_PERM(getCurrentUser(), PERM_SEECLOAK)) { sprintf(genbuf + strlen(genbuf), "\x1b[32m#\x1b[m"); } else return 0; } lpTmp = (char *) idle_str(buf,uentp); if (uentp->in_chat) { /* add by Luzi 1997.11.18 */ int res; sprintf(tmpstr, "/q %s", uentp->userid); chat_send(pthis, tmpstr); res = chat_recv(pthis, tmpstr, 30); if (res <= 0) return -1; tmpstr[res] = '\0'; if (tmpstr[0] == '1') { sprintf(genbuf + strlen(genbuf), "'%s' room as '%s'", tmpstr + 1, uentp->chatid); if (lpTmp[0] != ' ') sprintf(genbuf + strlen(genbuf), "[%s];", lpTmp); else strcat(genbuf, " ;"); return COUNT; } } sprintf(genbuf, "%s%-8s", genbuf, modestring(buf2,uentp->mode, uentp->destuid, 0, /* 1->0 不显示聊天对象等 modified by dong 1996.10.26 */ (uentp->in_chat ? uentp-> chatid : NULL))); if (lpTmp[0] != ' ') sprintf(genbuf + strlen(genbuf), "[%s];", lpTmp); else strcat(genbuf, " ;"); return COUNT; }
/* 2001/5/6 --wwj, 修改 ent_chat 函数 */ int ent_chat_conn(chatcontext * pthis, int chatnum) { struct sockaddr_in sin; int ch; char inbuf[128], *ptr; memset(&sin, 0, sizeof sin); sin.sin_family = PF_INET; sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* sin.sin_addr.s_addr = inet_addr("166.111.8.237"); */ if (chatnum == 1) sin.sin_port = htons(CHATPORT3); else sin.sin_port = htons(CHATPORT2); pthis->cfd = socket(sin.sin_family, SOCK_STREAM, 0); if (connect(pthis->cfd, (struct sockaddr *) &sin, sizeof sin)) { /*如果连接 chatd 失败,则启动chatd */ close(pthis->cfd); switch (ch = fork()) { case -1 /*fork failure */ : bbslog("chatd", "fork error"); break; case 0 /*fork success */ : bbslog("chatd", "fork success"); prints("开启聊天室..."); if (chatnum == 1) system("bin/chatd"); else system("bin/chatd 2"); exit(1); default: bbslog("chatd", "fork par-proc"); /* The chat daemon forks so we can wait on it here. */ waitpid(ch, NULL, 0); } pthis->cfd = socket(sin.sin_family, SOCK_STREAM, 0); if ((connect(pthis->cfd, (struct sockaddr *) &sin, sizeof sin))) { close(pthis->cfd); bbslog("chatd", "connect2 failed %d", errno); return -1; } } /* Leeward 98.04.26 */ move(3, 0); clrtoeol(); move(4, 0); /* Leave line 3 for error message while entering chat room */ prints ("输入字符 \033[1m\033[37m*\033[m 再按 \033[1m\033[37mEnter\033[m 可以取消进入聊天室。 "); clrtoeol(); move(5, 0); clrtoeol(); /* Clear line 5 for good looking */ while (1) { int gdataret; gdataret = getdata(2, 0, "请输入聊天代号:", inbuf, 9, DOECHO, NULL, true); if (gdataret == -1 || '*' == inbuf[0]) { /* Leeward 98.04.26 */ close(pthis->cfd); return 0; } if (inbuf[0] != '\0' && inbuf[0] != '\n' && inbuf[0] != '/') { strncpy(pthis->chatid, inbuf, 8); } else { strncpy(pthis->chatid, getCurrentUser()->userid, 8); } pthis->chatid[8] = '\0'; sprintf(inbuf, "/! %d %d %s %s", uinfo.uid, getCurrentUser()->userlevel, getCurrentUser()->userid, pthis->chatid); chat_send(pthis, inbuf); /* send user info to chatd , and chatd will check it */ if (chat_recv(pthis, inbuf, 3) != 3) { close(pthis->cfd); 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 ptr = "已经有一个窗口在聊天室里了(若非如此请退出BBS重新登录;若还不行再找在线站长)"; move(3, 0); prints(ptr); clrtoeol(); bell(); } return 1; }
int chat_parse(chatcontext * pthis) { int len; char *bptr; if (!pthis->bufptr || pthis->buf[pthis->bufptr - 1] != 0) { if (chat_recv(pthis, NULL, 0) < 0) return -1; } len = 0; bptr = pthis->buf; while (bptr < pthis->buf + pthis->bufptr) { for (len = 0; bptr + len < pthis->buf + pthis->bufptr; len++) { if (!bptr[len]) { len = -len; break; } } if (len > 0) break; len = -len + 1; /* skip 0 */ if (*bptr == '/') { /* 处理server传来的命令 */ switch (bptr[1]) { case 'p': /* add by KCN for list long emote */ /* chat_waitkey(pthis); removed by wwj */ break; case 'c': chat_clear(pthis); break; case 'n': strncpy(pthis->chatid, bptr + 2, 8); pthis->chatid[8] = 0; print_chatid(pthis); clrtoeol(); uinfo.in_chat = true; strcpy(uinfo.chatid, pthis->chatid); UPDATE_UTMP_STR(chatid, uinfo); break; case 'r': strncpy(pthis->chatroom, bptr + 2, IDLEN - 1); break; case 'z': strncpy(pthis->chatroom, bptr + 2, IDLEN - 1); /* fall throw */ case 't': move(0, 0); clrtoeol(); if (bptr[1] == 't') strcpy(pthis->topic, bptr + 2); prints ("\033[44m\033[33m 房间: \033[36m%-10s \033[33m话题:\033[36m%-51s\033[31m%2s\033[m", pthis->chatroom, pthis->topic, (pthis->rec) ? "录" : " "); break; } } else { printchatline(pthis, bptr); } bptr += len; len = 0; } if (len > 0) { memcpy(pthis->buf, bptr, pthis->bufptr - (bptr - pthis->buf)); pthis->bufptr -= bptr - pthis->buf; } else { pthis->bufptr = 0; } return 0; }
void server(int port) { linked_list_t *mapcycle_list = NULL; parse_mapcycle(&mapcycle_list); node_t *current_map = mapcycle_list->head; char port_game[100]; char port_chat[100]; char port_map[100]; sprintf(port_game, "%d", port); sprintf(port_chat, "%d", port + 1); sprintf(port_map, "%d", port + 2); signal(SIGTERM, sighandler); signal(SIGINT, sighandler); //node_t *current_map = mapcycle_list->head->next; while(server_running){ printf("[SERVER] NEW GAME\n"); player_list = malloc(sizeof(linked_list_t)); observer_list = malloc(sizeof(linked_list_t)); list_init(player_list); list_init(observer_list); int game_server_socket = prepare_server_UDP(port_game, AF_INET6); int chat_server_socket = prepare_server_TCP(port_chat, AF_INET6); int map_server_socket = prepare_server_TCP(port_map , AF_INET6); current_map = current_map->next; if(current_map == mapcycle_list->tail){ current_map = mapcycle_list->head->next; } game_server_init(current_map->data); fd_set descriptors_set; FD_ZERO(&descriptors_set); FD_SET(map_server_socket, &descriptors_set); FD_SET(chat_server_socket, &descriptors_set); FD_SET(game_server_socket, &descriptors_set); int max_fd = map_server_socket > chat_server_socket ? map_server_socket : chat_server_socket; max_fd = max_fd > game_server_socket ? max_fd : game_server_socket; struct timeval timeout; memset(&timeout, 0, sizeof(struct timeval)); timeout.tv_sec = 3; change_map = 0; while(!change_map){ if(select(max_fd + 1, &descriptors_set, NULL, NULL, &timeout) < 0) { continue; } timeout.tv_sec = 3; if (FD_ISSET(map_server_socket , &descriptors_set)){ map_server(map_server_socket, current_map_id); } if (FD_ISSET(chat_server_socket , &descriptors_set)){ chat_server(chat_server_socket); } if (FD_ISSET(game_server_socket , &descriptors_set)){ game_server(game_server_socket); } for (node_t *i = player_list->head->next; i != player_list->tail; i = i->next){ player_info_t *player_info = (player_info_t*)i->data; if (FD_ISSET(player_info->chat_descriptor , &descriptors_set)){ char buffer[129]; memset(buffer, 0, 129); int full_recv = 0; int bytes_recv = chat_recv(player_info->chat_descriptor, buffer, &full_recv); if(bytes_recv == 0){ //HANDLE DISCONNECT int player_id = player_info->playerID; close(player_info->chat_descriptor); node_t *previous = i->previous; list_remove_node(i, player_list); i = previous; if (player_id == 255){ continue; } char buffer[129]; sprintf(buffer, "Player %"SCNu8" disconnected", player_id); printf("[CHAT SERVER] %s\n", buffer); broadcast_disconnection_ack(game_server_socket, player_id, player_list); chat_forward_msg(0, buffer, player_list); }else if (bytes_recv < 0){ printf("[CHAT SERVER] Error receiving from %"SCNu8"%s\n", player_info->playerID, strerror(errno)); }else if (full_recv){ if (buffer[2] == '*'){ change_map = 1; } if (player_info->playerID == 255){ continue; } chat_forward_msg(player_info->playerID, &buffer[2], player_list); gettimeofday(&player_info->last_action, NULL); } } } remove_idle_players(game_server_socket); respawn_death_players(game_server_socket); FD_ZERO(&descriptors_set); FD_SET(map_server_socket, &descriptors_set); FD_SET(chat_server_socket, &descriptors_set); FD_SET(game_server_socket, &descriptors_set); max_fd = map_server_socket > chat_server_socket ? map_server_socket : chat_server_socket; max_fd = max_fd > game_server_socket ? max_fd : game_server_socket; for (node_t *i = player_list->head->next; i != player_list->tail; i = i->next){ player_info_t *player_info = (player_info_t*)i->data; FD_SET(player_info->chat_descriptor, &descriptors_set); if (player_info->chat_descriptor > max_fd){ max_fd = player_info->chat_descriptor; } } if (change_map){ sleep(5); broadcast_map_change(game_server_socket, player_list); } } change_map = 0; for(node_t *i = player_list->head->next; i != player_list->tail; i = i->next){ player_info_t *player_info = (player_info_t*)i->data; close(player_info->chat_descriptor); } list_delete(player_list); free(player_list); list_delete(observer_list); game_server_shutdown(); free(observer_list); close(map_server_socket); close(chat_server_socket); close(game_server_socket); } delete_mapcycle_list(&mapcycle_list); }