proto_header.h 5.15 KB
#pragma once

#include "common.h"

#pragma pack(1)

/**
 * @brief 接受客户端数据	
 */
class cli_recv_data_t : public el::lib_recv_data_t
{
public:
    static const uint32_t PKG_LEN_POS_IN_HEARDER = 0;

public:
	cli_recv_data_t(const void* recvdata, int readpos = 0)
		: el::lib_recv_data_t(recvdata, readpos)
    {
	}
public:
    /**
     * @brief 消息格式[pkg_len|......], pkg_len占用4个字节,pkg_len的值为包体的总长度	
     *
     * @return 返回包体的总长度	
     */
    virtual uint32_t get_len()
    {
        char* c = (char*)this->recv_data;
        c += PKG_LEN_POS_IN_HEARDER;

        PROTO_LEN pkg_len = EL_BYTE_SWAP((PROTO_LEN)(*(PROTO_LEN*)c));
		//TRACE_MSG_HEX_LOG(this->recv_data, pkg_len);
        return (uint32_t)(pkg_len);
    }

	inline uint32_t remain_len() 
    {
		return this->get_len() - this->read_pos;
	}
protected:
private:
	cli_recv_data_t(const cli_recv_data_t& cr); // 拷贝构造函数	
	cli_recv_data_t& operator=( const cli_recv_data_t& cr); // 赋值函数	
};

/**
 * @brief 接受服务器端数据	
 */
class server_recv_data_t : public el::lib_recv_data_t
{
public:
    static const uint32_t PKG_LEN_POS_IN_HEARDER = 0;

public:
	server_recv_data_t (const void* recvdata, int readpos = 0)
		: el::lib_recv_data_t(recvdata, readpos)
    {
	}
public:
    /**
     * @brief 消息格式[pkg_len|......], pkg_len占用四个字节,pkg_len的值为整个包的总长度	
     *
     * @return 返回包的总长度	
     */
    virtual uint32_t get_len()
    {
		char* c = (char*)this->recv_data;
		c += PKG_LEN_POS_IN_HEARDER;

		PROTO_LEN pkg_len = EL_BYTE_SWAP((PROTO_LEN)(*(PROTO_LEN*)c));
		return (uint32_t)(pkg_len);
    }

	inline uint32_t remain_len() 
    {
		return this->get_len() - this->read_pos;
	}
protected:
private:
	server_recv_data_t(const server_recv_data_t& cr); // 拷贝构造函数	
	server_recv_data_t& operator=( const server_recv_data_t& cr); // 赋值函数	
};

/**
 * @brief 协议包头	
 */
struct proto_head_t : public el::lib_proto_head_base_t
{
    static const uint32_t PROTO_HEAD_LEN = 24;

    PROTO_LEN length;    //报文总长度		
    uint32_t seq;       //序列号,需要原样返回	
    CMD_ID cmd;       //命令号	
    uint32_t result;     //返回值	
    USER_ID id;         //玩家id	
	static void pack(char* data, PROTO_LEN len, uint32_t seq, CMD_ID cmd, uint32_t result, USER_ID uid){
		PROTO_LEN* ppkg_len = (PROTO_LEN*)data;
		*ppkg_len = EL_BYTE_SWAP(len);

		uint32_t* ppkg_seq = (uint32_t*)(data + sizeof(PROTO_LEN));
		*ppkg_seq = EL_BYTE_SWAP(seq);

		CMD_ID* pcmd_id = (CMD_ID*)(data + sizeof(PROTO_LEN) + sizeof(uint32_t));
		*pcmd_id = EL_BYTE_SWAP(cmd);

		uint32_t* pret = (uint32_t*)(data + sizeof(PROTO_LEN) + sizeof(uint32_t) + sizeof(CMD_ID));
		*pret = EL_BYTE_SWAP(result);

		USER_ID* puid = (USER_ID*)(data + sizeof(PROTO_LEN) + sizeof(uint32_t) + sizeof(CMD_ID) + sizeof(uint32_t));
		*puid = EL_BYTE_SWAP(uid);
	}
	virtual void unpack(const void* data)
    {
		server_recv_data_t in(data);
		in>>this->length
            >>this->seq
            >>this->cmd
            >>this->result
            >>this->id;
	}

	virtual uint32_t len_offset()
    {
		return 0;
	}

	virtual void trace_log()
    {
		TRACE_MSG_LOG("[len:%u, cmd:%#x]", this->length, this->cmd);
	}

	virtual void error_log()
    {
		ERROR_LOG("[len:%u, cmd:%#x]", this->length, this->cmd);
	}

	void debug_log()
    {
		DEBUG_LOG("[len:%u, cmd:%#x]", this->length, this->cmd);
	}

    virtual uint32_t get_proto_head_len()
    {
        return PROTO_HEAD_LEN;
    }

    virtual bool is_all_len()
    {
        return true;
    }

    virtual uint32_t get_all_len()
    {
        return this->length;
    }

    virtual uint32_t get_body_len()
    {
        return this->length - proto_head_t::PROTO_HEAD_LEN;
    }

	virtual void* get_len_pointer()
    {
		return &this->length;
	}

	virtual uint32_t get_cmd()
    {
		return this->cmd;
	}

	virtual void set_len(uint32_t len)
    {
		this->length = len;
	}

	virtual void* get_data_pointer()
    {
		return &this->length;
	}

	proto_head_t ()
    {
		this->clear();
	}

	proto_head_t (uint32_t cmd)
    {
		this->clear();
		this->cmd = (CMD_ID)cmd;
	}

	void clear()
    {
		this->length= 0;
		this->seq = 0;
		this->cmd = 0;
		this->result = 0;
		this->id = 0;
	}
};

/**
 * @brief 服务器之间通讯发送数据结构	
 */
class server_send_data_t : public el::lib_send_data_t<proto_head_t>
{
public:
    server_send_data_t() : lib_send_data_t<proto_head_t>(send_data){ }

    virtual void set_head(const proto_head_t* head)
    {
        const uint32_t all_len = this->write_pos;
        this->write_pos = 0;

        uint32_t len = all_len;
        *this << len
            <<head->seq
            <<head->cmd
            <<head->result
            <<head->id;

        this->write_pos = all_len;

//        DEBUG_LOG("head len |%u", len);
    }

    void add_body_len(uint32_t body_len)
    {
        init();
        this->write_pos += body_len;
    }
public:
    char send_data[SERVER_PACK_DEFAULT_SIZE];
private:
    server_send_data_t(const server_send_data_t& cr); // 拷贝构造函数	
    server_send_data_t& operator=( const server_send_data_t& cr); // 赋值函数	
};


#pragma pack()