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

📄 qqclient.java

📁 java写的qq代码实现qq的部分功能
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        	logout();
        	// 起动事件触发线程
        	listenerThread = new ListenerThread(this);
        	listenerThread.start();
        	// 启动重发线程
        	resender = new Resender(this);
        	resender.start();
        	// 创建Selector
    	    porter = new Porter();
    	    // 创建端口管理器
    	    gate = new PortGate(porter);
        	// 设置状态为正在登陆
        	logging = true;    
            // 检查是什么登陆模式,udp还是tcp
            try {
                IPort port = null;
	            if (user.isUdp()) {
	                log.debug("使用UDP服务器: " + loginServer + " 端口:" + loginPort);          
	                // 创建端口类
	                if(proxyType == QQ.PROXY_SOCKS5) {
	                    log.debug("使用Socks 5代理 " + proxyAddress);
		                port = installUDPSocks5Port(MAIN_PORT, proxyAddress, new InetSocketAddress(loginServer, loginPort), proxyUsername, proxyPassword, false);
	                } else
	                    port = installUDPPort(MAIN_PORT, new InetSocketAddress(loginServer, loginPort), false);
	            } else {
                    log.debug("使用TCP服务器: " + loginServer + " 端口: " + loginPort);             
                    // 创建发送类和接收类
                    if(proxyType == QQ.PROXY_SOCKS5) {
                        log.debug("使用Socks 5代理 " + proxyAddress);
                        port = installTCPSocks5Port(MAIN_PORT, proxyAddress, new InetSocketAddress(loginServer, loginPort), proxyUsername, proxyPassword, false);
                    } else if(proxyType == QQ.PROXY_HTTP) {
                        log.debug("使用HTTP代理 " + proxyAddress);
                        port = installTCPHttpPort(MAIN_PORT, proxyAddress, new InetSocketAddress(loginServer, loginPort), proxyUsername, proxyPassword, false);
                    } else
                        port = installTCPPort(MAIN_PORT, new InetSocketAddress(loginServer, loginPort), false);
                } 
                
                // 如果登录令牌还是空,就构造请求登录令牌包,如果不是,直接登录
                OutPacket packet = null;
                if(user.getLoginToken() == null)
                    packet = new RequestLoginTokenPacket(user);
                else
                    packet = new LoginPacket(user);
                // 启动端口
            	porter.start();
            	port.start();
                // 发送请求包                
                gate.send(MAIN_PORT, packet, false);
            } catch (UnknownHostException e) {
                throw new Exception("服务器名称无法解析");
            } catch (UnresolvedAddressException e) {
			    throw new Exception("无法解析服务器地址");
			} catch (Exception e) {
			    throw e;
			}
        }
    }
    
    /**
     * 退出QQ会话
     */
    public void logout() {
        // 得到当前登录状态
        boolean isLoggedIn = user.isLoggedIn();
	    // 设置用户状态
    	if(!loginRedirect)
	    	user.setLoginToken(null);    
    	user.setLoggedIn(false);    	
    	// 设置正在登录标志为false
    	logging = false;
    	loginRedirect = false;
    	
    	if(gate != null) {
	    	if(gate.hasPort(MAIN_PORT)) {
		    	// 清空发送队列
		    	gate.clearSendQueue(MAIN_PORT);
		    	// 如果已经登录了,则发送logout包
		    	if(isLoggedIn) {
			    	LogoutPacket packet = new LogoutPacket(user);
		    		gate.send(MAIN_PORT, packet, false);	    		
		    	}
	    	}
	    	// 清空包监视缓冲
            gate.clearMonitorCache();
    	}
    	// 执行清理工作
    	if(listenerThread != null) {
	    	listenerThread.setStop(true);
	    	listenerThread = null;
    	}
    	if(resender != null) {
    	    resender.setStop(true);
    	    resender = null;
    	}
    	clean(kaThread, gate, porter);
    	gate = null;
    	porter = null;
    	kaThread = null;    	
    }

    /**
     * 处理Keep Alive成功信息,对Keep Alive Success,QQClient不作什么
     * 进一步的分析,只是顺便刷新一下好友状态
     * 
     * @param e
     */
    private void processKeepAliveSuccess(QQEvent e) {
        GetFriendOnlinePacket packet = new GetFriendOnlinePacket(user);
        sendPacket(packet);
    }

	/**
	 * 处理登陆成功事件
	 */
	private void processLoginSuccess() {
	    if(!user.isLoggedIn()) {
			user.setLoggedIn(true);
			this.logging = false;
			// 启动Keep Alive线程
			kaThread = new KeepAliveThread(this);
			kaThread.start();
			log.debug("Keep Alive线程已经启动");
			// 请求密钥
			requestKey(QQ.QQ_REQUEST_UNKNOWN_KEY);
			requestKey(QQ.QQ_REQUEST_FILE_AGENT_KEY);
			// 得到我的信息
			GetUserInfoPacket guiPacket = new GetUserInfoPacket(user);
	        sendPacket(guiPacket);
			// 手动更改我的在线状态,虽然服务器可能也会给我发送这样的信息
			ChangeStatusPacket csPacket = new ChangeStatusPacket(user);
			csPacket.setShowFakeCam(user.isShowFakeCam());
	        sendPacket(csPacket);	        
	    }
	}

    /**
     * 处理普通消息事件,只是发一个确认而已
     * 
     * @param e
     */
    private void processReceiveIM(QQEvent e) {
        // 得到包
        ReceiveIMPacket packet = (ReceiveIMPacket)e.getSource();
        
        // 生成确认包
        ReceiveIMReplyPacket reply = new ReceiveIMReplyPacket(packet.reply, user);
        reply.setSequence(packet.getSequence());
		gate.send(MAIN_PORT, reply, false);	
    }

	/* (non-Javadoc)
	 * @see edu.tsinghua.lumaqq.QQListener#qqEvent(edu.tsinghua.lumaqq.QQEvent)
	 */
	public void qqEvent(QQEvent e) {
		switch(e.type) {
		    case QQEvent.QQ_GET_LOGIN_TOKEN_SUCCESS:
		        processGetLoginTokenSuccess();
		    	break;
		    case QQEvent.QQ_GET_LOGIN_TOKEN_FAIL:
		        //processGetLoginTokenFail();
		    	break;
			case QQEvent.QQ_LOGIN_SUCCESS:
				processLoginSuccess();
				break;
			case QQEvent.QQ_KEEP_ALIVE_SUCCESS:
			    processKeepAliveSuccess(e);
				break;
			case QQEvent.QQ_RECEIVE_NORMAL_IM:
				processNormalIM(e);
				break;
			case QQEvent.QQ_KICKED_OUT_BY_SYSTEM:
			case QQEvent.QQ_RECEIVE_CLUSTER_IM:		
			case QQEvent.QQ_RECEIVE_TEMP_CLUSTER_IM:
			case QQEvent.QQ_RECEIVE_UNKNOWN_CLUSTER_IM:
			case QQEvent.QQ_REQUEST_SEND_FILE:
			case QQEvent.QQ_ACCEPT_SEND_FILE:
			case QQEvent.QQ_REJECT_SEND_FILE:
			case QQEvent.QQ_CANCEL_SEND_FILE:
			case QQEvent.QQ_NOTIFY_FILE_TRANSFER_ARGS:
			case QQEvent.QQ_REQUEST_ME_CONNECT:
			case QQEvent.QQ_UNKNOWN_TYPE_IM:
			case QQEvent.QQ_REQUEST_JOIN_CLUSTER:
			case QQEvent.QQ_REQUEST_JOIN_CLUSTER_APPROVED:
			case QQEvent.QQ_REQUEST_JOIN_CLUSTER_REJECTED:
			case QQEvent.QQ_I_AM_ADDED_TO_CLUSTER:
			case QQEvent.QQ_I_AM_REMOVED_FROM_CLUSTER:
			case QQEvent.QQ_RECEIVE_SMS:
			case QQEvent.QQ_RECEIVE_DUPLICATED_IM:
			    processReceiveIM(e);
				break;
			case QQEvent.QQ_OPERATION_TIMEOUT:
			    switch(e.operation) {
			        case QQ.QQ_CMD_LOGIN:
			        case QQ.QQ_CMD_REQUEST_LOGIN_TOKEN:
						processLoginTimeout();
			        	break;
			    }				
				break;
			case QQEvent.QQ_CONNECTION_LOST:
				processConnectionLost();
				break;
		}
	}

    /**
	 * 处理请求登录令牌成功事件
     */
    private void processGetLoginTokenSuccess() {
        LoginPacket packet = new LoginPacket(user);
		gate.send(MAIN_PORT, packet, false);	
    }

    /**
	 * 处理普通消息事件,核心层的处理是检查机器人设置,如果机器人打开了,则自动返回消息
	 * 
	 * @param e
	 * 		QQEvent
	 */
	private void processNormalIM(QQEvent e) {
		// 先返回确认
		processReceiveIM(e);
		
		// 得到消息包
		ReceiveIMPacket packet = (ReceiveIMPacket)e.getSource();
		doRobot(packet.header.sender, packet.normalIM.message, packet.normalIM.replyType == QQ.QQ_IM_AUTO_REPLY, packet.header.sender);
	}
	
	/**
	 * 检查机器人设置,如果机器人打开了,发送一条机器人消息
	 * 
	 * @param sender
	 * 		发送者QQ号
	 * @param message
	 * 		到达消息
	 * @param autoReply
	 * 		true表示是自动回复
	 * @param receiver
	 * 		接收者
	 */
	private void doRobot(int sender, String message, boolean autoReply, int receiver) {
		// 检查机器人设置
		if(isRobotMode()) {
			IRobot robot = getCurrentRobot();
			if(robot != null) {
			    String reply = robot.getReply(sender, message, autoReply);
			    if(reply != null)
			        sendIM(receiver, reply);
			}
		}
	}

	/**
	 * 处理连接丢失事件
	 */
	private void processConnectionLost() {
		user.setLoggedIn(false);
		logout();
	}

	/**
	 * 处理登陆超时事件
	 */
	private void processLoginTimeout() {
		logging = false;
		logout();
	} 
    
    /**
     * 发送一个消息,用给定的字体
     * @param receiver 接受者QQ号
     * @param message 消息
     * @param fontName 字体
     */
    public void sendIM(int receiver, String message) {
        this.sendIM(receiver, message, QQ.QQ_IM_NORMAL_REPLY);
    }
    
    /**
     * 发送一条消息,可以指定回复类型
     * @param receiver 接收者QQ号
     * @param message 消息
     * @param fontName 字体名
     * @param replyType 回复方式,正常回复还是自动回复
     */
    public void sendIM(int receiver, String message, byte replyType) {
        this.sendIM(receiver, message, "宋体", false, false, false, 9, 0, 0, 0, replyType);
    }
    
    /**
     * 发送一个消息,指定字体和字体颜色
     * 
     * @param receiver 接受者QQ号
     * @param message 消息
     * @param fontName 字体
     * @param bold 是否粗体
     * @param italic 是否斜体
     * @param underline 是否下划线
     * @param size 字体大小,最大是31
     * @param red 颜色Red
     * @param green 颜色Green
     * @param blue 颜色Blue
     * @param replyType 回复类型,自动回复还是正常回复
     */
    public void sendIM(
            int receiver, 
            String message, 
            String fontName, 
            boolean bold, 
            boolean italic, 
            boolean underline, 
            int size, 
            int red,
            int green,
            int blue,
            byte replyType) {
        sendIM(
                receiver, 
                message,
                (char)0,
                1,
                0,
                fontName,
                bold,
                italic,
                underline,
                size,
                red,
                green,
                blue,
                replyType);    	
    }
    
    /**
     * 发送普通消息
     * 
     * @param receiver
     * @param message
     * @param messageId
     * @param totalFragments
     * @param fragementSequence
     * @param fontName
     * @param bold
     * @param italic
     * @param underline
     * @param size
     * @param red
     * @param green
     * @param blue
     * @param replyType
     */
    public void sendIM(
            int receiver, 
            String message, 
            char messageId,
            int totalFragments,
            int fragementSequence,
            String fontName, 
            boolean bold, 
            boolean italic, 
            boolean underline, 
            int size, 
            int red,
            int green,
            int blue,
            byte replyType) {
    	if(user.isLoggedIn()) {
	        if(message.length() > QQ.QQ_MSG_IM_MAX) return;
	        SendIMPacket packet = new SendIMPacket(user);
	        packet.setReceiver(receiver);
	        packet.setMessage(message);
	        packet.setTotalFragments(totalFragments);
	        packet.setFragmentSequence(fragementSequence);
	        packet.setMessageId(messageId);
	        packet.setFontName(fontName);
	        packet.setFontSize((byte)(size & 0xFF));
	        packet.setRed((byte)(red & 0xFF));
	        packet.setGreen((byte)(green & 0xFF));
	        packet.setBlue((byte)(blue & 0xFF));
	        packet.setBold(bold);
	        packet.setItalic(italic);
	        packet.setUnderline(underline);
	        packet.setReplyType(replyType);
    		gate.send(MAIN_PORT, packet, true);	
    	}
    }
    
    /**
     * @param loginServer
     *            登陆服务器IP
     */
    public void setLoginServer(String loginServer) {
        this.loginServer = loginServer;
    }
    
    /**
     * @param user The user to set.
     */
    public void setUser(QQUser user) {
        this.user = user;
    }
    
	/**
	 * @return Returns the logging.
	 */
	public boolean isLogging() {
		return logging;
	}

⌨️ 快捷键说明

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