extern int handle_anongame_packet(t_connection * c, t_packet const * const packet)
		{
			switch (bn_byte_get(packet->u.client_anongame.option))
			{
			case CLIENT_FINDANONGAME_PROFILE:
				return _client_anongame_profile(c, packet);

			case CLIENT_FINDANONGAME_CANCEL:
				return _client_anongame_cancel(c);

			case CLIENT_FINDANONGAME_SEARCH:
			case CLIENT_FINDANONGAME_AT_INVITER_SEARCH:
			case CLIENT_FINDANONGAME_AT_SEARCH:
				return handle_anongame_search(c, packet); /* located in anongame.c */

			case CLIENT_FINDANONGAME_GET_ICON:
				return _client_anongame_get_icon(c, packet);

			case CLIENT_FINDANONGAME_SET_ICON:
				return _client_anongame_set_icon(c, packet);

			case CLIENT_FINDANONGAME_INFOS:
				return _client_anongame_infos(c, packet);

			case CLIENT_ANONGAME_TOURNAMENT:
				return _client_anongame_tournament(c, packet);

			case CLIENT_FINDANONGAME_PROFILE_CLAN:
				return _client_anongame_profile_clan(c, packet);

			default:
				eventlog(eventlog_level_error, __FUNCTION__, "got unhandled option %d", bn_byte_get(packet->u.client_findanongame.option));
				return -1;
			}
		}
Beispiel #2
0
static int on_d2cs_gameinforeply(t_connection * c, t_packet const * packet)
{
	t_game *		game;
	char const *		gamename;
	unsigned int		difficulty;
	t_game_difficulty	diff;

	if (!(c)) {
		eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
		return -1;
	}

	if (!(gamename = packet_get_str_const(packet,sizeof(t_d2cs_bnetd_gameinforeply),GAME_NAME_LEN))) 
	{
		eventlog(eventlog_level_error,__FUNCTION__,"missing or too long gamename");
		return -1;
	}

	if (!(game = gamelist_find_game(gamename,CLIENTTAG_DIABLO2DV_UINT,game_type_diablo2closed))
	    && !(game = gamelist_find_game(gamename,CLIENTTAG_DIABLO2XP_UINT,game_type_diablo2closed)))
	{
	       eventlog(eventlog_level_error,__FUNCTION__,"reply for unknown game \"%s\"",gamename);
               return -1;
	}

	difficulty = bn_byte_get(packet->u.d2cs_bnetd_gameinforeply.difficulty);

	switch (difficulty)
	{
		case 0:
			diff = game_difficulty_normal;
			break;
		case 1:
			diff = game_difficulty_nightmare;
			break;
		case 2:
			diff = game_difficulty_hell;
			break;
		default: 
			diff = game_difficulty_none;
	}

	game_set_difficulty(game,diff);
	
	return 0;	
}
Beispiel #3
0
extern int d2cs_handle_init_packet(t_connection * c, t_packet * packet)
{
	int	classs;
	int	retval;

	ASSERT(c,-1);
	ASSERT(packet,-1);
	classs=bn_byte_get(packet->u.client_initconn.classs);
	switch (classs) {
		case CLIENT_INITCONN_CLASS_D2CS:
			retval=on_d2cs_initconn(c);
			break;
		case CLIENT_INITCONN_CLASS_D2GS:
			retval=on_d2gs_initconn(c);
			break;
		default:
			eventlog(eventlog_level_error,__FUNCTION__,"got bad connection classs %d",classs);
			retval=-1;
			break;
	}
	return retval;
}
		static int _client_anongame_infos(t_connection * c, t_packet const * const packet)
		{
			t_packet * rpacket;

			if (bn_int_get(packet->u.client_findanongame_inforeq.count) > 1) {
				/* reply with 0 entries found */
				int	temp = 0;

				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_inforeply));
				packet_set_type(rpacket, SERVER_FINDANONGAME_INFOREPLY);
				bn_byte_set(&rpacket->u.server_findanongame_inforeply.option, CLIENT_FINDANONGAME_INFOS);
				bn_int_set(&rpacket->u.server_findanongame_inforeply.count, bn_int_get(packet->u.client_findanongame_inforeq.count));
				bn_byte_set(&rpacket->u.server_findanongame_inforeply.noitems, 0);
				packet_append_data(rpacket, &temp, 1);

				conn_push_outqueue(c, rpacket);
				packet_del_ref(rpacket);
			}
			else {
				int i;
				int client_tag;
				int server_tag_count = 0;
				int client_tag_unk;
				int server_tag_unk;
				bn_int temp;
				char noitems;
				char * tmpdata;
				int tmplen;
				t_clienttag clienttag = conn_get_clienttag(c);
				char last_packet = 0x00;
				char other_packet = 0x01;
				char langstr[5];
				t_gamelang gamelang = conn_get_gamelang(c);
				bn_int_tag_get((bn_int const *)&gamelang, langstr, 5);

				/* Send seperate packet for each item requested
				 * sending all at once overloaded w3xp
				 * [Omega] */
				for (i = 0; i < bn_byte_get(packet->u.client_findanongame_inforeq.noitems); i++){
					noitems = 0;

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

					/* Starting the packet stuff */
					packet_set_size(rpacket, sizeof(t_server_findanongame_inforeply));
					packet_set_type(rpacket, SERVER_FINDANONGAME_INFOREPLY);
					bn_byte_set(&rpacket->u.server_findanongame_inforeply.option, CLIENT_FINDANONGAME_INFOS);
					bn_int_set(&rpacket->u.server_findanongame_inforeply.count, 1);

					std::memcpy(&temp, (packet_get_data_const(packet, 10 + (i * 8), 4)), sizeof(int));
					client_tag = bn_int_get(temp);
					std::memcpy(&temp, packet_get_data_const(packet, 14 + (i * 8), 4), sizeof(int));
					client_tag_unk = bn_int_get(temp);

					switch (client_tag){
					case CLIENT_FINDANONGAME_INFOTAG_URL:
						bn_int_set((bn_int*)&server_tag_unk, 0xBF1F1047);
						packet_append_data(rpacket, "LRU\0", 4);
						packet_append_data(rpacket, &server_tag_unk, 4);
						// FIXME: Maybe need do do some checks to avoid prefs empty strings.
						tmpdata = anongame_infos_data_get_url(clienttag, conn_get_versionid(c), &tmplen);
						packet_append_data(rpacket, tmpdata, tmplen);
						noitems++;
						server_tag_count++;
						eventlog(eventlog_level_debug, __FUNCTION__, "client_tag request tagid=(0x%01x) tag=(%s)  tag_unk=(0x%04x)", i, "CLIENT_FINDANONGAME_INFOTAG_URL", client_tag_unk);
						break;
					case CLIENT_FINDANONGAME_INFOTAG_MAP:
						bn_int_set((bn_int*)&server_tag_unk, 0x70E2E0D5);
						packet_append_data(rpacket, "PAM\0", 4);
						packet_append_data(rpacket, &server_tag_unk, 4);
						tmpdata = anongame_infos_data_get_map(clienttag, conn_get_versionid(c), &tmplen);
						packet_append_data(rpacket, tmpdata, tmplen);
						noitems++;
						server_tag_count++;
						eventlog(eventlog_level_debug, __FUNCTION__, "client_tag request tagid=(0x%01x) tag=(%s)  tag_unk=(0x%04x)", i, "CLIENT_FINDANONGAME_INFOTAG_MAP", client_tag_unk);
						break;
					case CLIENT_FINDANONGAME_INFOTAG_TYPE:
						bn_int_set((bn_int*)&server_tag_unk, 0x7C87DEEE);
						packet_append_data(rpacket, "EPYT", 4);
						packet_append_data(rpacket, &server_tag_unk, 4);
						tmpdata = anongame_infos_data_get_type(clienttag, conn_get_versionid(c), &tmplen);
						packet_append_data(rpacket, tmpdata, tmplen);
						noitems++;
						server_tag_count++;
						eventlog(eventlog_level_debug, __FUNCTION__, "client_tag request tagid=(0x%01x) tag=(%s) tag_unk=(0x%04x)", i, "CLIENT_FINDANONGAME_INFOTAG_TYPE", client_tag_unk);
						break;
					case CLIENT_FINDANONGAME_INFOTAG_DESC:
						bn_int_set((bn_int*)&server_tag_unk, 0xA4F0A22F);
						packet_append_data(rpacket, "CSED", 4);
						packet_append_data(rpacket, &server_tag_unk, 4);
						tmpdata = anongame_infos_data_get_desc(langstr, clienttag, conn_get_versionid(c), &tmplen);
						packet_append_data(rpacket, tmpdata, tmplen);
						eventlog(eventlog_level_debug, __FUNCTION__, "client_tag request tagid=(0x%01x) tag=(%s) tag_unk=(0x%04x)", i, "CLIENT_FINDANONGAME_INFOTAG_DESC", client_tag_unk);
						noitems++;
						server_tag_count++;
						break;
					case CLIENT_FINDANONGAME_INFOTAG_LADR:
						bn_int_set((bn_int*)&server_tag_unk, 0x3BADE25A);
						packet_append_data(rpacket, "RDAL", 4);
						packet_append_data(rpacket, &server_tag_unk, 4);
						tmpdata = anongame_infos_data_get_ladr(langstr, clienttag, conn_get_versionid(c), &tmplen);
						packet_append_data(rpacket, tmpdata, tmplen);
						noitems++;
						server_tag_count++;
						eventlog(eventlog_level_debug, __FUNCTION__, "client_tag request tagid=(0x%01x) tag=(%s) tag_unk=(0x%04x)", i, "CLIENT_FINDANONGAME_INFOTAG_LADR", client_tag_unk);
						break;
					default:
						eventlog(eventlog_level_debug, __FUNCTION__, "unrec client_tag request tagid=(0x%01x) tag=(0x%04x)", i, client_tag);

					}
					//Adding a last padding null-byte
					if (server_tag_count == bn_byte_get(packet->u.client_findanongame_inforeq.noitems))
						packet_append_data(rpacket, &last_packet, 1); /* only last packet in group gets 0x00 */
					else
						packet_append_data(rpacket, &other_packet, 1); /* the rest get 0x01 */

					//Go,go,go
					bn_byte_set(&rpacket->u.server_findanongame_inforeply.noitems, noitems);
					conn_push_outqueue(c, rpacket);
					packet_del_ref(rpacket);
				}
			}
			return 0;
		}
