예제 #1
0
static int d2charsave_init(void * buffer,char const * charname,unsigned char classs,unsigned short status)
{
	ASSERT(buffer,-1);
	ASSERT(charname,-1);
	bn_byte_set((bn_byte *)((char *)buffer+D2CHARSAVE_CLASS_OFFSET), classs);
	bn_short_set((bn_short *)((char *)buffer+D2CHARSAVE_STATUS_OFFSET),status);
	strncpy((char *)buffer+D2CHARSAVE_CHARNAME_OFFSET,charname,MAX_CHARNAME_LEN);
	return 0;
}
예제 #2
0
static int on_client_gameinforeq(t_connection * c, t_packet * packet)
{
	t_game_charinfo	* info;
	t_packet	* rpacket;
	char const	* gamename;
	t_game		* game;
	unsigned int	seqno, n;

	if (!(gamename=packet_get_str_const(packet,sizeof(t_client_d2cs_gameinforeq),MAX_GAMENAME_LEN))) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad game name");
		return -1;
	}
	if (!(game=d2cs_gamelist_find_game(gamename))) {
		eventlog(eventlog_level_error,__FUNCTION__,"game %s not found",gamename);
		return 0;
	}
	seqno=bn_short_get(packet->u.client_d2cs_gameinforeq.seqno);
	if ((rpacket=packet_create(packet_class_d2cs))) {
		packet_set_size(rpacket,sizeof(t_d2cs_client_gameinforeply));
		packet_set_type(rpacket,D2CS_CLIENT_GAMEINFOREPLY);
		bn_short_set(&rpacket->u.d2cs_client_gameinforeply.seqno,seqno);
		bn_int_set(&rpacket->u.d2cs_client_gameinforeply.gameflag,game_get_gameflag(game));
		bn_int_set(&rpacket->u.d2cs_client_gameinforeply.etime,std::time(NULL)-d2cs_game_get_create_time(game));
		bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.charlevel,game_get_charlevel(game));
		bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.leveldiff,game_get_leveldiff(game));
		bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.maxchar,game_get_maxchar(game));
		packet_append_string(rpacket, game_get_desc(game) ? game_get_desc(game) : NULL);

		n=0;
		BEGIN_LIST_TRAVERSE_DATA_CONST(game_get_charlist(game),info,t_game_charinfo)
		{
			if (!info->charname) {
				eventlog(eventlog_level_error,__FUNCTION__,"got NULL charname in game %s char list",gamename);
				continue;
			}
			packet_append_string(rpacket,info->charname);
			bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.chclass[n],info->chclass);
			/* GUI is limited to a max level of 255 */
			if (info->level < 255) {
			bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.level[n],info->level);
			} else {
				bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.level[n], 255);
			}
			n++;
		}
		END_LIST_TRAVERSE_DATA_CONST()

		bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.currchar,n);
		if (n!=game_get_currchar(game)) {
			eventlog(eventlog_level_error,__FUNCTION__,"game %s character list corrupted",gamename);
		}
		conn_push_outqueue(c,rpacket);
		packet_del_ref(rpacket);
	}
