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

📄 handle_d2cs.c

📁 打魔兽战网的都知道他是什么
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2000,2001	Onlyer	(onlyer@263.net) * Copyright (C) 2004		Olaf Freyer (aaron@cs.tu-berlin.de) * * 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 "setup.h"#include <stdio.h>#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#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H#  include <malloc.h># endif#endif#include "compat/memcpy.h"#ifdef TIME_WITH_SYS_TIME# include <time.h># include <sys/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_SYS_STAT_H# include <sys/stat.h>#endif#ifdef HAVE_SYS_SOCKET_H# include <sys/socket.h>#endif#ifdef HAVE_NETINET_IN_H# include <netinet/in.h>#endif#include "compat/socket.h"#include "compat/netinet_in.h"#ifdef HAVE_ARPA_INET_H# include <arpa/inet.h>#endif#include "compat/inet_ntoa.h"#include "compat/pdir.h"#include "compat/mkdir.h"#include "d2charfile.h"#include "connection.h"#include "game.h"#include "bnetd.h"#include "d2cs_protocol.h"#include "d2cs_bnetd_protocol.h"#include "handle_d2cs.h"#include "d2ladder.h"#include "gamequeue.h"#include "serverqueue.h"#include "prefs.h"#include "common/bn_type.h"#include "common/queue.h"#include "common/packet.h"#include "common/eventlog.h"#include "d2charlist.h"#include "common/elist.h"#include "common/xalloc.h"#include "common/setup_after.h"static int d2cs_send_client_ladder(t_connection * c, unsigned char type, unsigned short from);static unsigned int d2cs_try_joingame(t_connection const * c, t_game const * game, char const * gamepass);DECLARE_PACKET_HANDLER(on_client_loginreq)DECLARE_PACKET_HANDLER(on_client_createcharreq)DECLARE_PACKET_HANDLER(on_client_creategamereq)DECLARE_PACKET_HANDLER(on_client_joingamereq)DECLARE_PACKET_HANDLER(on_client_gamelistreq)DECLARE_PACKET_HANDLER(on_client_gameinforeq)DECLARE_PACKET_HANDLER(on_client_charloginreq)DECLARE_PACKET_HANDLER(on_client_deletecharreq)DECLARE_PACKET_HANDLER(on_client_ladderreq)DECLARE_PACKET_HANDLER(on_client_motdreq)DECLARE_PACKET_HANDLER(on_client_cancelcreategame)DECLARE_PACKET_HANDLER(on_client_charladderreq)DECLARE_PACKET_HANDLER(on_client_charlistreq)DECLARE_PACKET_HANDLER(on_client_charlistreq_110)DECLARE_PACKET_HANDLER(on_client_convertcharreq)static t_packet_handle_table d2cs_packet_handle_table[]={/* 0x00 */ { 0,                                     conn_state_none,                          NULL                      },/* 0x01 */ { sizeof(t_client_d2cs_loginreq),        conn_state_connected,                     on_client_loginreq        },/* 0x02 */ { sizeof(t_client_d2cs_createcharreq),   conn_state_authed|conn_state_char_authed, on_client_createcharreq   },/* 0x03 */ { sizeof(t_client_d2cs_creategamereq),   conn_state_char_authed,                   on_client_creategamereq   },/* 0x04 */ { sizeof(t_client_d2cs_joingamereq),     conn_state_char_authed,                   on_client_joingamereq     },/* 0x05 */ { sizeof(t_client_d2cs_gamelistreq),     conn_state_char_authed,                   on_client_gamelistreq     },/* 0x06 */ { sizeof(t_client_d2cs_gameinforeq),     conn_state_char_authed,                   on_client_gameinforeq     },/* 0x07 */ { sizeof(t_client_d2cs_charloginreq),    conn_state_authed|conn_state_char_authed, on_client_charloginreq    },/* 0x08 */ { 0,                                     conn_state_none,                          NULL                      },/* 0x09 */ { 0,                                     conn_state_none,                          NULL                      },/* 0x0a */ { sizeof(t_client_d2cs_deletecharreq),   conn_state_authed|conn_state_char_authed, on_client_deletecharreq   },/* 0x0b */ { 0,                                     conn_state_none,                          NULL                      },/* 0x0c */ { 0,                                     conn_state_none,                          NULL                      },/* 0x0d */ { 0,                                     conn_state_none,                          NULL                      },/* 0x0e */ { 0,                                     conn_state_none,                          NULL                      },/* 0x0f */ { 0,                                     conn_state_none,                          NULL                      },/* 0x10 */ { 0,                                     conn_state_none,                          NULL                      },/* 0x11 */ { sizeof(t_client_d2cs_ladderreq),       conn_state_char_authed,                   on_client_ladderreq	},/* 0x12 */ { sizeof(t_client_d2cs_motdreq),         conn_state_char_authed,                   on_client_motdreq         },/* 0x13 */ { sizeof(t_client_d2cs_cancelcreategame),conn_state_char_authed,                   on_client_cancelcreategame},/* 0x14 */ { 0,                                     conn_state_none,                          NULL                      },/* 0x15 */ { 0,                                     conn_state_none,                          NULL                      },/* 0x16 */ { sizeof(t_client_d2cs_charladderreq),   conn_state_char_authed,                   on_client_charladderreq	},/* 0x17 */ { sizeof(t_client_d2cs_charlistreq),     conn_state_authed|conn_state_char_authed, on_client_charlistreq	},/* 0x18 */ { sizeof(t_client_d2cs_convertcharreq),  conn_state_authed|conn_state_char_authed, on_client_convertcharreq  },/* 0x19 */ { sizeof(t_client_d2cs_charlistreq_110), conn_state_authed|conn_state_char_authed, on_client_charlistreq_110 }};extern int d2cs_handle_d2cs_packet(t_connection * c, t_packet * packet){	return conn_process_packet(c,packet,d2cs_packet_handle_table,NELEMS(d2cs_packet_handle_table));}static int on_client_loginreq(t_connection * c, t_packet * packet){	t_packet	* bnpacket;	char const	* account;	t_sq		* sq;	unsigned int	sessionnum;	if (!(account=packet_get_str_const(packet,sizeof(t_client_d2cs_loginreq),MAX_CHARNAME_LEN))) {		eventlog(eventlog_level_error,__FUNCTION__,"got bad account name");		return -1;	}	if (d2char_check_acctname(account)<0) {		eventlog(eventlog_level_error,__FUNCTION__,"got bad account name");		return -1;	}	if (!bnetd_conn()) {		eventlog(eventlog_level_warn,__FUNCTION__,"d2cs is offline with bnetd, login request will be rejected");		return -1;	}	sessionnum=bn_int_get(packet->u.client_d2cs_loginreq.sessionnum);	conn_set_bnetd_sessionnum(c,sessionnum);	eventlog(eventlog_level_info,__FUNCTION__,"got client (*%s) login request sessionnum=0x%X",account,sessionnum);	if ((bnpacket=packet_create(packet_class_d2cs_bnetd))) {		if ((sq=sq_create(d2cs_conn_get_sessionnum(c),packet,0))) {			packet_set_size(bnpacket,sizeof(t_d2cs_bnetd_accountloginreq));			packet_set_type(bnpacket,D2CS_BNETD_ACCOUNTLOGINREQ);			bn_int_set(&bnpacket->u.d2cs_bnetd_accountloginreq.h.seqno,sq_get_seqno(sq));			bn_int_set(&bnpacket->u.d2cs_bnetd_accountloginreq.seqno,				bn_int_get(packet->u.client_d2cs_loginreq.seqno));			bn_int_set(&bnpacket->u.d2cs_bnetd_accountloginreq.sessionkey,				bn_int_get(packet->u.client_d2cs_loginreq.sessionkey));			bn_int_set(&bnpacket->u.d2cs_bnetd_accountloginreq.sessionnum,sessionnum);			memcpy(bnpacket->u.d2cs_bnetd_accountloginreq.secret_hash,				packet->u.client_d2cs_loginreq.secret_hash,				sizeof(bnpacket->u.d2cs_bnetd_accountloginreq.secret_hash));			packet_append_string(bnpacket,account);			conn_push_outqueue(bnetd_conn(),bnpacket);		}		packet_del_ref(bnpacket);	}	return 0;}static int on_client_createcharreq(t_connection * c, t_packet * packet){	t_packet	* rpacket, * bnpacket;	char const	* charname;	char const	* account;	char            * path;	t_pdir          * dir;	t_sq		* sq;	unsigned int	reply;	unsigned short	status, class;	t_d2charinfo_file	data;	if (!(charname=packet_get_str_const(packet,sizeof(t_client_d2cs_createcharreq),MAX_CHARNAME_LEN))) {		eventlog(eventlog_level_error,__FUNCTION__,"got bad character name");		return -1;	}	if (!(account=d2cs_conn_get_account(c))) {		eventlog(eventlog_level_error,__FUNCTION__,"missing account for character %s",charname);		return -1;	}	class=bn_short_get(packet->u.client_d2cs_createcharreq.class);	status=bn_short_get(packet->u.client_d2cs_createcharreq.status);	path=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1);	d2char_get_infodir_name(path,account);	if (!(dir=p_opendir(path))) {	        eventlog(eventlog_level_info,__FUNCTION__,"(*%s) charinfo directory do not exist, building it",account);		p_mkdir(path,S_IRWXU);	}	else	  p_closedir(dir);	xfree(path);	if (d2char_create(account,charname,class,status)<0) {		eventlog(eventlog_level_warn,__FUNCTION__,"error create character %s for account %s",charname,account);		reply=D2CS_CLIENT_CREATECHARREPLY_ALREADY_EXIST;	} else if (d2charinfo_load(account,charname,&data)<0) {		eventlog(eventlog_level_error,__FUNCTION__,"error loading charinfo for character %s(*%s)",charname,account);		reply=D2CS_CLIENT_CREATECHARREPLY_FAILED;	} else {		eventlog(eventlog_level_info,__FUNCTION__,"character %s(*%s) created",charname,account);		reply=D2CS_CLIENT_CREATECHARREPLY_SUCCEED;		conn_set_charinfo(c,&data.summary);		if ((bnpacket=packet_create(packet_class_d2cs_bnetd))) {			if ((sq=sq_create(d2cs_conn_get_sessionnum(c),packet,0))) {				packet_set_size(bnpacket,sizeof(t_d2cs_bnetd_charloginreq));				packet_set_type(bnpacket,D2CS_BNETD_CHARLOGINREQ);				bn_int_set(&bnpacket->u.d2cs_bnetd_charloginreq.h.seqno,sq_get_seqno(sq));				bn_int_set(&bnpacket->u.d2cs_bnetd_charloginreq.sessionnum,					conn_get_bnetd_sessionnum(c));				packet_append_string(bnpacket,charname);				packet_append_string(bnpacket,(char const *)&data.portrait);				conn_push_outqueue(bnetd_conn(),bnpacket);			}			packet_del_ref(bnpacket);		}		return 0;	}	if ((rpacket=packet_create(packet_class_d2cs))) {		packet_set_size(rpacket,sizeof(t_d2cs_client_createcharreply));		packet_set_type(rpacket,D2CS_CLIENT_CREATECHARREPLY);		bn_int_set(&rpacket->u.d2cs_client_createcharreply.reply,reply);		conn_push_outqueue(c,rpacket);		packet_del_ref(rpacket);	}	return 0;}static int on_client_creategamereq(t_connection * c, t_packet * packet){	char const	* gamename;	char const	* gamepass;	char const	* gamedesc;	t_game		* game;	t_d2gs		* gs;	t_gq		* gq;	unsigned int	tempflag,gameflag;	unsigned int	leveldiff, maxchar, difficulty, expansion, hardcore, ladder;	unsigned int	seqno, reply;	unsigned int	pos;	t_elem		* elem;	pos=sizeof(t_client_d2cs_creategamereq);	if (!(gamename=packet_get_str_const(packet,pos,MAX_GAMENAME_LEN))) {		eventlog(eventlog_level_error,__FUNCTION__,"got bad game name");		return -1;	}	pos+=strlen(gamename)+1;	if (!(gamepass=packet_get_str_const(packet,pos,MAX_GAMEPASS_LEN))) {		eventlog(eventlog_level_error,__FUNCTION__,"got bad game pass");		return -1;	}	pos+=strlen(gamepass)+1;	if (!(gamedesc=packet_get_str_const(packet,pos,MAX_GAMEDESC_LEN))) {		eventlog(eventlog_level_error,__FUNCTION__,"got bad game desc");		return -1;	}	tempflag=bn_int_get(packet->u.client_d2cs_creategamereq.gameflag);	leveldiff=bn_byte_get(packet->u.client_d2cs_creategamereq.leveldiff);	maxchar=bn_byte_get(packet->u.client_d2cs_creategamereq.maxchar);	difficulty=gameflag_get_difficulty(tempflag);	if (difficulty > conn_get_charinfo_difficulty(c)) {		eventlog(eventlog_level_error,__FUNCTION__,"game difficulty exceed character limit %d %d",difficulty,			conn_get_charinfo_difficulty(c));		return 0;	}	expansion=conn_get_charinfo_expansion(c);	hardcore=conn_get_charinfo_hardcore(c);	ladder=conn_get_charinfo_ladder(c);	gameflag=gameflag_create(ladder,expansion,hardcore,difficulty);	gs = NULL;	game = NULL;	gq=conn_get_gamequeue(c);	if (d2cs_gamelist_find_game(gamename)) {		eventlog(eventlog_level_info,__FUNCTION__,"game name %s is already exist in gamelist",gamename);		reply=D2CS_CLIENT_CREATEGAMEREPLY_NAME_EXIST;	} else if (!gq && gqlist_find_game(gamename)) {		eventlog(eventlog_level_info,__FUNCTION__,"game name %s is already exist in game queue",gamename);		reply=D2CS_CLIENT_CREATEGAMEREPLY_NAME_EXIST;	} else if (!(gs=d2gslist_choose_server())) {		if (gq) {			eventlog(eventlog_level_error,__FUNCTION__,"client %d is already in game queue",d2cs_conn_get_sessionnum(c));			conn_set_gamequeue(c,NULL);			gq_destroy(gq,&elem);			return 0;		} else if ((gq=gq_create(d2cs_conn_get_sessionnum(c), packet, gamename))) {			conn_set_gamequeue(c,gq);			d2cs_send_client_creategamewait(c,gqlist_get_length());			return 0;		}		reply=D2CS_CLIENT_CREATEGAMEREPLY_FAILED;	} else if (hardcore && conn_get_charinfo_dead(c)) {		reply=D2CS_CLIENT_CREATEGAMEREPLY_FAILED;	} else if (!(game=d2cs_game_create(gamename,gamepass,gamedesc,gameflag))) {		reply=D2CS_CLIENT_CREATEGAMEREPLY_NAME_EXIST;	} else {		reply=D2CS_CLIENT_CREATEGAMEREPLY_SUCCEED;		game_set_d2gs(game,gs);		d2gs_add_gamenum(gs, 1);		game_set_gameflag_ladder(game,ladder);		game_set_gameflag_expansion(game,expansion);		game_set_created(game,0);		game_set_leveldiff(game,leveldiff);		game_set_charlevel(game,conn_get_charinfo_level(c));		game_set_maxchar(game,maxchar);		game_set_gameflag_difficulty(game,difficulty);		game_set_gameflag_hardcore(game,hardcore);	}	seqno=bn_short_get(packet->u.client_d2cs_creategamereq.seqno);	if (reply!=D2CS_CLIENT_CREATEGAMEREPLY_SUCCEED) {		t_packet	* rpacket;		if ((rpacket=packet_create(packet_class_d2cs))) {			packet_set_size(rpacket,sizeof(t_d2cs_client_creategamereply));			packet_set_type(rpacket,D2CS_CLIENT_CREATEGAMEREPLY);			bn_short_set(&rpacket->u.d2cs_client_creategamereply.seqno,seqno);			bn_short_set(&rpacket->u.d2cs_client_creategamereply.u1,0);			bn_short_set(&rpacket->u.d2cs_client_creategamereply.gameid,0);			bn_int_set(&rpacket->u.d2cs_client_creategamereply.reply,reply);			conn_push_outqueue(c,rpacket);			packet_del_ref(rpacket);		}	} else {		t_packet	* gspacket;		t_sq		* sq;		struct in_addr	addr;		if ((gspacket=packet_create(packet_class_d2gs))) {			if ((sq=sq_create(d2cs_conn_get_sessionnum(c),packet,d2cs_game_get_id(game)))) {				packet_set_size(gspacket,sizeof(t_d2cs_d2gs_creategamereq));				packet_set_type(gspacket,D2CS_D2GS_CREATEGAMEREQ);				bn_int_set(&gspacket->u.d2cs_d2gs_creategamereq.h.seqno,sq_get_seqno(sq));				bn_byte_set(&gspacket->u.d2cs_d2gs_creategamereq.difficulty,difficulty);				bn_byte_set(&gspacket->u.d2cs_d2gs_creategamereq.hardcore,hardcore);				bn_byte_set(&gspacket->u.d2cs_d2gs_creategamereq.expansion,expansion);				bn_byte_set(&gspacket->u.d2cs_d2gs_creategamereq.ladder,ladder);				packet_append_string(gspacket,gamename);				packet_append_string(gspacket,gamepass);				packet_append_string(gspacket,gamedesc);				packet_append_string(gspacket,d2cs_conn_get_account(c));				packet_append_string(gspacket,d2cs_conn_get_charname(c));				addr.s_addr = htonl(d2cs_conn_get_addr(c));				packet_append_string(gspacket,inet_ntoa(addr));				conn_push_outqueue(d2gs_get_connection(gs),gspacket);			}			packet_del_ref(gspacket);			eventlog(eventlog_level_info,__FUNCTION__,"request create game %s on gs %d",gamename,d2gs_get_id(gs));		}	}	return 0;

⌨️ 快捷键说明

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