package com.wyp.materialqqlite.qqclient.task; import java.io.File; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import org.apache.http.client.HttpClient; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.wyp.materialqqlite.qqclient.QQUtils; import com.wyp.materialqqlite.qqclient.protocol.QQProtocol; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.BuddyMessage; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.Content; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.ContentType; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.GetQQNumResult; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.GroupInfoResult; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.GroupMessage; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.KickMessage; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.QQCallBackMsg; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.QQMsgType; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.SessMessage; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.StatusChangeMessage; import com.wyp.materialqqlite.qqclient.protocol.protocoldata.SysGroupMessage; public class RecvMsgTask2 extends HttpTask { public byte[] m_msgData; private HashMap<String, RMT_BUDDY_DATA> m_mapBuddyData; private HashMap<String, RMT_GROUP_DATA> m_mapGroupData; private HashMap<String, Integer> m_mapGroupId2Code; private HashMap<String, RMT_BUDDY_DATA> m_mapGMemberData; private static int m_nPreMsgId, m_nPreMsgId2; private static long m_lChatPicCnt = 0; private class RecvMsg { public QQMsgType m_nType; public Object m_objMsg; public int getMsgId() { if (null == m_objMsg) return 0; switch (m_nType) { case QQ_MSG_TYPE_BUDDY: return ((BuddyMessage)m_objMsg).m_nMsgId; case QQ_MSG_TYPE_GROUP: return ((GroupMessage)m_objMsg).m_nMsgId; case QQ_MSG_TYPE_SESS: return ((SessMessage)m_objMsg).m_nMsgId; default: return 0; } } public int getMsgId2() { if (null == m_objMsg) return 0; switch (m_nType) { case QQ_MSG_TYPE_BUDDY: return ((BuddyMessage)m_objMsg).m_nMsgId2; case QQ_MSG_TYPE_GROUP: return ((GroupMessage)m_objMsg).m_nMsgId2; case QQ_MSG_TYPE_SESS: return ((SessMessage)m_objMsg).m_nMsgId2; default: return 0; } } public int getTime() { if (null == m_objMsg) return 0; switch (m_nType) { case QQ_MSG_TYPE_BUDDY: return ((BuddyMessage)m_objMsg).m_nTime; case QQ_MSG_TYPE_GROUP: return ((GroupMessage)m_objMsg).m_nTime; case QQ_MSG_TYPE_SESS: return ((SessMessage)m_objMsg).m_nTime; default: return 0; } } } private class RMT_BUDDY_DATA { int nQQNum; String strNickName; } private class RMT_GROUP_DATA { boolean bHasGroupInfo; int nGroupNum; } public RecvMsgTask2(String strTaskName, HttpClient httpClient) { super(strTaskName, httpClient); // TODO Auto-generated constructor stub m_mapBuddyData = new HashMap<String, RMT_BUDDY_DATA>(); m_mapGroupData = new HashMap<String, RMT_GROUP_DATA>(); m_mapGroupId2Code = new HashMap<String, Integer>(); m_mapGMemberData = new HashMap<String, RMT_BUDDY_DATA>(); } private boolean handleMsg(byte[] bytMsgData) { if (null == bytMsgData) return false; ArrayList<RecvMsg> arrMsg = new ArrayList<RecvMsg>(); boolean bRet = parseMsg(bytMsgData, arrMsg); if (!bRet || arrMsg.size() <= 0) return false; if (arrMsg.size() > 1) sortMsgByTime(arrMsg); for (int i = 0; i < arrMsg.size(); i++) { RecvMsg msg = arrMsg.get(i); if (null == msg) continue; if (QQMsgType.QQ_MSG_TYPE_BUDDY == msg.m_nType) { handleBuddyMsg(msg); } else if (QQMsgType.QQ_MSG_TYPE_GROUP == msg.m_nType) { handleGroupMsg(msg); } else if (QQMsgType.QQ_MSG_TYPE_SESS == msg.m_nType) { handleSessMsg(msg); } else if (QQMsgType.QQ_MSG_TYPE_STATUSCHANGE == msg.m_nType) { handleStatusChangeMsg(msg); } else if (QQMsgType.QQ_MSG_TYPE_KICK == msg.m_nType) { handleKickMsg(msg); } else if (QQMsgType.QQ_MSG_TYPE_SYSGROUP == msg.m_nType) { handleSysGroupMsg(msg); } } return true; } private boolean parseMsg(byte[] bytMsgData, ArrayList<RecvMsg> arrMsg) { if (null == bytMsgData || bytMsgData.length <= 0 || null == arrMsg) return false; try { String strData = new String(bytMsgData, "UTF-8"); System.out.println(strData); JSONObject json = new JSONObject(strData); int nRetCode = json.getInt("retcode"); switch (nRetCode) { case 0: { JSONArray json2 = json.getJSONArray("result"); for (int i = 0; i < json2.length(); i++) { RecvMsg msg = new RecvMsg(); JSONObject josn3 = json2.getJSONObject(i); boolean bRet = parseMsg(josn3, msg); if (bRet && !isMsgRepeat(arrMsg, msg)) arrMsg.add(msg); } } break; case 116: break; default: return false; } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return true; } private boolean parseMsg(JSONObject json, RecvMsg msg) { String strPollType; try { strPollType = json.getString("poll_type"); if (BuddyMessage.isType(strPollType)) // 好友消息 { BuddyMessage buddyMsg = new BuddyMessage(); boolean bRet = buddyMsg.parse(json.getJSONObject("value")); if (!bRet) return false; msg.m_nType = QQMsgType.QQ_MSG_TYPE_BUDDY; msg.m_objMsg = buddyMsg; } else if (GroupMessage.isType(strPollType)) // 群消息 { GroupMessage groupMsg = new GroupMessage(); boolean bRet = groupMsg.parse(json.getJSONObject("value")); if (!bRet) return false; msg.m_nType = QQMsgType.QQ_MSG_TYPE_GROUP; msg.m_objMsg = groupMsg; } else if (SessMessage.isType(strPollType)) // 临时会话消息 { SessMessage sessMsg = new SessMessage(); boolean bRet = sessMsg.parse(json.getJSONObject("value")); if (!bRet) return false; msg.m_nType = QQMsgType.QQ_MSG_TYPE_SESS; msg.m_objMsg = sessMsg; } else if (StatusChangeMessage.isType(strPollType)) // 状态改变通知消息 { StatusChangeMessage statusChangeMsg = new StatusChangeMessage(); boolean bRet = statusChangeMsg.parse(json.getJSONObject("value")); if (!bRet) return false; msg.m_nType = QQMsgType.QQ_MSG_TYPE_STATUSCHANGE; msg.m_objMsg = statusChangeMsg; } else if (KickMessage.isType(strPollType)) // 被踢下线通知消息 { KickMessage kickMsg = new KickMessage(); boolean bRet = kickMsg.parse(json.getJSONObject("value")); if (!bRet) return false; msg.m_nType = QQMsgType.QQ_MSG_TYPE_KICK; msg.m_objMsg = kickMsg; } else if (SysGroupMessage.isType(strPollType)) // 群系统消息 { SysGroupMessage sysGroupMsg = new SysGroupMessage(); boolean bRet = sysGroupMsg.parse(json.getJSONObject("value")); if (!bRet) return false; msg.m_nType = QQMsgType.QQ_MSG_TYPE_SYSGROUP; msg.m_objMsg = sysGroupMsg; } else { // Unknown message type return false; } return true; } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } private boolean isMsgRepeat(ArrayList<RecvMsg> arrMsg, RecvMsg msg) { if (null == arrMsg || null == msg) return true; if (msg.m_nType != QQMsgType.QQ_MSG_TYPE_BUDDY && msg.m_nType != QQMsgType.QQ_MSG_TYPE_GROUP && msg.m_nType != QQMsgType.QQ_MSG_TYPE_SESS) return false; int nMsgId = msg.getMsgId(); int nMsgId2 = msg.getMsgId2(); for (int i = 0; i < arrMsg.size(); i++) { RecvMsg msg2 = arrMsg.get(i); if (msg2 != null && msg2.getMsgId() == nMsgId && msg2.getMsgId2() == nMsgId2) return true; } if (m_nPreMsgId == nMsgId && m_nPreMsgId2 == nMsgId2) return true; m_nPreMsgId = nMsgId; m_nPreMsgId2 = nMsgId2; return false; } private void sortMsgByTime(ArrayList<RecvMsg> arrMsg) { RecvMsg msg1, msg2; boolean bExchange; int nCount; nCount = arrMsg.size(); for (int i = 0; i < nCount-1; i++) { bExchange = false; for (int j = nCount-1; j > i; j--) { msg1 = arrMsg.get(j-1); msg2 = arrMsg.get(j); if (msg1 != null && msg2 != null) { if (msg2.getTime() < msg1.getTime()) { arrMsg.set(j-1, msg2); arrMsg.set(j, msg1); bExchange = true; } } } if (!bExchange) break; } } private boolean handleBuddyMsg(RecvMsg recvMsg) { if (null == recvMsg || null == recvMsg.m_objMsg) return false; BuddyMessage msg = (BuddyMessage)recvMsg.m_objMsg; int nQQNum = 0; String strNickName = ""; RMT_BUDDY_DATA buddyData = getBuddyData(msg.m_nFromUin); if (buddyData != null) { nQQNum = buddyData.nQQNum; strNickName = buddyData.strNickName; } QQUtils.writeBuddyMsgLog(m_QQUser, nQQNum, strNickName, false, msg); // 写入消息记录 if (isNeedDownloadPic(msg.m_arrContent)) // 需要下载图片 startChatPicTask(ChatPicTask.OP_TYPE_BUDDY_PIC, msg); else sendMessage(QQCallBackMsg.BUDDY_MSG, msg.m_nFromUin, 0, msg); return true; } private boolean handleGroupMsg(RecvMsg recvMsg) { if (null == recvMsg || null == recvMsg.m_objMsg) return false; GroupMessage msg = (GroupMessage)recvMsg.m_objMsg; int nGroupNum = 0; int nQQNum = 0; String strNickName = ""; RMT_GROUP_DATA groupData = getGroupData(msg.m_nGroupCode); if (groupData != null) nGroupNum = groupData.nGroupNum; RMT_BUDDY_DATA buddyData = getGMemberData(msg.m_nGroupCode, msg.m_nSendUin); if (buddyData != null) { nQQNum = buddyData.nQQNum; strNickName = buddyData.strNickName; } if (null == strNickName) { System.out.println("空的"); } QQUtils.writeGroupMsgLog(m_QQUser, nGroupNum, nQQNum, strNickName, msg); // 写入消息记录 if (isNeedDownloadPic(msg.m_arrContent)) // 需要下载图片 startChatPicTask(ChatPicTask.OP_TYPE_GROUP_PIC, msg); else sendMessage(QQCallBackMsg.GROUP_MSG, msg.m_nGroupCode, 0, msg); return true; } private boolean handleSessMsg(RecvMsg recvMsg) { if (null == recvMsg || null == recvMsg.m_objMsg) return false; SessMessage msg = (SessMessage)recvMsg.m_objMsg; int nQQNum = 0; String strNickName = ""; int nGroupCode = groupId2Code(msg.m_nGroupId); // 群标识转换到群代码 if (nGroupCode != 0) { RMT_GROUP_DATA groupData = getGroupData(nGroupCode); // 确保群信息已获取 RMT_BUDDY_DATA buddyData = getGMemberData(nGroupCode, msg.m_nFromUin); if (buddyData != null) { nQQNum = buddyData.nQQNum; strNickName = buddyData.strNickName; } } QQUtils.writeSessMsgLog(m_QQUser, nQQNum, strNickName, false, msg); // 写入消息记录 if (isNeedDownloadPic(msg.m_arrContent)) // 需要下载图片 startChatPicTask(ChatPicTask.OP_TYPE_SESS_PIC, msg); else sendMessage(QQCallBackMsg.SESS_MSG, nGroupCode, msg.m_nFromUin, msg); return true; } private boolean handleStatusChangeMsg(RecvMsg recvMsg) { if (null == recvMsg || null == recvMsg.m_objMsg) return false; sendMessage(QQCallBackMsg.STATUS_CHANGE_MSG, 0, 0, recvMsg.m_objMsg); return true; } private boolean handleKickMsg(RecvMsg recvMsg) { if (null == recvMsg || null == recvMsg.m_objMsg) return false; sendMessage(QQCallBackMsg.KICK_MSG, 0, 0, recvMsg.m_objMsg); return true; } private boolean handleSysGroupMsg(RecvMsg recvMsg) { if (null == recvMsg || null == recvMsg.m_objMsg) return false; sendMessage(QQCallBackMsg.SYS_GROUP_MSG, 0, 0, recvMsg.m_objMsg); return true; } private RMT_BUDDY_DATA getBuddyData(int nQQUin) { String strKey = String.valueOf(nQQUin); RMT_BUDDY_DATA data = m_mapBuddyData.get(strKey); if (data != null) { if (data.nQQNum != 0 && data.strNickName != null) return data; else m_mapBuddyData.remove(strKey); } data = new RMT_BUDDY_DATA(); m_mapBuddyData.put(strKey, data); sendMessage(QQCallBackMsg.INTERNAL_GETBUDDYDATA, nQQUin, 0, null, true); data.nQQNum = m_QQUser.m_internalData.m_nQQNum; if (m_QQUser.m_internalData.m_strNickName != null) data.strNickName = new String(m_QQUser.m_internalData.m_strNickName); if (data.nQQNum != 0 && data.strNickName != null) return data; if (0 == data.nQQNum) { GetQQNumResult result = new GetQQNumResult(); boolean bRet = false; int nRetry = 3; for (int i = 0; i < nRetry; i++) { bRet = QQProtocol.getQQNum(m_httpClient, true, nQQUin, m_QQUser.m_LoginResult2.m_strVfWebQq, result); if (bRet && 0 == result.m_nRetCode) break; } if (bRet && 0 == result.m_nRetCode) { data.nQQNum = result.m_nQQNum; sendMessage(QQCallBackMsg.UPDATE_BUDDY_NUMBER, 0, 0, result); } } if (null == data.strNickName) { // 假定昵称一定能够从好友列表获取到,这里不处理 } return data; } private RMT_GROUP_DATA getGroupData(int nGroupCode) { String strKey = String.valueOf(nGroupCode); RMT_GROUP_DATA data = m_mapGroupData.get(strKey); if (data != null) { if (data.bHasGroupInfo && data.nGroupNum != 0) return data; else m_mapGroupData.remove(strKey); } data = new RMT_GROUP_DATA(); m_mapGroupData.put(strKey, data); sendMessage(QQCallBackMsg.INTERNAL_GETGROUPDATA, nGroupCode, 0, null, true); data.bHasGroupInfo = m_QQUser.m_internalData.m_bHasGroupInfo; data.nGroupNum = m_QQUser.m_internalData.m_nGroupNum; if (data.bHasGroupInfo && data.nGroupNum != 0) return data; if (!data.bHasGroupInfo) { GroupInfoResult result = new GroupInfoResult(); boolean bRet = false; int nRetry = 3; for (int i = 0; i < nRetry; i++) { bRet = QQProtocol.getGroupInfo(m_httpClient, nGroupCode, m_QQUser.m_LoginResult2.m_strVfWebQq, result); if (bRet && 0 == result.m_nRetCode) break; if (bRet && 6 == result.m_nRetCode) nRetry = 3; } if (bRet && 0 == result.m_nRetCode) { data.bHasGroupInfo = true; } sendMessage(QQCallBackMsg.UPDATE_GROUP_INFO, 0, 0, result); } if (0 == data.nGroupNum) { GetQQNumResult result = new GetQQNumResult(); boolean bRet = false; int nRetry = 3; for (int i = 0; i < nRetry; i++) { bRet = QQProtocol.getQQNum(m_httpClient, false, nGroupCode, m_QQUser.m_LoginResult2.m_strVfWebQq, result); if (bRet && 0 == result.m_nRetCode) break; } if (bRet && 0 == result.m_nRetCode) { data.nGroupNum = result.m_nQQNum; sendMessage(QQCallBackMsg.UPDATE_GROUP_NUMBER, nGroupCode, 0, result); } } return data; } private RMT_BUDDY_DATA getGMemberData(int nGroupCode, int nQQUin) { String strKey = String.valueOf(nGroupCode) + "_" + String.valueOf(nQQUin); RMT_BUDDY_DATA data = m_mapGMemberData.get(strKey); if (data != null) { if (data.nQQNum != 0 && data.strNickName != null) return data; else m_mapGMemberData.remove(strKey); } data = new RMT_BUDDY_DATA(); m_mapGMemberData.put(strKey, data); sendMessage(QQCallBackMsg.INTERNAL_GETGMEMBERDATA, nGroupCode, nQQUin, null, true); data.nQQNum = m_QQUser.m_internalData.m_nQQNum; if (m_QQUser.m_internalData.m_strNickName != null) data.strNickName = new String(m_QQUser.m_internalData.m_strNickName); if (data.nQQNum != 0 && data.strNickName != null) return data; if (0 == data.nQQNum) { GetQQNumResult result = new GetQQNumResult(); boolean bRet = false; int nRetry = 3; for (int i = 0; i < nRetry; i++) { bRet = QQProtocol.getQQNum(m_httpClient, true, nQQUin, m_QQUser.m_LoginResult2.m_strVfWebQq, result); if (bRet && 0 == result.m_nRetCode) break; } if (bRet && 0 == result.m_nRetCode) { data.nQQNum = result.m_nQQNum; sendMessage(QQCallBackMsg.UPDATE_GMEMBER_NUMBER, nGroupCode, 0, result); } } if (null == data.strNickName) { // 假定昵称一定能够从好友列表获取到,这里不处理 } return data; } private int groupId2Code(int nGroupId) { String strKey = String.valueOf(nGroupId); Integer nGroupCode = m_mapGroupId2Code.get(strKey); if (nGroupCode != null) { if (nGroupCode != 0) return nGroupCode; else m_mapGroupId2Code.remove(strKey); } sendMessage(QQCallBackMsg.INTERNAL_GROUPID2CODE, nGroupId, 0, null, true); nGroupCode = m_QQUser.m_internalData.m_nGroupCode; if (nGroupCode != 0) { m_mapGroupId2Code.put(strKey, nGroupCode); return nGroupCode; } return 0; } private boolean isNeedDownloadPic(ArrayList<Content> arrContent) { for (int i = 0; i < arrContent.size(); i++) { Content content = arrContent.get(i); if (null == content) continue; if (ContentType.CONTENT_TYPE_CUSTOM_FACE == content.m_nType || ContentType.CONTENT_TYPE_OFF_PIC == content.m_nType) { String strFullName = m_QQUser.getChatPicFullName(content.m_CFaceInfo.m_strName); File file = new File(strFullName); if (!file.exists()) return true; } } return false; } private boolean startChatPicTask(int nType, Object objMsg) { String strTaskName = "ChatPicTask_" + m_lChatPicCnt; ChatPicTask task = new ChatPicTask(strTaskName, m_httpClient.getHttpClient()); task.m_QQUser = m_QQUser; task.m_nType = nType; task.m_objMsg = objMsg; m_taskMgr.addTask(task); m_lChatPicCnt++; return true; } @Override public void doTask() { if (null == m_httpClient || null == m_QQUser || null == m_msgData) { return; } try { handleMsg(m_msgData); } catch (Exception e) { e.printStackTrace(); } finally { } m_mapBuddyData.clear(); m_mapGroupData.clear(); m_mapGroupId2Code.clear(); m_mapGMemberData.clear(); m_nPreMsgId = 0; m_nPreMsgId2 = 0; m_lChatPicCnt = 0; } }