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

📄 qqclient.java

📁 类似于MSN
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
* LumaQQ - Java QQ Client
*
* Copyright (C) 2004 luma <stubma@163.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package edu.tsinghua.lumaqq.qq;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.channels.UnresolvedAddressException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import edu.tsinghua.lumaqq.qq.beans.ContactInfo;
import edu.tsinghua.lumaqq.qq.beans.FriendRemark;
import edu.tsinghua.lumaqq.qq.beans.QQUser;
import edu.tsinghua.lumaqq.qq.events.QQEvent;
import edu.tsinghua.lumaqq.qq.events.QQListener;
import edu.tsinghua.lumaqq.qq.packets.OutPacket;
import edu.tsinghua.lumaqq.qq.packets.Packet;
import edu.tsinghua.lumaqq.qq.packets.in.GetFriendListReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.GetFriendOnlineReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.GetUserInfoReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.ReceiveIMPacket;
import edu.tsinghua.lumaqq.qq.packets.out.AddFriendAuthPacket;
import edu.tsinghua.lumaqq.qq.packets.out.AddFriendPacket;
import edu.tsinghua.lumaqq.qq.packets.out.ChangeStatusPacket;
import edu.tsinghua.lumaqq.qq.packets.out.ClusterActivatePacket;
import edu.tsinghua.lumaqq.qq.packets.out.ClusterAuthPacket;
import edu.tsinghua.lumaqq.qq.packets.out.ClusterCreatePacket;
import edu.tsinghua.lumaqq.qq.packets.out.ClusterExitPacket;
import edu.tsinghua.lumaqq.qq.packets.out.ClusterGetInfoPacket;
import edu.tsinghua.lumaqq.qq.packets.out.ClusterGetMemberInfoPacket;
import edu.tsinghua.lumaqq.qq.packets.out.ClusterGetOnlineMemberPacket;
import edu.tsinghua.lumaqq.qq.packets.out.ClusterJoinPacket;
import edu.tsinghua.lumaqq.qq.packets.out.ClusterModifyInfoPacket;
import edu.tsinghua.lumaqq.qq.packets.out.ClusterSearchPacket;
import edu.tsinghua.lumaqq.qq.packets.out.ClusterSendIMPacket;
import edu.tsinghua.lumaqq.qq.packets.out.DeleteFriendPacket;
import edu.tsinghua.lumaqq.qq.packets.out.FriendRemarkOpPacket;
import edu.tsinghua.lumaqq.qq.packets.out.GetFriendListPacket;
import edu.tsinghua.lumaqq.qq.packets.out.GetFriendOnlinePacket;
import edu.tsinghua.lumaqq.qq.packets.out.GetUserInfoPacket;
import edu.tsinghua.lumaqq.qq.packets.out.LoginPacket;
import edu.tsinghua.lumaqq.qq.packets.out.LogoutPacket;
import edu.tsinghua.lumaqq.qq.packets.out.ModifyInfoPacket;
import edu.tsinghua.lumaqq.qq.packets.out.ReceiveIMReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.out.RemoveSelfPacket;
import edu.tsinghua.lumaqq.qq.packets.out.RequestKeyPacket;
import edu.tsinghua.lumaqq.qq.packets.out.SearchUserPacket;
import edu.tsinghua.lumaqq.qq.packets.out.SendIMPacket;

/**
 * QQ的客户端类,这个类为用户提供一个方便的接口,比如发送消息之类的,只需要调用一个
 * 方法便可以完成了
 * 
 * @author 马若劼
 */
public class QQClient implements QQListener {
    /**
     * <pre>
     * 执行清理任务的Runnable类
     * </pre>
     * 
     * @author 马若劼
     */
    private class CleanRunnable implements Runnable {
        private KeepAliveThread thread;
        private IPort port;
        
        public CleanRunnable(KeepAliveThread thread, IPort port) {
            this.thread = thread;
            this.port = port;
        }

        public void run() {
        	// 终止Keep Alive线程
            if(thread != null) 
                thread.setStop(true); 
            // 停止接收发送线程 
        	try {
                if(port != null)
                    port.dispose();
            } catch (IOException e) {
                log.error(e.getMessage());
            }
        }
    }
    
    // Log对象
    private static Log log = LogFactory.getLog(QQClient.class);
    // Keep Alive 线程
    private KeepAliveThread kaThread;
    // 登陆的服务器IP
    private String loginServer;
    // packet monitor
    private PacketMonitor monitor;
    // 包处理类
    private PacketProcessor pp;
    // 保存QQ事件监听器的List
    private List qqListeners;
    // QQ用户
    private QQUser user;
    // 是否在登陆后自动请求好友列表
    private boolean autoGetFriend;
    // 当前是否正在登陆
    private boolean logging;
    // 当前是否在重定向登录
    private boolean loginRedirect;
    // port接口
    private IPort port;
    // 代理类型
    private int proxyType;
    // 代理服务器地址
    private InetSocketAddress proxyAddress;
    // 代理服务器验证用户名,null表示不需要验证
    private String proxyUsername;
    // 代理服务器验证密码
    private String proxyPassword;

