?? bnchat.c
字號:
/* * Copyright (C) 1998,1999,2000,2001 Ross Combs (rocombs@cs.nmsu.edu) * Copyright (C) 1999 Oleg Drokin (green@ccssu.ccssu.crimea.ua) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "common/setup_before.h"#include <stdio.h>#ifdef HAVE_STDDEF_H# include <stddef.h>#else# ifndef NULL# define NULL ((void *)0)# endif#endif#include "compat/exitstatus.h"#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H# include <strings.h># endif#endif#include "compat/strchr.h"#include "compat/strdup.h"#include "compat/strcasecmp.h"#include "compat/vargs.h"#include <ctype.h>#include <errno.h>#include "compat/strerror.h"#ifdef TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# ifdef HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#ifdef HAVE_FCNTL_H# include <fcntl.h>#else# ifdef HAVE_SYS_FILE_H# include <sys/file.h># endif#endif#ifdef HAVE_TERMIOS_H# include <termios.h>#endif#include "compat/termios.h"#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#ifdef HAVE_SIGACTION# include <signal.h># include "compat/signal.h"#endif#ifdef HAVE_SYS_SELECT_H# include <sys/select.h>#endif#ifdef HAVE_SYS_SOCKET_H# include <sys/socket.h>#endif#include "compat/socket.h"#ifdef HAVE_SYS_PARAM_H# include <sys/param.h>#endif#ifdef HAVE_NETINET_IN_H# include <netinet/in.h>#endif#include "compat/netinet_in.h"#ifdef HAVE_ARPA_INET_H# include <arpa/inet.h>#endif#include "compat/inet_ntoa.h"#include "compat/psock.h"#include "common/packet.h"#include "common/init_protocol.h"#include "common/udp_protocol.h"#include "common/bnet_protocol.h"#include "common/file_protocol.h"#include "common/tag.h"#include "common/bn_type.h"#include "common/field_sizes.h"#include "common/network.h"#include "common/bnethash.h"#include "common/bnethashconv.h"#include "ansi_term.h"#include "common/version.h"#include "common/util.h"#include "common/xalloc.h"#include "common/hexdump.h"#ifdef CLIENTDEBUG# include "common/eventlog.h"#endif#include "client.h"#include "udptest.h"#include "client_connect.h"#ifdef WIN32# include <conio.h> /* for kbhit() and getch() */#endif#include "compat/vsnprintf.h"#include "common/setup_after.h"#ifdef CLIENTDEBUG# define dprintf printf#else# define dprintf if (0) printf#endif#define CHANNEL_BNCHATBOT "Chat"#define CHANNEL_STARCRAFT "Starcraft"#define CHANNEL_BROODWARS "Brood War"#define CHANNEL_SHAREWARE "Starcraft Shareware"#define CHANNEL_DIABLORTL "Diablo Retail"#define CHANNEL_DIABLOSHR "Diablo Shareware" /* FIXME: is this one right? */#define CHANNEL_WARCIIBNE "War2BNE"#define CHANNEL_DIABLO2DV "Diablo II"#define CHANNEL_DIABLO2XP "Diablo II"#define CHANNEL_WARCRAFT3 "W3"#define CHANNEL_WAR3XP "W3"volatile int handle_winch=0;typedef enum { mode_chat, mode_command, mode_waitstat, mode_waitgames, mode_waitladder, mode_gamename, mode_gamepass, mode_gamewait, mode_gamestop, mode_claninvite} t_mode;typedef struct _client_state{ int useansi; int sd; struct sockaddr_in saddr; unsigned int sessionkey; unsigned int sessionnum; unsigned int currsize; unsigned int commpos; struct termios in_attr_old; struct termios in_attr_new; int changed_in; int fd_stdin; unsigned int screen_width,screen_height; int munged; t_mode mode; char text[MAX_MESSAGE_LEN];} t_client_state;typedef struct _user_info{ char const * clienttag; char const * archtag; char const * gamelang; char player[MAX_MESSAGE_LEN]; char const * cdowner; char const * cdkey; char const * channel; char curr_gamename[GAME_NAME_LEN]; char curr_gamepass[GAME_PASS_LEN]; int count, clantag; char const * inviter;} t_user_info;static char const * mflags_get_str(unsigned int flags);static char const * cflags_get_str(unsigned int flags);static char const * mode_get_prompt(t_mode mode);static int print_file(struct sockaddr_in * saddr, char const * filename, char const * progname, char const * clienttag);static void usage(char const * progname);#ifdef HAVE_SIGACTIONstatic void winch_sig_handle(int unused);#endif#ifdef HAVE_SIGACTIONstatic void winch_sig_handle(int unused){ handle_winch = 1;}#endifstatic char const * mflags_get_str(unsigned int flags){ static char buffer[32]; buffer[0]=buffer[1] = '\0'; if (flags&MF_BLIZZARD) strcat(buffer,",Blizzard"); if (flags&MF_GAVEL) strcat(buffer,",Gavel"); if (flags&MF_VOICE) strcat(buffer,",Megaphone"); if (flags&MF_BNET) strcat(buffer,",BNET"); if (flags&MF_PLUG) strcat(buffer,",Plug"); if (flags&MF_X) strcat(buffer,",X"); if (flags&MF_SHADES) strcat(buffer,",Shades"); if (flags&MF_PGLPLAY) strcat(buffer,",PGL_Player"); if (flags&MF_PGLOFFL) strcat(buffer,",PGL_Official"); buffer[0] = '['; strcat(buffer,"]"); return buffer;}static char const * cflags_get_str(unsigned int flags){ static char buffer[32]; buffer[0]=buffer[1] = '\0'; if (flags&CF_PUBLIC) strcat(buffer,",Public"); if (flags&CF_MODERATED) strcat(buffer,",Moderated"); if (flags&CF_RESTRICTED) strcat(buffer,",Restricted"); if (flags&CF_THEVOID) strcat(buffer,",The Void"); if (flags&CF_SYSTEM) strcat(buffer,",System"); if (flags&CF_OFFICIAL) strcat(buffer,",Official"); buffer[0] = '['; strcat(buffer,"]"); return buffer;}static char const * mode_get_prompt(t_mode mode){ switch (mode) { case mode_chat: return "] "; case mode_command: return "command> "; case mode_waitstat: case mode_waitgames: case mode_waitladder: case mode_gamewait: return "*please wait* "; case mode_gamename: return "Name: "; case mode_gamepass: return "Password: "; case mode_gamestop: return "[Return to kill game] "; default: return "? "; }}static int print_file(struct sockaddr_in * saddr, char const * filename, char const * progname, char const * clienttag){ int sd; t_packet * ipacket; t_packet * packet; t_packet * rpacket; t_packet * fpacket; unsigned int currsize; unsigned int filelen; if (!saddr || !filename || !progname) return -1; if ((sd = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_STREAM,PSOCK_IPPROTO_TCP))<0) { fprintf(stderr,"%s: could not create socket (psock_socket: %s)\n",progname,pstrerror(psock_errno())); return -1; } if (psock_connect(sd,(struct sockaddr *)saddr,sizeof(*saddr))<0) { fprintf(stderr,"%s: could not connect to server (psock_connect: %s)\n",progname,pstrerror(psock_errno())); return -1; } if (!(ipacket = packet_create(packet_class_init))) { fprintf(stderr,"%s: could not create packet\n",progname); return -1; } bn_byte_set(&ipacket->u.client_initconn.class,CLIENT_INITCONN_CLASS_FILE); client_blocksend_packet(sd,ipacket); packet_del_ref(ipacket); if (!(rpacket = packet_create(packet_class_file))) { fprintf(stderr,"%s: could not create packet\n",progname); return -1; } if (!(fpacket = packet_create(packet_class_raw))) { fprintf(stderr,"%s: could not create packet\n",progname); return -1; } if (!(packet = packet_create(packet_class_file))) { fprintf(stderr,"%s: could not create packet\n",progname); return -1; } packet_set_size(packet,sizeof(t_client_file_req)); packet_set_type(packet,CLIENT_FILE_REQ); bn_int_tag_set(&packet->u.client_file_req.archtag,ARCHTAG_WINX86); bn_int_tag_set(&packet->u.client_file_req.clienttag,clienttag); bn_int_set(&packet->u.client_file_req.adid,0); bn_int_set(&packet->u.client_file_req.extensiontag,0); bn_int_set(&packet->u.client_file_req.startoffset,0); bn_long_set_a_b(&packet->u.client_file_req.timestamp,0x00000000,0x00000000); packet_append_string(packet,filename); client_blocksend_packet(sd,packet); packet_del_ref(packet); do if (client_blockrecv_packet(sd,rpacket)<0) { fprintf(stderr,"%s: server closed file connection\n",progname); packet_del_ref(fpacket); packet_del_ref(rpacket); return -1; } while (packet_get_type(rpacket)!=SERVER_FILE_REPLY); filelen = bn_int_get(rpacket->u.server_file_reply.filelen); packet_del_ref(rpacket); for (currsize=0; currsize+MAX_PACKET_SIZE<=filelen; currsize+=MAX_PACKET_SIZE) { if (client_blockrecv_raw_packet(sd,fpacket,MAX_PACKET_SIZE)<0) { fflush(stdout); fprintf(stderr,"%s: server closed file connection\n",progname); packet_del_ref(fpacket); return -1; } str_print_term(stdout,packet_get_raw_data_const(fpacket,0),MAX_PACKET_SIZE,1); } filelen -= currsize; if (filelen) { if (client_blockrecv_raw_packet(sd,fpacket,filelen)<0) { fflush(stdout); fprintf(stderr,"%s: server closed file connection\n",progname); packet_del_ref(fpacket); return -1; } str_print_term(stdout,packet_get_raw_data_const(fpacket,0),filelen,1); } fflush(stdout); psock_close(sd); packet_del_ref(fpacket); return 0;}static void usage(char const * progname){ fprintf(stderr,"usage: %s [<options>] [<servername> [<TCP portnumber>]]\n",progname); fprintf(stderr, " -a, --ansi-color use ANSI colors\n" " -n, --new-account create a new account\n" " -c, --change-password change account password\n" " --client=CHAT report client as a chat bot\n" " -b, --client=SEXP report client as Brood Wars\n" " -d, --client=DRTL report client as Diablo Retail\n" " --client=DSHR report client as Diablo Shareware\n"); fprintf(stderr, " -s, --client=STAR report client as Starcraft (default)\n" " --client=SSHR report client as Starcraft Shareware\n" " -w, --client=W2BN report client as Warcraft II BNE\n" " --client=D2DV report client as Diablo II\n" " --client=D2XP report client as Diablo II: LoD\n" " --client=WAR3 report client as Warcraft III\n" " --client=W3XP report client as Warcraft III Frozen Throne\n" " --arch=IX86 report architecture as Intel x86 (default)\n" " --arch=PMAC report architecture as PowerPC MacOS\n"
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -