Пример #1
0
static int chrif_reconnect(DBKey key,void *data,va_list ap)
{
	struct auth_node *node=(struct auth_node*)data;
	switch (node->state) {
	case ST_LOGIN:
		if (node->sd && node->char_dat == NULL)
		{	//Since there is no way to request the char auth, make it fail.
			pc_authfail(node->sd);
			chrif_char_offline_nsd(node->account_id, node->char_id);
			chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
		}
		break;
	case ST_LOGOUT:
		//Re-send final save
		chrif_save(node->sd, 1);
		break;
	case ST_MAPCHANGE:
		{	//Re-send map-change request.
		struct map_session_data *sd = node->sd;
		uint32 ip;
		uint16 port;
		if(map_mapname2ipport(sd->mapindex,&ip,&port)==0)
			chrif_changemapserver(sd, ip, port);
		else //too much lag/timeout is the closest explanation for this error.
			clif_authfail_fd(sd->fd, 3);
		break;
		}
	}
	return 0;
}
Пример #2
0
/*==========================================
 * new auth system [Kevin]
 *------------------------------------------*/
void chrif_authreq(struct map_session_data *sd)
{
	struct auth_node *node= chrif_search(sd->bl.id);

	if(!node) {
		//data from char server has not arrived yet.
		chrif_sd_to_auth(sd, ST_LOGIN);
		return;
	}

	if(node->state == ST_LOGIN &&
		node->char_dat &&
		node->account_id == sd->status.account_id &&
		node->char_id == sd->status.char_id &&
		node->login_id1 == sd->login_id1)
	{	//auth ok
		if (!pc_authok(sd, node->login_id2, node->connect_until_time, node->char_dat))
		{
			chrif_char_offline(sd); //Set client offline
			chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
		}
		else {
			//char_dat no longer needed, but player auth is not completed yet.
			aFree(node->char_dat);
			node->char_dat = NULL;
			node->sd = sd;
			chrif_char_online(sd); //Set client online
		}
	} else { //auth failed
		pc_authfail(sd);
		chrif_char_offline(sd); //Set client offline
		chrif_auth_delete(sd->status.account_id, sd->status.char_id, ST_LOGIN);
	}
	return;
}
Пример #3
0
/*==========================================
 * マップ鯖間移動ack
 *------------------------------------------
 */
static
int chrif_changemapserverack(Session *, const Packet_Fixed<0x2b06>& fixed)
{
    dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(fixed.account_id));

    if (sd == nullptr || sd->status_key.char_id != fixed.char_id)
        return -1;

    // I am fairly certain that this is not possible
    if (fixed.error == 1)
    {
        if (battle_config.error_log)
            PRINTF("map server change failed.\n"_fmt);
        pc_authfail(sd->status_key.account_id);
        return 0;
    }
    MapName mapname = fixed.map_name;
    uint16_t x = fixed.x;
    uint16_t y = fixed.y;
    IP4Address ip = fixed.map_ip;
    uint16_t port = fixed.map_port;
    clif_changemapserver(sd, mapname, x, y, ip, port);

    return 0;
}
Пример #4
0
/*==========================================
 * new auth system [Kevin]
 *------------------------------------------*/
