一、包对象的基类中,包含的属性有:
1、log对象(import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;)
2、解密者 (Crypter)
3、包体缓冲区 (ByteBuffer 类型:ByteBuffer)
4、调试模式开关 (DebugSwitch 类型:Debug切换类,单一实例,控制debug状态的设置和管理Debug客户端,其负责向客户端转发 Debug事件。所以可以有多个调试客户端同时存在。)
5、包命令, 0x03~0x04 (command 类型:char)
6、源标志, 0x01~0x02 (source 类型:char)
7、包序号, 0x05~0x06 (sequence 类型:char)
8、包头字节 (header 类型:byte)
9、QQUser 对象 (封装QQ用户的信息类)
10、duplicated(由于LumaQQ较常发生 消息确认包丢失的问题,所以,这里加一个字段来表示到来的消息包是重复的。类型:boolean)
11、明文包体 bodyDecrypted (类型:byte[])
二、构造函数的构造
1、
/**
* 构造一个指定参数的包
*
* @param header
* 包头
* @param source
* 包源
* @param command
* 包命令
* @param sequence
* 包序号
* @param user
* QQ用户对象
*/
public Packet(byte header, char source, char command, char sequence, QQUser user) {
this.user = user;
this.source = source;
this.command = command;
this.sequence = sequence;
this.duplicated = false;
this.header = header;
}
2、
/**
* 从buf中构造一个OutPacket,用于调试。这个buf里面可能包含了抓包软件抓来的数据
*
* @param buf
* ByteBuffer
* @throws PacketParseException
* 解析出错
*/
protected Packet(ByteBuffer buf, QQUser user) throws PacketParseException {
this(buf, buf.limit() - buf.position(), user);
}
3、
/**
* 从buf中构造一个OutPacket,用于调试。这个buf里面可能包含了抓包软件抓来的数据
*
* @param buf
* ByteBuffer
* @param length
* 要解析的内容长度
* @throws PacketParseException
* 如果解析出错
*/
protected Packet(ByteBuffer buf, int length, QQUser user) throws PacketParseException {
this.user = user;
// 解析头部
parseHeader(buf);
// 检查QQ号
if(!validateHeader())
throw new PacketParseException("包头有误,抛弃该包: " + toString());
// 得到包体
byte[] body = getBodyBytes(buf, length);
bodyDecrypted = decryptBody(body, 0, body.length);
if(bodyDecrypted == null)
throw new PacketParseException("包内容解析出错,抛弃该包: " + toString());
// 包装到ByteBuffer
ByteBuffer tempBuf = ByteBuffer.wrap(bodyDecrypted);
try {
// 解析
parseBody(tempBuf);
} catch (BufferUnderflowException e) {
throw new PacketParseException(e.getMessage());
}
parseTail(buf);
// 查看是否打开了调试模式,如果有,则触发调试事件
if(ds.isDebug()) {
byte[] debugContent = dump();
IDebugObject obj = new PacketDO(getPacketName(), debugContent, this instanceof InPacket, getHeadLength(), debugContent.length - getTailLength());
ds.deliverDebugObject(obj);
}
}
4、
/**
* 构造一个包对象,什么字段也不填,仅限于子类使用
*/
protected Packet() {
}