예제 #3
0
static int d2charinfo_init(t_d2charinfo_file * chardata, char const * account, char const * charname,
			   unsigned char classs, unsigned short status)
{
	unsigned int		i;
	time_t		now;

	now=time(NULL);
	bn_int_set(&chardata->header.magicword,D2CHARINFO_MAGICWORD);
	bn_int_set(&chardata->header.version,D2CHARINFO_VERSION);
	bn_int_set(&chardata->header.create_time,now);
	bn_int_set(&chardata->header.last_time,now);
	bn_int_set(&chardata->header.total_play_time,0);

	memset(chardata->header.charname, 0,MAX_CHARNAME_LEN);
	strncpy(chardata->header.charname,charname,MAX_CHARNAME_LEN);
	memset(chardata->header.account, 0,MAX_ACCTNAME_LEN);
	strncpy(chardata->header.account,account,MAX_ACCTNAME_LEN);
	memset(chardata->header.realmname, 0,MAX_REALMNAME_LEN);
	strncpy(chardata->header.realmname,prefs_get_realmname(),MAX_REALMNAME_LEN);
	bn_int_set(&chardata->header.checksum,0);
	for (i=0; i<NELEMS(chardata->header.reserved); i++) {
		bn_int_set(&chardata->header.reserved[i],0);
	}
	bn_int_set(&chardata->summary.charlevel,1);
	bn_int_set(&chardata->summary.experience,0);
	bn_int_set(&chardata->summary.charclass,classs);
	bn_int_set(&chardata->summary.charstatus,status);

	memset(chardata->portrait.gfx,D2CHARINFO_PORTRAIT_PADBYTE,sizeof(chardata->portrait.gfx));
	memset(chardata->portrait.color,D2CHARINFO_PORTRAIT_PADBYTE,sizeof(chardata->portrait.color));
	memset(chardata->portrait.u2,D2CHARINFO_PORTRAIT_PADBYTE,sizeof(chardata->portrait.u2));
	memset(chardata->portrait.u1,D2CHARINFO_PORTRAIT_MASK,sizeof(chardata->portrait.u1));
	memset(chardata->pad,0,sizeof(chardata->pad));

	bn_short_set(&chardata->portrait.header,D2CHARINFO_PORTRAIT_HEADER);
	bn_byte_set(&chardata->portrait.status,status|D2CHARINFO_PORTRAIT_MASK);
	bn_byte_set(&chardata->portrait.classs,classs+1);
	bn_byte_set(&chardata->portrait.level,1);
	if (charstatus_get_ladder(status))
		bn_byte_set(&chardata->portrait.ladder, 1);
	else
		bn_byte_set(&chardata->portrait.ladder, D2CHARINFO_PORTRAIT_PADBYTE);
	bn_byte_set(&chardata->portrait.end,'\0');

	memset(chardata->pad,0,sizeof(chardata->pad));
	
	return 0;
}
예제 #4
0
		/* tournament notice disabled at this time, but responce is sent to cleint */
		static int _client_anongame_tournament(t_connection * c, t_packet const * const packet)
		{
			t_packet * rpacket;

			t_account * account = conn_get_account(c);
			t_clienttag clienttag = conn_get_clienttag(c);

			unsigned int start_prelim = tournament_get_start_preliminary();
			unsigned int end_signup = tournament_get_end_signup();
			unsigned int end_prelim = tournament_get_end_preliminary();
			unsigned int start_r1 = tournament_get_start_round_1();

			if ((rpacket = packet_create(packet_class_bnet)) == NULL) {
				eventlog(eventlog_level_error, __FUNCTION__, "could not create new packet");
				return -1;
			}

			packet_set_size(rpacket, sizeof(t_server_anongame_tournament_reply));
			packet_set_type(rpacket, SERVER_FINDANONGAME_TOURNAMENT_REPLY);
			bn_byte_set(&rpacket->u.server_anongame_tournament_reply.option, 7);
			bn_int_set(&rpacket->u.server_anongame_tournament_reply.count,
				bn_int_get(packet->u.client_anongame_tournament_request.count));

			if (!start_prelim || (end_signup <= now && tournament_user_signed_up(account) < 0) ||
				tournament_check_client(clienttag) < 0) { /* No Tournament Notice */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.type, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown4, 0);
				bn_int_set(&rpacket->u.server_anongame_tournament_reply.timestamp, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown5, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.countdown, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown2, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.wins, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.losses, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.ties, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown3, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.selection, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.descnum, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.nulltag, 0);
			}
			else if (start_prelim >= now) { /* Tournament Notice */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.type, 1);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown4, 0x0000); /* random */
				bn_int_set(&rpacket->u.server_anongame_tournament_reply.timestamp, _tournament_time_convert(start_prelim));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown5, 0x01);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.countdown, start_prelim - now);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown2, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.wins, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.losses, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.ties, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown3, 0x00);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.selection, 2);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.descnum, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.nulltag, 0);
			}
			else if (end_signup >= now) { /* Tournament Signup Notice - Play Game Active */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.type, 2);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown4, 0x0828); /* random */
				bn_int_set(&rpacket->u.server_anongame_tournament_reply.timestamp, _tournament_time_convert(end_signup));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown5, 0x01);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.countdown, end_signup - now);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown2, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.wins, tournament_get_stat(account, 1));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.losses, tournament_get_stat(account, 2));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.ties, tournament_get_stat(account, 3));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown3, 0x08);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.selection, 2);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.descnum, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.nulltag, 0);
			}
			else if (end_prelim >= now) { /* Tournament Prelim Period - Play Game Active */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.type, 3);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown4, 0x0828); /* random */
				bn_int_set(&rpacket->u.server_anongame_tournament_reply.timestamp, _tournament_time_convert(end_prelim));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown5, 0x01);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.countdown, end_prelim - now);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown2, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.wins, tournament_get_stat(account, 1));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.losses, tournament_get_stat(account, 2));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.ties, tournament_get_stat(account, 3));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown3, 0x08);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.selection, 2);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.descnum, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.nulltag, 0);
			}
			else if (start_r1 >= now && (tournament_get_game_in_progress())) { /* Prelim Period Over - Shows user stats (not all prelim games finished) */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.type, 4);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown4, 0x0000); /* random */
				bn_int_set(&rpacket->u.server_anongame_tournament_reply.timestamp, _tournament_time_convert(start_r1));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown5, 0x01);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.countdown, start_r1 - now);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown2, 0); /* 00 00 */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.wins, tournament_get_stat(account, 1));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.losses, tournament_get_stat(account, 2));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.ties, tournament_get_stat(account, 3));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown3, 0x08);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.selection, 2);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.descnum, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.nulltag, 0);
			}
			else if (!(tournament_get_in_finals_status(account))) { /* Prelim Period Over - user did not make finals - Shows user stats */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.type, 5);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown4, 0);
				bn_int_set(&rpacket->u.server_anongame_tournament_reply.timestamp, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown5, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.countdown, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown2, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.wins, tournament_get_stat(account, 1));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.losses, tournament_get_stat(account, 2));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.ties, tournament_get_stat(account, 3));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown3, 0x04);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.selection, 2);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.descnum, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.nulltag, 0);
			}
			/* cycle through [type-6] & [type-7] packets
			 *
			 * use [type-6] to show client "eliminated" or "continue"
			 *     timestamp , countdown & round number (of next round) must be set if clinet continues
			 *
			 * use [type-7] to make cleint wait for 44FF packet option 1 to start game (A guess, not tested)
			 *
			 * not sure if there is overall winner packet sent at end of last final round
			 */
			// UNDONE: next two conditions never executed
			else if ((0)) { /* User in finals - Shows user stats and start of next round*/
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.type, 6);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown4, 0x0000);
				bn_int_set(&rpacket->u.server_anongame_tournament_reply.timestamp, _tournament_time_convert(start_r1));
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown5, 0x01);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.countdown, start_r1 - now);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown2, 0x0000); /* 00 00 */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.wins, 4); /* round number */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.losses, 0); /* 0 = continue , 1= eliminated */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.ties, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown3, 0x04); /* number of rounds in finals */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.selection, 2);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.descnum, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.nulltag, 0);
			}
			else if ((0)) { /* user waiting for match to be made */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.type, 7);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown4, 0);
				bn_int_set(&rpacket->u.server_anongame_tournament_reply.timestamp, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown5, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.countdown, 0);
				bn_short_set(&rpacket->u.server_anongame_tournament_reply.unknown2, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.wins, 1); /* round number */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.losses, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.ties, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.unknown3, 0x04); /* number of finals */
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.selection, 2);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.descnum, 0);
				bn_byte_set(&rpacket->u.server_anongame_tournament_reply.nulltag, 0);
			}

			conn_push_outqueue(c, rpacket);
			packet_del_ref(rpacket);
			return 0;
		}
