/*
* Copyright 2006-2010 Daniel Henninger. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package net.sf.kraken.protocols.qq;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.sf.jqql.QQ;
import net.sf.jqql.QQClient;
import net.sf.jqql.beans.QQUser;
import net.sf.jqql.net.PortGateFactory;
import net.sf.kraken.registration.Registration;
import net.sf.kraken.session.TransportSession;
import net.sf.kraken.type.ChatStateType;
import net.sf.kraken.type.ConnectionFailureReason;
import net.sf.kraken.type.PresenceType;
import net.sf.kraken.type.TransportLoginStatus;
import org.apache.log4j.Logger;
import org.xmpp.packet.JID;
public class QQSession extends TransportSession<QQBuddy> {
static Logger Log = Logger.getLogger(QQSession.class);
private List<String> tcpServerList = new ArrayList<String>();
private List<String> udpServerList = new ArrayList<String>();
private QQClient qqclient;
private QQUser qquser;
// private Map<Integer,
// ClusterInfo> clusters = new HashMap<Integer, ClusterInfo>();
// private Map<Integer,
// Map<Integer, String>> clusterMembers = new Hashtable<Integer,
// Map<Integer, String>>(); //group members
/**
* QQ session listener.
*/
private QQListener qqListener;
private void setupDefaultServerList() {
// set up default tcp server list
Collections.addAll(tcpServerList,
"tcpconn.tencent.com",
"tcpconn2.tencent.com",
"tcpconn3.tencent.com",
"tcpconn4.tencent.com",
"tcpconn5.tencent.com",
"tcpconn6.tencent.com"
);
Collections.shuffle(tcpServerList);
// set up default udp server list
Collections.addAll(udpServerList,
"sz.tencent.com",
"sz2.tencent.com",
"sz3.tencent.com",
"sz4.tencent.com",
"sz5.tencent.com",
"sz6.tencent.com",
"sz7.tencent.com",
"sz8.tencent.com",
"sz9.tencent.com"
);
Collections.shuffle(udpServerList);
// TODO: Add preferred server to top of list, and add checkbox for udp vs tcp
}
public QQSession(Registration registration, JID jid,
QQTransport transport, Integer priority) {
super(registration, jid, transport, priority);
qquser = new QQUser(Integer.parseInt(registration.getUsername()),
registration.getPassword());
qquser.setStatus(QQ.QQ_LOGIN_MODE_NORMAL);
qquser.setUdp(true);
qquser.setShowFakeCam(false);
setupDefaultServerList();
}
@Override
public void updateStatus(PresenceType presenceType, String verboseStatus) {
if (isLoggedIn()) {
if (presenceType.equals(PresenceType.dnd)) {
qqclient.status_Busy();
}
else if (presenceType.equals(PresenceType.away) ||
presenceType.equals(PresenceType.xa)) {
qqclient.status_Away();
}
else {
qqclient.status_Online();
}
// try {
// qquser.setStatus(((QQTransport) getTransport()).
// convertJabStatusToQQ(presenceType));
// } catch (IllegalStateException e) {
// // Nothing to do
// Log.debug("Failed to change QQ status: ", e);
// }
}
}
@Override
public void addContact(JID jid, String nickname, ArrayList<String> groups) {
//qqclient.addFriend(Integer.valueOf(getTransport().convertJIDToID(jid)));
qqclient.user_SendAuth(Integer.valueOf(getTransport().convertJIDToID(jid)), "Please accept my friend request!");
qqclient.user_Add(Integer.valueOf(getTransport().convertJIDToID(jid)));
}
@Override
public void removeContact(QQBuddy transportBuddy) {
qqclient.user_Delete(Integer.valueOf(getTransport().convertJIDToID(transportBuddy.getJID())));
}
@Override
public void updateContact(QQBuddy transportBuddy) {
// There's nothing to change here currently.
}
/**
* @see net.sf.kraken.session.TransportSession#acceptAddContact(JID)
*/
@Override
public void acceptAddContact(JID jid) {
int qqNum = Integer.parseInt(getTransport().convertJIDToID(jid));
qqclient.user_ApproveAdd(qqNum);
}
@Override
public void sendMessage(JID jID, String message) {
try {
int qqNum = Integer.parseInt(getTransport().convertJIDToID(jID));
// if (clusters.get(qqNum) != null) {
// qqclient.sendClusterIM(clusters.get(qqNum).clusterId,
// message);
// } else {
qqclient.im_Send(qqNum, message.getBytes());
// }
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override
public void sendChatState(JID jID, ChatStateType chatStateType) {
// either not supported by QQ, or not supported by the lumaqq library
}
@Override
public void sendBuzzNotification(JID jID, String string) {
// either not supported by QQ, or not supported by the lumaqq library
}
@Override
public void logIn(PresenceType presenceType, String string) {
setPendingPresenceAndStatus(presenceType, verboseStatus);
if (udpServerList.isEmpty()) {
// Ran out of servers to try to log in to. Dooh.
sessionDisconnectedNoReconnect("Unable to log into any QQ servers.");
return;
}
String qqserver = udpServerList.remove(0); // pull a server to connect to from the end of the list
setLoginStatus(TransportLoginStatus.LOGGING_IN);
qqclient = new QQClient();
qqclient.setUser(qquser);
qqclient.setConnectionPoolFactory(new PortGateFactory());
//qqclient.setTcpLoginPort(8000);
qqListener = new QQListener(this);
qqclient.addQQListener(qqListener);
//qquser.setServerPort(8000);
qqclient.setLoginServer("sz.tencent.com");
try {
qqclient.sendTouch();
}
catch (Exception e) {
Log.debug("Login attempt at server "+qqserver+" failed, trying next.");
setFailureStatus(ConnectionFailureReason.CAN_NOT_CONNECT);
}
}
@Override
public void logOut() {
cleanUp();
sessionDisconnectedNoReconnect(null);
}
@Override
public void cleanUp() {
if (qqclient != null) {
qqclient.logout();
qqclient.release();
}
qqclient = null;
}
@Override
public void updateLegacyAvatar(String string, byte[] byteArray) {
}
public QQUser getQQUser() {
return qquser;
}
public QQClient getQQClient() {
return qqclient;
}
}