void chrif_authreq(struct map_session_data *sd)
{
	struct auth_node *auth_data;
	auth_data=idb_get(auth_db, sd->bl.id);

	if(auth_data) {
		if(auth_data->char_dat &&
			auth_data->account_id== sd->bl.id &&
			auth_data->login_id1 == sd->login_id1)
		{	//auth ok
			pc_authok(sd, auth_data->login_id2, auth_data->connect_until_time, auth_data->char_dat);
		} else { //auth failed
			pc_authfail(sd);
			chrif_char_offline(sd); //Set him offline, the char server likely has it set as online already.
		}
		if (auth_data->char_dat)
			aFree(auth_data->char_dat);
		idb_remove(auth_db, sd->bl.id);
	} else { //data from char server has not arrived yet.
		auth_data = aCalloc(1,sizeof(struct auth_node));
		auth_data->sd = sd;
		auth_data->fd = sd->fd;
		auth_data->account_id = sd->bl.id;
		auth_data->login_id1 = sd->login_id1;
		auth_data->node_created = gettick();
		uidb_put(auth_db, sd->bl.id, auth_data);
	}
	return;
}
Пример #5
0
//character selected, insert into auth db
void chrif_authok(int fd)
{
	struct auth_node *auth_data;
	TBL_PC* sd;
	//Check if we don't already have player data in our server
	//(prevents data that is to be saved from being overwritten by
	//this received status data if this auth is later successful) [Skotlex]
	if ((sd = map_id2sd(RFIFOL(fd, 4))) != NULL)
	{
		struct mmo_charstatus *status = (struct mmo_charstatus *)RFIFOP(fd, 20);
		//Auth check is because this could be the very same sd that is waiting char-server authorization.
		if (sd->state.auth && sd->status.char_id == status->char_id)
			return;
	}
	
	if ((auth_data =uidb_get(auth_db, RFIFOL(fd, 4))) != NULL)
	{	//Is the character already awaiting authorization?
		if (auth_data->sd)
		{
			//First, check to see if the session data still exists (avoid dangling pointers)
			if(session[auth_data->fd] && session[auth_data->fd]->session_data == auth_data->sd)
			{	
				if (auth_data->char_dat == NULL &&
					auth_data->account_id == RFIFOL(fd, 4) &&
					auth_data->login_id1 == RFIFOL(fd, 8))
				{ //Auth Ok
					pc_authok(auth_data->sd, RFIFOL(fd, 16), RFIFOL(fd, 12), (struct mmo_charstatus*)RFIFOP(fd, 20));
				} else { //Auth Failed
					pc_authfail(auth_data->sd);
					chrif_char_offline(auth_data->sd); //Set him offline, the char server likely has it set as online already.
				}
			} //else: Character no longer exists, just go through.
		}
		//Delete the data of this node...
		if (auth_data->char_dat)
			aFree (auth_data->char_dat);
		uidb_remove(auth_db, RFIFOL(fd, 4));
		return;
	}
	// Awaiting for client to connect.
	auth_data = (struct auth_node *)aCalloc(1,sizeof(struct auth_node));
	auth_data->char_dat = (struct mmo_charstatus *) aCalloc(1,sizeof(struct mmo_charstatus));

	auth_data->account_id=RFIFOL(fd, 4);
	auth_data->login_id1=RFIFOL(fd, 8);
	auth_data->connect_until_time=RFIFOL(fd, 12);
	auth_data->login_id2=RFIFOL(fd, 16);
	memcpy(auth_data->char_dat,RFIFOP(fd, 20),sizeof(struct mmo_charstatus));
	auth_data->node_created=gettick();
	uidb_put(auth_db, RFIFOL(fd, 4), auth_data);
}
Пример #6
0
//character selected, insert into auth db
void chrif_authok(int fd)
{
	struct auth_node *node;
	int account_id = RFIFOL(fd, 4);
	struct mmo_charstatus *status = (struct mmo_charstatus *)RFIFOP(fd, 20);
	int char_id = status->char_id;
	TBL_PC* sd;

	//Check if both servers agree on the struct's size
	if( RFIFOW(fd,2) - 20 != sizeof(struct mmo_charstatus) )
	{
		ShowError("chrif_authok: Data size mismatch! %d != %d\n", RFIFOW(fd,2) - 20, sizeof(struct mmo_charstatus));
		return;
	}

	//Check if we don't already have player data in our server
	//Causes problems if the currently connected player tries to quit or this data belongs to an already connected player which is trying to re-auth.
	if ((sd = map_id2sd(account_id)) != NULL)
		return;
	
	if ((node = chrif_search(account_id)))
	{	//Is the character already awaiting authorization?
		if (node->state != ST_LOGIN)
			return; //character in logout phase, do not touch that data.
		if (node->sd)
		{
			sd = node->sd;
			if(node->char_dat == NULL &&
				node->account_id == account_id &&
				node->char_id == char_id &&
				node->login_id1 == RFIFOL(fd, 8))
			{ //Auth Ok
				if (pc_authok(sd, RFIFOL(fd, 16), RFIFOL(fd, 12), status))
				{
					chrif_char_online(sd);
					return;
				}
			} else { //Auth Failed
				pc_authfail(sd);				
			}
			chrif_char_offline(sd); //Set client offline
			chrif_auth_delete(account_id, char_id, ST_LOGIN);
			return;
		}
		//When we receive double login info and the client has not connected yet,
		//discard the older one and keep the new one.
		chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
	}

	// Awaiting for client to connect.
	node = ers_alloc(auth_db_ers, struct auth_node);
	memset(node, 0, sizeof(struct auth_node));
	node->char_dat = (struct mmo_charstatus *) aMalloc(sizeof(struct mmo_charstatus));

	node->account_id=account_id;
	node->char_id=char_id;
	node->login_id1=RFIFOL(fd, 8);
	node->connect_until_time=RFIFOL(fd, 12);
	node->login_id2=RFIFOL(fd, 16);
	memcpy(node->char_dat,status,sizeof(struct mmo_charstatus));
	node->node_created=gettick();
	idb_put(auth_db, account_id, node);
}
Пример #7
0
/*==========================================
 * Auth confirmation ack
 *------------------------------------------*/