예제 #5
0
		/* Open portrait in Warcraft 3 user profile */
		static int _client_anongame_get_icon(t_connection * c, t_packet const * const packet)
		{
			t_packet * rpacket;
			//BlacKDicK 04/20/2003 Need some huge re-work on this.
			{
				struct
				{
					char	 icon_code[4];
					unsigned int portrait_code;
					char	 race;
					bn_short	 required_wins;
					char	 client_enabled;
				} tempicon;

				//FIXME: Add those to the prefs and also merge them on accoun_wrap;
				// FIXED BY DJP 07/16/2003 FOR 110 CHANGE ( TOURNEY & RACE WINS ) + Table_witdh
				short icon_req_race_wins;
				short icon_req_tourney_wins;
				int race[] = { W3_RACE_RANDOM, W3_RACE_HUMANS, W3_RACE_ORCS, W3_RACE_UNDEAD, W3_RACE_NIGHTELVES, W3_RACE_DEMONS };
				char race_char[6] = { 'R', 'H', 'O', 'U', 'N', 'D' };
				char icon_pos[5] = { '2', '3', '4', '5', '6', };
				char table_width = 6;
				char table_height = 5;
				int i, j;
				char rico;
				unsigned int rlvl, rwins;
				t_clienttag clienttag;
				t_account * acc;

				char user_icon[5];
				char const * uicon;

				clienttag = conn_get_clienttag(c);
				acc = conn_get_account(c);
				/* WAR3 uses a different table size, might change if blizzard add tournament support to RoC */
				if (clienttag == CLIENTTAG_WARCRAFT3_UINT) {
					table_width = 5;
					table_height = 4;
				}

				eventlog(eventlog_level_info, __FUNCTION__, "[%d] got FINDANONGAME Get Icons packet", conn_get_socket(c));

				if ((rpacket = packet_create(packet_class_bnet)) == NULL) {
					eventlog(eventlog_level_error, __FUNCTION__, "could not create new packet");
					return -1;
				}

				packet_set_size(rpacket, sizeof(t_server_findanongame_iconreply));
				packet_set_type(rpacket, SERVER_FINDANONGAME_ICONREPLY);
				bn_int_set(&rpacket->u.server_findanongame_iconreply.count, bn_int_get(packet->u.client_findanongame_inforeq.count));
				bn_byte_set(&rpacket->u.server_findanongame_iconreply.option, CLIENT_FINDANONGAME_GET_ICON);
				
				
				if (prefs_get_custom_icons() == 1)
				{
					// get current custom icon
					t_icon_info * icon;
					if (icon = customicons_get_icon_by_account(acc, clienttag))
						std::memcpy(&rpacket->u.server_findanongame_iconreply.curricon, icon->icon_code, 4);
				}
				else if ((uicon = account_get_user_icon(acc, clienttag)))
				{
					std::memcpy(&rpacket->u.server_findanongame_iconreply.curricon, uicon, 4);
				}
				else
				{
					account_get_raceicon(acc, &rico, &rlvl, &rwins, clienttag);
					std::sprintf(user_icon, "%1d%c3W", rlvl, rico);
					std::memcpy(&rpacket->u.server_findanongame_iconreply.curricon, user_icon, 4);
				}

				bn_byte_set(&rpacket->u.server_findanongame_iconreply.table_width, table_width);
				bn_byte_set(&rpacket->u.server_findanongame_iconreply.table_size, table_width*table_height);
				for (j = 0; j < table_height; j++){
					icon_req_race_wins = anongame_infos_get_ICON_REQ(j + 1, clienttag);
					for (i = 0; i < table_width; i++){
						tempicon.race = i;
						tempicon.icon_code[0] = icon_pos[j];
						tempicon.icon_code[1] = race_char[i];
						tempicon.icon_code[2] = '3';
						tempicon.icon_code[3] = 'W';
						tempicon.portrait_code = (account_icon_to_profile_icon(tempicon.icon_code, acc, clienttag));
						if (i <= 4){
							//Building the icon for the races
							bn_short_set(&tempicon.required_wins, icon_req_race_wins);
							if (account_get_racewins(acc, race[i], clienttag) >= icon_req_race_wins) {
								if (prefs_get_custom_icons() == 1)
									tempicon.client_enabled = 0;
								else
									tempicon.client_enabled = 1;
							}
							else{
								tempicon.client_enabled = 0;
							}
						}
						else{
							//Building the icon for the tourney
							icon_req_tourney_wins = anongame_infos_get_ICON_REQ_TOURNEY(j + 1);
							bn_short_set(&tempicon.required_wins, icon_req_tourney_wins);
							if (account_get_racewins(acc, race[i], clienttag) >= icon_req_tourney_wins) {
								if (prefs_get_custom_icons() == 1)
									tempicon.client_enabled = 0;
								else
									tempicon.client_enabled = 1;
							}
							else{
								tempicon.client_enabled = 0;
							}
						}
						packet_append_data(rpacket, &tempicon, sizeof(tempicon));
					}
				}
				//Go,go,go
				conn_push_outqueue(c, rpacket);
				packet_del_ref(rpacket);
			}
			return 0;
		}
