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

📄 fileagentpacket.java

📁 LUMAQQ源代码 JAVA 地球人都知道
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
     * @param in
     * @throws PacketParseException
     */
    private void parseForward(ByteBuffer in) throws PacketParseException {
        // 会话ID
        sessionId = (char)in.getInt();
        // 未知的4字节
        in.getInt();
        // 被转发的包长度
        in.getChar();
        // 被转发的包
        fdp.parse(in);
    }

    /**
     * 从in的当前位置开始解析请求中转回复包包体
     * @param in ByteBuffer对象
     * @throws PacketParseException
     */
    private void parseRequestAgent(ByteBuffer in) throws PacketParseException {
        // 应答码
        replyCode = in.getChar();
        if(replyCode == QQ.QQ_FILE_AGENT_SERVICE_APPROVED) {
            // 得到中转服务器ip和端口
            agentIp = new byte[4];
            agentIp[3] = in.get();
            agentIp[2] = in.get();
            agentIp[1] = in.get();
            agentIp[0] = in.get();
            agentPort = in.getChar();
            // 文件会话id
            sessionId = (char)in.getInt();
        } else if(replyCode == QQ.QQ_FILE_AGENT_SERVICE_REDIRECTED) {
            in.position(in.position() + 10);
            // 得到重定向服务器ip和端口
            agentIp = new byte[4];
            agentIp[3] = in.get();
            agentIp[2] = in.get();
            agentIp[1] = in.get();
            agentIp[0] = in.get();
            agentPort = in.getChar();
        } else
            throw new PacketParseException("请求中转回复包的应答类型不支持");
    }

    /**
     * 从in的当前位置开始解析头部
     * @param in
     * @throws PacketParseException
     */
    private void parseHead(ByteBuffer in) throws PacketParseException {
        // 检查包头标志
        if(in.get() != QQ.QQ_HEADER_04_FAMILY)
            throw new PacketParseException("错误的中转包头");
        // 跳过source
        in.getChar();
        // 得到包长,检查包长是否正确(通过检查最后一个字节是不是0x3)
        int len = in.getChar();
        if(in.get(in.position() + len - 4) != QQ.QQ_TAIL_BASIC_FAMILY)
            throw new PacketParseException("中转包长度有误");
        // 命令
        command = in.getChar();
        // 序号
        sequence = in.getChar();
        // 检查QQ号字段
        if(in.getInt() != watcher.getMyQQ())
            throw new PacketParseException("不是给我的包,抛弃");
        // 未知的8字节
        in.getLong();
    }

    /**
     * 从out的当前未知填充包尾
     * @param out
     */
    private void putTail(ByteBuffer out) {
        out.put(QQ.QQ_TAIL_BASIC_FAMILY);
    }

    /**
     * 从out的当前未知开始填充包体
     * @param out ByteBuffer对象
     */
    private void putBody(ByteBuffer out) {
        switch(command) {
        	case QQ.QQ_FILE_CMD_REQUEST_AGENT:
        	    /* 0x0001 */
        	    initRequestAgent(out);
        	    break;
        	case QQ.QQ_FILE_CMD_CHECK_IN:
        	    /* 0x0002 */
        	    initCheckIn(out);
        		break;
        	case QQ.QQ_FILE_CMD_FORWARD:
        	    /* 0x0003 */
        	    initForward(out);
        	    break;
        	case QQ.QQ_FILE_CMD_FORWARD_FINISHED:
        	    /* 0x0004 */
        	    initForwardFinished(out);
        	    break;
        	case QQ.QQ_FILE_CMD_IT_IS_TIME:
        	    /* 0x0005 */
        	    initItIsTime(out);
        	    break;
        	case QQ.QQ_FILE_CMD_I_AM_READY:
        	    /* 0x0006 */
        	    initIAmReady(out);
        	    break;
        	default:
        	    log.error("不支持的命令类型");
        	    break;
        }
    }

    /**
     * 从out当前位置开始填充报到包
     * @param out ByteBuffer对象
     */
    private void initCheckIn(ByteBuffer out) {
        out.putInt(watcher.getSessionSequence());
        
        buffer.clear();
        buffer.putChar((char)watcher.getFileAgentToken().length);
        buffer.put(watcher.getFileAgentToken());
        byte[] backArray = buffer.array();
        out.put(crypter.encrypt(backArray, 0, buffer.position(), watcher.getFileAgentKey()));
    }

    /**
     * 从out当前位置开始填充我准备好了的请求包
     * @param out ByteBuffer对象
     */
    private void initIAmReady(ByteBuffer out) {
        out.putInt(watcher.getSessionSequence());
        
        buffer.clear();
        buffer.putChar((char)0);
        byte[] backArray = buffer.array();
        out.put(crypter.encrypt(backArray, 0, buffer.position(), watcher.getFileAgentKey()));
    }

    /**
     * 从out当前位置开始填充准备传输回复包
     * @param out ByteBuffer对象
     */
    private void initItIsTime(ByteBuffer out) {
        out.putInt(watcher.getSessionSequence());
        
        buffer.clear();
        buffer.putInt(0);
        byte[] backArray = buffer.array();
        out.put(crypter.encrypt(backArray, 0, buffer.position(), watcher.getFileAgentKey()));
    }

    /**
     * 从out当前位置开始填充中转结束包的其余部分
     * @param out ByteBuffer对象
     */
    private void initForwardFinished(ByteBuffer out) {
        out.putInt(watcher.getSessionSequence());
        
        buffer.clear();
        buffer.putInt(watcher.getMyQQ())
        	.putChar((char)0);
        byte[] backArray = buffer.array();
        out.put(crypter.encrypt(backArray, 0, buffer.position(), watcher.getFileAgentKey()));
    }

    /**
     * 从out当前位置开始填充中转包的其余部分
     * @param out ByteBuffer对象
     */
    private void initForward(ByteBuffer out) {
        // TODO 未知的4字节先用0
        out.putInt(watcher.getSessionSequence())
        	.putInt(0)
        	.putChar((char)0); // 数据包长度,暂时设为0
        // 保存当前位置
        int pos = out.position();
        // 写入数据包
        fdp.fill(out, pos);
        // 修改数据包长度字段
        out.putChar(pos - 2, (char)(out.position() - pos));
    }

    /**
     * 从out当前位置开始填充请求中转包的其余部分
     * @param out ByteBuffer对象
     */
    private void initRequestAgent(ByteBuffer out) {
        out.putChar((char)watcher.getFileAgentToken().length)
        	.put(watcher.getFileAgentToken());
        
        buffer.clear();
        buffer.putChar((char)0x07D0)
        	.putInt(watcher.getHisQQ());
        byte[] backArray = buffer.array();
        out.put(crypter.encrypt(backArray, 0, buffer.position(), watcher.getFileAgentKey()));
    }

    /**
     * 从out的当前未知开始填充包头
     * @param out ByteBuffer对象
     */
    private void putHead(ByteBuffer out) {
        // TODO 暂时未知的8字节用0
        out.put(QQ.QQ_HEADER_04_FAMILY)
        	.putChar(QQ.QQ_CLIENT_VERSION)
        	.putChar((char)0)
        	.putChar(command)
        	.putChar(sequence)
        	.putInt(watcher.getMyQQ())
        	.putLong(0);
    }
    
    /**
     * @return Returns the command.
     */
    public char getCommand() {
        return command;
    }
    
    /**
     * @param command The command to set.
     */
    public void setCommand(char command) {
        this.command = command;
    }
    
    /**
     * @return Returns the sequence.
     */
    public char getSequence() {
        return sequence;
    }
    
    /**
     * @param sequence The sequence to set.
     */
    public void setSequence(char sequence) {
        this.sequence = sequence;
    }
    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object obj) {
        if(obj instanceof FileAgentPacket)       
            return ((FileAgentPacket)obj).hashCode() == hashCode();
        else
            return false;
    }
    
    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    public int hashCode() {
        return (sequence << 16) | command; 
    }
}

⌨️ 快捷键说明

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