示例#1
0
		static int dbs_packet_charlock(t_d2dbs_connection * conn)
		{
			char CharName[MAX_CHARNAME_LEN];
			char AccountName[MAX_USERNAME_LEN];
			char RealmName[MAX_REALMNAME_LEN];
			t_d2gs_d2dbs_char_lock * charlock;
			char * readpos;

			readpos = conn->ReadBuf;
			charlock = (t_d2gs_d2dbs_char_lock*)readpos;

			readpos += sizeof(*charlock);
			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(charlock->h.size)) {
				eventlog(eventlog_level_error, __FUNCTION__, "request packet size error");
				return -1;
			}

			if (bn_int_get(charlock->lockstatus)) {
				if (cl_lock_char((unsigned char*)CharName, (unsigned char*)RealmName, conn->serverid) != 0) {
					eventlog(eventlog_level_error, __FUNCTION__, "failed to lock character %s(*%s)@%s for gs %s(%d)", CharName, AccountName, RealmName, conn->serverip, conn->serverid);
				}
				else {
					eventlog(eventlog_level_info, __FUNCTION__, "lock character %s(*%s)@%s for gs %s(%d)", CharName, AccountName, RealmName, conn->serverip, conn->serverid);
				}
			}
			else {
				if (cl_unlock_char((unsigned char*)CharName, (unsigned char*)RealmName, conn->serverid) != 0) {
					eventlog(eventlog_level_error, __FUNCTION__, "failed to unlock character %s(*%s)@%s for gs %s(%d)", CharName, AccountName, RealmName, conn->serverip, conn->serverid);
				}
				else {
					eventlog(eventlog_level_info, __FUNCTION__, "unlock character %s(*%s)@%s for gs %s(%d)", CharName, AccountName, RealmName, conn->serverip, conn->serverid);
				}
			}
			return 1;
		}
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 dbs_packet_updateladder(t_d2dbs_connection * conn)
		{
			char CharName[MAX_CHARNAME_LEN];
			char RealmName[MAX_REALMNAME_LEN];
			t_d2gs_d2dbs_update_ladder	* updateladder;
			char * readpos;
			t_d2ladder_info			charladderinfo;

			readpos = conn->ReadBuf;
			updateladder = (t_d2gs_d2dbs_update_ladder *)readpos;

			readpos += sizeof(*updateladder);
			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(updateladder->h.size)) {
				eventlog(eventlog_level_error, __FUNCTION__, "request packet size error");
				return -1;
			}

			std::strcpy(charladderinfo.charname, CharName);
			charladderinfo.experience = bn_int_get(updateladder->charexplow);
			charladderinfo.level = bn_int_get(updateladder->charlevel);
			charladderinfo.status = bn_short_get(updateladder->charstatus);
			charladderinfo.chclass = bn_short_get(updateladder->charclass);
			eventlog(eventlog_level_info, __FUNCTION__, "update ladder for %s@%s for gs %s(%d)", CharName, RealmName, conn->serverip, conn->serverid);
			d2ladder_update(&charladderinfo);
			return 1;
		}