예제 #6
0
파일: packet.cpp 프로젝트: DizKragnet/pvpgn
extern int packet_set_type(t_packet * packet, unsigned int type)
{
    if (!packet)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
	return -1;
    }

    switch (packet->pclass)
    {
    case packet_class_init:
	if (type!=CLIENT_INITCONN)
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"init packet type 0x%08x is not valid",type);
	    return -1;
	}
	return 0;

    case packet_class_bnet:
	if (packet_get_size(packet)<sizeof(t_bnet_header))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"bnet packet is shorter than header (len=%u)",packet_get_size(packet));
	    return -1;
	}
	if (type>MAX_NORMAL_TYPE)
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"bnet packet type 0x%08x is too large",type);
	    return -1;
	}
	bn_short_set(&packet->u.bnet.h.type,(unsigned short)type);
	return 0;

    case packet_class_file:
	if (packet_get_size(packet)<sizeof(t_file_header))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"file packet is shorter than header (len=%u)",packet_get_size(packet));
	    return -1;
	}
	if (type>MAX_FILE_TYPE)
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"file packet type 0x%08x is too large",type);
	    return -1;
	}
	bn_short_set(&packet->u.file.h.type,(unsigned short)type);
	return 0;

    case packet_class_udp:
	if (packet_get_size(packet)<sizeof(t_udp_header))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"udp packet is shorter than header (len=%u)",packet_get_size(packet));
	    return -1;
	}
	bn_int_set(&packet->u.udp.h.type,type);
	return 0;

    case packet_class_d2game:
	if (packet_get_size(packet)<sizeof(t_d2game_header))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"d2game packet is shorter than header (len=%u)",packet_get_size(packet));
	    return -1;
	}
	bn_byte_set(&packet->u.d2game.h.type,type);
	return 0;

    case packet_class_d2gs:
        if (packet_get_size(packet)<sizeof(t_d2cs_d2gs_header))
        {
            eventlog(eventlog_level_error,__FUNCTION__,"d2gs packet is shorter than header (len=%u)",packet_get_size(packet));
            return -1;
        }
        bn_short_set(&packet->u.d2cs_d2gs.h.type,type);
        return 0;

    case packet_class_d2cs_bnetd:
        if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_header))
        {
            eventlog(eventlog_level_error,__FUNCTION__,"d2cs_bnetd packet is shorter than header (len=%u)",packet_get_size(packet));
            return -1;
        }
        bn_short_set(&packet->u.d2cs_bnetd.h.type,type);
        return 0;

    case packet_class_d2cs:
        if (packet_get_size(packet)<sizeof(t_d2cs_client_header))
        {
            eventlog(eventlog_level_error,__FUNCTION__,"d2cs packet is shorter than header (len=%u)",packet_get_size(packet));
            return -1;
        }
        bn_byte_set(&packet->u.d2cs_client.h.type,type);
        return 0;

    case packet_class_w3route:
	if (packet_get_size(packet)<sizeof(t_w3route_header))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"w3route packet is shorter than header (len=%u)",packet_get_size(packet));
	    return -1;
	}
	bn_short_set(&packet->u.w3route.h.type,(unsigned short)type);
	return 0;

    case packet_class_wolgameres:
	eventlog(eventlog_level_error,__FUNCTION__,"can not set packet type for wol gameres packet");
	return 0;

    case packet_class_raw:
	eventlog(eventlog_level_error,__FUNCTION__,"can not set packet type for raw packet");
	return 0;

    default:
	eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->pclass);
	return -1;
    }
}
예제 #7
0
파일: packet.cpp 프로젝트: DizKragnet/pvpgn
extern int packet_set_size(t_packet * packet, unsigned int size)
{
    if (!packet)
    {
        eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
	return -1;
    }
    if (size>MAX_PACKET_SIZE)
    {
        eventlog(eventlog_level_error,__FUNCTION__,"got bad size %u",size);
	return -1;
    }

    switch (packet->pclass)
    {
    case packet_class_init:
	if (size!=0 && size!=sizeof(t_client_initconn))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"invalid size %u for init packet",size);
	    return -1;
	}
	packet->len = size;
        return 0;
    case packet_class_bnet:
	if (size!=0 && size<sizeof(t_bnet_header))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"invalid size %u for bnet packet",size);
	    return -1;
	}
        bn_short_set(&packet->u.bnet.h.size,size);
        return 0;
    case packet_class_file:
	if (size!=0 && size<sizeof(t_file_header))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"invalid size %u for file packet",size);
	    return -1;
	}
        bn_short_set(&packet->u.file.h.size,size);
        return 0;
    case packet_class_udp:
	if (size!=0 && size<sizeof(t_udp_header))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"invalid size %u for udp packet",size);
	    return -1;
	}
	packet->len = size;
	return 0;
    case packet_class_raw:
	packet->len = size;
	return 0;
    case packet_class_d2game:
	packet->len = size; /* FIXME: does header not contain the size? */
	return 0;
    case packet_class_d2cs:
        bn_short_set(&packet->u.d2cs_client.h.size,size);
        return 0;
    case packet_class_d2gs:
        bn_short_set(&packet->u.d2cs_d2gs.h.size,size);
        return 0;
    case packet_class_d2cs_bnetd:
        bn_short_set(&packet->u.d2cs_bnetd.h.size,size);
        return 0;
    case packet_class_w3route:
	if (size!=0 && size<sizeof(t_w3route_header))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"invalid size %u for w3route packet",size);
	    return -1;
	}
        bn_short_set(&packet->u.w3route.h.size,size);
        return 0;
     case packet_class_wolgameres:
        /* PELISH: useless - there is no server packet for wolgameres */
        packet->len = size;
        return 0;
    default:
	eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->pclass);
	return -1;
    }
}
예제 #8
0
static int on_client_gamelistreq(t_connection * c, t_packet * packet)
{
	t_packet	* rpacket;
	t_game		* game;
	unsigned int	count;
	unsigned int	seqno;
	std::time_t		now;
	unsigned int	maxlifetime;
	t_elem const	* start_elem;
	t_elem const	* elem;

	seqno=bn_short_get(packet->u.client_d2cs_gamelistreq.seqno);
	/* if (seqno%2) return 0; */
	count=0;
	now=std::time(NULL);
	maxlifetime=prefs_get_game_maxlifetime();

	elem=start_elem=gamelist_get_curr_elem();
	if (!elem) elem=list_get_first_const(d2cs_gamelist());
	else elem=elem_get_next_const(d2cs_gamelist(),elem);

	for (; elem != start_elem; elem=elem_get_next_const(d2cs_gamelist(),elem)) {
		if (!elem) {
			elem=list_get_first_const(d2cs_gamelist());
			if (elem == start_elem) break;
		}
		if (!(game=(t_game*)elem_get_data(elem))) {
			eventlog(eventlog_level_error,__FUNCTION__,"got NULL game");
			break;
		}
		if (maxlifetime && (now-game->create_time>maxlifetime)) continue;
		if (!game_get_currchar(game)) continue;
		if (!prefs_allow_gamelist_showall()) {
			if (conn_get_charinfo_difficulty(c)!=game_get_gameflag_difficulty(game)) continue;
		}
		if (prefs_hide_pass_games())
			if (d2cs_game_get_pass(game)) continue;

		if (d2cs_try_joingame(c,game,"")!=D2CS_CLIENT_JOINGAMEREPLY_SUCCEED) continue;
		if ((rpacket=packet_create(packet_class_d2cs))) {
			packet_set_size(rpacket,sizeof(t_d2cs_client_gamelistreply));
			packet_set_type(rpacket,D2CS_CLIENT_GAMELISTREPLY);
			bn_short_set(&rpacket->u.d2cs_client_gamelistreply.seqno,seqno);
			bn_int_set(&rpacket->u.d2cs_client_gamelistreply.token,d2cs_game_get_id(game));
			bn_byte_set(&rpacket->u.d2cs_client_gamelistreply.currchar,game_get_currchar(game));
			bn_int_set(&rpacket->u.d2cs_client_gamelistreply.gameflag,game_get_gameflag(game));
			packet_append_string(rpacket,d2cs_game_get_name(game));
			packet_append_string(rpacket,game_get_desc(game));
			conn_push_outqueue(c,rpacket);
			packet_del_ref(rpacket);
			count++;
			if (prefs_get_maxgamelist() && count>=prefs_get_maxgamelist()) break;
		}
	}
	gamelist_set_curr_elem(elem);
	if (count) {
		if ((rpacket=packet_create(packet_class_d2cs))) {
			packet_set_size(rpacket,sizeof(t_d2cs_client_gamelistreply));
			packet_set_type(rpacket,D2CS_CLIENT_GAMELISTREPLY);
			bn_short_set(&rpacket->u.d2cs_client_gamelistreply.seqno,seqno);
			bn_int_set(&rpacket->u.d2cs_client_gamelistreply.token,0);
			bn_byte_set(&rpacket->u.d2cs_client_gamelistreply.currchar,0);
			bn_int_set(&rpacket->u.d2cs_client_gamelistreply.gameflag,0);
			packet_append_string(rpacket,"");
			packet_append_string(rpacket,"");
			packet_append_string(rpacket,"");
			conn_push_outqueue(c,rpacket);
			packet_del_ref(rpacket);
		}
	}
	return 0;
}
예제 #9
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;
}
예제 #10
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+=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;
	}
	pos+=std::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;
}
예제 #11
0
extern int d2ladder_saveladder(void)
{
	t_d2ladderfile_ladderindex	lhead[D2LADDER_MAXTYPE];
	t_d2ladderfile_header		fileheader;
	std::FILE				* fdladder;
	int				start;
	unsigned int			i,j, number;
	t_d2ladder			* d2ladder;
	t_d2ladderfile_ladderinfo	* ldata;
	char                            * XMLfilename;
        std::FILE                            * XMLfile;

/*
	if(!d2ladder_change_count) {
		eventlog(eventlog_level_debug,__FUNCTION__,"ladder data unchanged, skip saving");
		return 0;
	}
*/
	start=sizeof(fileheader)+sizeof(lhead);

	for(i=0;i<D2LADDER_MAXTYPE;i++) {
		d2ladder=d2ladderlist_find_type(i);
		bn_int_set(&lhead[i].type,d2ladder->type);
		bn_int_set(&lhead[i].offset,start);
		bn_int_set(&lhead[i].number,d2ladder->len);
		start+=d2ladder->len*sizeof(*ldata);
	}

	if (!d2ladder_ladder_file) return -1;
	if (!d2ladder_backup_file) return -1;

	if(d2ladder_checksum_check()==1) {
		eventlog(eventlog_level_info,__FUNCTION__,"backup ladder file");
		if (p_rename(d2ladder_ladder_file,d2ladder_backup_file)==-1) {
			eventlog(eventlog_level_warn,__FUNCTION__,"error std::rename %s to %s", d2ladder_ladder_file, d2ladder_backup_file);
		}
	}

	fdladder=std::fopen(d2ladder_ladder_file,"wb");
	if(!fdladder) {
		eventlog(eventlog_level_error,__FUNCTION__,"error open ladder file %s",d2ladder_ladder_file);
		return -1;
	}

	// aaron: add extra output for XML ladder here --->
	if (d2dbs_prefs_get_XML_output_ladder())
	{
	  XMLfilename = (char*)xmalloc(std::strlen(d2dbs_prefs_get_ladder_dir())+1+std::strlen(XMLname)+1);
	  std::sprintf(XMLfilename,"%s/%s",d2dbs_prefs_get_ladder_dir(),XMLname);
	  if (!(XMLfile = std::fopen(XMLfilename,"w")))
	  {
	      eventlog(eventlog_level_error,__FUNCTION__,"could not open XML ladder file for output");
	  }
	  else
	  {
             d2ladder_print_XML(XMLfile);
	     std::fclose(XMLfile);
	     xfree(XMLfilename);
	  }
	}

	// <---

	bn_int_set(&fileheader.maxtype,d2ladder_maxtype);
	bn_int_set(&fileheader.checksum,0);
	std::fwrite(&fileheader,1,sizeof(fileheader),fdladder);
	std::fwrite(lhead,1,sizeof(lhead),fdladder);
	for(i=0;i<d2ladder_maxtype;i++) {
		number=bn_int_get(lhead[i].number);
		if(number<=0) continue;
		d2ladder=d2ladderlist_find_type(i);
		ldata=(t_d2ladderfile_ladderinfo*)xmalloc(number * sizeof(*ldata));
		std::memset(ldata,0,number * sizeof(*ldata));
		for (j=0; j< number; j++) {
			bn_int_set(&ldata[j].experience,d2ladder->info[j].experience);
			bn_short_set(&ldata[j].status, d2ladder->info[j].status);
			bn_byte_set(&ldata[j].level, d2ladder->info[j].level);
			bn_byte_set(&ldata[j].chclass, d2ladder->info[j].chclass);
			std::strncpy(ldata[j].charname,d2ladder->info[j].charname,sizeof(ldata[j].charname));
		}
		std::fwrite(ldata,1,number*sizeof(*ldata),fdladder);
		xfree(ldata);
	}
	std::fclose(fdladder);
	d2ladder_checksum_set();
	eventlog(eventlog_level_info,__FUNCTION__,"ladder file saved (%d changes)",d2ladder_change_count);
	d2ladder_change_count=0;
	return 0;
}
예제 #12
0
		static int dbs_packet_getdata(t_d2dbs_connection * conn)
		{
			unsigned short	writelen;
			unsigned short	datatype;
			unsigned short	datalen;
			unsigned int	result;
			char		AccountName[MAX_USERNAME_LEN];
			char		CharName[MAX_CHARNAME_LEN];
			char		RealmName[MAX_REALMNAME_LEN];
			t_d2gs_d2dbs_get_data_request	* getcom;
			t_d2dbs_d2gs_get_data_reply	* getret;
			char		* readpos;
			char		* writepos;
			char		databuf[kBufferSize];
			t_d2charinfo_file charinfo;
			unsigned short	charinfolen;
			unsigned int	gsid;

			readpos = conn->ReadBuf;
			getcom = (t_d2gs_d2dbs_get_data_request *)readpos;
			datatype = bn_short_get(getcom->datatype);

			readpos += sizeof(*getcom);
			std::strncpy(AccountName, readpos, MAX_USERNAME_LEN);
			if (AccountName[MAX_USERNAME_LEN - 1] != 0)
			{
				eventlog(eventlog_level_error, __FUNCTION__, "max account name length exceeded");
				return -1;
			}
			readpos += std::strlen(AccountName) + 1;
			std::strncpy(CharName, readpos, MAX_CHARNAME_LEN);
			if (CharName[MAX_CHARNAME_LEN - 1] != 0)
			{
				eventlog(eventlog_level_error, __FUNCTION__, "max char name length exceeded");
				return -1;
			}
			readpos += std::strlen(CharName) + 1;
			std::strncpy(RealmName, readpos, MAX_REALMNAME_LEN);
			if (RealmName[MAX_REALMNAME_LEN - 1] != 0)
			{
				eventlog(eventlog_level_error, __FUNCTION__, "max realm name length exceeded");
				return -1;
			}
			readpos += std::strlen(RealmName) + 1;

			if (readpos != conn->ReadBuf + bn_short_get(getcom->h.size)) {
				eventlog(eventlog_level_error, __FUNCTION__, "request packet size error");
				return -1;
			}
			writepos = conn->WriteBuf + conn->nCharsInWriteBuffer;
			getret = (t_d2dbs_d2gs_get_data_reply *)writepos;
			datalen = 0;
			if (datatype == D2GS_DATA_CHARSAVE) {
				if (cl_query_charlock_status((unsigned char*)CharName, (unsigned char*)RealmName, &gsid) != 0) {
					eventlog(eventlog_level_warn, __FUNCTION__, "char %s(*%s)@%s is already locked on gs %u", CharName, AccountName, RealmName, gsid);
					result = D2DBS_GET_DATA_CHARLOCKED;
				}
				else if (cl_lock_char((unsigned char*)CharName, (unsigned char*)RealmName, conn->serverid) != 0) {
					eventlog(eventlog_level_error, __FUNCTION__, "failed to lock char %s(*%s)@%s for gs %s(%d)", CharName, AccountName, RealmName, conn->serverip, conn->serverid);
					result = D2DBS_GET_DATA_CHARLOCKED;
				}
				else {
					eventlog(eventlog_level_info, __FUNCTION__, "lock char %s(*%s)@%s for gs %s(%d)", CharName, AccountName, RealmName, conn->serverip, conn->serverid);
					datalen = dbs_packet_getdata_charsave(conn, AccountName, CharName, databuf, kBufferSize);
					if (datalen > 0) {
						result = D2DBS_GET_DATA_SUCCESS;
						charinfolen = dbs_packet_getdata_charinfo(conn, AccountName, CharName, (char *)&charinfo, sizeof(charinfo));
						if (charinfolen > 0) {
							result = D2DBS_GET_DATA_SUCCESS;
						}
						else {
							result = D2DBS_GET_DATA_FAILED;
							if (cl_unlock_char((unsigned char*)CharName, (unsigned char*)RealmName, gsid) != 0) {
								eventlog(eventlog_level_error, __FUNCTION__, "failed to unlock char %s(*%s)@%s for gs %s(%d)", CharName, \
									AccountName, RealmName, conn->serverip, conn->serverid);
							}
							else {
								eventlog(eventlog_level_info, __FUNCTION__, "unlock char %s(*%s)@%s for gs %s(%d)", CharName, \
									AccountName, RealmName, conn->serverip, conn->serverid);
							}
						}
					}
					else {
						datalen = 0;
						result = D2DBS_GET_DATA_FAILED;
						if (cl_unlock_char((unsigned char*)CharName, (unsigned char*)RealmName, gsid) != 0) {
							eventlog(eventlog_level_error, __FUNCTION__, "faled to unlock char %s(*%s)@%s for gs %s(%d)", CharName, \
								AccountName, RealmName, conn->serverip, conn->serverid);
						}
						else {
							eventlog(eventlog_level_info, __FUNCTION__, "unlock char %s(*%s)@%s for gs %s(%d)", CharName, \
								AccountName, RealmName, conn->serverip, conn->serverid);
						}

					}
				}
				if (result == D2DBS_GET_DATA_SUCCESS) {
					bn_int_set(&getret->charcreatetime, bn_int_get(charinfo.header.create_time));
					/* FIXME: this should be rewritten to support string formatted std::time */
					if (bn_int_get(charinfo.header.create_time) >= prefs_get_ladderinit_time()) {
						bn_int_set(&getret->allowladder, 1);
					}
					else {
						bn_int_set(&getret->allowladder, 0);
					}
				}
				else {
					bn_int_set(&getret->charcreatetime, 0);
					bn_int_set(&getret->allowladder, 0);
				}
			}
			else if (datatype == D2GS_DATA_PORTRAIT) {
				datalen = dbs_packet_getdata_charinfo(conn, AccountName, CharName, databuf, kBufferSize);
				if (datalen > 0) result = D2DBS_GET_DATA_SUCCESS;
				else {
					datalen = 0;
					result = D2DBS_GET_DATA_FAILED;
				}
			}
			else {
				eventlog(eventlog_level_error, __FUNCTION__, "unknown data type %d", datatype);
				return -1;
			}
			writelen = datalen + sizeof(*getret) + std::strlen(CharName) + 1;
			if (writelen > kBufferSize - conn->nCharsInWriteBuffer) return 0;
			bn_short_set(&getret->h.type, D2DBS_D2GS_GET_DATA_REPLY);
			bn_short_set(&getret->h.size, writelen);
			bn_int_set(&getret->h.seqno, bn_int_get(getcom->h.seqno));
			bn_short_set(&getret->datatype, bn_short_get(getcom->datatype));
			bn_int_set(&getret->result, result);
			bn_short_set(&getret->datalen, datalen);
			writepos += sizeof(*getret);
			std::strncpy(writepos, CharName, MAX_CHARNAME_LEN);
			writepos += std::strlen(CharName) + 1;
			if (datalen) std::memcpy(writepos, databuf, datalen);
			conn->nCharsInWriteBuffer += writelen;
			return 1;
		}
