⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 handle_irc.c

📁 打魔兽战网的都知道他是什么
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (C) 2001  Marco Ziech (mmz@gmx.net) * Copyright (C) 2005  Bryan Biedenkapp (gatekeep@gmail.com) * * 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. */ #define CONNECTION_INTERNAL_ACCESS#include "common/setup_before.h"#include "common/util.h"#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H#  include <malloc.h># endif#endif#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H#  include <strings.h># endif# ifdef HAVE_MEMORY_H#  include <memory.h># endif#endif#include "compat/strdup.h"#include "compat/strcasecmp.h"#include <errno.h>#include "compat/strerror.h"#include "common/irc_protocol.h"#include "common/packet.h"#include "common/eventlog.h"#include "connection.h"#include "common/bn_type.h"#include "common/field_sizes.h"#include "common/addr.h"#include "common/version.h"#include "common/queue.h"#include "common/list.h"#include "common/bnethash.h"#include "common/bnethashconv.h"#include "message.h"#include "account.h"#include "account_wrap.h"#include "channel.h"#include "irc.h"#include "prefs.h"#include "tick.h"#include "timer.h"#include "server.h"#include "command.h"#include "handle_irc.h"#include "topic.h"#include "command_groups.h"#include "common/tag.h"#include "common/xalloc.h"#include "ctype.h"#include "common/setup_after.h"typedef int (* t_irc_command)(t_connection * conn, int numparams, char ** params, char * text);typedef struct {	const char     * irc_command_string;	t_irc_command    irc_command_handler;} t_irc_command_table_row;static int _handle_nick_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_user_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_ping_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_pong_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_pass_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_privmsg_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_notice_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_quit_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_who_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_list_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_topic_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_join_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_names_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_mode_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_userhost_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_ison_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_whois_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_part_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_cvers_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_verchk_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_lobcount_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_whereto_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_apgar_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_serial_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_squadinfo_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_setopt_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_setcodepage_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_setlocale_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_getcodepage_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_getlocale_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_joingame_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_gameopt_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_finduserex_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_page_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_startg_command(t_connection * conn, int numparams, char ** params, char * text);static int _handle_listsearch_command(t_connection * conn, int numparams, char ** params, char * text);/* state "connected" handlers */static const t_irc_command_table_row irc_con_command_table[] ={	{ "NICK"		, _handle_nick_command },	{ "USER"		, _handle_user_command },	{ "PING"		, _handle_ping_command },	{ "PONG"		, _handle_pong_command },	{ "PASS"		, _handle_pass_command },	{ "PRIVMSG"		, _handle_privmsg_command },	{ "NOTICE"		, _handle_notice_command },	{ "QUIT"		, _handle_quit_command },	{ "CVERS"		, _handle_cvers_command },		{ "VERCHK"		, _handle_verchk_command },		{ "LOBCOUNT"	, _handle_lobcount_command },	{ "WHERETO"		, _handle_whereto_command },	{ "APGAR"		, _handle_apgar_command },		{ "SERIAL"		, _handle_serial_command },		{ NULL			, NULL }};/* state "logged in" handlers */static const t_irc_command_table_row irc_log_command_table[] ={	{ "WHO"			, _handle_who_command },	{ "LIST"		, _handle_list_command },	{ "TOPIC"		, _handle_topic_command },	{ "JOIN"		, _handle_join_command },	{ "NAMES"		, _handle_names_command },	{ "MODE"		, _handle_mode_command },	{ "USERHOST"		, _handle_userhost_command },	{ "ISON"		, _handle_ison_command },	{ "WHOIS"		, _handle_whois_command },	{ "PART"		, _handle_part_command },	{ "SQUADINFO"	, _handle_squadinfo_command },		{ "SETOPT"		, _handle_setopt_command },			{ "SETCODEPAGE"	, _handle_setcodepage_command },	{ "SETLOCALE"	, _handle_setlocale_command },		{ "GETCODEPAGE"	, _handle_getcodepage_command },	{ "GETLOCALE"	, _handle_getlocale_command },		{ "JOINGAME"	, _handle_joingame_command },		{ "GAMEOPT"		, _handle_gameopt_command },		{ "FINDUSEREX"	, _handle_finduserex_command },		{ "PAGE"		, _handle_page_command },			{ "STARTG"		, _handle_startg_command },			{ "LISTSEARCH"	, _handle_listsearch_command },	{ NULL			, NULL }};static int handle_irc_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text){  t_irc_command_table_row const *p;  for (p = irc_con_command_table; p->irc_command_string != NULL; p++) {    if (strcasecmp(command, p->irc_command_string)==0) {	  if (p->irc_command_handler != NULL) 		  return ((p->irc_command_handler)(conn,numparams,params,text));	}  }  return -1;}static int handle_irc_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text){  t_irc_command_table_row const *p;  for (p = irc_log_command_table; p->irc_command_string != NULL; p++) {    if (strcasecmp(command, p->irc_command_string)==0) {	  if (p->irc_command_handler != NULL) 		  return ((p->irc_command_handler)(conn,numparams,params,text));	}  }  return -1;}static int handle_irc_line(t_connection * conn, char const * ircline){   	/* [:prefix] <command> [[param1] [param2] ... [paramN]] [:<text>] */    char * line; /* copy of ircline */    char * prefix = NULL; /* optional; mostly NULL */    char * command; /* mandatory */    char ** params = NULL; /* optional (array of params) */    char * text = NULL; /* optional */	char * bnet_command = NULL;  /* amadeo: used for battle.net.commands */    int unrecognized_before = 0;	int linelen; /* amadeo: counter for stringlenghts */    int numparams = 0;    char * tempparams;	int i; 	char paramtemp[MAX_IRC_MESSAGE_LEN*2];	int first = 1;    if (!conn) {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");	return -1;    }    if (!ircline) {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL ircline");	return -1;    }    if (ircline[0] == '\0') {	eventlog(eventlog_level_error,__FUNCTION__,"got empty ircline");	return -1;    }	//amadeo: code was sent by some unknown fellow of pvpgn, prevents buffer-overflow for	// too long irc-lines    if (strlen(ircline)>254) {        char * tmp = (char *)ircline;	eventlog(eventlog_level_warn,__FUNCTION__,"line to long, truncation...");	tmp[254]='\0';    }        line = xstrdup(ircline);    /* split the message */    if (line[0] == ':') {	/* The prefix is optional and is rarely provided */	prefix = line;	if (!(command = strchr(line,' '))) {	    eventlog(eventlog_level_warn,__FUNCTION__,"got malformed line (missing command)");	    xfree(line);	    return -1;	}	*command++ = '\0';    } 	else {	/* In most cases command is the first thing on the line */	command = line;    }        tempparams = strchr(command,' ');    if (tempparams) {	*tempparams++ = '\0';	 if (tempparams[0]==':') {	    text = tempparams+1; /* theres just text, no params. skip the colon */	} else {	    for (i=0;tempparams[i]!='\0';i++) {	    	if ((tempparams[i]==' ')&&(tempparams[i+1]==':')) {		    text = tempparams+i; 		    *text++ = '\0';		    text++; /* skip the colon */		    break; /* text found, stop search */	    	}	    }	    params = irc_get_paramelems(tempparams);	}    }    if (params) {	/* count parameters */	for (numparams=0;params[numparams];numparams++);    }	memset(paramtemp,0,sizeof(paramtemp));    	for (i=0;((numparams>0)&&(params[i]));i++) {		if (!first) 			strcat(paramtemp," ");	    strcat(paramtemp,"\"");	    strcat(paramtemp,params[i]);	    strcat(paramtemp,"\"");	    first = 0;    	}    	eventlog(eventlog_level_debug,__FUNCTION__,"[%d] got \"%s\" \"%s\" [%s] \"%s\"",conn_get_socket(conn),((prefix)?(prefix):("")),command,paramtemp,((text)?(text):("")));    if (conn_get_state(conn)==conn_state_connected) {	t_timer_data temp;		conn_set_state(conn,conn_state_bot_username);	temp.n = prefs_get_irc_latency();	conn_test_latency(conn,time(NULL),temp);    }	if (handle_irc_con_command(conn, command, numparams, params, text)!=-1) {}    else if (conn_get_state(conn)!=conn_state_loggedin) {	char temp[MAX_IRC_MESSAGE_LEN+1];		if ((38+strlen(command)+16+1)<sizeof(temp)) {	    sprintf(temp,":Unrecognized command \"%s\" (before login)",command);	    irc_send(conn,ERR_UNKNOWNCOMMAND,temp);	} else {	    irc_send(conn,ERR_UNKNOWNCOMMAND,":Unrecognized command (before login)");	}    } else {        /* command is handled later */	unrecognized_before = 1;    }    /* --- The following should only be executable after login --- */    if ((conn_get_state(conn)==conn_state_loggedin)&&(unrecognized_before)) {		if (handle_irc_log_command(conn, command, numparams, params, text)!=-1) {}		else if ((strstart(command,"LAG")!=0)&&(strstart(command,"JOIN")!=0)){			linelen = strlen (ircline);			bnet_command = xmalloc(linelen + 2);			bnet_command[0]='/';			strcpy(bnet_command + 1, ircline);			handle_command(conn,bnet_command); 			xfree((void*)bnet_command);		}    } /* loggedin */    if (params)	irc_unget_paramelems(params);    xfree(line);    return 0;}extern int handle_irc_packet(t_connection * conn, t_packet const * const packet){    unsigned int i;    char ircline[MAX_IRC_MESSAGE_LEN];    int ircpos;    char const * data;    if (!packet) {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");	return -1;    }    if ((conn_get_class(conn) != conn_class_irc) &&		(conn_get_class(conn) != conn_class_wol)) {	eventlog(eventlog_level_error,__FUNCTION__,"FIXME: handle_irc_packet without any reason (conn->class != conn_class_irc)");	return -1;    }	    /* eventlog(eventlog_level_debug,__FUNCTION__,"got \"%s\"",packet_get_raw_data_const(packet,0)); */    memset(ircline,0,sizeof(ircline));    data = conn_get_ircline(conn); /* fetch current status */    if (data)	strcpy(ircline,data);    ircpos = strlen(ircline);    data = packet_get_raw_data_const(packet,0);	    for (i=0; i < packet_get_size(packet); i++) {	if ((data[i] == '\r')||(data[i] == '\0')) {	    /* kindly ignore \r and NUL ... */	} else if (data[i] == '\n') {	    /* end of line */	    handle_irc_line(conn,ircline);	    memset(ircline,0,sizeof(ircline));	    ircpos = 0;	} else {	    if (ircpos < MAX_IRC_MESSAGE_LEN-1)		ircline[ircpos++] = data[i];	    else {		ircpos++; /* for the statistic :) */	    	eventlog(eventlog_level_warn,__FUNCTION__,"[%d] client exceeded maximum allowed message length by %d characters",conn_get_socket(conn),ircpos-MAX_IRC_MESSAGE_LEN);		if ((ircpos-MAX_IRC_MESSAGE_LEN)>100) {		    /* automatic flood protection */		    eventlog(eventlog_level_error,__FUNCTION__,"[%d] excess flood",conn_get_socket(conn));		    return -1;		}	    }	}    }    conn_set_ircline(conn,ircline); /* write back current status */    return 0;}static int _handle_nick_command(t_connection * conn, int numparams, char ** params, char * text){	/* FIXME: more strict param checking */	if ((conn_get_loggeduser(conn))&&	    (conn_get_state(conn)!=conn_state_bot_password && 	     conn_get_state(conn)!=conn_state_bot_username)) {	    irc_send(conn,ERR_RESTRICTED,":You can't change your nick after login");	} 	else {	    if ((params)&&(params[0])) {			if (conn_get_loggeduser(conn))			    irc_send_cmd2(conn,conn_get_loggeduser(conn),"NICK","",params[0]);			conn_set_loggeduser(conn,params[0]);	    }	    else if (text) {			if (conn_get_loggeduser(conn))			    irc_send_cmd2(conn,conn_get_loggeduser(conn),"NICK","",text);			conn_set_loggeduser(conn,text);	    }	    else	        irc_send(conn,ERR_NEEDMOREPARAMS,":Too few arguments to NICK");	    if ((conn_get_user(conn))&&(conn_get_loggeduser(conn)))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -