📄 qqclient.java
字号:
GetFriendListPacket packet = new GetFriendListPacket(user);
pool.send(MAIN.name, packet, false);
}
}
/**
* 请求取得好友名单,position指定了名单开始的偏移,建议初级用户不要使用此API
* @param position
*/
public void getFriendList(char position) {
if(pool.hasConnection(MAIN.name)) {
// 请求取得好友名单
GetFriendListPacket packet = new GetFriendListPacket(user);
packet.setStartPosition(position);
pool.send(MAIN.name, packet, false);
}
}
/**
* 请求取得当前在线好友列表
*/
public void getFriendOnline() {
if(pool.hasConnection(MAIN.name)) {
GetOnlineOpPacket packet = new GetOnlineOpPacket(user);
pool.send(MAIN.name, packet, false);
}
}
/**
* 请求取得当前在线好友列表
*/
public void getFriendOnline(int startPosition) {
if(pool.hasConnection(MAIN.name)) {
GetOnlineOpPacket packet = new GetOnlineOpPacket(user);
packet.setStartPosition(startPosition);
pool.send(MAIN.name, packet, false);
}
}
/**
* 得到用户属性
*
* @param startPosition
*/
public void getUserProperty(char startPosition) {
if(pool.hasConnection(MAIN.name)) {
UserPropertyOpPacket packet = new UserPropertyOpPacket(user);
packet.setStartPosition(startPosition);
packet.setSubCommand(QQ.QQ_SUB_CMD_GET_USER_PROPERTY);
pool.send(MAIN.name, packet, false);
}
}
/**
* 使我的状态改变成在线
*/
public void makeMeOnline() {
if(user.isLoggedIn() && pool.hasConnection(MAIN.name)) {
user.setStatus(QQ.QQ_STATUS_ONLINE);
ChangeStatusPacket packet = new ChangeStatusPacket(user);
packet.setShowFakeCam(user.isShowFakeCam());
pool.send(MAIN.name, packet, false);
}
}
/**
* 使我的状态改变成离开
*/
public void makeMeAway() {
if(user.isLoggedIn() && pool.hasConnection(MAIN.name)) {
user.setStatus(QQ.QQ_STATUS_AWAY);
ChangeStatusPacket packet = new ChangeStatusPacket(user);
packet.setShowFakeCam(user.isShowFakeCam());
pool.send(MAIN.name, packet, false);
}
}
/**
* 使我的状态改变为隐身
*/
public void makeMeHidden() {
if(user.isLoggedIn() && pool.hasConnection(MAIN.name)) {
user.setStatus(QQ.QQ_STATUS_HIDDEN);
ChangeStatusPacket packet = new ChangeStatusPacket(user);
packet.setShowFakeCam(user.isShowFakeCam());
pool.send(MAIN.name, packet, false);
}
}
/**
* 请求密钥
* @param request
*/
public void requestKey(byte request) {
if(pool != null && user.isLoggedIn() && pool.hasConnection(MAIN.name)) {
RequestKeyPacket packet = new RequestKeyPacket(user);
packet.setRequest(request);
pool.send(MAIN.name, packet, true);
}
}
/**
* 请求得到多人对话列表
*/
public void getDialogList() {
if(user.isLoggedIn()) {
ClusterSubClusterOpPacket packet = new ClusterSubClusterOpPacket(user);
packet.setOpByte(QQ.QQ_CLUSTER_SUB_CMD_GET_DIALOG_LIST);
pool.send(MAIN.name, packet, false);
}
}
/**
* 请求得到讨论组列表
*
* @param clusterId
* 群id
*/
public void getSubjectList(int clusterId) {
if(user.isLoggedIn()) {
ClusterSubClusterOpPacket packet = new ClusterSubClusterOpPacket(user);
packet.setOpByte(QQ.QQ_CLUSTER_SUB_CMD_GET_SUBJECT_LIST);
packet.setClusterId(clusterId);
pool.send(MAIN.name, packet, false);
}
}
/**
* 通用方法,发送一个packet
* 这个方法用在一些包构造比较复杂的情况下,比如上传分组信息这种包,
* 包中数据的来源是无法知道的也不是用几个参数就能概括的,可能也和实现有关。
*
* @param packet OutPacket子类
*/
public void sendPacket(OutPacket packet) {
if(user.isLoggedIn())
pool.send(MAIN.name, packet, true);
}
/**
* 通过指定port发送一个包
*
* @param packet
* @param port
*/
public void sendPacket(OutPacket packet, String port) {
sendPacket(packet, port, true);
}
/**
* 通过指定port发送一个包
*
* @param packet
* 输出包对象
* @param port
* port名称
* @param monitor
* true表示加入到包监视缓冲
*/
public void sendPacket(OutPacket packet, String port, boolean monitor) {
if(user.isLoggedIn())
pool.send(port, packet, monitor);
}
/**
* 不管有没有登录,都把包发出去
*
* @param packet
* @param port
*/
public void sendPacketAnyway(OutPacket packet, String port) {
pool.send(port, packet, true);
}
/**
* @return 登陆服务器IP
*/
public String getLoginServer() {
return loginServer;
}
/**
* @return Returns the user.
*/
public QQUser getUser() {
return user;
}
/**
* 添加一个QQ事件监听器
*
* @param listener
* QQListener
*/
public void addQQListener(IQQListener listener) {
if(!qqListeners.contains(listener)) {
qqListeners.add(listener);
setListenerChanged(true);
}
}
/**
* 移去一个QQ事件监听器
* @param listener QQListener
*/
public void removeQQListener(IQQListener listener) {
if(qqListeners.contains(listener)) {
qqListeners.remove(listener);
setListenerChanged(true);
}
}
/**
* 设置listener changed标志
*
* @param b
*/
private synchronized void setListenerChanged(boolean b) {
listenerChanged = b;
}
/**
* 得到listener changed标志
*
* @return
* true表示有新的listener添加了进来
*/
private synchronized boolean isListenerChanged() {
return listenerChanged;
}
/**
* 检查监听器是否已经改变,如果是则更新监听器
*/
private synchronized void checkListenerChange() {
if(isListenerChanged()) {
qqListenersBackup.clear();
qqListenersBackup.addAll(qqListeners);
setListenerChanged(false);
}
}
/**
* 触发QQ事件
* @param e QQEvent
*/
public void fireQQEvent(QQEvent e) {
checkListenerChange();
int size = qqListenersBackup.size();
for(int i = 0; i < size; i++)
qqListenersBackup.get(i).qqEvent(e);
}
/**
* 登陆,使用缺省端口
*
* @throws Exception
* 如果登录出错
*/
public void login() throws Exception {
if (user != null && !logging && loginServer != null) {
// 登陆
if(user.isUdp())
login(loginServer, QQ.QQ_PORT_UDP);
else
login(loginServer, tcpLoginPort);
}
}
/**
* 用指定的服务器和端口登录
*
* @param server 登陆服务器
* @param p 登陆端口
* @throws Exception
* 如果登录出错
*/
protected void login(String server, int p) throws Exception {
// 检查是否设置了用户名和密码
if (user != null && poolFactory != null) {
// 停止以前的线程,如果有的话
logout();
// 设置状态为正在登陆
logging = true;
// 检查是什么登陆模式,udp还是tcp
try {
IConnection con = MAIN.create(this, new InetSocketAddress(server, p), proxyAddress, proxyUsername, proxyPassword, false);
// 如果登录令牌还是空,就构造请求登录令牌包,如果不是,直接登录
OutPacket packet = null;
if(user.getLoginToken() == null)
packet = new RequestLoginTokenPacket(user);
else
packet = new LoginPacket(user);
// 启动连接池
pool.start();
// 启动端口
con.start();
// 发送请求包
pool.send(MAIN.name, packet, false);
} 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(pool != null) {
IConnection con = pool.getConnection(MAIN.name);
if(con != null) {
con.clearSendQueue();
// 如果已经登录了,则发送logout包
if(isLoggedIn) {
LogoutPacket packet = new LogoutPacket(user);
pool.send(MAIN.name, packet, false);
}
}
pool.dispose();
}
pool = poolFactory.newPool();
// 执行清理工作
if(keepAliveFuture != null) {
keepAliveFuture.cancel(false);
keepAliveFuture = null;
}
resendTrigger.clear();
}
/**
* 释放这个QQClient,如果不继续使用QQClient,则必须释放此客户端以便
* SingleExecutor释放资源
*/
public void release() {
executor.decreaseClient();
}
/**
* 处理Keep Alive成功信息,对Keep Alive Success,QQClient不作什么
* 进一步的分析,只是顺便刷新一下好友状态
*
* @param e
*/
private void processKeepAliveSuccess(QQEvent e) {
GetOnlineOpPacket packet = new GetOnlineOpPacket(user);
sendPacket(packet);
}
/**
* 处理登陆成功事件
*/
private void processLoginSuccess() {
if(!user.isLoggedIn()) {
user.setLoggedIn(true);
this.logging = false;
// 请求密钥
requestKey(QQ.QQ_SUB_CMD_REQUEST_UNKNOWN03_KEY);
requestKey(QQ.QQ_SUB_CMD_REQUEST_FILE_AGENT_KEY);
requestKey(QQ.QQ_SUB_CMD_REQUEST_UNKNOWN06_KEY);
requestKey(QQ.QQ_SUB_CMD_REQUEST_UNKNOWN07_KEY);
requestKey(QQ.QQ_SUB_CMD_REQUEST_UNKNOWN08_KEY);
// 得到我的信息
GetUserInfoPacket guiPacket = new GetUserInfoPacket(user);
sendPacket(guiPacket);
// 手动更改我的在线状态,虽然服务器可能也会给我发送这样的信息
ChangeStatusPacket csPacket = new ChangeStatusPacket(user);
csPacket.setShowFakeCam(user.isShowFakeCam());
sendPacket(csPacket);
// 调度keep alive动作
keepAliveFuture = executor.scheduleWithFixedDelay(keepAliveTrigger, QQ.QQ_INTERVAL_KEEP_ALIVE, QQ.QQ_INTERVAL_KEEP_ALIVE, TimeUnit.MILLISECONDS);
}
}
/**
* 处理普通消息事件,只是发一个确认而已
*
* @param e
*/
private void processReceiveIM(QQEvent e) {
// 得到包
ReceiveIMPacket packet = (ReceiveIMPacket)e.getSource();
// 生成确认包
ReceiveIMReplyPacket reply = new ReceiveIMReplyPacket(packet.reply, user);
reply.setSequence(packet.getSequence());
pool.send(MAIN.name, reply, false);
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.QQListener#qqEvent(edu.tsinghua.lumaqq.QQEvent)
*/
public void qqEvent(QQEvent e) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -