📄 receiveimpacket.java
字号:
* 如果是0x0041,可能是向服务器报告最后连接情况的包,格式为
* 1 - 27. 和0x003B时相同,差别只有命令不同,为0x0041
*
* 如果是取消传送文件请求,格式为:
* 1 - 18. 与普通消息格式相同,差别只有12部分,为0x0049,表示是取消传送文件
* 19. 未用部分,全0,15字节
* 20. 固定字节0x65
* 21. 尾部
* </pre>
*
* @see edu.tsinghua.lumaqq.qq.beans.NormalIM
* @see edu.tsinghua.lumaqq.qq.beans.NormalIMHeader
* @see edu.tsinghua.lumaqq.qq.beans.ReceiveIMHeader
* @see edu.tsinghua.lumaqq.qq.beans.ClusterIM
* @see edu.tsinghua.lumaqq.qq.beans.FileTransferArgs
* @see edu.tsinghua.lumaqq.qq.beans.FileInfo
* @see edu.tsinghua.lumaqq.qq.beans.TempSessionIM
* @see edu.tsinghua.lumaqq.qq.beans.SMS
*
* @author luma
*/
public class ReceiveIMPacket extends BasicInPacket {
// 用于发送确认
public byte[] reply;
// 为true时表示收到的消息是空的
public boolean empty;
// 整个包的头
public ReceiveIMHeader header;
// 仅用于普通消息时
public NormalIMHeader normalHeader;
public NormalIM normalIM;
// 仅用于系统通知时
public byte systemMessageType;
public String sysMessage;
// 仅用于文件传输时
public FileInfo fileInfo;
public FileTransferArgs fileArgs;
public byte transferType;
// 仅用于群普通消息时
public ClusterIM clusterIM;
// 仅用于其他类型群消息
public int externalId;
public byte clusterType;
public int sender;
public String message;
// 用于群通知时
public byte role;
public byte opCode;
public int memberQQ;
// 用户个性签名通知
public int signatureOwner;
public int modifiedTime;
public String signature;
// 用于手机短信消息
public SMS sms;
// 临时会话消息
public TempSessionIM tempSessionIM;
/**
* 构造函数
* @param buf 缓冲区
* @param length 包长度
* @throws PacketParseException 解析错误
*/
public ReceiveIMPacket(ByteBuffer buf, int length, QQUser user) throws PacketParseException {
super(buf, length, user);
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.qq.packets.InPacket#getPacketName()
*/
@Override
public String getPacketName() {
return "Receive IM Packet";
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.qq.packets.InPacket#parseBody(java.nio.ByteBuffer)
*/
@Override
protected void parseBody(ByteBuffer buf) throws PacketParseException {
empty = false;
// 检查消息长度,至少要有16字节,因为我们需要前16字节做为确认发回
if(buf.remaining() < 16)
throw new PacketParseException("收到的消息太短,抛弃该消息");
// 得到前16个字节用作回复
reply = new byte[16];
buf.get(reply);
// 读取消息头
buf.rewind();
header = new ReceiveIMHeader();
header.readBean(buf);
// 检查输入流可用字节
if(!buf.hasRemaining()) {
empty = true;
return;
}
// 判断消息类型
int len = 0;
switch(header.type) {
case QQ.QQ_RECV_IM_FRIEND:
case QQ.QQ_RECV_IM_STRANGER:
/* 是从好友或者陌生人处发来的消息 */
parseNormalIM(buf);
break;
case QQ.QQ_RECV_IM_TEMP_SESSION:
tempSessionIM = new TempSessionIM();
tempSessionIM.readBean(buf);
break;
case QQ.QQ_RECV_IM_SYS_MESSAGE:
/* 是系统消息 */
parseSystemMessage(buf);
break;
case QQ.QQ_RECV_IM_CLUSTER:
/* 群消息 */
parseClusterIM(buf);
break;
case QQ.QQ_RECV_IM_TEMP_CLUSTER:
/* 临时群消息 */
parseTempClusterIM(buf);
break;
case QQ.QQ_RECV_IM_UNKNOWN_CLUSTER:
parseUnknownClusterIM(buf);
break;
case QQ.QQ_RECV_IM_BIND_USER:
sms = new SMS();
sms.readBindUserSMS(buf);
break;
case QQ.QQ_RECV_IM_MOBILE_QQ:
sms = new SMS();
sms.readMobileQQSMS(buf);
break;
case QQ.QQ_RECV_IM_MOBILE_QQ_2:
sms = new SMS();
sms.readMobileQQ2SMS(buf);
break;
case QQ.QQ_RECV_IM_MOBILE:
sms = new SMS();
sms.readMobileSMS(buf);
break;
case QQ.QQ_RECV_IM_CREATE_CLUSTER:
case QQ.QQ_RECV_IM_ADDED_TO_CLUSTER:
case QQ.QQ_RECV_IM_DELETED_FROM_CLUSTER:
externalId = buf.getInt();
clusterType = buf.get();
sender = buf.getInt();
break;
case QQ.QQ_RECV_IM_APPROVE_JOIN_CLUSTER:
case QQ.QQ_RECV_IM_REJECT_JOIN_CLUSTER:
case QQ.QQ_RECV_IM_REQUEST_JOIN_CLUSTER:
externalId = buf.getInt();
clusterType = buf.get();
sender = buf.getInt();
len = buf.get() & 0xFF;
byte[] b = new byte[len];
buf.get(b);
message = Util.getString(b);
break;
case QQ.QQ_RECV_IM_CLUSTER_NOTIFICATION:
externalId = buf.getInt();
clusterType = buf.get();
opCode = buf.get();
memberQQ = buf.getInt();
role = buf.get();
sender = externalId;
break;
case QQ.QQ_RECV_IM_SIGNATURE:
signatureOwner = buf.getInt();
modifiedTime = buf.getInt();
len = buf.get() & 0xFF;
signature = Util.getString(buf, len);
break;
default:
// 其他类型的消息我们现在没有办法处理,忽略
break;
}
}
/**
* @param buf
*/
private void parseUnknownClusterIM(ByteBuffer buf) {
clusterIM = new ClusterIM(QQ.QQ_RECV_IM_UNKNOWN_CLUSTER);
clusterIM.readBean(buf);
}
/**
* 解析临时组消息
*
* @param buf
*/
private void parseTempClusterIM(ByteBuffer buf) {
clusterIM = new ClusterIM(QQ.QQ_RECV_IM_TEMP_CLUSTER);
clusterIM.readBean(buf);
}
/**
* 解析群普通消息
*/
private void parseClusterIM(ByteBuffer buf) {
clusterIM = new ClusterIM(QQ.QQ_RECV_IM_CLUSTER);
clusterIM.readBean(buf);
}
/**
* 解析系统消息
*/
private void parseSystemMessage(ByteBuffer buf) {
// 系统消息类型
systemMessageType = buf.get();
// 系统消息长度
int len = buf.get() & 0xFF;
// 系统消息
sysMessage = Util.getString(buf, len);
}
/**
* 解析普通消息
*/
private void parseNormalIM(ByteBuffer buf) throws PacketParseException {
try {
// 读入普通消息头
normalHeader = new NormalIMHeader();
normalHeader.readBean(buf);
// 判断普通消息类型
if(normalHeader.type == QQ.QQ_IM_TYPE_TEXT) {
normalIM = new NormalIM();
normalIM.readBean(buf);
} else if(normalHeader.type == QQ.QQ_IM_TYPE_UDP_REQUEST
|| normalHeader.type == QQ.QQ_IM_TYPE_TCP_REQUEST){
fileArgs = new FileTransferArgs();
fileArgs.readBean(buf);
fileInfo = new FileInfo();
fileInfo.readBean(buf);
} else if(normalHeader.type == QQ.QQ_IM_TYPE_ACCEPT_UDP_REQUEST
|| normalHeader.type == QQ.QQ_IM_TYPE_NOTIFY_IP) {
fileArgs = new FileTransferArgs();
fileArgs.readBean(buf);
}
//log.debug("收到的普通消息类型为:" + Util.getNormalIMTypeString(normalHeader.type));
} catch (Exception e) {
throw new PacketParseException(e.getMessage());
}
}
/**
* @return
* 消息种类
*/
public int getMessageCategory() {
switch(header.type) {
case QQ.QQ_RECV_IM_SYS_MESSAGE:
return QQ.QQ_IM_FROM_SYS;
case QQ.QQ_RECV_IM_FRIEND:
case QQ.QQ_RECV_IM_STRANGER:
return QQ.QQ_IM_FROM_USER;
case QQ.QQ_RECV_IM_TEMP_SESSION:
return QQ.QQ_IM_FROM_TEMP_SESSION;
case QQ.QQ_RECV_IM_CLUSTER:
case QQ.QQ_RECV_IM_TEMP_CLUSTER:
case QQ.QQ_RECV_IM_UNKNOWN_CLUSTER:
return QQ.QQ_IM_FROM_CLUSTER;
case QQ.QQ_RECV_IM_BIND_USER:
case QQ.QQ_RECV_IM_MOBILE_QQ:
case QQ.QQ_RECV_IM_MOBILE_QQ_2:
case QQ.QQ_RECV_IM_MOBILE:
return QQ.QQ_IM_FROM_SMS;
default:
return QQ.QQ_IM_FROM_SYS;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -