예제 #1
0
/*==========================================
 *
 *------------------------------------------*/
int chrif_parse(int fd)
{
	int packet_len, cmd;

	// only process data from the char-server
	if (fd != char_fd)
	{
		ShowDebug("chrif_parse: Disconnecting invalid session #%d (is not the char-server)\n", fd);
		do_close(fd);
		return 0;
	}

	if (session[fd]->flag.eof)
	{
		if (chrif_connected == 1)
			chrif_disconnect(fd);

		do_close(fd);
		return 0;
	}

	while (RFIFOREST(fd) >= 2)
	{
		cmd = RFIFOW(fd,0);
		if (cmd < 0x2af8 || cmd >= 0x2af8 + ARRAYLENGTH(packet_len_table) || packet_len_table[cmd-0x2af8] == 0)
		{
			int r = intif_parse(fd); // intifに渡す

			if (r == 1) continue;	// intifで処理した
			if (r == 2) return 0;	// intifで処理したが、データが足りない

			ShowWarning("chrif_parse: session #%d, intif_parse failed (unrecognized command 0x%.4x).\n", fd, cmd);
			set_eof(fd);
			return 0;
		}

		packet_len = packet_len_table[cmd-0x2af8];
		if (packet_len == -1)
		{ // dynamic-length packet, second WORD holds the length
			if (RFIFOREST(fd) < 4)
				return 0;
			packet_len = RFIFOW(fd,2);
		}

		if ((int)RFIFOREST(fd) < packet_len)
			return 0;

		//ShowDebug("Received packet 0x%4x (%d bytes) from char-server (connection %d)\n", RFIFOW(fd,0), packet_len, fd);

		switch(cmd)
		{
		case 0x2af9: chrif_connectack(fd); break;
		case 0x2afb: chrif_sendmapack(fd); break;
		case 0x2afd: chrif_authok(fd); break;
		case 0x2b00: map_setusers(RFIFOL(fd,2)); chrif_keepalive(fd); break;
		case 0x2b03: clif_charselectok(RFIFOL(fd,2)); break;
		case 0x2b04: chrif_recvmap(fd); break;
		case 0x2b06: chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break;
		case 0x2b07: clif_updatemaxid(RFIFOL(fd,2), RFIFOL(fd,6)); break;
		case 0x2b09: map_addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break;
		case 0x2b0b: chrif_changedgm(fd); break;
		case 0x2b0d: chrif_changedsex(fd); break;
		case 0x2b0f: chrif_char_ask_name_answer(RFIFOL(fd,2), (char*)RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32)); break;
		case 0x2b12: chrif_divorce(RFIFOL(fd,2), RFIFOL(fd,6)); break;
		case 0x2b13: chrif_accountdeletion(fd); break;
		case 0x2b14: chrif_accountban(fd); break;
		case 0x2b15: chrif_recvgmaccounts(fd); break;
		case 0x2b1b: chrif_recvfamelist(fd); break;
		case 0x2b1d: chrif_load_scdata(fd); break;
		case 0x2b1e: chrif_update_ip(fd); break;
		case 0x2b1f: chrif_disconnectplayer(fd); break;
		case 0x2b20: chrif_removemap(fd); break;
		case 0x2b21: chrif_save_ack(fd); break;
		case 0x2b22: chrif_updatefamelist_ack(fd); break;
		case 0x2b24: chrif_keepalive_ack(fd); break;
		default:
			ShowError("chrif_parse : unknown packet (session #%d): 0x%x. Disconnecting.\n", fd, cmd);
			set_eof(fd);
			return 0;
		}
		if (fd == char_fd) //There's the slight chance we lost the connection during parse, in which case this would segfault if not checked [Skotlex]
			RFIFOSKIP(fd, packet_len);
	}

	return 0;
}
예제 #2
0
파일: chrif.cpp 프로젝트: Rosalila/tswa
/*==========================================
 *
 *------------------------------------------
 */
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();
}