⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 receiveimpacket.java

📁 java写的qq代码实现qq的部分功能
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
* LumaQQ - Java QQ Client
*
* Copyright (C) 2004 luma <stubma@163.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package edu.tsinghua.lumaqq.qq.packets.in;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.nio.ByteBuffer;

import edu.tsinghua.lumaqq.qq.PacketParseException;
import edu.tsinghua.lumaqq.qq.QQ;
import edu.tsinghua.lumaqq.qq.Util;
import edu.tsinghua.lumaqq.qq.beans.ClusterIM;
import edu.tsinghua.lumaqq.qq.beans.FileInfo;
import edu.tsinghua.lumaqq.qq.beans.FileTransferArgs;
import edu.tsinghua.lumaqq.qq.beans.NormalIM;
import edu.tsinghua.lumaqq.qq.beans.NormalIMHeader;
import edu.tsinghua.lumaqq.qq.beans.QQUser;
import edu.tsinghua.lumaqq.qq.beans.ReceiveIMHeader;
import edu.tsinghua.lumaqq.qq.beans.SMS;
import edu.tsinghua.lumaqq.qq.packets.BasicInPacket;


/**
 * <pre>
 * 别人发来的消息包,如果是普通消息,格式为
 * 1. 头部
 * 2. 发送者QQ号,4字节
 * 3. 接收者QQ号,4字节
 * 4. 包序号(并非我们发送时候的序号,因为这个是4字节,可能是服务器端得总序号)
 * 5. 发送者IP,如果是服务器转发的,那么ip就是服务器ip, 4字节
 * 6. 发送者端口,如果是服务器转发的,那么就是服务器的端口,2字节
 * 7. 消息类型,是好友发的,还是陌生人发的,还是系统消息等等, 2字节
 * 8. 发送者QQ版本,2字节
 * 9. 发送者的QQ号,4字节
 * 10. 接受者的QQ号,4字节
 * 11. md5处理的发送方的uid和session key,16字节
 * 12. 普通消息类型,比如是文本消息还是其他什么消息,2字节
 * 13. 会话ID,2字节,如果是一个操作需要发送多个包才能完成,则这个id必须一致
 * 14. 发送时间,4字节
 * 15. 1字节未知
 * 16. 发送者头像,1字节
 * 17. 是否有字体属性,4字节,有一般是0x00000001
 * 18. 消息的分片数,1字节
 * 19. 分片序号,1字节,从0开始
 * 20. 消息id,2字节,同一条消息的不同分片id相同
 * 21. 消息类型,这里的类型表示是正常回复还是自动回复之类的信息, 1字节
 * 22. 消息正文,0是分隔符
 * 23. 字体属性,和SendIMPacket中的相同
 * 24. 尾部
 * 
 * 如果是系统消息:
 * 1-7. 与普通消息相同,只不过7是0x0030,表示是系统消息
 * 8. 系统消息类型,1字节
 * 9. 系统消息长度,1字节
 * 10. 系统消息
 * 
 * 如果是来自绑定手机的手机短消息,格式为:
 * 1-7. 与普通消息相同,只不过7是0x000B,表示手机短消息
 * 8.   未知1字节,0x0
 * 9.   发送者QQ号,4字节
 * 10.  未知1字节,0x0
 * 11.  未知1字节
 * 12.  发送者名称,最多13字节,不足后面补0
 * 13.  未知的1字节,0x4D
 * 14.  消息内容,一直到结尾都是,这个包长度200字节,如果不足,后面补0
 * 15.  尾部
 * 
 * 如果是来自移动QQ用户的手机短消息,格式为:
 * 1 - 13. 与绑定手机短信相同,只不过7为0x0013
 * 14. 短信发送时间
 * 15. 未知1字节,0x03
 * 16. 短信内容,0结尾,最大160字节
 * 17. 尾部
 * 
 * 如果是请求传送文件,格式为
 * 1 - 18. 与普通消息格式相同,差别只有12部分,为0x0035,表示是请求传送文件
 * 19.     未用部分,全0,15字节
 * 20.     传输类型,1字节
 * 21.     连接方式,1字节
 * 22.     请求者外部ip,4字节
 * 23.     请求者QQ端口,2字节,如果连接方式为0x3,则这个部分没有
 * 24.     第一个监听端口,2字节
 * 25.     请求者真实ip,4字节
 * 26.     第二个监听端口,2字节
 * 27.     空格符0x20
 * 28.     分隔符0x1F
 * 29.     文件名,不定长,不包含路径名
 * 30.     分隔符0x1F
 * 31.     文件字节数的字符串形式加“ 字节”
 * 32.     尾部
 * 
 * 如果是接受传送文件的请求,格式为
 * 1 - 18. 与普通消息格式相同,差别只有12部分,对于UDP请求,为0x0037
 * 19 - 26 和0x0035时相同
 * 27.     尾部 
 * 
 * 如果是通知文件传送的端口,格式为
 * 1 - 18. 与普通消息格式相同,差别只有12部分,为0x003B,表示是通知文件传送端口
 * 19 - 26 和0x0035时相同
 * 27. 尾部
 *
 * 未知类型的群消息
 * 1-7. 与普通消息相同,只不过发送者QQ号相当于是群的内部ID,7部分为0x0020
 * 8.   群外部ID,4字节
 * 9.   群类型,1字节
 * 10.  发送者QQ号,4字节
 * 11.  未知的两字节,全0
 * 12.  消息序号,2字节
 * 13.  消息发送时间,4字节
 * 14.  未知的4字节
 * 15.  后面的数据的长度,2字节
 * 16.  以0结尾的消息内容
 * 17.  字体属性,和SendIMPacket中的相同
 * 18.  尾部
 *  
 * 如果是讨论组或者多人对话消息,讨论组和多人对话属于临时群,格式为
 * 1 - 7 部分与普通消息相同,只不过7部分是0x002A
 * 8.   父群内部ID,4字节
 * 9.   群类型,1字节
 * 10.  讨论组内部ID,4字节
 * 11.  发送者QQ号,4字节
 * 12.  未知的两字节,全0
 * 13.  消息序号,2字节
 * 14.  消息发送时间,4字节
 * 15.  Version ID, 4字节,所谓version id,是我这里根据这个字段的意思乱编的。
 *      其作用主要是标识群信息的版本,比如一开始,群内有两个人,这个时候版本是0,然后我删
 *      除一个人,那么群的版本就要加1,于是就变成了1。然后我又加了2个人,于是版本再加1变成3,
 *      假如我再删一个人又加一个人,那么版本就要加2变成5了。为什么要加2呢,因为我做了两次操作,
 *      一次删,一次加,所以版本号加了2,你可能奇怪:为什么我不一次搞定,然后版本加1啊?因为
 *      QQ的协议就是这样,它的协议不能同时做删除和添加成员的操作,晕吧?所以我要做两次操作,
 *      也就是要发两个包才能又加人又删人,所以版本号加了2。那么这个字段有什么用呢?主要是用来
 *      通知客户端群内的成员变化了以便刷新,客户端对每一个群都要保存这么一个version ID,一旦
 *      收到的消息大于我本地的version id,说明群内成员变了,于是就发个包过去请求得到目前的
 *      成员列表。所以你会看到,QQ在发临时群消息的时候,成员如果变化了,会即时的反映出来,就是
 *      如此实现的了。这个id不光是在修改成员的时候才变,修改基本信息也照样变,用来表示这个群的
 *      信息修改过了。注意:这个version id是从0开始持续增长的,所以如果是固定群,这个version
 *      id,这个值可能会很大,因为它是固定的嘛,成员总是在变化,版本也就一直往上长了。
 * 16.  后面内容的长度
 * 17.  Content Type, 2字节,0x0001表示纯文件,0x0002表示有自定义表情
 * 18.  消息的分片数,1字节
 * 19.  分片序号,1字节,从0开始
 * 20.  消息id,2字节,同一条消息的不同分片id相同
 * 21.  4字节,未知
 * 22.  以0结尾的消息内容
 * 23.  字体属性,和SendIMPacket中的相同
 * 24.  尾部
 * 
 * 如果是示范群或会员创建的群发来的消息,这些群都是固定群,格式为
 * 1 - 7 部分与普通消息相同,只不过7部分是0x002B
 * 8.   群外部ID,4字节
 * 9.   群类型,1字节
 * 10.  发送者QQ号,4字节
 * 11.  未知的两字节
 * 12.  消息序号,2字节
 * 13.  消息发送时间,4字节
 * 14.  Version ID, 4字节
 * 15.  后面内容的长度
 * 16.  Content Type, 2字节,0x0001表示纯文件,0x0002表示有自定义表情
 * 17.  消息的分片数,1字节
 * 18.  分片序号,1字节,从0开始
 * 19.  消息id,2字节,同一条消息的不同分片id相同
 * 20.  4字节,未知
 * 21.  以0结尾的消息内容
 * 22.  字体属性,和SendIMPacket中的相同
 * 23.  尾部
 * 
 * 如果是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
 * 
 * @author 马若劼
 */
public class ReceiveIMPacket extends BasicInPacket {
	// 流对象
	private ByteArrayInputStream bais;
	private DataInputStream dis;
	
	// 用于发送确认

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -