/* * 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; } }