void chrif_authok(int fd) {
	int account_id, group_id, char_id;
	uint32 login_id1,login_id2;
	time_t expiration_time;
	struct mmo_charstatus* status;
	struct auth_node *node;
	bool changing_mapservers;
	TBL_PC* sd;

	//Check if both servers agree on the struct's size
	if( RFIFOW(fd,2) - 25 != sizeof(struct mmo_charstatus) ) {
		ShowError("chrif_authok: Data size mismatch! %d != %d\n", RFIFOW(fd,2) - 25, sizeof(struct mmo_charstatus));
		return;
	}

	account_id = RFIFOL(fd,4);
	login_id1 = RFIFOL(fd,8);
	login_id2 = RFIFOL(fd,12);
	expiration_time = (time_t)(int32)RFIFOL(fd,16);
	group_id = RFIFOL(fd,20);
	changing_mapservers = (RFIFOB(fd,24));
	status = (struct mmo_charstatus*)RFIFOP(fd,25);
	char_id = status->char_id;

	//Check if we don't already have player data in our server
	//Causes problems if the currently connected player tries to quit or this data belongs to an already connected player which is trying to re-auth.
	if ( ( sd = map_id2sd(account_id) ) != NULL )
		return;
	
	if ( ( node = chrif_search(account_id) ) == NULL )
		return; // should not happen

	if ( node->state != ST_LOGIN )
		return; //character in logout phase, do not touch that data.

	if ( node->sd == NULL ) {
		/*
		//When we receive double login info and the client has not connected yet,
		//discard the older one and keep the new one.
		chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
		*/
		return; // should not happen
	}

	sd = node->sd;

	if( runflag == MAPSERVER_ST_RUNNING &&
		node->char_dat == NULL &&
		node->account_id == account_id &&
		node->char_id == char_id &&
		node->login_id1 == login_id1 )
	{ //Auth Ok
		if (pc_authok(sd, login_id2, expiration_time, group_id, status, changing_mapservers))
			return;
	} else { //Auth Failed
		pc_authfail(sd);
	}
	
	chrif_char_offline(sd); //Set him offline, the char server likely has it set as online already.
	chrif_auth_delete(account_id, char_id, ST_LOGIN);
}
Пример #8
0
/*==========================================
 *
 *------------------------------------------
 */