示例#4
0
static int d2ladder_append_ladder(unsigned int type, t_d2ladderfile_ladderinfo * info)
{
	t_d2cs_client_ladderinfo	* ladderinfo;
	unsigned short			ladderstatus;
	unsigned short			status;
	unsigned char			class;

	if (!info) {
		log_error("got NULL info");
		return -1;
	}
	if (type > max_ladder_type) {
		log_error("ladder type %d exceed max ladder type %d",type,max_ladder_type);
		return -1;
	}
	if (!ladder_data[type].info) {
		log_error("ladder data info not initialized");
		return -1;
	}
	if (ladder_data[type].curr_len >= ladder_data[type].len) {
		log_error("ladder data overflow %d > %d", ladder_data[type].curr_len, ladder_data[type].len);
		return -1;
	}
	status = bn_short_get(info->status);
	class = bn_byte_get(info->class);
	ladderstatus = (status & LADDERSTATUS_FLAG_DIFFICULTY);
	if (charstatus_get_hardcore(status)) {
		ladderstatus |= LADDERSTATUS_FLAG_HARDCORE;
		if (charstatus_get_dead(status)) {
			ladderstatus |= LADDERSTATUS_FLAG_DEAD;
		}
	}
	if (charstatus_get_expansion(status)) {
		ladderstatus |= LADDERSTATUS_FLAG_EXPANSION;
		ladderstatus |= min(class,D2CHAR_EXP_CLASS_MAX);
	} else {
示例#5
0
/* size of the _complete_ packet, not the amount currently received or sent */
extern unsigned int packet_get_size(t_packet const * packet)
{
    unsigned int size;

    if (!packet)
    {
        eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
	return 0;
    }

    switch (packet->pclass)
    {
    case packet_class_init:
        size = sizeof(t_client_initconn);
	break;
    case packet_class_bnet:
        size = (unsigned int)bn_short_get(packet->u.bnet.h.size);
	break;
    case packet_class_file:
        size = (unsigned int)bn_short_get(packet->u.file.h.size);
	break;
    case packet_class_udp:
	size = packet->len;
	break;
    case packet_class_raw:
	size = packet->len;
	break;
    case packet_class_d2game:
	size = packet->len; /* FIXME: does header not contain the size? */
	break;
    case packet_class_d2gs:
        size = (unsigned int)bn_short_get(packet->u.d2cs_d2gs.h.size);
        break;
    case packet_class_d2cs_bnetd:
        size = (unsigned int)bn_short_get(packet->u.d2cs_bnetd.h.size);
        break;
    case packet_class_d2cs:
        size = (unsigned int)bn_short_get(packet->u.d2cs_client.h.size);
        break;
    case packet_class_w3route:
        size = (unsigned int)bn_short_get(packet->u.w3route.h.size);
        break;
    case packet_class_wolgameres:
        /* PELISH: We check and return size explicitly in this case, 
                   because we need to check MAX_WOL_GAMERES_PACKET_SIZE */
        {
            size = (unsigned int)bn_short_nget(packet->u.wolgameres.h.size);
            if (size == 0) /* RNGD sends size on rngd_size */
                size = (unsigned int)bn_short_nget(packet->u.wolgameres.h.rngd_size);
//            if (size>MAX_WOL_GAMERES_PACKET_SIZE) { /* PELISH: Fix for bug but also disable WOL gameres */
            if (size>MAX_PACKET_SIZE) {
               // eventlog(eventlog_level_error,__FUNCTION__,"packet has bad size %u",size);
                return 0;
            }
        }
        return size;
    default:
        eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->pclass);
	return 0;
    }

    if (size>MAX_PACKET_SIZE)
    {
        eventlog(eventlog_level_error,__FUNCTION__,"packet has bad size %u",size);
	return 0;
    }
    return size;
}
示例#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";
}
示例#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_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;
}
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
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;
}
示例#12
0
		/*
			return value:
			1  :  process one or more packet
			0  :  not get a whole packet,do nothing
			-1 :  error
			*/
		extern int dbs_packet_handle(t_d2dbs_connection* conn)
		{
			unsigned short		readlen, writelen;
			t_d2dbs_d2gs_header	* readhead;
			int		retval;

			if (conn->stats == 0) {
				if (conn->nCharsInReadBuffer < (signed)sizeof(t_d2gs_d2dbs_connect)) {
					return 0;
				}
				conn->stats = 1;
				conn->type = conn->ReadBuf[0];

				if (conn->type == CONNECT_CLASS_D2GS_TO_D2DBS) {
					if (dbs_verify_ipaddr(d2dbs_prefs_get_d2gs_list(), conn) < 0) {
						eventlog(eventlog_level_error, __FUNCTION__, "d2gs connection from unknown ip address");
						return -1;
					}
					readlen = 1;
					writelen = 0;
					eventlog(eventlog_level_info, __FUNCTION__, "set connection type for gs %s(%d) on socket %d", conn->serverip, conn->serverid, conn->sd);
					eventlog_step(prefs_get_logfile_gs(), eventlog_level_info, __FUNCTION__, "set connection type for gs %s(%d) on socket %d", conn->serverip, conn->serverid, conn->sd);
				}
				else {
					eventlog(eventlog_level_error, __FUNCTION__, "unknown connection type");
					return -1;
				}
				conn->nCharsInReadBuffer -= readlen;
				std::memmove(conn->ReadBuf, conn->ReadBuf + readlen, conn->nCharsInReadBuffer);
			}
			else if (conn->stats == 1) {
				if (conn->type == CONNECT_CLASS_D2GS_TO_D2DBS) {
					while (conn->nCharsInReadBuffer >= (signed)sizeof(*readhead)) {
						readhead = (t_d2dbs_d2gs_header *)conn->ReadBuf;
						readlen = bn_short_get(readhead->size);
						if (conn->nCharsInReadBuffer < readlen) break;
						switch (bn_short_get(readhead->type)) {
						case D2GS_D2DBS_SAVE_DATA_REQUEST:
							retval = dbs_packet_savedata(conn);
							break;
						case D2GS_D2DBS_GET_DATA_REQUEST:
							retval = dbs_packet_getdata(conn);
							break;
						case D2GS_D2DBS_UPDATE_LADDER:
							retval = dbs_packet_updateladder(conn);
							break;
						case D2GS_D2DBS_CHAR_LOCK:
							retval = dbs_packet_charlock(conn);
							break;
						case D2GS_D2DBS_ECHOREPLY:
							retval = dbs_packet_echoreply(conn);
							break;
						default:
							eventlog(eventlog_level_error, __FUNCTION__, "unknown request type %d", \
								bn_short_get(readhead->type));
							retval = -1;
						}
						if (retval != 1) return retval;
						conn->nCharsInReadBuffer -= readlen;
						std::memmove(conn->ReadBuf, conn->ReadBuf + readlen, conn->nCharsInReadBuffer);
					}
				}
				else {
					eventlog(eventlog_level_error, __FUNCTION__, "unknown connection type %d", conn->type);
					return -1;
				}
			}
			else {
				eventlog(eventlog_level_error, __FUNCTION__, "unknown connection stats");
				return -1;
			}
			return 1;
		}
示例#13
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;
		}
示例#14
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;
		}