Beispiel #5
0
extern int handle_init_packet(t_connection * c, t_packet const * const packet)
{
    if (!c)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"[%d] got NULL connection",conn_get_socket(c));
	return -1;
    }
    if (!packet)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"[%d] got NULL packet",conn_get_socket(c));
	return -1;
    }
    if (packet_get_class(packet)!=packet_class_init)
    {
        eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad packet (class %d)",conn_get_socket(c),(int)packet_get_class(packet));
        return -1;
    }
    
    switch (packet_get_type(packet))
    {
    case CLIENT_INITCONN:
	switch (bn_byte_get(packet->u.client_initconn.classs))
	{
	case CLIENT_INITCONN_CLASS_BNET:
	    eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated bnet connection",conn_get_socket(c));
	    conn_set_state(c,conn_state_connected);
	    conn_set_class(c,conn_class_bnet);

	    break;

	case CLIENT_INITCONN_CLASS_FILE:
	    eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated file download connection",conn_get_socket(c));
	    conn_set_state(c,conn_state_connected);
	    conn_set_class(c,conn_class_file);
	    
	    break;
	    
	case CLIENT_INITCONN_CLASS_BOT:
	    eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated chat bot connection",conn_get_socket(c));
	    conn_set_state(c,conn_state_connected);
	    conn_set_class(c,conn_class_bot);
	    
	    break;
	    
	case CLIENT_INITCONN_CLASS_TELNET:
	    eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated telnet connection",conn_get_socket(c));
	    conn_set_state(c,conn_state_connected);
	    conn_set_class(c,conn_class_telnet);
	    
	    break;

        case CLIENT_INITCONN_CLASS_D2CS_BNETD:
            {
              eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated d2cs_bnetd connection",conn_get_socket(c));

              if (!(realmlist_find_realm_by_ip(conn_get_addr(c))))
              {
                 eventlog(eventlog_level_info,__FUNCTION__, "[%d] d2cs connection from unknown ip address %s",conn_get_socket(c),addr_num_to_addr_str(conn_get_addr(c),conn_get_port(c)));
                 return -1;
              }

              conn_set_state(c,conn_state_connected);
              conn_set_class(c,conn_class_d2cs_bnetd);
              if (handle_d2cs_init(c)<0)
              {
                  eventlog(eventlog_level_info,__FUNCTION__,"faild to init d2cs connection");
                  return -1;
              }
           }
           break;
	    
	case CLIENT_INITCONN_CLASS_ENC:
	    eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated encrypted connection (not supported)",conn_get_socket(c));
	    return -1;

	default:
	    eventlog(eventlog_level_error,__FUNCTION__,"[%d] client requested unknown classs 0x%02x (length %d) (closing connection)",conn_get_socket(c),(unsigned int)bn_byte_get(packet->u.client_initconn.classs),packet_get_size(packet));
	    return -1;
	}
	break;
    default:
	eventlog(eventlog_level_error,__FUNCTION__,"[%d] unknown init packet type 0x%04x, len %u",conn_get_socket(c),packet_get_type(packet),packet_get_size(packet));
	return -1;
    }
    
    return 0;
}
Beispiel #6
0
extern char const * packet_get_type_str(t_packet const * packet, t_packet_dir dir)
{
    if (!packet)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
	return "unknown";
    }

    switch (dir)
    {
    case packet_dir_from_client:
	switch (packet->pclass)
	{
	case packet_class_init:
	    return "CLIENT_INITCONN";
	case packet_class_bnet:
	    if (packet_get_size(packet)<sizeof(t_bnet_header))
	    {
		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
		return "unknown";
	    }
	    switch (bn_short_get(packet->u.bnet.h.type))
	    {
	    case CLIENT_COMPINFO1:
				return "CLIENT_COMPINFO1";
			case CLIENT_COMPINFO2:
				return "CLIENT_COMPINFO2";
			case CLIENT_COUNTRYINFO1:
				return "CLIENT_COUNTRYINFO1";
			case CLIENT_COUNTRYINFO_109:
				return "CLIENT_COUNTRYINFO_109";
			case CLIENT_CREATEACCTREQ1:
				return "CLIENT_CREATEACCTREQ1";
			case CLIENT_UNKNOWN_2B:
				return "CLIENT_UNKNOWN_2B";
			case CLIENT_PROGIDENT:
				return "CLIENT_PROGIDENT";
			case CLIENT_AUTHREQ1:
				return "CLIENT_AUTHREQ1";
			case CLIENT_AUTHREQ_109:
				return "CLIENT_AUTHREQ_109";
			case CLIENT_REGSNOOPREPLY:
				return "CLIENT_REGSNOOPREPLY";
			case CLIENT_ICONREQ:
				return "CLIENT_ICONREQ";
			case CLIENT_LADDERSEARCHREQ:
				return "CLIENT_LADDERSEARCHREQ";
			case CLIENT_CDKEY:
				return "CLIENT_CDKEY";
			case CLIENT_CDKEY2:
				return "CLIENT_CDKEY2";
			case CLIENT_CDKEY3:
				return "CLIENT_CDKEY3";
			case CLIENT_REALMLISTREQ:
				return "CLIENT_REALMLISTREQ";
			case CLIENT_REALMLISTREQ_110:
				return "CLIENT_REALMLISTREQ_110";
			case CLIENT_PROFILEREQ:
				return "CLIENT_PROFILEREQ";
			case CLIENT_UNKNOWN_37:
				return "CLIENT_UNKNOWN_37";
			case CLIENT_UNKNOWN_39:
				return "CLIENT_UNKNOWN_39";
			case CLIENT_LOGINREQ2:
				return "CLIENT_LOGINREQ2";
			case CLIENT_MOTD_W3:
				return "CLIENT_MOTD_W3";
			case CLIENT_LOGINREQ_W3:
				return "CLIENT_LOGINREQ_W3";
			case CLIENT_LOGONPROOFREQ:
				return "CLIENT_LOGONPROOFREQ";
			case CLIENT_CREATEACCOUNT_W3:
				return "CLIENT_CREATEACCOUNT_W3";
			case CLIENT_PASSCHANGEREQ:
				return "CLIENT_PASSCHANGEREQ";
			case CLIENT_PASSCHANGEPROOFREQ:
				return "CLIENT_PASSCHANGEPROOFREQ";
			case CLIENT_CHANGEGAMEPORT:
				return "CLIENT_CHANGEGAMEPORT";
			case CLIENT_CREATEACCTREQ2:
				return "CLIENT_CREATEACCTREQ2";
			case CLIENT_UDPOK:
				return "CLIENT_UDPOK";
			case CLIENT_FILEINFOREQ:
				return "CLIENT_FILEINFOREQ";
			case CLIENT_STATSREQ:
				return "CLIENT_STATSREQ";
			case CLIENT_LOGINREQ1:
				return "CLIENT_LOGINREQ1";
			case CLIENT_CHANGEPASSREQ:
				return "CLIENT_CHANGEPASSREQ";
			case CLIENT_PLAYERINFOREQ:
				return "CLIENT_PLAYERINFOREQ";
			case CLIENT_PROGIDENT2:
				return "CLIENT_PROGIDENT2";
			case CLIENT_JOINCHANNEL:
				return "CLIENT_JOINCHANNEL";
			case CLIENT_MESSAGE:
				return "CLIENT_MESSAGE";
			case CLIENT_GAMELISTREQ:
				return "CLIENT_GAMELISTREQ";
			case CLIENT_STARTGAME1:
				return "CLIENT_STARTGAME1";
			case CLIENT_UNKNOWN_1B:
				return "CLIENT_UNKNOWN_1B";
			case CLIENT_STARTGAME3:
				return "CLIENT_STARTGAME3";
			case CLIENT_STARTGAME4:
				return "CLIENT_STARTGAME4";
			case CLIENT_CLOSEGAME:
				return "CLIENT_CLOSEGAME";
			case CLIENT_CLOSEGAME2:
				return "CLIENT_CLOSEGAME2";
			case CLIENT_LEAVECHANNEL:
				return "CLIENT_LEAVECHANNEL";
			case CLIENT_MAPAUTHREQ1:
				return "CLIENT_MAPAUTHREQ1";
			case CLIENT_MAPAUTHREQ2:
				return "CLIENT_MAPAUTHREQ2";
			case CLIENT_ADREQ:
				return "CLIENT_ADREQ";
			case CLIENT_ADACK:
				return "CLIENT_ADACK";
			case CLIENT_ADCLICK:
				return "CLIENT_ADCLICK";
			case CLIENT_ADCLICK2:
				return "CLIENT_ADCLICK2";
			case CLIENT_UNKNOWN_17:
				return "CLIENT_UNKNOWN_17";
			case CLIENT_UNKNOWN_24:
				return "CLIENT_UNKNOWN_24";
			case CLIENT_LADDERREQ:
				return "CLIENT_LADDERREQ";
			case CLIENT_ECHOREPLY:
				return "CLIENT_ECHOREPLY";
			case CLIENT_PINGREQ:
				return "CLIENT_PINGREQ";
			case CLIENT_GAME_REPORT:
				return "CLIENT_GAME_REPORT";
			case CLIENT_JOIN_GAME:
				return "CLIENT_JOIN_GAME";
			case CLIENT_STATSUPDATE:
				return "CLIENT_STATSUPDATE";
			case CLIENT_REALMJOINREQ_109:
				return "CLIENT_REALMJOINREQ_109";
			case CLIENT_CHANGECLIENT:
				return "CLIENT_CHANGECLIENT";
			case CLIENT_SETEMAILREPLY:
				return "CLIENT_SETEMAILREPLY";
			case CLIENT_GETPASSWORDREQ:
				return "CLIENT_GETPASSWORDREQ";
			case CLIENT_CHANGEEMAILREQ:
				return "CLIENT_CHANGEEMAILREQ";
			case CLIENT_CRASHDUMP:
				return "CLIENT_CRASHDUMP";
			case CLIENT_FINDANONGAME:
				return "CLIENT_FINDANONGAME";
			case CLIENT_ARRANGEDTEAM_FRIENDSCREEN:
				return "CLIENT_ARRANGEDTEAM_FRIENDSCREEN";
			case CLIENT_ARRANGEDTEAM_INVITE_FRIEND:
				return "CLIENT_ARRANGEDTEAM_INVITE_FRIEND";
			case CLIENT_ARRANGEDTEAM_ACCEPT_DECLINE_INVITE:
				return "CLIENT_ARRANGEDTEAM_ACCEPT_DECLINE_INVITE";
			case CLIENT_FRIENDSLISTREQ:
				return "CLIENT_FRIENDSLISTREQ";
			case CLIENT_FRIENDINFOREQ:
				return "CLIENT_FRIENDINFOREQ";
			case CLIENT_CLANINFOREQ:
				return "CLIENT_CLANINFOREQ";
			case CLIENT_CLAN_CREATEREQ:
				return "CLIENT_CLAN_CREATEREQ";
			case CLIENT_CLAN_CREATEINVITEREQ:
				return "CLIENT_CLAN_CREATEINVITEREQ";
			case CLIENT_CLAN_CREATEINVITEREPLY:
				return "CLIENT_CLAN_CREATEINVITEREPLY";
			case CLIENT_CLAN_DISBANDREQ:
				return "CLIENT_CLAN_DISBANDREQ";
			case CLIENT_CLAN_MEMBERNEWCHIEFREQ:
				return "CLIENT_CLAN_MEMBERNEWCHIEFREQ";
			case CLIENT_CLAN_INVITEREQ:
				return "CLIENT_CLAN_INVITEREQ";
			case CLIENT_CLANMEMBER_REMOVE_REQ:
				return "CLIENT_CLANMEMBER_REMOVE_REQ";
			case CLIENT_CLAN_INVITEREPLY:
				return "CLIENT_CLAN_INVITEREPLY";
			case CLIENT_CLANMEMBER_RANKUPDATE_REQ:
				return "CLIENT_CLANMEMBER_RANKUPDATE_REQ";
			case CLIENT_CLAN_MOTDCHG:
				return "CLIENT_CLAN_MOTDCHG";
			case CLIENT_CLAN_MOTDREQ:
				return "CLIENT_CLAN_MOTDREQ";
			case CLIENT_CLANMEMBERLIST_REQ:
				return "CLIENT_CLANMEMBERLIST_REQ";
			}
			return "unknown";

	case packet_class_file:
	    if (packet_get_size(packet)<sizeof(t_file_header))
	    {
		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
		return "unknown";
	    }
	    switch (bn_short_get(packet->u.file.h.type))
	    {
	    case CLIENT_FILE_REQ:
		return "CLIENT_FILE_REQ";
	    }
	    return "unknown";

	case packet_class_udp:
	    if (packet_get_size(packet)<sizeof(t_udp_header))
	    {
		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
		return "unknown";
	    }
	    switch (bn_int_get(packet->u.udp.h.type))
	    {
	    case SERVER_UDPTEST: /* we get these if we send stuff to ourself */
		return "SERVER_UDPTEST";
	    case CLIENT_UDPPING:
		return "CLIENT_UDPPING";
	    case CLIENT_SESSIONADDR1:
		return "CLIENT_SESSIONADDR1";
	    case CLIENT_SESSIONADDR2:
		return "CLIENT_SESSIONADDR2";
	    }
	    return "unknown";

	case packet_class_raw:
	    return "CLIENT_RAW";

       case packet_class_d2game:
	    if (packet_get_size(packet)<sizeof(t_d2game_header))
	    {
               eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
               return "unknown";
	    }
	    switch (bn_byte_get(packet->u.d2game.h.type))
	    {
	    default:
		return "CLIENT_D2GAME";
	    }
	    return "unknown";

        case packet_class_d2cs:
                return "D2CS";
        case packet_class_d2gs:
                return "D2GS";
        case packet_class_d2cs_bnetd:
                return "D2CS_BNETD";

	case packet_class_w3route:
	    if (packet_get_size(packet)<sizeof(t_w3route_header))
	    {
		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
		return "unknown";
	    }
	    switch (bn_short_get(packet->u.bnet.h.type))
	    {
	    case CLIENT_W3ROUTE_REQ:
	        return "CLIENT_W3ROUTE_REQ";
	    case CLIENT_W3ROUTE_LOADINGDONE:
	        return "CLIENT_W3ROUTE_LOADINGDONE";
	    case CLIENT_W3ROUTE_ABORT:
	        return "CLIENT_W3ROUTE_ABORT";
	    case CLIENT_W3ROUTE_CONNECTED:
	        return "CLIENT_W3ROUTE_CONNECTED";
	    case CLIENT_W3ROUTE_ECHOREPLY:
	        return "CLIENT_W3ROUTE_ECHOREPLY";
	    case CLIENT_W3ROUTE_GAMERESULT:
	        return "CLIENT_W3ROUTE_GAMERESULT";
	    case CLIENT_W3ROUTE_GAMERESULT_W3XP:
	        return "CLIENT_W3ROUTE_GAMERESULT_W3XP";
	    }
	    return "unknown";

	case packet_class_none:
	    return "unknown";
	}

	eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->pclass);
	return "unknown";

    case packet_dir_from_server:
	switch (packet->pclass)
	{
	case packet_class_init:
	    return "unknown";
	case packet_class_bnet:
	    if (packet_get_size(packet)<sizeof(t_bnet_header))
	    {
		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
		return "unknown";
	    }
	    switch (bn_short_get(packet->u.bnet.h.type))
	    {
	    case SERVER_COMPREPLY:
				return "SERVER_COMPREPLY";
			case SERVER_SESSIONKEY1:
				return "SERVER_SESSIONKEY1";
			case SERVER_SESSIONKEY2:
				return "SERVER_SESSIONKEY2";
			case SERVER_CREATEACCTREPLY1:
				return "SERVER_CREATEACCTREPLY1";
			case SERVER_AUTHREQ1:
				return "SERVER_AUTHREQ1";
			case SERVER_AUTHREQ_109:
				return "SERVER_AUTHREQ_109";
			case SERVER_AUTHREPLY1:
				return "SERVER_AUTHREPLY1";
			case SERVER_AUTHREPLY_109:
				return "SERVER_AUTHREPLY_109";
			case SERVER_REGSNOOPREQ:
				return "SERVER_REGSNOOPREQ";
			case SERVER_ICONREPLY:
				return "SERVER_ICONREPLY";
			case SERVER_LADDERSEARCHREPLY:
				return "SERVER_LADDERSEARCHREPLY";
			case SERVER_CDKEYREPLY:
				return "SERVER_CDKEYREPLY";
			case SERVER_CDKEYREPLY2:
				return "SERVER_CDKEYREPLY2";
			case SERVER_CDKEYREPLY3:
				return "SERVER_CDKEYREPLY3";
			case SERVER_REALMLISTREPLY:
				return "SERVER_REALMLISTREPLY";
			case SERVER_REALMLISTREPLY_110:
				return "SERVER_REALMLISTREPLY_110";
			case SERVER_PROFILEREPLY:
				return "SERVER_PROFILEREPLY";
			case SERVER_UNKNOWN_37:
				return "SERVER_UNKNOWN_37";
			case SERVER_MOTD_W3:
				return "SERVER_MOTD_W3";
			case SERVER_LOGINREPLY_W3:
				return "SERVER_LOGINREPLY_W3";
			case SERVER_LOGONPROOFREPLY:
				return "SERVER_LOGONPROOFREPLY";
			case SERVER_CREATEACCOUNT_W3:
				return "SERVER_CREATEACCOUNT_W3";
			case SERVER_PASSCHANGEREPLY:
				return "SERVER_PASSCHANGEREPLY";
			case SERVER_PASSCHANGEPROOFREPLY:
				return "SERVER_PASSCHANGEPROOFREPLY";
			case SERVER_LOGINREPLY2:
				return "SERVER_LOGINREPLY2";
			case SERVER_CREATEACCTREPLY2:
				return "SERVER_CREATEACCTREPLY2";
			case SERVER_FILEINFOREPLY:
				return "SERVER_FILEINFOREPLY";
			case SERVER_STATSREPLY:
				return "SERVER_STATSREPLY";
			case SERVER_LOGINREPLY1:
				return "SERVER_LOGINREPLY1";
			case SERVER_CHANGEPASSACK:
				return "SERVER_CHANGEPASSACK";
			case SERVER_PLAYERINFOREPLY:
				return "SERVER_PLAYERINFOREPLY";
			case SERVER_CHANNELLIST:
				return "SERVER_CHANNELLIST";
			case SERVER_SERVERLIST:
				return "SERVER_SERVERLIST";
			case SERVER_MESSAGE:
				return "SERVER_MESSAGE";
			case SERVER_GAMELISTREPLY:
				return "SERVER_GAMELISTREPLY";
			case SERVER_STARTGAME1_ACK:
				return "SERVER_STARTGAME1_ACK";
			case SERVER_STARTGAME3_ACK:
				return "SERVER_STARTGAME3_ACK";
			case SERVER_STARTGAME4_ACK:
				return "SERVER_STARTGAME4_ACK";
			case SERVER_MAPAUTHREPLY1:
				return "SERVER_MAPAUTHREPLY1";
			case SERVER_MAPAUTHREPLY2:
				return "SERVER_MAPAUTHREPLY2";
			case SERVER_ADREPLY:
				return "SERVER_ADREPLY";
			case SERVER_ADCLICKREPLY2:
				return "SERVER_ADCLICKREPLY2";
			case SERVER_LADDERREPLY:
				return "SERVER_LADDERREPLY";
			case SERVER_ECHOREQ:
				return "SERVER_ECHOREQ";
			case SERVER_PINGREPLY:
				return "SERVER_PINGREPLY";
			case SERVER_REALMJOINREPLY_109:
				return "SERVER_REALMJOINREPLY_109";
			case SERVER_SETEMAILREQ:
				return "SERVER_SETEMAILREQ";
			case SERVER_FINDANONGAME:
				return "SERVER_FINDANONGAME";
			case SERVER_ARRANGEDTEAM_FRIENDSCREEN:
				return "SERVER_ARRANGEDTEAM_FRIENDSCREEN";
			case SERVER_ARRANGEDTEAM_INVITE_FRIEND_ACK:
				return "SERVER_ARRANGEDTEAM_INVITE_FRIEND_ACK";
			case SERVER_ARRANGEDTEAM_SEND_INVITE:
				return "SERVER_ARRANGEDTEAM_SEND_INVITE";
			case SERVER_ARRANGEDTEAM_MEMBER_DECLINE:
				return "SERVER_ARRANGEDTEAM_MEMBER_DECLINE";
			case SERVER_FRIENDSLISTREPLY:
				return "SERVER_FRIENDSLISTREPLY";
			case SERVER_FRIENDINFOREPLY:
				return "SERVER_FRIENDINFOREPLY";
			case SERVER_FRIENDADD_ACK:
				return "SERVER_FRIENDADD_ACK";
			case SERVER_FRIENDDEL_ACK:
				return "SERVER_FRIENDDEL_ACK";
			case SERVER_FRIENDMOVE_ACK:
				return "SERVER_FRIENDMOVE_ACK";
			case SERVER_CLANINFOREPLY:
				return "SERVER_CLANINFO_REPLY";
			case SERVER_CLAN_CREATEREPLY:
				return "SERVER_CLAN_CREATEREPLY";
			case SERVER_CLAN_CREATEINVITEREPLY:
				return "SERVER_CLAN_CREATEINVITEREPLY";
			case SERVER_CLAN_CREATEINVITEREQ:
				return "SERVER_CLAN_CREATEINVITEREQ";
			case SERVER_CLAN_DISBANDREPLY:
				return "SERVER_CLAN_DISBANDREPLY";
			case SERVER_CLAN_MEMBERNEWCHIEFREPLY:
				return "SERVER_CLAN_MEMBERNEWCHIEFREPLY";
			case SERVER_CLAN_CLANACK:
				return "SERVER_CLAN_CLANACK";
			case SERVER_CLANQUITNOTIFY:
				return "SERVER_CLANQUITNOTIFY";
			case SERVER_CLAN_INVITEREPLY:
				return "SERVER_CLAN_INVITEREPLY";
			case SERVER_CLANMEMBER_REMOVE_REPLY:
				return "SERVER_CLANMEMBER_REMOVE_REPLY";
			case SERVER_CLAN_INVITEREQ:
				return "SERVER_CLAN_INVITEREQ";
			case SERVER_CLANMEMBER_RANKUPDATE_REPLY:
				return "SERVER_CLANMEMBER_RANKUPDATE_REPLY";
			case SERVER_CLAN_MOTDREPLY:
				return "SERVER_CLAN_MOTDREPLY";
			case SERVER_CLANMEMBERLIST_REPLY:
				return "SERVER_CLANMEMBERLIST_REPLY";
			case SERVER_CLANMEMBER_REMOVED_NOTIFY:
				return "SERVER_CLANMEMBER_REMOVED_NOTIFY";
			case SERVER_CLANMEMBERUPDATE:
				return "SERVER_CLANMEMBERUPDATE";
			}
			return "unknown";

	case packet_class_file:
	    if (packet_get_size(packet)<sizeof(t_file_header))
	    {
		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
		return "unknown";
	    }
	    switch (bn_short_get(packet->u.file.h.type))
	    {
	    case SERVER_FILE_REPLY:
		return "SERVER_FILE_REPLY";
	    }
	    return "unknown";

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

	case packet_class_raw:
	    return "SERVER_RAW";

	case packet_class_d2game:
	    if (packet_get_size(packet)<sizeof(t_d2game_header))
	    {
		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
		return "unknown";
	    }
	    switch (bn_byte_get(packet->u.d2game.h.type))
	    {
	    default:
		return "SERVER_D2GAME";
	    }
	    return "unknown";

        case packet_class_d2cs:
                return "D2CS";
        case packet_class_d2gs:
                return "D2GS";
        case packet_class_d2cs_bnetd:
                return "D2CS_BNETD";

	case packet_class_w3route:
	    if (packet_get_size(packet)<sizeof(t_w3route_header))
	    {
		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
		return "unknown";
	    }
	    switch (bn_short_get(packet->u.bnet.h.type))
	    {
	    case SERVER_W3ROUTE_READY:
	        return "SERVER_W3ROUTE_READY";
	    case SERVER_W3ROUTE_LOADINGACK:
	        return "SERVER_W3ROUTE_LOADINGACK";
	    case SERVER_W3ROUTE_ECHOREQ:
	        return "SERVER_W3ROUTE_ECHOREQ";
	    case SERVER_W3ROUTE_ACK:
	        return "SERVER_W3ROUTE_ACK";
	    case SERVER_W3ROUTE_PLAYERINFO:
	        return "SERVER_W3ROUTE_PLAYERINFO";
	    case SERVER_W3ROUTE_LEVELINFO:
	        return "SERVER_W3ROUTE_LEVELINFO";
	    case SERVER_W3ROUTE_STARTGAME1:
	        return "SERVER_W3ROUTE_STARTGAME1";
	    case SERVER_W3ROUTE_STARTGAME2:
	        return "SERVER_W3ROUTE_STARTGAME2";
	    }
	    return "unknown";
 	case packet_class_wolgameres:
	    return "CLIENT_WOLGAMERES";
	case packet_class_none:
	    return "unknown";
	}

	eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->pclass);
	return "unknown";
    }

    eventlog(eventlog_level_error,__FUNCTION__,"got unknown direction %d",(int)dir);
    return "unknown";
}
Beispiel #7
0
extern unsigned int packet_get_type(t_packet const * packet)
{
    if (!packet)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
	return 0;
    }

    switch (packet->pclass)
    {
    case packet_class_init:
	return CLIENT_INITCONN; /* all init packets are of this type */

    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 0;
	}
	return (unsigned int)bn_short_get(packet->u.bnet.h.type);

    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 0;
	}
	return (unsigned int)bn_short_get(packet->u.file.h.type);

    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 0;
	}
	return bn_int_get(packet->u.udp.h.type);

    case packet_class_raw:
	return 0; /* raw packets don't have a type, but don't warn because the packet dump tries anyway */

    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 0;
	}
	return bn_byte_get(packet->u.d2game.h.type);

    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 0;
        }
        return bn_short_get(packet->u.d2cs_d2gs.h.type);
    case packet_class_d2cs_bnetd:
        if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_header)) {
                eventlog(eventlog_level_error,__FUNCTION__,"d2cs_bnetd packet shorter than header (len=%u)",packet_get_size(packet));
                return 0;
        }
        return bn_short_get(packet->u.d2cs_d2gs.h.type);

    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 0;
        }
        return bn_byte_get(packet->u.d2cs_client.h.type);

    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 0;
	}
	return bn_short_get(packet->u.w3route.h.type);
    case packet_class_wolgameres:
	    return 0; /* wolgameres packets don't have a type */

    default:
	eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->pclass);
	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+=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;
}
Beispiel #9
0
int d2ladder_readladder(void)
{
	t_d2ladder 		* d2ladder;
	t_d2ladderfile_header fileheader;
	std::FILE * 			fdladder;
	t_d2ladderfile_ladderindex 	* lhead;
	t_d2ladderfile_ladderinfo 	* ldata;
	t_d2ladder_info			* info;
	t_d2ladder_info			temp;
	long 			leftsize,blocksize;
	unsigned int		laddertype;
	unsigned int		tempmaxtype;
	int 			readlen;
	unsigned int			i, number;

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

	std::fseek(fdladder,0,SEEK_END);
	leftsize=std::ftell(fdladder);
	std::rewind(fdladder);

	blocksize=sizeof(fileheader) ;
	if (leftsize<blocksize) {
		eventlog(eventlog_level_error,__FUNCTION__,"file size error");
		std::fclose(fdladder);
		return -1;
	}

	readlen=std::fread(&fileheader,1,sizeof(fileheader),fdladder);
	if (readlen<=0) {
		eventlog(eventlog_level_error,__FUNCTION__,"file %s read error(read:%s)",d2ladder_ladder_file,std::strerror(errno));
		std::fclose(fdladder);
		return -1;
	}
	tempmaxtype=bn_int_get(fileheader.maxtype);
	leftsize-=blocksize;

	if(tempmaxtype>D2LADDER_MAXTYPE) {
		eventlog(eventlog_level_error,__FUNCTION__,"ladder type > D2LADDER_MAXTYPE error");
		std::fclose(fdladder);
		return -1;
	}
	d2ladder_maxtype=tempmaxtype;

	blocksize=d2ladder_maxtype*sizeof(*lhead);
	if (leftsize < blocksize ) {
		eventlog(eventlog_level_error,__FUNCTION__,"file size error");
		std::fclose(fdladder);
		return -1;
	}

	lhead=(t_d2ladderfile_ladderindex*)xmalloc(blocksize);
	readlen=std::fread(lhead,1,d2ladder_maxtype*sizeof(*lhead),fdladder);
	if (readlen<=0) {
		eventlog(eventlog_level_error,__FUNCTION__,"file %s read error(read:%s)",d2ladder_ladder_file,std::strerror(errno));
		xfree(lhead);
		std::fclose(fdladder);
		return -1;
	}
	leftsize-=blocksize;

	blocksize=0;
	for(i=0;i<d2ladder_maxtype;i++) {
		blocksize+=bn_int_get(lhead[i].number)*sizeof(*ldata);
	}
	if (leftsize < blocksize ) {
		eventlog(eventlog_level_error,__FUNCTION__,"file size error");
		xfree(lhead);
		std::fclose(fdladder);
		return -1;
	}

	for(laddertype=0;laddertype<d2ladder_maxtype;laddertype++) {
		number= bn_int_get(lhead[laddertype].number);
		if(number<=0) continue;
		d2ladder=d2ladderlist_find_type(laddertype);
		if (!d2ladder) {
			eventlog(eventlog_level_error,__FUNCTION__,"could not find ladder type %d",laddertype);
			continue;
		}
		ldata=(t_d2ladderfile_ladderinfo*)xmalloc(number*sizeof(*ldata));
		info=(t_d2ladder_info*)xmalloc(number * sizeof(*info));
		std::memset(info,0,number * sizeof(*info));
		std::fseek(fdladder,bn_int_get(lhead[laddertype].offset),SEEK_SET);
		readlen=std::fread(ldata,1,number*sizeof(*ldata),fdladder);
		if (readlen<=0) {
			eventlog(eventlog_level_error,__FUNCTION__,"file %s read error(read:%s)",d2ladder_ladder_file,std::strerror(errno));
			xfree(ldata);
			xfree(info);
			continue;
		}
		d2ladder->info=info;
		d2ladder->len=number;
		for (i=0; i< number; i++) {
			if (!ldata[i].charname[0]) continue;
			temp.experience=bn_int_get(ldata[i].experience);
			temp.status=bn_short_get(ldata[i].status);
			temp.level=bn_byte_get(ldata[i].level);
			temp.chclass=bn_byte_get(ldata[i].chclass);
			std::strncpy(temp.charname,ldata[i].charname,sizeof(info[i].charname));
			if (d2ladder_update_info_and_pos(d2ladder,&temp,
				d2ladder_find_char_all(d2ladder,&temp),
				d2ladder_find_pos(d2ladder,&temp))==1) {
				d2ladder_change_count++;
			}
		}
		xfree(ldata);
	}
	leftsize-=blocksize;

	xfree(lhead);
	std::fclose(fdladder);
	return 0;
}
Beispiel #10
0
extern int d2charinfo_load(char const * account, char const * charname, t_d2charinfo_file * data)
{
	char			* file;
	int			size, ladder_time;

	if (d2char_check_charname(charname)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad character name \"%s\"",charname);
		return -1;
	}
	if (d2char_check_acctname(account)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad account name \"%s\"",account);
		return -1;
	}
	file=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
	d2char_get_infofile_name(file,account,charname);
	size=sizeof(t_d2charinfo_file);
	if (file_read(file,data,&size)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"error loading character file %s",file);
		xfree(file);
		return -1;
	}
	if (size!=sizeof(t_d2charinfo_file)) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad charinfo file %s (length %d)",charname,size);
		xfree(file);
		return -1;
	}
	d2char_portrait_init(&data->portrait);
	if (d2charinfo_check(data) < 0) {
		xfree(file);
		return -1;
	}
	if (!(charstatus_get_ladder(bn_int_get(data->summary.charstatus)))) {
		bn_byte_set(&data->portrait.ladder, D2CHARINFO_PORTRAIT_PADBYTE);
		xfree(file);
		return 0;
	}
	ladder_time = prefs_get_ladder_start_time();
	if ((ladder_time > 0) && bn_int_get(data->header.create_time) < ladder_time) {
		char			buffer[MAX_SAVEFILE_SIZE];
		unsigned int		status_offset;
		unsigned char		status;
		unsigned int		charstatus;
		unsigned int		size;
		unsigned int		version;
		unsigned int		checksum;
		FILE			* fp;

		eventlog(eventlog_level_info,__FUNCTION__,"%s(*%s) was created in old ladder season, set to non-ladder", charname, account);
		if (!(fp=fopen(file,"wb"))) {
			eventlog(eventlog_level_error,__FUNCTION__,"charinfo file \"%s\" does not exist for account \"%s\"",file,account);
			xfree(file);
			return 0;
		}
		xfree(file);
		charstatus = bn_int_get(data->summary.charstatus);
		charstatus_set_ladder(charstatus, 0);
		bn_int_set(&data->summary.charstatus, charstatus);

		status=bn_byte_get(data->portrait.status);
		charstatus_set_ladder(status,0);
		bn_byte_set(&data->portrait.status,status);
		bn_byte_set(&data->portrait.ladder, D2CHARINFO_PORTRAIT_PADBYTE);

		if (fwrite(data,1,sizeof(*data),fp)!=sizeof(*data)) {
			eventlog(eventlog_level_error,__FUNCTION__,"error writing charinfo file for character \"%s\" (fwrite: %s)",charname,pstrerror(errno));
			fclose(fp);
			return 0;
}
		fclose(fp);

		file=xmalloc(strlen(prefs_get_charsave_dir())+1+strlen(charname)+1);
		d2char_get_savefile_name(file,charname);

		if (!(fp=fopen(file,"rb+"))) {
			eventlog(eventlog_level_error,__FUNCTION__,"could not open charsave file \"%s\" for reading and writing (fopen: %s)",file,pstrerror(errno));
			xfree(file);
			return 0;
		}
		xfree(file);
		size=fread(buffer,1,sizeof(buffer),fp);
		if (!feof(fp)) {
			eventlog(eventlog_level_error,__FUNCTION__,"error reading charsave file for character \"%s\" (fread: %s)",charname,pstrerror(errno));
			fclose(fp);
			return 0;
		}
		version=bn_int_get(buffer+D2CHARSAVE_VERSION_OFFSET);
		if (version>=0x5C) {
			status_offset=D2CHARSAVE_STATUS_OFFSET_109;
		} else {
			status_offset=D2CHARSAVE_STATUS_OFFSET;
		}
		status=bn_byte_get(buffer+status_offset);
		charstatus_set_ladder(status,0);
		/* FIXME: shouldn't abuse bn_*_set()... what's the best way to do this? */
		bn_byte_set((bn_byte *)(buffer+status_offset),status);
		if (version>=0x5C) {
			checksum=d2charsave_checksum(buffer,size,D2CHARSAVE_CHECKSUM_OFFSET);
			bn_int_set((bn_int *)(buffer+D2CHARSAVE_CHECKSUM_OFFSET),checksum);
		}
		fseek(fp,0,SEEK_SET);
		if (fwrite(buffer,1,size,fp)!=size) {
			eventlog(eventlog_level_error,__FUNCTION__,"error writing charsave file for character %s (fwrite: %s)",charname,pstrerror(errno));
			fclose(fp);
			return 0;
		}
		fclose(fp);
	} else {
		bn_byte_set(&data->portrait.ladder, 1);
		xfree(file);
	}
	return 0;
}
Beispiel #11
0
extern int d2char_convert(char const * account, char const * charname)
{
	FILE			* fp;
	char			* file;
	unsigned char		buffer[MAX_SAVEFILE_SIZE];
	unsigned int		status_offset;
	unsigned char		status;
	unsigned int		charstatus;
	t_d2charinfo_file	charinfo;
	unsigned int		size;
	unsigned int		version;
	unsigned int		checksum;

	ASSERT(account,-1);
	ASSERT(charname,-1);

/*	Playing with a expanstion char on a classic realm
	will cause the game server to crash, therefore
	I recommed setting allow_convert = 0 in the d2cs.conf
	We need to do this to prevent creating classic char
	and converting to expantion on a classic realm.
	LOD Char must be created on LOD realm	*/
		
	if (!prefs_get_allow_convert()) {
		eventlog(eventlog_level_info,__FUNCTION__,"Convert char has been disabled");
		return -1;
	}

/*	Procedure is stopped here and returned if
	allow_convet = 0 in d2cs.conf */
		
	if (d2char_check_charname(charname)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad character name \"%s\"",charname);
		return -1;
	}
	if (d2char_check_acctname(account)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad account name \"%s\"",account);
		return -1;
	}
	file=xmalloc(strlen(prefs_get_charinfo_dir())+1+strlen(account)+1+strlen(charname)+1);
	d2char_get_infofile_name(file,account,charname);
	if (!(fp=fopen(file,"rb+"))) {
		eventlog(eventlog_level_error,__FUNCTION__,"unable to open charinfo file \"%s\" for reading and writing (fopen: %s)",file,pstrerror(errno));
		xfree(file);
		return -1;
	}
	xfree(file);
	if (fread(&charinfo,1,sizeof(charinfo),fp)!=sizeof(charinfo)) {
		eventlog(eventlog_level_error,__FUNCTION__,"error reading charinfo file for character \"%s\" (fread: %s)",charname,pstrerror(errno));
		fclose(fp);
		return -1;
	}
	charstatus=bn_int_get(charinfo.summary.charstatus);
	charstatus_set_expansion(charstatus,1);
	bn_int_set(&charinfo.summary.charstatus,charstatus);
	
	status=bn_byte_get(charinfo.portrait.status);
	charstatus_set_expansion(status,1);
	bn_byte_set(&charinfo.portrait.status,status);
	
	fseek(fp,0,SEEK_SET); /* FIXME: check return */
	if (fwrite(&charinfo,1,sizeof(charinfo),fp)!=sizeof(charinfo)) {
		eventlog(eventlog_level_error,__FUNCTION__,"error writing charinfo file for character \"%s\" (fwrite: %s)",charname,pstrerror(errno));
		fclose(fp);
		return -1;
	}
	if (fclose(fp)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"could not close charinfo file for character \"%s\" after writing (fclose: %s)",charname,pstrerror(errno));
		return -1;
	}
	
	file=xmalloc(strlen(prefs_get_charsave_dir())+1+strlen(charname)+1);
	d2char_get_savefile_name(file,charname);
	if (!(fp=fopen(file,"rb+"))) {
		eventlog(eventlog_level_error,__FUNCTION__,"could not open charsave file \"%s\" for reading and writing (fopen: %s)",file,pstrerror(errno));
		xfree(file);
		return -1;
	}
	xfree(file);
	size=fread(buffer,1,sizeof(buffer),fp);
	if (!feof(fp)) {
		eventlog(eventlog_level_error,__FUNCTION__,"error reading charsave file for character \"%s\" (fread: %s)",charname,pstrerror(errno));
		fclose(fp);
		return -1;
	}
	version=bn_int_get(buffer+D2CHARSAVE_VERSION_OFFSET);
	if (version>=0x0000005C) {
		status_offset=D2CHARSAVE_STATUS_OFFSET_109;
	} else {
		status_offset=D2CHARSAVE_STATUS_OFFSET;
	}
	status=bn_byte_get(buffer+status_offset);
	charstatus_set_expansion(status,1);
	bn_byte_set((bn_byte *)(buffer+status_offset),status); /* FIXME: shouldn't abuse bn_*_set()... what's the best way to do this? */
	if (version>=0x0000005C) {
		checksum=d2charsave_checksum(buffer,size,D2CHARSAVE_CHECKSUM_OFFSET);
		bn_int_set((bn_int *)(buffer+D2CHARSAVE_CHECKSUM_OFFSET),checksum); /* FIXME: shouldn't abuse bn_*_set()... what's the best way to do this? */
	}
	fseek(fp,0,SEEK_SET); /* FIXME: check return */
	if (fwrite(buffer,1,size,fp)!=size) {
		eventlog(eventlog_level_error,__FUNCTION__,"error writing charsave file for character %s (fwrite: %s)",charname,pstrerror(errno));
		fclose(fp);
		return -1;
	}
	if (fclose(fp)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"could not close charsave file for character \"%s\" after writing (fclose: %s)",charname,pstrerror(errno));
		return -1;
	}
	eventlog(eventlog_level_info,__FUNCTION__,"character %s(*%s) converted to expansion",charname,account);
	return 0;
}