static
void chrif_parse(Session *s)
{
    assert (s == char_session);

    RecvResult rv = RecvResult::Complete;
    uint16_t packet_id;
    while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id))
    {
        switch (packet_id)
        {
            case 0x2af9:
            {
                Packet_Fixed<0x2af9> fixed;
                rv = recv_fpacket<0x2af9, 3>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_connectack(s, fixed);
                break;
            }
            case 0x2afa:
            {
                Packet_Fixed<0x2afa> fixed;
                rv = recv_fpacket<0x2afa, 10>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                ladmin_itemfrob(s, fixed);
                break;
            }
            case 0x2afb:
            {
                Packet_Fixed<0x2afb> fixed;
                rv = recv_fpacket<0x2afb, 27>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_sendmapack(s, fixed);
                break;
            }
            case 0x2afd:
            {
                Packet_Payload<0x2afd> payload;
                rv = recv_ppacket<0x2afd>(s, payload);
                if (rv != RecvResult::Complete)
                    break;

                AccountId id = payload.account_id;
                int login_id2 = payload.login_id2;
                TimeT connect_until_time = payload.connect_until;
                short tmw_version = payload.packet_tmw_version;
                CharKey st_key = payload.char_key;
                CharData st_data = payload.char_data;
                pc_authok(id, login_id2,
                        connect_until_time, tmw_version,
                        &st_key, &st_data);
                break;
            }
            case 0x2afe:
            {
                Packet_Fixed<0x2afe> fixed;
                rv = recv_fpacket<0x2afe, 6>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                pc_authfail(fixed.account_id);
                break;
            }
            case 0x2b00:
            {
                Packet_Fixed<0x2b00> fixed;
                rv = recv_fpacket<0x2b00, 6>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                map_setusers(fixed.users);
                break;
            }
            case 0x2b03:
            {
                Packet_Fixed<0x2b03> fixed;
                rv = recv_fpacket<0x2b03, 7>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                clif_charselectok(account_to_block(fixed.account_id));
                break;
            }
            case 0x2b04:
            {
                Packet_Head<0x2b04> head;
                std::vector<Packet_Repeat<0x2b04>> repeat;
                rv = recv_vpacket<0x2b04, 10, 16>(s, head, repeat);
                if (rv != RecvResult::Complete)
                    break;

                chrif_recvmap(s, head, repeat);
                break;
            }
            case 0x2b06:
            {
                Packet_Fixed<0x2b06> fixed;
                rv = recv_fpacket<0x2b06, 44>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_changemapserverack(s, fixed);
                break;
            }
            case 0x2b0b:
            {
                Packet_Fixed<0x2b0b> fixed;
                rv = recv_fpacket<0x2b0b, 10>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_changedgm(s, fixed);
                break;
            }
            case 0x2b0d:
            {
                Packet_Fixed<0x2b0d> fixed;
                rv = recv_fpacket<0x2b0d, 7>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_changedsex(s, fixed);
                break;
            }
            case 0x2b0f:
            {
                Packet_Fixed<0x2b0f> fixed;
                rv = recv_fpacket<0x2b0f, 34>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_char_ask_name_answer(s, fixed);
                break;
            }
            case 0x2b11:
            {
                Packet_Head<0x2b11> head;
                std::vector<Packet_Repeat<0x2b11>> repeat;
                rv = recv_vpacket<0x2b11, 8, 36>(s, head, repeat);
                if (rv != RecvResult::Complete)
                    break;

                chrif_accountreg2(s, head, repeat);
                break;
            }
            case 0x2b12:
            {
                Packet_Fixed<0x2b12> fixed;
                rv = recv_fpacket<0x2b12, 10>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_divorce(fixed.char_id, fixed.partner_id);
                break;
            }
            case 0x2b13:
            {
                Packet_Fixed<0x2b13> fixed;
                rv = recv_fpacket<0x2b13, 6>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_accountdeletion(s, fixed);
                break;
            }
            case 0x2b14:
            {
                Packet_Fixed<0x2b14> fixed;
                rv = recv_fpacket<0x2b14, 11>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_accountban(s, fixed);
                break;
            }
            case 0x2b15:
            {
                std::vector<Packet_Repeat<0x2b15>> repeat;
                rv = recv_packet_repeatonly<0x2b15, 4, 5>(s, repeat);
                if (rv != RecvResult::Complete)
                    break;

                chrif_recvgmaccounts(s, repeat);
                break;
            }
            default:
            {
                RecvResult r = intif_parse(s, packet_id);

                if (r == RecvResult::Complete)
                    break;
                if (r == RecvResult::Incomplete)
                    return;

                if (battle_config.error_log)
                    PRINTF("chrif_parse : unknown packet %d %d\n"_fmt, s,
                            packet_id);
                s->set_eof();
                return;
            }
        }
    }
    if (rv == RecvResult::Error)
        s->set_eof();
}