    /**
     * 构造函数
     */
    public QQClient() {
        pp = new PacketProcessor(this);
        qqListeners = new ArrayList();
        monitor = PacketMonitor.getInstance();
        autoGetFriend = true;
        logging = false;
        loginRedirect = false;
    }
    
    /**
     * 设置代理类型
     * @param type
     */
    public void setProxyType(String type) {
        if(type.equalsIgnoreCase("None"))
            proxyType = QQ.PROXY_NONE;
        else if(type.equalsIgnoreCase("Socks5"))
            proxyType = QQ.PROXY_SOCKS5;
        else if(type.equalsIgnoreCase("Http"))
            proxyType = QQ.PROXY_HTTP;
        else
            proxyType = QQ.PROXY_NONE;
    }
    
    /**
     * 设置代理服务器地址
     * @param proxyAddress
     */
    public void setProxy(InetSocketAddress proxyAddress) {
        this.proxyAddress = proxyAddress;
    }
    
    /**
     * 上传好友备注信息
     * @param qqNum 好友的QQ号
     * @param remark 备注类
     */
    public void uploadFriendRemark(int qqNum, FriendRemark remark) {
    	if(user.isLoggedIn()) {
    		FriendRemarkOpPacket packet = new FriendRemarkOpPacket();
    		packet.setRemark(remark);
    		packet.setQQ(qqNum);
    		monitor.putRequest(packet);
    		port.add(packet);
    	}
    }
    
    /**
     * 下载好友备注信息
     * @param qqNum 好友的QQ号
     */
    public void downloadFriendRemark(int qqNum) {
    	if(user.isLoggedIn()) {
    		FriendRemarkOpPacket packet = new FriendRemarkOpPacket();
    		packet.setType(QQ.QQ_DOWNLOAD_FRIEND_REMARK);
    		packet.setQQ(qqNum);
	        port.add(packet);
    	}
    }
    
    /**
     * 搜索所有的在线用户
     * @param page 页号,从0开始
     */
    public void searchUser(int page) {
    	if(user.isLoggedIn()) {
    		SearchUserPacket packet = new SearchUserPacket();
    		packet.setPage(page);
	        port.add(packet);
    	}
    }
    
    /**
     * 自定义搜索用户
     * @param page 页号
     * @param qqNum 要搜索的QQ号字符串形式
     * @param nick 要搜索的昵称
     * @param email 要搜索的email
     * @param matchEntire 字符串是否完全匹配
     */
    public void searchUser(int page, String qqStr, String nick, String email, boolean matchEntire) {
    	if(user.isLoggedIn()) {
    		SearchUserPacket packet = new SearchUserPacket();
    		packet.setSearchType(QQ.QQ_SEARCH_CUSTOM);
    		packet.setPage(page);
    		packet.setQQStr(qqStr);
    		packet.setNick(nick);
    		packet.setEmail(email);
    		packet.setMatchEntireString(matchEntire);
	        port.add(packet);
    	}
    }
    
    /**
     * 添加一个好友
     * @param qqNum 要添加的人的QQ号
     * @return 发送出的包的序号
     */
    public int addFriend(int qqNum) {
    	if(user.isLoggedIn()) {
	        AddFriendPacket packet = new AddFriendPacket();
	        packet.setTo(qqNum);
	        monitor.putRequest(packet);
	        port.add(packet);
	        return (int)packet.getSequence();
    	}
    	return -1;
    }
    
    /**
     * 删除一个好友
     * @param qqNum 要删除的好友的QQ号
     * @return 如果包发送成功则返回包序号,否则返回-1
     */
    public int deleteFriend(int qqNum) {
    	if(user.isLoggedIn()) {
	        DeleteFriendPacket packet = new DeleteFriendPacket();
	        packet.setTo(qqNum);
	        monitor.putRequest(packet);
	        port.add(packet);		
	        return (int)packet.getSequence();
    	}
    	return -1;
    }
    
    /**
     * 把某人的好友列表中的自己删除
     * @param qqNum 我想把我自己删除的好友的QQ号
     */
    public void removeSelfFrom(int qqNum) {
    	if(user.isLoggedIn()) {
	        RemoveSelfPacket packet = new RemoveSelfPacket();
	        packet.setRemoveFrom(qqNum);
	        monitor.putRequest(packet);
	        port.add(packet);  		
    	}
    }
    
    /**
     * 如果要加的人需要认证,用这个方法发送验证请求
     * @param qqNum 要加的人的QQ号
     * @param message 附加的请求消息内容
     */
    public void sendAddFriendAuth(int qqNum, String message) {
    	if(user.isLoggedIn()) {
	        AddFriendAuthPacket packet = new AddFriendAuthPacket();
	        packet.setTo(qqNum);
	        packet.setMessage(message);
	        packet.setType(QQ.QQ_MY_AUTH_REQUEST);	      
	        monitor.putRequest(packet);
	        port.add(packet);
    	}
    }
    
