Esempio n. 1
0
static int on_bnetd_charloginreply(t_connection * c, t_packet * packet)
{
	unsigned int	seqno;
	t_sq		* sq;
	t_connection	* client;
	t_packet	* opacket, * rpacket;
	int		result, reply, type;
	char const	* charname;
	t_elem		* elem;

	if (!packet || !c)
	    return -1;

	seqno=bn_int_get(packet->u.d2cs_bnetd.h.seqno);
	if (!(sq=sqlist_find_sq(seqno))) {
		eventlog(eventlog_level_error,__FUNCTION__,"seqno %d not found",seqno);
		return -1;
	}
	if (!(client=d2cs_connlist_find_connection_by_sessionnum(sq_get_clientid(sq)))) {
		eventlog(eventlog_level_error,__FUNCTION__,"client %d not found",sq_get_clientid(sq));
		sq_destroy(sq,&elem);
		return -1;
	}
	if (!(opacket=sq_get_packet(sq))) {
		eventlog(eventlog_level_error,__FUNCTION__,"previous packet missing (seqno: %d)",seqno);
		sq_destroy(sq,&elem);
		return -1;
	}
	type=packet_get_type(opacket);
	result=bn_int_get(packet->u.bnetd_d2cs_charloginreply.reply);
	if (type==CLIENT_D2CS_CREATECHARREQ) {
		charname=packet_get_str_const(opacket,sizeof(t_client_d2cs_createcharreq),MAX_CHARNAME_LEN);
		if (result==BNETD_D2CS_CHARLOGINREPLY_SUCCEED) {
			if (conn_check_multilogin(client,charname)<0) {
				eventlog(eventlog_level_error,__FUNCTION__,"character %s is already logged in",charname);
				reply = D2CS_CLIENT_CHARLOGINREPLY_FAILED;
			} else {
				reply= D2CS_CLIENT_CREATECHARREPLY_SUCCEED;
				eventlog(eventlog_level_info,__FUNCTION__,"character %s authed",charname);
				d2cs_conn_set_charname(client,charname);
				d2cs_conn_set_state(client,conn_state_char_authed);
			}
		} else {
			reply = D2CS_CLIENT_CREATECHARREPLY_FAILED;
			eventlog(eventlog_level_error,__FUNCTION__,"failed to auth character %s",charname);
		}
		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(client,rpacket);
			packet_del_ref(rpacket);
		}
	} else if (type==CLIENT_D2CS_CHARLOGINREQ) {
		charname=packet_get_str_const(opacket,sizeof(t_client_d2cs_charloginreq),MAX_CHARNAME_LEN);
		if (result==BNETD_D2CS_CHARLOGINREPLY_SUCCEED) {
			if (conn_check_multilogin(client,charname)<0) {
				eventlog(eventlog_level_error,__FUNCTION__,"character %s is already logged in",charname);
				reply = D2CS_CLIENT_CHARLOGINREPLY_FAILED;
			} else {
				reply = D2CS_CLIENT_CHARLOGINREPLY_SUCCEED;
				eventlog(eventlog_level_info,__FUNCTION__,"character %s authed",charname);
				d2cs_conn_set_charname(client,charname);
				d2cs_conn_set_state(client,conn_state_char_authed);
			}
		} else {
			reply = D2CS_CLIENT_CHARLOGINREPLY_FAILED;
			eventlog(eventlog_level_error,__FUNCTION__,"failed to auth character %s",charname);
		}
		if ((rpacket=packet_create(packet_class_d2cs))) {
			packet_set_size(rpacket,sizeof(t_d2cs_client_charloginreply));
			packet_set_type(rpacket,D2CS_CLIENT_CHARLOGINREPLY);
			bn_int_set(&rpacket->u.d2cs_client_charloginreply.reply,reply);
			conn_push_outqueue(client,rpacket);
			packet_del_ref(rpacket);
		}
	} else {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad packet type %d",type);
		sq_destroy(sq,&elem);
		return -1;
	}
	sq_destroy(sq,&elem);
	return 0;
}
Esempio n. 2
0
static int on_client_joingamereq(t_connection * c, t_packet * packet)
{
	char const	* gamename;
	char const	* gamepass;
	char const	* charname;
	char const	* account;
	t_game		* game;
	t_d2gs		* gs;
	int		reply;
	unsigned int	pos;
	unsigned int	seqno;

	gs = NULL;
	pos=sizeof(t_client_d2cs_joingamereq);
	if (!(gamename=packet_get_str_const(packet,pos,MAX_GAMENAME_LEN))) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad game name");
		return -1;
	}
	pos+=std::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;
	}
	if (!(charname=d2cs_conn_get_charname(c))) {
		eventlog(eventlog_level_error,__FUNCTION__,"missing character name for connection");
		return -1;
	}
	if (!(account=d2cs_conn_get_account(c))) {
		eventlog(eventlog_level_error,__FUNCTION__,"missing account for connection");
		return -1;
	}
	if (conn_check_multilogin(c,charname)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"character %s is already logged in",charname);
		return -1;
	}
	if (!(game=d2cs_gamelist_find_game(gamename))) {
		eventlog(eventlog_level_info,__FUNCTION__,"game %s not found",gamename);
		reply=D2CS_CLIENT_JOINGAMEREPLY_NOT_EXIST;
	} else if (!(gs=game_get_d2gs(game))) {
		eventlog(eventlog_level_error,__FUNCTION__,"missing game server for game %s",gamename);
		reply=D2CS_CLIENT_JOINGAMEREPLY_NOT_EXIST;
	} else {
		reply=d2cs_try_joingame(c,game,gamepass);
	}

	seqno=bn_short_get(packet->u.client_d2cs_joingamereq.seqno);
	if (reply!=D2CS_CLIENT_JOINGAMEREPLY_SUCCEED) {
		t_packet	* rpacket;

		if ((rpacket=packet_create(packet_class_d2cs))) {
			packet_set_size(rpacket,sizeof(t_d2cs_client_joingamereply));
			packet_set_type(rpacket,D2CS_CLIENT_JOINGAMEREPLY);
			bn_short_set(&rpacket->u.d2cs_client_joingamereply.seqno,seqno);
			bn_short_set(&rpacket->u.d2cs_client_joingamereply.u1,0);
			bn_short_set(&rpacket->u.d2cs_client_joingamereply.gameid,0);
			bn_int_set(&rpacket->u.d2cs_client_joingamereply.addr,0);
			bn_int_set(&rpacket->u.d2cs_client_joingamereply.token,0);
			bn_int_set(&rpacket->u.d2cs_client_joingamereply.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_joingamereq));
				packet_set_type(gspacket,D2CS_D2GS_JOINGAMEREQ);
				bn_int_set(&gspacket->u.d2cs_d2gs_joingamereq.h.seqno,sq_get_seqno(sq));
				bn_int_set(&gspacket->u.d2cs_d2gs_joingamereq.gameid,
					game_get_d2gs_gameid(game));
				sq_set_gametoken(sq,d2gs_make_token(gs));
				bn_int_set(&gspacket->u.d2cs_d2gs_joingamereq.token,sq_get_gametoken(sq));
				packet_append_string(gspacket,charname);
				packet_append_string(gspacket,account);
				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 join game %s for character %s on gs %d",gamename,
				charname,d2gs_get_id(gs));
		}
	}
	return 0;
}