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

📄 receiveimpacket.java

📁 MilyQQ是一个使用控制台的QQ客户端,基于LumaQQ的核心JQL包开发,只有一个可执行的jar包(MilyQQ.jar),携带方便,由于是Java程序,因此理论上应该可以运行于所有平台,不过基于
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
 * 如果是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 + -