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

📄 connection.c

📁 打魔兽战网的都知道他是什么
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 1998  Mark Baysinger (mbaysing@ucsd.edu) * Copyright (C) 1998,1999,2000,2001  Ross Combs (rocombs@cs.nmsu.edu) * Copyright (C) 2000,2001  Marco Ziech (mmz@gmx.net) * * 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 <stdio.h>// amadeo#ifdef WIN32_GUI#include <win32/winmain.h>#endif#ifdef HAVE_STDDEF_H# include <stddef.h>#else# ifndef NULL#  define NULL ((void *)0)# endif#endif#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H#  include <malloc.h># endif#endif#include "compat/strtoul.h"#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H#  include <strings.h># endif#endif#ifdef HAVE_ASSERT_H# include <assert.h>#endif#include "compat/strchr.h"#include "compat/strrchr.h"#include "compat/strdup.h"#include "compat/strcasecmp.h"#include "compat/strncasecmp.h"#include <errno.h>#include "compat/strerror.h"#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#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#include "compat/difftime.h"#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#ifdef HAVE_SYS_SOCKET_H# include <sys/socket.h>#endif#include "compat/socket.h"#include "compat/psock.h"#include "common/eventlog.h"#include "common/addr.h"#include "account.h"#include "account_wrap.h"#include "realm.h"#include "channel.h"#include "game.h"#include "common/queue.h"#include "tick.h"#include "common/packet.h"#include "common/tag.h"#include "common/bn_type.h"#include "message.h"#include "common/version.h"#include "prefs.h"#include "common/util.h"#include "common/list.h"#include "watch.h"#include "timer.h"#include "irc.h"#include "ipban.h"#include "game_conv.h"#include "udptest_send.h"#include "character.h"#include "versioncheck.h"#include "common/bnet_protocol.h"#include "common/field_sizes.h"#include "anongame.h"#include "clan.h"#include "connection.h"#include "topic.h"#include "server.h"#include "handle_d2cs.h"#include "command_groups.h"#include "attrlayer.h"#include "common/rcm.h"#include "common/fdwatch.h"#include "common/elist.h"#include "common/xalloc.h"#include "common/setup_after.h"/* types and data structures used for the connlist array */typedef struct {    t_connection *c;    t_elist freelist;} t_conn_entry;t_conn_entry *connarray = NULL;t_elist arrayflist;static int      totalcount=0;static t_list * conn_head=NULL;static t_list * conn_dead=NULL;static void conn_send_welcome(t_connection * c);static void conn_send_issue(t_connection * c);static int connarray_create(void);static void connarray_destroy(void);static t_connection *connarray_get_conn(unsigned index);static unsigned connarray_add_conn(t_connection *c);static void connarray_del_conn(unsigned index);static void conn_send_welcome(t_connection * c){    char const * filename;    FILE *       fp;        if (!c)    {        eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");	return;    }        if (c->protocol.cflags & conn_flags_welcomed)	return;    if ((conn_get_class(c)==conn_class_irc)||        (conn_get_class(c)==conn_class_wol))    {	c->protocol.cflags|= conn_flags_welcomed;	return;    }    if ((filename = prefs_get_motdfile()))    {	if ((fp = fopen(filename,"r")))	{	    message_send_file(c,fp);	    if (fclose(fp)<0)	      { eventlog(eventlog_level_error,__FUNCTION__,"could not close MOTD file \"%s\" after reading (fopen: %s)",filename,pstrerror(errno)); }	}	else	  { eventlog(eventlog_level_error,__FUNCTION__,"could not open MOTD file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno)); }    }    c->protocol.cflags|= conn_flags_welcomed;}static void conn_send_issue(t_connection * c){    char const * filename;    FILE *       fp;        if (!c)    {        eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");	return;    }        if ((filename = prefs_get_issuefile()))	if ((fp = fopen(filename,"r")))	{	    message_send_file(c,fp);	    if (fclose(fp)<0)		eventlog(eventlog_level_error,__FUNCTION__,"could not close issue file \"%s\" after reading (fopen: %s)",filename,pstrerror(errno));	}	else	    eventlog(eventlog_level_error,__FUNCTION__,"could not open issue file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno));    else	eventlog(eventlog_level_debug,__FUNCTION__,"no issue file");}// [zap-zero] 20020629extern void conn_shutdown(t_connection * c, time_t now, t_timer_data foo){    if (!c)    {        eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");        return;    }    if (now==(time_t)0) /* zero means user logged out before expiration */    {	eventlog(eventlog_level_trace,__FUNCTION__,"[%d] connection allready closed",conn_get_socket(c));	return;    }    eventlog(eventlog_level_trace,__FUNCTION__,"[%d] closing connection",conn_get_socket(c));    conn_set_state(c, conn_state_destroy);}extern void conn_test_latency(t_connection * c, time_t now, t_timer_data delta){    t_packet * packet;        if (!c)    {        eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");        return;    }    if (now==(time_t)0) /* zero means user logged out before expiration */	return;    if (conn_get_state(c)==conn_state_destroy)	// [zap-zero] 20020910    	return;					// state_destroy: do nothing        if ((conn_get_class(c)==conn_class_irc)||        (conn_get_class(c)==conn_class_wol)) {    	/* We should start pinging the client after we received the first line ... */    	/* NOTE: RFC2812 only suggests that PINGs are being sent     	 * if no other activity is detected. However it explecitly     	 * allows PINGs to be sent if there is activity on this     	 * connection. In other words we just don't care :)    	 */	if (conn_get_ircping(c)!=0) {	    eventlog(eventlog_level_warn,__FUNCTION__,"[%d] ping timeout (closing connection)",conn_get_socket(c));	    conn_set_latency(c,0); 	    conn_set_state(c,conn_state_destroy);	}	irc_send_ping(c);    } else if(conn_get_class(c)==conn_class_w3route) {        if(!(packet = packet_create(packet_class_w3route))) {	    eventlog(eventlog_level_error,__FUNCTION__,"[%d] packet_create failed",conn_get_socket(c));	} else {    	    packet_set_size(packet,sizeof(t_server_w3route_echoreq));	    packet_set_type(packet,SERVER_W3ROUTE_ECHOREQ);	    bn_int_set(&packet->u.server_w3route_echoreq.ticks,get_ticks());	    conn_push_outqueue(c, packet);	    packet_del_ref(packet);	}    } else {    	/* FIXME: I think real Battle.net sends these even before login */    	if (!conn_get_game(c))	{            if ((packet = packet_create(packet_class_bnet)))	    {	    	packet_set_size(packet,sizeof(t_server_echoreq));	    	packet_set_type(packet,SERVER_ECHOREQ);	    	bn_int_set(&packet->u.server_echoreq.ticks,get_ticks());	    	conn_push_outqueue(c,packet);	    	packet_del_ref(packet);	    }	    else	      { eventlog(eventlog_level_error,__FUNCTION__,"could not create packet"); }	}    }        if (timerlist_add_timer(c,now+(time_t)delta.n,conn_test_latency,delta)<0)	eventlog(eventlog_level_error,__FUNCTION__,"could not add timer");}static void conn_send_nullmsg(t_connection * c, time_t now, t_timer_data delta){    if (!c)    {        eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");        return;    }       if (now==(time_t)0) /* zero means user logged out before expiration */        return;       message_send_text(c,message_type_null,c,NULL);        if (timerlist_add_timer(c,now+(time_t)delta.n,conn_send_nullmsg,delta)<0)        eventlog(eventlog_level_error,__FUNCTION__,"could not add timer");}extern char const * conn_class_get_str(t_conn_class class){    switch (class)    {    case conn_class_init:	return "init";    case conn_class_bnet:	return "bnet";    case conn_class_file:	return "file";    case conn_class_bot:	return "bot";    case conn_class_d2cs_bnetd:	return "d2cs_bnetd";    case conn_class_telnet:	return "telnet";    case conn_class_irc:	return "irc";	case conn_class_wol:    return "wol";    case conn_class_none:	return "none";	case conn_class_w3route:	return "w3route";    default:	return "UNKNOWN";    }}extern char const * conn_state_get_str(t_conn_state state){    switch (state)    {    case conn_state_empty:	return "empty";    case conn_state_initial:	return "initial";    case conn_state_connected:	return "connected";    case conn_state_bot_username:	return "bot_username";    case conn_state_bot_password:	return "bot_password";    case conn_state_loggedin:	return "loggedin";    case conn_state_destroy:	return "destroy";    case conn_state_untrusted:	return "untrusted";    case conn_state_pending_raw:	return "pending_raw";    default:	return "UNKNOWN";    }}extern int conn_set_realm_cb(void *data, void *newref);extern t_connection * conn_create(int tsock, int usock, unsigned int real_local_addr, unsigned short real_local_port, unsigned int local_addr, unsigned short local_port, unsigned int addr, unsigned short port){    t_connection * temp;	        if (tsock<0)    {        eventlog(eventlog_level_error,__FUNCTION__,"got bad TCP socket %d",tsock);        return NULL;    }    if (usock<-1) /* -1 is allowed for some connection classes like bot, irc, and telnet */    {        eventlog(eventlog_level_error,__FUNCTION__,"got bad UDP socket %d",usock);        return NULL;    }        temp = xmalloc(sizeof(t_connection));    temp->socket.tcp_sock               = tsock;    temp->socket.tcp_addr               = addr;    temp->socket.tcp_port               = port;    temp->socket.udp_sock               = usock;    temp->socket.udp_addr               = addr; /* same for now but client can request it to be different */    temp->socket.local_addr             = local_addr;    temp->socket.local_port             = local_port;    temp->socket.real_local_addr        = real_local_addr;    temp->socket.real_local_port        = real_local_port;    temp->socket.udp_port               = port;    temp->socket.fdw_idx		= -1;    temp->protocol.class                = conn_class_init;    temp->protocol.state                = conn_state_initial;    temp->protocol.sessionkey           = ((unsigned int)rand())^((unsigned int)now+(unsigned int)real_local_port);    temp->protocol.sessionnum           = connarray_add_conn(temp);    temp->protocol.secret               = ((unsigned int)rand())^(totalcount+((unsigned int)now));    temp->protocol.flags                = MF_PLUG;    temp->protocol.latency              = 0;    temp->protocol.chat.dnd                      = NULL;    temp->protocol.chat.away                     = NULL;    temp->protocol.chat.ignore_list              = NULL;    temp->protocol.chat.ignore_count             = 0;    temp->protocol.chat.quota.totcount           = 0;    temp->protocol.chat.quota.list = list_create();    temp->protocol.client.versionid              = 0;    temp->protocol.client.gameversion            = 0;    temp->protocol.client.checksum               = 0;    temp->protocol.client.archtag                = 0;    temp->protocol.client.clienttag              = 0;    temp->protocol.client.clientver              = NULL;    temp->protocol.client.gamelang               = 0;    temp->protocol.client.country                = NULL;    temp->protocol.client.tzbias                 = 0;    temp->protocol.client.host                   = NULL;    temp->protocol.client.user                   = NULL;    temp->protocol.client.clientexe              = NULL;    temp->protocol.client.owner                  = NULL;    temp->protocol.client.cdkey                  = NULL;    temp->protocol.client.versioncheck           = NULL;    temp->protocol.account                       = NULL;    temp->protocol.chat.channel                  = NULL;    temp->protocol.chat.last_message             = now;    temp->protocol.chat.lastsender               = NULL;    temp->protocol.chat.irc.ircline              = NULL;    temp->protocol.chat.irc.ircping              = 0;    temp->protocol.chat.irc.ircpass              = NULL;    temp->protocol.chat.tmpOP_channel		 = NULL;    temp->protocol.chat.tmpVOICE_channel	 = NULL;    temp->protocol.game                     = NULL;    temp->protocol.queues.outqueue               = NULL;    temp->protocol.queues.outsize                = 0;    temp->protocol.queues.outsizep               = 0;    temp->protocol.queues.inqueue                = NULL;    temp->protocol.queues.insize                 = 0;    temp->protocol.loggeduser			 = NULL;    temp->protocol.d2.realm                      = NULL;    rcm_regref_init(&temp->protocol.d2.realm_regref,&conn_set_realm_cb,temp);    temp->protocol.d2.character                  = NULL;    temp->protocol.d2.realminfo                  = NULL;    temp->protocol.d2.charname                   = NULL;    temp->protocol.w3.w3_playerinfo              = NULL;    temp->protocol.w3.routeconn                  = NULL;    temp->protocol.w3.anongame                   = NULL;    temp->protocol.w3.anongame_search_starttime  = 0;    temp->protocol.bound                         = NULL;    elist_init(&temp->protocol.timers);    temp->protocol.wol.ingame			         = 0;        temp->protocol.wol.codepage			         = 0;    temp->protocol.wol.locale			         = 0;    temp->protocol.wol.gameType			         = 0;    temp->protocol.wol.apgar			         = NULL;    temp->protocol.wol.gameOptions		         = NULL;    temp->protocol.cr_time                       = now;    temp->protocol.passfail_count                = 0;    temp->protocol.cflags                        = 0;	    list_prepend_data(conn_head,temp);        eventlog(eventlog_level_info,__FUNCTION__,"[%d][%d] sessionkey=0x%08x sessionnum=0x%08x",temp->socket.tcp_sock,temp->socket.udp_sock,temp->protocol.sessionkey,temp->protocol.sessionnum);        return temp;}extern t_anongame * conn_create_anongame(t_connection *c){    t_anongame * temp;    int i;    if(c->protocol.w3.anongame) {        eventlog(eventlog_level_error,__FUNCTION__,"anongame already allocated");	return c->protocol.w3.anongame;    }    temp = xmalloc(sizeof(t_anongame));    temp->count		= 0;    temp->id		= 0;    temp->tid		= 0;        for (i=0; i < ANONGAME_MAX_GAMECOUNT/2; i++)	temp->tc[i]	= NULL;        temp->race		= 0;    temp->playernum	= 0;

⌨️ 快捷键说明

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