예제 #13
0
		static int dbs_packet_savedata(t_d2dbs_connection * conn)
		{
			unsigned short writelen;
			unsigned short      datatype;
			unsigned short      datalen;
			unsigned int        result;
			char AccountName[MAX_USERNAME_LEN];
			char CharName[MAX_CHARNAME_LEN];
			char RealmName[MAX_REALMNAME_LEN];
			t_d2gs_d2dbs_save_data_request	* savecom;
			t_d2dbs_d2gs_save_data_reply	* saveret;
			char * readpos;
			unsigned char * writepos;

			readpos = conn->ReadBuf;
			savecom = (t_d2gs_d2dbs_save_data_request	*)readpos;
			datatype = bn_short_get(savecom->datatype);
			datalen = bn_short_get(savecom->datalen);

			readpos += sizeof(*savecom);
			std::strncpy(AccountName, readpos, MAX_USERNAME_LEN);
			if (AccountName[MAX_USERNAME_LEN - 1] != 0)
			{
				eventlog(eventlog_level_error, __FUNCTION__, "max acccount name length exceeded");
				return -1;
			}
			readpos += std::strlen(AccountName) + 1;
			std::strncpy(CharName, readpos, MAX_CHARNAME_LEN);
			if (CharName[MAX_CHARNAME_LEN - 1] != 0)
			{
				eventlog(eventlog_level_error, __FUNCTION__, "max char name length exceeded");
				return -1;
			}
			readpos += std::strlen(CharName) + 1;
			std::strncpy(RealmName, readpos, MAX_REALMNAME_LEN);
			if (RealmName[MAX_REALMNAME_LEN - 1] != 0)
			{
				eventlog(eventlog_level_error, __FUNCTION__, "max realm name length exceeded");
				return -1;
			}
			readpos += std::strlen(RealmName) + 1;

			if (readpos + datalen != conn->ReadBuf + bn_short_get(savecom->h.size)) {
				eventlog(eventlog_level_error, __FUNCTION__, "request packet size error");
				return -1;
			}

			if (datatype == D2GS_DATA_CHARSAVE) {
				if (dbs_packet_savedata_charsave(conn, AccountName, CharName, readpos, datalen) > 0 &&
					dbs_packet_fix_charinfo(conn, AccountName, CharName, readpos)) {
					result = D2DBS_SAVE_DATA_SUCCESS;
				}
				else {
					datalen = 0;
					result = D2DBS_SAVE_DATA_FAILED;
				}
			}
			else if (datatype == D2GS_DATA_PORTRAIT) {
				/* if level is > 255 , sets level to 255 */
				dbs_packet_set_charinfo_level(CharName, readpos);
				if (dbs_packet_savedata_charinfo(conn, AccountName, CharName, readpos, datalen) > 0) {
					result = D2DBS_SAVE_DATA_SUCCESS;
				}
				else {
					datalen = 0;
					result = D2DBS_SAVE_DATA_FAILED;
				}
			}
			else {
				eventlog(eventlog_level_error, __FUNCTION__, "unknown data type %d", datatype);
				return -1;
			}
			writelen = sizeof(*saveret) + std::strlen(CharName) + 1;
			if (writelen > kBufferSize - conn->nCharsInWriteBuffer) return 0;
			writepos = (unsigned char*)(conn->WriteBuf + conn->nCharsInWriteBuffer);
			saveret = (t_d2dbs_d2gs_save_data_reply *)writepos;
			bn_short_set(&saveret->h.type, D2DBS_D2GS_SAVE_DATA_REPLY);
			bn_short_set(&saveret->h.size, writelen);
			bn_int_set(&saveret->h.seqno, bn_int_get(savecom->h.seqno));
			bn_short_set(&saveret->datatype, bn_short_get(savecom->datatype));
			bn_int_set(&saveret->result, result);
			writepos += sizeof(*saveret);
			std::strncpy((char*)writepos, CharName, MAX_CHARNAME_LEN);
			conn->nCharsInWriteBuffer += writelen;
			return 1;
		}