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

📄 qqclient.java

📁 类似于MSN
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     */
    public String getLoginServer() {
        return loginServer;
    }
    
    /**
     * @return Returns the user.
     */
    public QQUser getUser() {
        return user;
    }
    
    /**
     * 在登陆之后,为sender和packet processor加上QQListener
     */
    private void initQQListeners() {
    	port.removeAllQQListener();
    	pp.removeAllQQListener();
    	int size = qqListeners.size();
    	for(int i = 0; i < size; i++) {
    	    port.addQQListener((QQListener)qqListeners.get(i));    		
    		pp.addQQListener((QQListener)qqListeners.get(i));    		
    	}
    	port.addQQListener(this);
    	pp.addQQListener(this);
    }

    /**
     * 登陆
     */
    /*
    public void login() {
        if (user != null && !logging) {
        	// 设置状态为正在登陆
        	logging = true;
	    	// 如果登陆服务器未设置,随机在列表中选择一个
        	if(loginServer == null) {
	        	if(user.isUdp())
	        		loginServer = QQ.udpServers[new Random().nextInt(QQ.udpServerAmount)];
	        	else 
	        		loginServer = QQ.tcpServers[new Random().nextInt(QQ.tcpServerAmout)];        		
        	}
        	
	        // 登陆
	        login(loginServer, QQ.QQ_UDP_PORT);
       } 
    }*/
    
    /**
     * 登陆
     * @throws Exception
     */
    public void login() throws Exception {
        if (user != null && !logging && loginServer != null) {   	
	        // 登陆
	        login(loginServer, user.isUdp()?QQ.QQ_UDP_PORT:QQ.QQ_TCP_PORT);
       } 
    }
    
    /**
     * @param loginServer 登陆服务器
     * @param loginPort 登陆端口
     * @throws Exception
     */
    protected void login(String loginServer, int loginPort) throws Exception {
        // 检查是否设置了用户名和密码
        if (user != null) {
        	// 停止以前的线程,如果有的话
        	logout();
        	// 设置状态为正在登陆
        	logging = true;    
            // 检查是什么登陆模式,udp还是tcp
            try {
	            if (user.isUdp()) {
	                log.debug("使用UDP服务器: " + loginServer);          
	                // 创建端口类
	                if(proxyType == QQ.PROXY_SOCKS5) {
	                    log.debug("使用Socks 5代理 " + proxyAddress);
		                port = new UDPSocks5Port(proxyAddress, new InetSocketAddress(loginServer, loginPort), proxyUsername, proxyPassword);
	                } else
	                    port = new UDPPort(new InetSocketAddress(loginServer, loginPort));
	            } else {
                    log.debug("使用TCP服务器: " + loginServer);             
                    // 创建发送类和接收类
                    if(proxyType == QQ.PROXY_SOCKS5) {
                        log.debug("使用Socks 5代理 " + proxyAddress);
                        port = new TCPSocks5Port(proxyAddress, new InetSocketAddress(loginServer, loginPort), proxyUsername, proxyPassword);
                    } else if(proxyType == QQ.PROXY_HTTP) {
                        log.debug("使用HTTP代理 " + proxyAddress);
                        port = new TCPHttpPort(proxyAddress, new InetSocketAddress(loginServer, QQ.QQ_HTTP_PORT), proxyUsername, proxyPassword);
                    } else
                        port = new TCPPort(new InetSocketAddress(loginServer, loginPort));
                } 
                // 添加包事件监听器
                port.addPacketListener(pp);
                // 初始化QQ事件监听器
                initQQListeners();
                // 构造登陆请求包
                LoginPacket packet = new LoginPacket();
                log.debug("登陆请求包已构造,序号为: " + (int)packet.getSequence());
                // 启动port
	            port.start();
                // 发送请求包
                port.add(packet);
            } catch (UnknownHostException e) {
                throw new Exception("服务器名称无法解析");
            } catch (SocketException e) {
                throw new Exception("无法连接上服务器");
            } catch (IOException e) {
                throw new Exception("无法连接上服务器");
			} catch (UnresolvedAddressException e) {
			    throw new Exception("无法解析服务器地址");
			} catch (Exception e) {
			    throw new Exception("未知错误");
			}
        }
    }
    
    /**
     * 退出QQ会话
     */
    public void logout() {
        // 情况包监视器缓冲
        monitor.clear();
	    // 设置用户状态
    	if(!loginRedirect && (logging || user.isLoggedIn()))
			user.setStatus(QQ.QQ_FRIEND_STATUS_OFFLINE);
    	user.setLoggedIn(false);    	    
    	// 设置正在登录标志为false
    	logging = false;
    	loginRedirect = false;
    	if(port != null) {
	    	// 情况发送队列
	    	port.clear();
	    	// 发送logout包
	    	LogoutPacket packet = new LogoutPacket();
    		port.send(packet); 		
    	} 
    	// 执行清理工作
    	clean(kaThread, port);
    	port = null;
    	kaThread = null;
    }
	
    // 处理得到好友列表结束事件
    private void processGetFriendListEnd(QQEvent e) {
        // 好友已经全部得到了,那么接着发送请求在线好友列表的包
        log.debug("好友全部得到,开始请求在线好友名单");
        getFriendOnline();
    }

    // 处理得到好友列表成功事件
    private void processGetFriendListSuccess(QQEvent e) {
        // 得到包
        GetFriendListReplyPacket packet = (GetFriendListReplyPacket)e.getSource();
        // 如果包的position属性不等于QQ_FRIENDS_LIST_POSITION_END,表明还有好友没有得到,继续请求
        log.debug("还有好友没有列出,继续请求好友");
        GetFriendListPacket gflPacket = new GetFriendListPacket();
        gflPacket.setStartPosition(packet.position);
        sendPacket(gflPacket);
    }    

    // 处理得到在线好友列表成功事件
    private void processGetFriendOnlineSuccess(QQEvent e) {
        // 得到包
        GetFriendOnlineReplyPacket packet = (GetFriendOnlineReplyPacket)e.getSource();
        // 如果position不等于QQ_FRIEND_ONLINE_LIST_POSITION_END,说明还有信息没有得到
        log.debug("还有在线好友没有列出,继续请求在线好友列表");
        GetFriendOnlinePacket gfoPacket = new GetFriendOnlinePacket();
        gfoPacket.setStartPosition(packet.position);
        sendPacket(gfoPacket);
    }

    // 处理得到用户信息成功事件
    private void processGetUserInfoSuccess(QQEvent e) {
        // 得到包
        GetUserInfoReplyPacket packet = (GetUserInfoReplyPacket)e.getSource();
        // 如果这个user就是我,那就设置我的信息
        if(Utils.getInt(packet.contactInfo.infos[packet.contactInfo.qqStr], 0) == user.getQQ())
            user.setContactInfo(packet.contactInfo); 	
    }

    // 处理Keep Alive成功信息,对Keep Alive Success,QQClient不作什么
	//     进一步的分析,只是顺便刷新一下好友状态
    private void processKeepAliveSuccess(QQEvent e) {
        GetFriendOnlinePacket packet = new GetFriendOnlinePacket();
        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();
	        sendPacket(guiPacket);
			// 手动更改我的在线状态,虽然服务器可能也会给我发送这样的信息
			ChangeStatusPacket csPacket = new ChangeStatusPacket();
	        sendPacket(csPacket);	        
			// 如果设置了自动得到好友信息,就请求
			if(autoGetFriend)
				getFriendList();
	    }
	}
	
    // 处理普通消息事件,只是发一个确认而已
    private void processReceiveIM(QQEvent e) {
        // 得到包
        ReceiveIMPacket packet = (ReceiveIMPacket)e.getSource();
        
        // 生成确认包
        ReceiveIMReplyPacket reply = new ReceiveIMReplyPacket(packet.reply);
        reply.setSequence(packet.getSequence());
        if(port != null)
            port.add(reply);
    }

    // 检查系统消息是否是被踢出,其他消息不关心
    private void processKickedOutBySystem(QQEvent e) {
        // 得到包
        ReceiveIMPacket packet = (ReceiveIMPacket)e.getSource();
        // 生成确认包
        ReceiveIMReplyPacket reply = new ReceiveIMReplyPacket(packet.reply);
        reply.setSequence(packet.getSequence());
        if(port != null)
            port.add(reply);
        // 判断类型
        if(packet.systemMessageType == QQ.QQ_RECV_IM_KICK_OUT) {
            log.debug("被系统踢出,可能是同一QQ号码在别处登陆");
            user.setLoggedIn(false);
            logout();
        }
    }

	/* (non-Javadoc)
	 * @see edu.tsinghua.lumaqq.QQListener#qqEvent(edu.tsinghua.lumaqq.QQEvent)
	 */
	public void qqEvent(QQEvent e) {
		switch(e.type) {
			case QQEvent.QQ_LOGIN_SUCCESS:
				processLoginSuccess();
				break;
			case QQEvent.QQ_GET_FRIEND_LIST_SUCCESS:
			    processGetFriendListSuccess(e);
				break;
			case QQEvent.QQ_GET_FRIEND_LIST_END:
			    processGetFriendListEnd(e);
				break;
			case QQEvent.QQ_GET_FRIEND_ONLINE_SUCCESS:
			    processGetFriendOnlineSuccess(e);
				break;
			case QQEvent.QQ_GET_USER_INFO_SUCCESS:
			    processGetUserInfoSuccess(e);
				break;
			case QQEvent.QQ_KEEP_ALIVE_SUCCESS:
			    processKeepAliveSuccess(e);
				break;
			case QQEvent.QQ_KICKED_OUT_BY_SYSTEM:
			    processKickedOutBySystem(e);
				break;
			case QQEvent.QQ_RECEIVE_NORMAL_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_RECEIVE_CLUSTER_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:
			    processReceiveIM(e);
				break;
			case QQEvent.QQ_OPERATION_TIMEOUT:
				if(e.operation == QQ.QQ_CMD_LOGIN)
					processLoginTimeout();
				break;
			case QQEvent.QQ_CONNECTION_LOST:
				processConnectionLost();
				break;
		}
	}

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

	// 处理登陆超时事件
	private void processLoginTimeout() {
		logging = false;
		logout();
	}

	/**
     * 移去一个QQ事件监听器
     * @param listener QQListener
     */
    public void removeQQListener(QQListener listener) {
    	qqListeners.remove(listener);
    	if(port != null)
    	    port.removeQQListener(listener);
    	if(pp != null)
    		pp.removeQQListener(listener);
    }    
    
    /**
     * 发送一个消息,用给定的字体
     * @param message 消息
     * @param receiver 接受者QQ号
     * @param fontName 字体
     */
    public void sendMessage(String message, int receiver, String fontName) {
        this.sendMessage(message, receiver, fontName, QQ.QQ_IM_NORMAL_REPLY);
    }
    
    /**
     * 发送一条消息,可以指定回复类型
     * @param message 消息
     * @param receiver 接收者QQ号
     * @param fontName 字体名
     * @param replyType 回复方式,正常回复还是自动回复
     */
    public void sendMessage(String message, int receiver, String fontName, byte replyType) {
        this.sendMessage(message, receiver, fontName, 9, false, false, false, 0, 0, 0, replyType);
    }
    
    /**
     * 发送一个消息,制定字体和字体颜色
     * @param message 消息
     * @param receiver 接受者QQ号
     * @param fontName 字体
     * @param size 字体大小,最大是31
     * @param bold 是否粗体
     * @param italic 是否斜体
     * @param underline 是否下划线
     * @param red 颜色Red
     * @param green 颜色Green
     * @param blue 颜色Blue
     * @param replyType 回复类型,自动回复还是正常回复
     */
    public void sendMessage(String message, int receiver, String fontName, int size, boolean bold, boolean italic, boolean underline, int red, int green, int blue, byte replyType) {
    	if(user.isLoggedIn()) {
	        if(message.length() > QQ.QQ_MSG_IM_MAX) return;
	        SendIMPacket packet = new SendIMPacket();
	        packet.setReceiver(receiver);
	        packet.setMessage(message);
	        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);
	        monitor.putRequest(packet);
	        port.add(packet);		
    	}
    }
    
    /**
     * @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;
        Packet.setUser(user);
    }
    
	/**
	 * @param autoGetFriend The autoGetFriend to set.
	 */
	public void setAutoGetFriend(boolean autoGetFriend) {
		this.autoGetFriend = autoGetFriend;
	}
	
	/**
	 * @return Returns the logging.
	 */
	public boolean isLogging() {
		return logging;
	}
	
    /**
     * @return Returns the port.
     */
    public IPort getPort() {
        return port;
    }
    
    /**
     * @param password The password to set.
     */
    public void setProxyPassword(String password) {
        this.proxyPassword = password;
    }
    
    /**
     * @param username The username to set.
     */
    public void setProxyUsername(String username) {
        this.proxyUsername = username;
    }
    
    /**
     * @param loginRedirect The loginRedirect to set.
     */
    public void setLoginRedirect(boolean loginRedirect) {
        this.loginRedirect = loginRedirect;
    }
}

⌨️ 快捷键说明

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