    /**
     * 发送传送文件请求包,我们把包序号用作会话序号返回
     * @param filePath 文件名,不包含路径
     * @param fileSize 文件大小
     * @param directPort 直接端口
     * @param udp true表示UDP方式
     * @return 文件传输会话序号
     */
    public char requestSendFile(int receiver, String filePath, int fileSize, int directPort, boolean udp) {
    	if(user.isLoggedIn()) {
    		SendIMPacket packet = new SendIMPacket();
    		packet.setMessageType(udp ? QQ.QQ_IM_UDP_REQUEST : QQ.QQ_IM_TCP_REQUEST);
    		packet.setReceiver(receiver);
    		packet.setFileName(filePath);
    		packet.setFileSize(fileSize);
    		packet.setDirectPort(directPort);
    		monitor.putRequest(packet);
	        port.add(packet);
    		return packet.getSequence(); 
    	} else
    	    return 0;
    }
    
    /**
     * 取消发送文件
     * @param receiver
     * @param sequence
     */
    public void cancelSendFile(int receiver, char sequence) {
        if(user.isLoggedIn()) {
            SendIMPacket packet = new SendIMPacket();
            packet.setMessageType(QQ.QQ_IM_REQUEST_CANCELED);
            packet.setReceiver(receiver);
            packet.setRequestSequence(sequence);
            monitor.putRequest(packet);
	        port.add(packet);
        }
    }
    
    /**
     * 发送同意接收文件包
     * @param receiver 接收者
     * @param directPort 我的直接端口
     * @param sequence 会话序号
     * @param udp true表示UDP方式
     */
    public void acceptSendFile(int receiver, int directPort, char sequence, boolean udp) {
    	if(user.isLoggedIn()) {
    		SendIMPacket packet = new SendIMPacket();
    		packet.setMessageType(udp ? QQ.QQ_IM_ACCEPT_UDP_REQUEST : QQ.QQ_IM_ACCEPT_TCP_REQUEST);
    		packet.setReceiver(receiver);
    		packet.setDirectPort(directPort);
    		packet.setRequestSequence(sequence);
    		monitor.putRequest(packet);
	        port.add(packet);
    	}
    }
    
    /**
     * 发送拒绝接收文件包
     * @param receiver 接收者
     * @param sequence 会话序号
     * @param udp true表示是UDP请求,false表示TCP请求
     */
    public void rejectSendFile(int receiver, char sequence, boolean udp) {
    	if(user.isLoggedIn()) {
    		SendIMPacket packet = new SendIMPacket();
    		packet.setMessageType(udp ? QQ.QQ_IM_REJECT_UDP_REQUEST : QQ.QQ_IM_REJECT_TCP_REQUEST);
    		packet.setReceiver(receiver);
    		packet.setRequestSequence(sequence);
    		monitor.putRequest(packet);
	        port.add(packet);
    	}
    }
    
    /**
     * 发送通知端口信息包
     * @param receiver
     * @param directPort
     * @param localIp
     * @param localPort
     * @param sequence
     */
    public void notifyFilePort(int receiver, int directPort, byte[] localIp, int localPort, char sequence) {
        if(user.isLoggedIn()) {
            SendIMPacket packet = new SendIMPacket();
            packet.setMessageType(QQ.QQ_IM_NOTIFY_IP);
            packet.setReceiver(receiver);
            packet.setRequestSequence(sequence);
            packet.setDirectPort(directPort);
            packet.setLocalIp(localIp);
            packet.setLocalPort(localPort);
            monitor.putRequest(packet);
	        port.add(packet);
        }
    }
    
    /**
     * 请求对方连接我
     * @param receiver
     * @param directPort
     * @param sequence
     */
    public void pleaseConnectMe(int receiver, int directPort, char sequence) {
        if(user.isLoggedIn()) {
            SendIMPacket packet = new SendIMPacket();
            packet.setMessageType(QQ.QQ_IM_ARE_YOU_BEHIND_FIREWALL);
            packet.setReceiver(receiver);
            packet.setRequestSequence(sequence);
            packet.setDirectPort(directPort);
            monitor.putRequest(packet);
	        port.add(packet);
        }
    }
    
    /**
     * 如果我要拒绝一个人加我为好友的请求,用这个方法发送拒绝消息
     * @param qqNum 请求加我的人的QQ号
     * @param message 附加消息
     */
    public void rejectAddMe(int qqNum, String message) {
    	if(user.isLoggedIn()) {
	        AddFriendAuthPacket packet = new AddFriendAuthPacket();
	        packet.setTo(qqNum);
	        packet.setMessage(message);
	        packet.setType(QQ.QQ_MY_AUTH_REJECT);
	        monitor.putRequest(packet);
	        port.add(packet);
    	}
    }
    
    /**
     * 如果我要同意一个人加我为好友的请求,用这个方法发送同意消息
     * @param qqNum 请求加我的人的QQ号
     */
    public void approveAddMe(int qqNum) {
    	if(user.isLoggedIn()) {

⌨️ 快捷键说明

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