qq_src
 

 /**
 * $Revision$
 * $Date$
 *
 * Copyright (C) 2006 Jive Software. 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 org.jivesoftware.wildfire.gateway.protocols.qq;

import org.jivesoftware.util.Log;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.wildfire.gateway.*;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
import edu.tsinghua.lumaqq.qq.QQ;

/**
 * MSN Transport Interface.
 *
 * This handles the bulk of the XMPP work via BaseTransport and provides
 * some gateway specific interactions.
 *
 * @author Daniel Henninger
 */
public class QQTransport extends BaseTransport {


    /**
     * @see org.jivesoftware.wildfire.gateway.BaseTransport#getTerminologyUsername()
     */
    public String getTerminologyUsername() {
        return LocaleUtils.getLocalizedString("gateway.qq.username", "gateway");
    }

    /**
     * @see org.jivesoftware.wildfire.gateway.BaseTransport#getTerminologyPassword()
     */
    public String getTerminologyPassword() {
        return LocaleUtils.getLocalizedString("gateway.qq.password", "gateway");
    }

    /**
     * @see org.jivesoftware.wildfire.gateway.BaseTransport#getTerminologyNickname()
     */
    public String getTerminologyNickname() {
        return null;
    }

    /**
     * @see org.jivesoftware.wildfire.gateway.BaseTransport#getTerminologyRegistration()
     */
    public String getTerminologyRegistration() {
        return LocaleUtils.getLocalizedString("gateway.qq.registration",
                                              "gateway");
    }

    /**
     * @see org.jivesoftware.wildfire.gateway.BaseTransport#isPasswordRequired()
     */
    public Boolean isPasswordRequired() {
        return true;
    }

    /**
     * @see org.jivesoftware.wildfire.gateway.BaseTransport#isNicknameRequired()
     */
    public Boolean isNicknameRequired() {
        return false;
    }

