receiveimpacket.java

来自「java写的qq代码实现qq的部分功能」· Java 代码 · 共 415 行 · 第 1/2 页

JAVA
415
字号
    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 SMS sms;
    
    // 仅用于其他类型群消息
    public int externalId;
    public byte clusterType;
    public int sender;
    public String message;
    
    /**
     * 构造函数
     * @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()
     */
    public String getPacketName() {
        return "Receive IM Packet";
    }

    /* (non-Javadoc)
     * @see edu.tsinghua.lumaqq.qq.packets.InPacket#parseBody(java.nio.ByteBuffer)
     */
    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;
        }
	    // 判断消息类型
        switch(header.type) {
		    case QQ.QQ_RECV_IM_FROM_FRIEND:
		    case QQ.QQ_RECV_IM_FROM_STRANGER:
		        /* 是从好友或者陌生人处发来的消息 */			        
		        parseNormalIM(buf);
		    	break;
		    case QQ.QQ_RECV_IM_SYS_MESSAGE:
		        /* 是系统消息 */
		        parseSystemMessage(buf);
		    	break;
		    case QQ.QQ_RECV_IM_CLUSTER_IM:
		    	/* 群消息 */
		        parseClusterIM(buf);
		    	break;
		    case QQ.QQ_RECV_IM_TEMP_CLUSTER_IM:
		        /* 临时群消息 */
		        parseTempClusterIM(buf);
		    	break;
		    case QQ.QQ_RECV_IM_UNKNOWN_CLUSTER_IM:
		        parseUnknownClusterIM(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();
		    	int len = buf.get() & 0xFF;
		    	byte[] b = new byte[len];
		    	buf.get(b);
		    	message = Util.getString(b);
		    	break;
		    case QQ.QQ_RECV_IM_SMS:		        
		        processSMS(buf);
		    	break;
		    case QQ.QQ_RECV_IM_MOBILE_QQ:
		        processMobileQQ(buf);
		    	break;
		    default:
		        // 其他类型的消息我们现在没有办法处理,忽略
		        break;     
        }
    }

	/**
     * @param buf
     */
    private void parseUnknownClusterIM(ByteBuffer buf) {
		clusterIM = new ClusterIM(QQ.QQ_RECV_IM_UNKNOWN_CLUSTER_IM);
		clusterIM.readBean(buf);
    }

    /**
	 * 解析临时组消息
	 * 
     * @param buf
     */
    private void parseTempClusterIM(ByteBuffer buf) {
		clusterIM = new ClusterIM(QQ.QQ_RECV_IM_TEMP_CLUSTER_IM);
		clusterIM.readBean(buf);
    }    

    /**
	 * 解析群普通消息
	 */
	private void parseClusterIM(ByteBuffer buf) {
		clusterIM = new ClusterIM(QQ.QQ_RECV_IM_CLUSTER_IM);
		clusterIM.readBean(buf);
	}

    /**
	 * 解析手机短消息,来自移动QQ用户
     * @param buf
     */
    private void processMobileQQ(ByteBuffer buf) {
        sms = new SMS();
        sms.readMobileQQSMS(buf);
    }

    /**
	 * 解析手机短消息,来自普通手机绑定用户
	 * 
     * @param buf
     */
    private void processSMS(ByteBuffer buf) {
        sms = new SMS();
        sms.readBindUserSMS(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_NORMAL_TEXT) {
                normalIM = new NormalIM();
                normalIM.readBean(buf);			            
            } else if(normalHeader.type == QQ.QQ_IM_UDP_REQUEST 
            		|| normalHeader.type == QQ.QQ_IM_TCP_REQUEST){
            	fileArgs = new FileTransferArgs();
            	fileArgs.readBean(buf);
            	fileInfo = new FileInfo();
            	fileInfo.readBean(buf);
            } else if(normalHeader.type == QQ.QQ_IM_ACCEPT_UDP_REQUEST
            		|| normalHeader.type == QQ.QQ_IM_NOTIFY_IP) {
            	fileArgs = new FileTransferArgs();
            	fileArgs.readBean(buf);
            } 
            log.debug("收到的普通消息类型为:" + Util.getNormalIMTypeString(normalHeader.type));
        } catch (Exception e) {
            throw new PacketParseException(e.getMessage());
        }
	}
}

⌨️ 快捷键说明

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