    /**
     * @see org.jivesoftware.wildfire.gateway.BaseTransport#isUsernameValid(String)
     */
    public Boolean isUsernameValid(String username) {
        System.out.println("需要检查的 qq 用户名为 " + username);
        try {
            Integer.parseInt(username);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * Handles creating a QQ session and triggering a login.
     *
     * @param registration Registration information to be used to log in.
     * @param jid JID that is logged into the transport.
     * @param presenceType Type of presence.
     * @param verboseStatus Longer status description.
     */
    public TransportSession registrationLoggedIn(Registration registration,
                                                 JID jid,
                                                 PresenceType presenceType,
                                                 String verboseStatus,
                                                 Integer priority) {
        Log.debug("Logging in to QQ gateway.");
        TransportSession session = new QQSession(registration, jid, this,
                                                 priority);
        this.getSessionManager().startThread(session);
        ((QQSession) session).logIn(presenceType, verboseStatus);
        return session;
    }

    /**
     * Handles logging out of a QQ session.
     *
     * @param session The session to be disconnected.
     */
    public void registrationLoggedOut(TransportSession session) {
        System.out.println("Logging out of QQ gateway.");
        ((QQSession) session).logOut();
        session.sessionDone();
        // Just in case.
        session.setLoginStatus(TransportLoginStatus.LOGGED_OUT);
    }

    /**
     * Converts a jabber status to an QQ status.
     *
     * @param jabStatus Jabber presence type.
     * @return QQ user status id.
     */
    public byte convertJabStatusToQQ(PresenceType jabStatus) {
        if (jabStatus == PresenceType.available) {
            return QQ.QQ_STATUS_ONLINE;
        } else if (jabStatus == PresenceType.away) {
            return QQ.QQ_STATUS_AWAY;
        } else if (jabStatus == PresenceType.xa) {
            return QQ.QQ_STATUS_AWAY;
        } else if (jabStatus == PresenceType.dnd) {
            return QQ.QQ_STATUS_AWAY;
        } else if (jabStatus == PresenceType.chat) {
            return QQ.QQ_STATUS_ONLINE;
        } else if (jabStatus == PresenceType.unavailable) {
            return QQ.QQ_STATUS_OFFLINE;
        } else {
            return QQ.QQ_STATUS_ONLINE;
        }
    }

    /**
     * Sets up a presence packet according to QQ status.
     *
     * @param msnStatus QQ ContactStatus constant.
     * @param packet Presence packet to set up.
     */
    public void setUpPresencePacket(Presence packet, byte qqStatus) {
        switch (qqStatus) {
        case QQ.QQ_STATUS_AWAY:
            packet.setShow(Presence.Show.chat);
            break;
        case QQ.QQ_STATUS_HIDDEN:
            packet.setShow(Presence.Show.xa);
            break;
        case QQ.QQ_STATUS_OFFLINE:
            packet.setShow(Presence.Show.xa);
            break;
        case QQ.QQ_STATUS_ONLINE:
            packet.setShow(Presence.Show.chat);
            break;
        default:
            packet.setShow(Presence.Show.chat);
            break;
        }
    }

}





----------------------------------------------------------

/**
 * $Revision$
 * $Date$
 *
 * Copyright (C) 2006 Jive Software. 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 org.jivesoftware.wildfire.gateway.protocols.qq;


import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.gateway.*;
import org.jivesoftware.wildfire.gateway.protocols.msn.MSNTransport;
import org.jivesoftware.wildfire.roster.RosterItem;
import org.jivesoftware.wildfire.user.UserNotFoundException;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
import org.xmpp.packet.Presence;

import edu.tsinghua.lumaqq.qq.QQ;
import edu.tsinghua.lumaqq.qq.QQClient;
import edu.tsinghua.lumaqq.qq.beans.QQUser;
import edu.tsinghua.lumaqq.qq.beans.QQFriend;
import edu.tsinghua.lumaqq.qq.beans.ClusterIM;
import edu.tsinghua.lumaqq.qq.net.PortGateFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Represents a QQ session.
 *
 * This is the interface with which the base transport functionality will
 * communicate with QQ.
 *
 * @author Daniel Henninger
 */
public class QQSession extends TransportSession {

    /**
     * Create a QQ Session instance.
     *
     * @param registration Registration informationed used for logging in.
     * @param jid JID associated with this session.
     * @param transport Transport instance associated with this session.
     * @param priority Priority of this session.
     */
    public QQSession(Registration registration, JID jid, QQTransport transport,
                     Integer priority) {
        super(registration, jid, transport, priority);

        Log.debug("Creating QQ session for " + registration.getUsername());
        qquser = new QQUser(Integer.parseInt(registration.getUsername()),
                            registration.getPassword());
        qquser.setStatus(QQ.QQ_LOGIN_MODE_NORMAL);
        qquser.setUdp(true);
        qquser.setShowFakeCam(false);
        qqclient = new QQClient();
        qqclient.setUser(qquser);
        qqclient.setConnectionPoolFactory(new PortGateFactory());

    }

    /**
     * QQ session
     */
    private QQClient qqclient;
    private QQUser qquser;
    /**
     * QQ contacts/friends.
     */
    private ConcurrentHashMap<String,
                              QQFriend> qqContacts = new ConcurrentHashMap<
                                      String, QQFriend>();

    private final String udpServerList[] = {
                                           "sz.tencent.com", // 61.144.238.145
                                           "sz2.tencent.com", // 61.144.238.146
                                           "sz3.tencent.com", // 202.104.129.251
                                           "sz4.tencent.com", // 202.104.129.254
                                           "sz5.tencent.com", // 61.141.194.203
                                           "sz6.tencent.com", // 202.104.129.252
                                           "sz7.tencent.com", // 202.104.129.253
//        "202.104.129.254",
                                           "219.133.41.75",
                                           "219.133.49.167",
                                           "219.133.49.77",
                                           "202.96.170.163",
                                           "202.96.170.164",
                                           "219.133.38.129",
                                           "219.133.38.130",
                                           "219.133.38.43",
                                           "219.133.38.44",
//        "219.133.40.215",
                                           "219.133.40.216",
                                           "219.133.48.100"
    };
    /**
     * Log in to QQ.
     *
     * @param presenceType Type of presence.
     * @param verboseStatus Long representation of status.
     */
    public void logIn(PresenceType presenceType, String verboseStatus) {
        if (!this.isLoggedIn()) {
            try {
                Log.debug("Logging in to QQ session for " + qquser.getQQ());
                setLoginStatus(TransportLoginStatus.LOGGING_IN);
                qqclient.addQQListener(new QqSessionListener(this));
                String qqserver = udpServerList[(int) Math.round(Math.random() *
                        udpServerList.length)];
                qqclient.setLoginServer(qqserver);
                // qqclient.setLoginServer("sz4.tencent.com");
                System.out.println("开始登陆 " + qqclient.getUser().getQQ() + " 到 " +
                                   qqserver);
                qqclient.login();
            } catch (Exception e) {
                Log.error("QQ user is not able to log in: " + qquser.getQQ(), e);
            }
        }
    }

    /**
     * Log out of QQ.
     */
    public void logOut() {
        if (this.isLoggedIn()) {
            setLoginStatus(TransportLoginStatus.LOGGING_OUT);
            ///qqMessenger.logout();
            qqclient.logout();

        }
        Presence p = new Presence(Presence.Type.unavailable);
        p.setTo(getJID());
        p.setFrom(getTransport().getJID());
        getTransport().sendPacket(p);
        setLoginStatus(TransportLoginStatus.LOGGED_OUT);
    }


    /**
     * Records information about a person on the user's contact list.
     *
     * @param qqContact QQ contact we are storing a copy of.
     */
//    public void storeFriend(MsnContact qqContact) {
//        qqContacts.put(qqContact.getEmail().toString(), qqContact);
//    }

    /**
     * Records information about a group on the user's contact list.
     *
     * @param qqGroup QQ group we are storing a copy of.
     */
    public void storeGroup(ClusterIM qqGroup) {
        //   qqGroups.put(qqGroup.externalId, qqGroup);
    }

    /**
     * Syncs up the QQ roster with the jabber roster.
     */
    public void syncUsers() {
        List<TransportBuddy> legacyusers = new ArrayList<TransportBuddy>();
        for (QQFriend friend : qqContacts.values()) {
            ArrayList<String> friendGroups = new ArrayList<String>();
            if (friendGroups.size() < 1) {
                friendGroups.add("qq"+ qqclient.getUser().getQQ()+"的好友");
            }
            legacyusers.add(new TransportBuddy(friend.qqNum + "", friend.nick,
                                               friendGroups.get(0)));
        }
        try {
            getTransport().syncLegacyRoster(getJID(), legacyusers);
        } catch (UserNotFoundException e) {
            Log.error("Unable to sync QQ contact list for " + getJID(), e);
        }

        // Lets send initial presence statuses
        for (QQFriend friend : qqContacts.values()) {
            Presence p = new Presence();
            p.setTo(getJID());
            p.setFrom(getTransport().convertIDToJID(friend.qqNum + ""));
            p.setShow(Presence.Show.dnd);
            //((QQTransport)getTransport()).setUpPresencePacket(p, friend.getStatus());
            getTransport().sendPacket(p);
        }
    }

    /**
     * @see org.jivesoftware.wildfire.gateway.TransportSession#addContact(org.jivesoftware.wildfire.roster.RosterItem)
     */
    public void addContact(RosterItem item) {
        int qq = Integer.parseInt(getTransport().convertJIDToID(item.getJid()));
        System.out.println("添加qq好友:" + qq + " RosterItem == " + item);
        qqclient.addFriend(qq);
    }

    /**
     * @see org.jivesoftware.wildfire.gateway.TransportSession#removeContact(org.jivesoftware.wildfire.roster.RosterItem)
     */
    public void removeContact(RosterItem item) {
        int qq = Integer.parseInt(getTransport().convertJIDToID(item.getJid()));
        System.out.println("删除qq好友:" + qq + " RosterItem == " + item);
        qqclient.removeFriendFromList(qq);

    }

    /**
     * @see org.jivesoftware.wildfire.gateway.TransportSession#updateContact(org.jivesoftware.wildfire.roster.RosterItem)
     */
    public void updateContact(RosterItem item) {
        int qq = Integer.parseInt(getTransport().convertJIDToID(item.getJid()));
        String nickname = getTransport().convertJIDToID(item.getJid());
        if (item.getNickname() != null && !item.getNickname().equals("")) {
            nickname = item.getNickname();
        }
        System.out.println("更新 qq " + qq + " RosterItem == " + item);
//        qqclient.renameFriend(contact, nickname);
//        syncContactGroups(contact, item.getGroups());
    }

    /**
     * Given a legacy contact and a list of groups, makes sure that the list is in sync with
     * the actual group list.
     *
     * @param contact Email address of contact.
     * @param groups List of groups contact should be in.
     */
//    public void syncContactGroups(Email contact, List<String> groups) {
//        if (groups.isEmpty()) {
//            groups.add("Transport Buddies");
//        }
//        MsnContact qqContact = qqContacts.get(contact.toString());
//        // Create groups that do not currently exist.
//        for (String group : groups) {
//            if (!qqGroups.containsKey(group)) {
//                qqMessenger.addGroup(group);
//            }
//        }
//        // Lets update our list of groups.
//        for (QqGroup qqGroup : qqMessenger.getContactList().getGroups()) {
//            storeGroup(qqGroup);
//        }
//        // Make sure contact belongs to groups that we want.
//        for (String group : groups) {
//            QqGroup qqGroup = qqGroups.get(group);
//            if (!qqContact.belongGroup(qqGroup)) {
//                qqMessenger.copyFriend(contact, group);
//            }
//        }
//        // Now we will clean up groups that we should no longer belong to.
//        for (QqGroup qqGroup : qqContact.getBelongGroups()) {
//            if (!groups.contains(qqGroup.getGroupName())) {
//                qqMessenger.removeFriend(contact, qqGroup.getGroupId());
//            }
//        }
//    }

    /**
     * @see org.jivesoftware.wildfire.gateway.TransportSession#sendMessage(org.xmpp.packet.JID, String)
     */
    public void sendMessage(JID jid, String message) {
        System.out.println("发送消息到:" + jid + " 内容为:" + message);
        qqclient.sendIM(Integer.parseInt(getTransport().convertJIDToID(jid)),
                        message.getBytes());
        //  qqMessenger.sendText(Email.parseStr(getTransport().convertJIDToID(jid)), message);
    }

    /**
     * @see org.jivesoftware.wildfire.gateway.TransportSession#sendServerMessage(String)
     */
    public void sendServerMessage(String message) {
        System.out.println("发送消息到服务器:" + message);
    }

    /**
     * @see org.jivesoftware.wildfire.gateway.TransportSession#retrieveContactStatus(org.xmpp.packet.JID)
     */
    public void retrieveContactStatus(JID jid) {
        QQFriend qqContact = qqContacts.get(getTransport().convertJIDToID(jid));
        Presence p = new Presence();
        p.setTo(getJID());
        if (qqContact != null) {
            p.setFrom(getTransport().convertIDToJID(qqContact.qqNum + ""));
            ((QQTransport) getTransport()).setUpPresencePacket(p,
                    QQ.QQ_STATUS_OFFLINE);
        } else {
            // User was not found so send an error presence
            p.setFrom(jid);
            p.setError(PacketError.Condition.forbidden);
        }
        getTransport().sendPacket(p);
    }

    /**
     * @see org.jivesoftware.wildfire.gateway.TransportSession#updateStatus(org.jivesoftware.wildfire.gateway.PresenceType, String)
     */
    public void updateStatus(PresenceType presenceType, String verboseStatus) {
        if (isLoggedIn()) {
            try {
                qquser.setStatus(((QQTransport) getTransport()).
                                 convertJabStatusToQQ(presenceType));

                //qqclient
                //  qqMessenger.getOwner().setStatus(((QQTransport)getTransport()).convertJabStatusToQQ(presenceType));
            } catch (IllegalStateException e) {
//                // Hrm, not logged in?  Lets fix that.
//                qqMessenger.getOwner().setInitStatus(((QQTransport)getTransport()).convertJabStatusToQQ(presenceType));
//                qqMessenger.login();
            }
        } else {
//            // Hrm, not logged in?  Lets fix that.
//            qqMessenger.getOwner().setInitStatus(((QQTransport)getTransport()).convertJabStatusToQQ(presenceType));
//            qqMessenger.login();
        }
    }

    /**
     * @see org.jivesoftware.wildfire.gateway.TransportSession#resendContactStatuses(org.xmpp.packet.JID)
     */
    public void resendContactStatuses(JID jid) {
        for (QQFriend friend : qqContacts.values()) {
            Presence p = new Presence();
            p.setTo(getJID());
            p.setFrom(getTransport().convertIDToJID(friend.qqNum + ""));
            //p.setShow(Presence.Show.dnd);
            //((QQTransport)getTransport()).setUpPresencePacket(p, friend.getStatus());
            getTransport().sendPacket(p);
        }
    }

    public QQClient getQqclient() {
        return qqclient;
    }

    public ConcurrentHashMap<String, QQFriend> getQqContacts() {
        return qqContacts;
    }

    public QQUser getQquser() {
        return qquser;
    }

}

-----------------------------------------------------------------------


/**
 * $Revision$
 * $Date$
 *
 * Copyright (C) 2006 Jive Software. 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 org.jivesoftware.wildfire.gateway.protocols.qq;

import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.gateway.TransportLoginStatus;
import org.xmpp.packet.Message;
import org.xmpp.packet.Presence;

import edu.tsinghua.lumaqq.qq.QQ;
import edu.tsinghua.lumaqq.qq.beans.ClusterIM;
import edu.tsinghua.lumaqq.qq.beans.ClusterInfo;
import edu.tsinghua.lumaqq.qq.beans.ContactInfo;
import edu.tsinghua.lumaqq.qq.beans.DownloadFriendEntry;
import edu.tsinghua.lumaqq.qq.beans.FriendOnlineEntry;
import edu.tsinghua.lumaqq.qq.beans.NormalIM;
import edu.tsinghua.lumaqq.qq.beans.QQFriend;
import edu.tsinghua.lumaqq.qq.beans.Weather;
import edu.tsinghua.lumaqq.qq.events.IQQListener;
import edu.tsinghua.lumaqq.qq.events.QQEvent;
import edu.tsinghua.lumaqq.qq.packets.in.ClusterCommandReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.DownloadGroupFriendReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.FriendChangeStatusPacket;
import edu.tsinghua.lumaqq.qq.packets.in.GetFriendListReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.GetOnlineOpReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.GetUserInfoReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.ReceiveIMPacket;
import edu.tsinghua.lumaqq.qq.packets.in.SignatureOpReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.WeatherOpReplyPacket;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * MSN Listener Interface.
 *
 * This handles real interaction with MSN, but mostly is a listener for
 * incoming events from MSN.
 *
 * @author Daniel Henninger
 */
public class QqSessionListener implements IQQListener {
    private int initStep;
    private final int stepCount = 5; //5次后才算登陆成功
    private String talkingName; //当前聊天的好友Nick
    private QQSession qqSession = null;
    /**
     * Creates the QQ Listener instance.
     *
     * @param session Session this listener is associated with.
     */
    public QqSessionListener(QQSession session) {
        this.qqSession = session;
        initStep = 0;
        talkingName = "";
    }

    public void qqEvent(QQEvent e) {
        switch (e.type) {
        case QQEvent.QQ_LOGIN_SUCCESS:
            System.out.println("登陆成功, 等待状态改变.");
            qqSession.getRegistration().setLastLogin(new Date());
            qqSession.setLoginStatus(TransportLoginStatus.LOGGED_IN);
            initStep = 1;
            break;
        case QQEvent.QQ_LOGIN_FAIL:
        case QQEvent.QQ_LOGIN_REDIRECT_NULL:
        case QQEvent.QQ_LOGIN_UNKNOWN_ERROR:
            System.out.println( +qqSession.getQqclient().getUser().getQQ() +
                               "登陆失败,退出.");

            //System.exit(-1);
            break;
        case QQEvent.QQ_CHANGE_STATUS_SUCCESS:
            System.out.println("改变状态完成.");
            if (initStep >= stepCount) {
                System.out.print(talkingName + ">");
            }
            if (initStep == 1) {
                initStep = 2;

                qqSession.getQqclient().getFriendList();
                qqSession.getQqclient().downloadFriend(0);
            }
            break;
        case QQEvent.QQ_CHANGE_STATUS_FAIL:
            System.out.println("改变状态失败.");
            break;
        case QQEvent.QQ_GET_FRIEND_LIST_SUCCESS:
            processFriendList(e);
            break;
        case QQEvent.QQ_DOWNLOAD_GROUP_FRIEND_SUCCESS:
            processGroupFriend(e);
            break;
        case QQEvent.QQ_DOWNLOAD_GROUP_FRIEND_FAIL:
            System.out.println("下载好友分组失败, 注销!");
            qqSession.getQqclient().logout();
            break;
        case QQEvent.QQ_GET_CLUSTER_INFO_SUCCESS:
            processClusterInfo(e);
            break;
        case QQEvent.QQ_GET_CLUSTER_INFO_FAIL:
            System.out.println("得到群信息错误. 注销!");
            qqSession.getQqclient().logout();
            break;
        case QQEvent.QQ_GET_MEMBER_INFO_SUCCESS:
            processMemberInfo(e);
            break;
        case QQEvent.QQ_GET_MEMBER_INFO_FAIL:
            System.out.println("得到成员信息错误. 注销!");
            qqSession.getQqclient().logout();
            break;
        case QQEvent.QQ_RECEIVE_CLUSTER_IM:
            processClusterIM(e);
            break;
        case QQEvent.QQ_RECEIVE_NORMAL_IM:
            processNormalIM(e);
            break;
        case QQEvent.QQ_CONNECTION_BROKEN:
            System.out.println("连接被打断, 重新连接...");
            try {
                qqSession.getQqclient().login();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            break
                    ;
        case QQEvent.QQ_CONNECTION_LOST:
            System.out.println("连接被丢失, 重新连接...");
            try {
                qqSession.getQqclient().login();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            break
                    ;
        case QQEvent.QQ_OPERATION_TIMEOUT:
            System.out.println("操作超时,按回车试试.");
            if (e.operation == QQ.QQ_CMD_LOGIN
                || e.operation == QQ.QQ_CMD_REQUEST_LOGIN_TOKEN) {
                qqSession.getQqclient().logout();
                System.err.println("遭遇致命错误, 按 Ctrl+C 退出!");
            }
            break;
        case QQEvent.QQ_GET_FRIEND_ONLINE_SUCCESS:
            processFriendOnline(e);
            break;
        case QQEvent.QQ_FRIEND_CHANGE_STATUS:
            if (initStep >= stepCount) {
                processFriendChangeStatus(e);
            }
            break;
        case QQEvent.QQ_GET_USER_INFO_SUCCESS:
            if (initStep >= stepCount) {
                processUserInfo(e);
            }
            break;
        case QQEvent.QQ_GET_WEATHER_SUCCESS:
            processWeather(e);
            break;
        case QQEvent.QQ_GET_WEATHER_FAIL:

            //回复包里面没有有用信息,所以不处理了
            break;
        case QQEvent.QQ_GET_SIGNATURE_SUCCESS:
            processSignature(e);
            break;
        case QQEvent.QQ_GET_SIGNATURE_FAIL:
            break;
        case QQEvent.QQ_RECEIVE_SYS_MESSAGE:

            //QQ系统广播,不理它
            System.out.println("QQ系统广播,不理它");
            break;
        }

    }

    private void processSignature(QQEvent e) {
        try {
            SignatureOpReplyPacket p =
                    (SignatureOpReplyPacket) e.getSource();
            /*            String signature = friends.get(p.friendQQ);
                                    if(friendName==null) friendName="";
             String msg = "\nMilyQQ通知您: 好友 "+friendName+"("+p.friendQQ+") "
                                            + getCurrentStatus(p.status);
             */
            System.out.println(p.nextQQ);
            System.out.print(talkingName + ">");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void processFriendChangeStatus(QQEvent e) {
        try {
            FriendChangeStatusPacket p =
                    (FriendChangeStatusPacket) e.getSource();
            //String friendName = friends.get(p.friendQQ);
//                if(friendName==null) friendName="";
//                String msg = "\nMilyQQ通知您: 好友 "+friendName+"("+p.friendQQ+") "
//                    + getCurrentStatus(p.status);
//                System.out.println(msg);
            System.out.print(talkingName + ">");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void processWeather(QQEvent e) {
        try {
            WeatherOpReplyPacket p = (WeatherOpReplyPacket) e.getSource();
            System.out.print("\n未来" + p.weathers.size() + "天内天气情况:\n");
            for (Weather w : p.weathers) {
                String msg = w.year + "年" + w.month + "月" + w.day + "日: " +
                             w.shortDesc
                             + ", " + w.wind + ", 最低气温" + w.lowTemperature
                             + "摄氏度, 最高气温" + w.highTemperature + "摄氏度"
                             + "\n贴心小提示: " + w.hint + "\n\n";
                System.out.print(msg);
            }
            System.out.print(talkingName + ">");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void processUserInfo(QQEvent e) {
        String[] zodiac = {"未知", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴",
                          "鸡", "狗", "猪"};
        String[] blood = {"未知", "A", "B", "O", "AB", "其他"};
        String[] horoscope = {"未知", "水瓶", "双鱼", "牧羊", "金牛", "双子", "巨蟹", "狮子",
                             "处女", "天秤", "天蝎", "射手", "魔蝎"};
        try {
            GetUserInfoReplyPacket p =
                    (GetUserInfoReplyPacket) e.getSource();
            ContactInfo info = p.contactInfo;
            String msg =
                    "\n" + info.nick + "(" + info.qq + ")" + " 性别:" +
                    info.gender + " 年方:" + info.age
                    + "\n来自: " + info.country + " " + info.province + "省 " +
                    info.city + "市 "
                    + "\n邮编:" + info.zipcode + " 地址:" + info.address
                    + "\n电话: " + info.telephone + " 手机: " + info.mobile +
                    "\n真名叫做:" + info.name
                    + " E-mail为:" + info.email + "\n职业是:" + info.occupation +
                    " 毕业于:" + info.college
                    + "\n个人主页:" + info.homepage
                    + "\n属" + zodiac[(info.zodiac >= 0 && info.zodiac <= 12) ?
                    info.zodiac : 0]
                    + "的, " + blood[(info.blood >= 0 && info.blood <= 5) ?
                    info.blood : 0]
                    + "型血, " +
                    horoscope[(info.horoscope >= 0 && info.horoscope <= 12) ?
                    info.horoscope : 0]
                    + "座.\n开场白:\n" + info.intro + "\n";
            System.out.print(msg);
            System.out.print(talkingName + ">");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void processFriendOnline(QQEvent e) {
        try {
            GetOnlineOpReplyPacket p =
                    (GetOnlineOpReplyPacket) e.getSource();
            for (FriendOnlineEntry f : p.onlineFriends) {
                //String qqName = friends.get(f.status.qqNum);
                //if (qqName == null) qqName = "";
                //onlines.put(f.status.qqNum, qqName);

              //  System.out.println("下载在线好友 " + f.status.qqNum);
            }
            if (!p.finished) {
                //if (onlineFinished) {
                //    //onlines.clear();
                //onlineFinished = false;
                //}
                qqSession.getQqclient().getFriendOnline(p.position);
            } else {
                //onlineFinished = true;//完成
                initStep++;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    //处理普通消息
    private void processNormalIM(QQEvent e) {
        try {
            ReceiveIMPacket p = (ReceiveIMPacket) e.getSource();
            NormalIM im = p.normalIM;
            Message m = new Message();
            m.setType(Message.Type.chat);
            m.setTo(qqSession.getJIDWithHighestPriority());
            m.setFrom(qqSession.getTransport().convertIDToJID("" +
                    p.normalHeader.sender));
            String b = " ";
            try {
                b = new String(im.messageBytes);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            m.setBody(b);
           // System.out.println("消息为:" + m);
            qqSession.getTransport().sendPacket(m);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    //处理群消息
    private void processClusterIM(QQEvent e) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm");
            ReceiveIMPacket p = (ReceiveIMPacket) e.getSource();
            ClusterIM im = p.clusterIM;
            String sDate = sdf.format(new Date(im.sendTime));
//                String clusterName = clusters.get(im.externalId);
//                if (clusterName == null) clusterName = "";
//                String senderName = membersAll.get(im.sender);
//                if (senderName == null)     senderName = "";
//                int num=0;
//                if(index.contains(im.externalId))
//                    num=1+index.indexOf(im.externalId);
//                String msg = "\n[" + (num>0 ? num : "") +"]群:"
//                        + clusterName + "(" + im.externalId + ") 里的 "
//                        + senderName + "(" + im.sender + ") "
//                        + sDate    + "\n"
//                        + new String(im.messageBytes) + "\n";
//                dispAndLog(msg);
            System.out.print(talkingName + ">");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     *    处理群成员信息,全部放到hash表membersAll中,同时保存一个
     *    保存hash表的hash表,用来显示每个群的成员,这个方法不好,
     *    占用内存较多,但是暂时还没找到更好的办法
     */
    private void processMemberInfo(QQEvent e) {
        try {
            ClusterCommandReplyPacket p = (ClusterCommandReplyPacket) e.
                                          getSource();
            HashMap<Integer, String> temp = new HashMap<Integer, String>();
            for (Object obj : p.memberInfos) {
                QQFriend m = (QQFriend) obj;
                //群信息全部保存到一个临时hash表
                temp.put(m.qqNum, m.nick);
                //保存一个全部群成员的hash表
                //membersAll.put(m.qqNum,m.nick);
            }
//                if(membersIndex.containsKey(p.clusterId)){
//                    //如果外表中已经含有同样的群号键值,则先取出来,放到上面的temp表中
//                    for (Map.Entry<Integer, String> entry
//                        : membersIndex.get(p.clusterId).entrySet()){
//                        temp.put(entry.getKey(),entry.getValue());
//                    }
//                    //然后再把temp表保存到外表中
//                    membersIndex.put(p.clusterId,temp);
//                }else{
//                    //没有键值就直接往里面压
//                    membersIndex.put(p.clusterId,temp);
//                }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void processClusterInfo(QQEvent e) {
        try {
            ClusterCommandReplyPacket p = (ClusterCommandReplyPacket) e.
                                          getSource();
            ClusterInfo info = p.info;
            //p.description,p.notice两个字段用在info中
            // 如果是固定群,externalId表示外部ID,如果是临时群,这个表示父群ID
            //clusters.put(info.externalId, info.name);
            //保存外部ID到内部ID的索引
            //clustersIn.put(info.externalId, info.clusterId);
            //p.members字段为群成员列表,元素类型为Integer,包含了成员的QQ号
            qqSession.getQqclient().getClusterMemberInfo(info.clusterId,
                    p.members);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    //处理好友分组,MilyQQ没有分组的概念,因此全部放到我的好友下面
    private void processGroupFriend(QQEvent e) {
        try {
            DownloadGroupFriendReplyPacket p =
                    (DownloadGroupFriendReplyPacket) e.getSource();
            for (DownloadFriendEntry entry : p.friends) {
                if (entry.isCluster()) {
                    qqSession.getQqclient().getClusterInfo(entry.qqNum);
                }
            }
            if (p.beginFrom != 0) {
                qqSession.getQqclient().downloadFriend(p.beginFrom);
            } else {
                System.out.println("下载好友分组完成.");
                //下载好友分组完成,继续下载在线好友列表
                qqSession.getQqclient().getFriendOnline();
                initStep++;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    //处理好友名单
    private void processFriendList(QQEvent e) {
        try {
            GetFriendListReplyPacket p =
                    (GetFriendListReplyPacket) e.getSource();
            for (QQFriend f : p.friends) {
                qqSession.getQqContacts().put("" + f.qqNum, f);
            }
            if (p.position != 0xFFFF) {
                qqSession.getQqclient().getFriendList(p.position);
            } else {
                System.out.println("获取好友列表完成.");
                initStep++;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        qqSession.syncUsers();
    }
}