[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/codeindeep/TTServer/master/cpp/src/msg_server/GroupChat.cpp [Back]  [Original]

/*
 * GroupChat.cpp
 *
 *  Created on: 2014-1-3
 *      Author: ziteng@mogujie.com
 */

#include "GroupChat.h"
#include "MsgConn.h"
#include "DBServConn.h"
#include "RouteServConn.h"
#include "AttachData.h"
#include "ImUser.h"
CGroupChat* CGroupChat::s_group_chat_instance = NULL;

CGroupChat* CGroupChat::GetInstance()
{
	if (!s_group_chat_instance) {
		s_group_chat_instance = new CGroupChat();
	}

	return s_group_chat_instance;
}

void CGroupChat::HandleClientGroupListRequest(CImPduClientGroupListRequest* pPdu, CMsgConn* pFromConn)
{
	uint16_t cmd_id = pPdu->GetCommandId();
	uint16_t serv_cmd_id = (cmd_id == CID_GROUP_LIST_REQUEST) ?
						IM_PDU_TYPE_GROUP_LIST_REQUEST : IM_PDU_TYPE_GROUP_DIALOG_LIST_REQUEST;
	uint16_t cli_res_cmd_id = (cmd_id == CID_GROUP_LIST_REQUEST) ?
						CID_GROUP_LIST_RESPONSE : CID_GROUP_DIALOG_LIST_RESPONSE;
	uint32_t user_id = pFromConn->GetUserId();
	log("HandleClientGroupListReq, cmd_id=%u, user_id=%u\n", cmd_id, user_id);

	CDBServConn* pDbConn = get_db_serv_conn();
	if (pDbConn) {
        CDbAttachData attach_data(ATTACH_TYPE_HANDLE, pFromConn->GetHandle(), 0);
		CImPduGroupListRequest pdu(serv_cmd_id, user_id, attach_data.GetLength(), attach_data.GetBuffer());
		pdu.SetReserved(pPdu->GetReserved());
		pDbConn->SendPdu(&pdu);
	} else {
		CImPduClientGroupListResponse pdu(pFromConn->GetPduVersion(), cli_res_cmd_id, 0);
		pdu.SetReserved(pPdu->GetReserved());
		pFromConn->SendPdu(&pdu);
	}
}

void CGroupChat::HandleGroupListResponse(CImPduGroupListResponse* pPdu)
{
	uint16_t serv_cmd_id = pPdu->GetCommandId();
	uint16_t resp_cmd_id = (serv_cmd_id == IM_PDU_TYPE_GROUP_LIST_RESPONSE) ?
			CID_GROUP_LIST_RESPONSE : CID_GROUP_DIALOG_LIST_RESPONSE;
	uint32_t req_user_id = pPdu->GetReqUserId();
	uint32_t group_cnt = pPdu->GetGroupCnt();
    CDbAttachData attach_data(pPdu->GetAttachData(), pPdu->GetAttachLen());
	uint32_t handle = attach_data.GetHandle();
    
	group_info_t* group_list = pPdu->GetGroupList();
	log("HandleGroupListRes, cmd_id=%u, req_id=%u, group_cnt=%u\n", serv_cmd_id, req_user_id, group_cnt);

	for (uint32_t i = 0; i < group_cnt; i++) {
		_UpdateGroupMap(group_list[i].group_id, &(group_list[i].group_memeber_list));
	}

    CMsgConn* pConn = CImUserManager::GetInstance()->GetMsgConnByHandle(req_user_id, handle);
	if (pConn) {
		CImPduClientGroupListResponse pdu(resp_cmd_id, group_cnt, group_list);
		pdu.SetReserved(pPdu->GetReserved());
		pConn->SendPdu(&pdu);
	}

	CRouteServConn* pRouteConn = get_route_serv_conn();
	if (pRouteConn && group_cnt > 0) {
		set all_id_set;
		for (uint32_t i = 0; i < group_cnt; i++) {
			for (list::iterator it = group_list[i].group_memeber_list.begin();
					it != group_list[i].group_memeber_list.end();
					it++) {
				if (*it != req_user_id) {
					all_id_set.insert(*it);
				}
			}
		}

		list all_id_list;
		for (set::iterator it = all_id_set.begin(); it != all_id_set.end(); it++) {
			all_id_list.push_back(*it);
		}
		CImPduFriendStatusQuery pdu(2, req_user_id, &all_id_list);
		pRouteConn->SendPdu(&pdu);
	}
}

void CGroupChat::HandleClientGroupUserListRequest(CImPduClientGroupUserListRequest* pPdu, CMsgConn* pFromConn)
{
	uint32_t user_id = pFromConn->GetUserId();
	string group_id_url(pPdu->GetGroupId(), pPdu->GetGroupIdLen());
	uint32_t group_id = urltoid(group_id_url.c_str());
	log("HandleClientGroupUserListReq, user_id=%u, group_id=%u\n", user_id, group_id);

	CDBServConn* pDbConn = get_db_serv_conn();
	if (pDbConn) {
        CPduAttachData pduAttachData(ATTACH_TYPE_HANDLE_AND_PDU, pFromConn->GetHandle(), 0, (uchar_t*)pPdu);
		CImPduGroupUserListRequest pdu(user_id, group_id, pduAttachData.GetLength(), pduAttachData.GetBuffer());
		pdu.SetReserved(pPdu->GetReserved());
		pDbConn->SendPdu(&pdu);
	} else {
		CImPduClientGroupUserListResponse pdu(pFromConn->GetPduVersion(), group_id_url.c_str(), 2);
		pdu.SetReserved(pPdu->GetReserved());
		pFromConn->SendPdu(&pdu);
	}
}

void CGroupChat::HandleGroupUserListResponse(CImPduGroupUserListResponse* pPdu)
{
	uint32_t req_user_id = pPdu->GetReqUserId();
	uint32_t group_id = pPdu->GetGroupId();
	uint32_t result = pPdu->GetResult();
	string group_name(pPdu->GetGroupName(), pPdu->GetGroupNameLen());
	string group_avatar(pPdu->GetGroupAvatar(), pPdu->GetGroupAvatarLen());
	uint32_t group_creator_id = pPdu->GetGroupCreatorId();
	uint32_t group_type = pPdu->GetGroupType();
	uint32_t user_cnt = pPdu->GetUserCnt();
	uint32_t* user_list = pPdu->GetUserList();
	uint32_t attach_len = pPdu->GetAttachLen();
	uchar_t* attach_data = pPdu->GetAttachData();
	log("HandleGroupUserListRes, req_user_id=%u, group_id=%u, group_name=%s, group_avatar=%s, creator_id=%u, user_cnt=%u\n",
			req_user_id, group_id, group_name.c_str(), group_avatar.c_str(), group_creator_id, user_cnt);

    CPduAttachData pduAttachData(attach_data, attach_len);

	if (pduAttachData.GetPduLength() > 0) {
		log("GroupUserListRequest is send by server, group_id=%u\n", group_id);

		if (result) {
			log("something very bad happened!!!\n");
			return;
		}

		_UpdateGroupMap(group_id, user_cnt, user_list);

		group_member_t* group_member = _GetGroupMember(group_id);
		if (group_member) {
			group_member_t::iterator it;
			for (it = group_member->begin(); it != group_member->end(); it++) {
				uint32_t member_user_id = *it;
                CImUser* pImUser = CImUserManager::GetInstance()->GetImUserById(member_user_id);
                if (pImUser) {
                    CMsgConn* pFromConn = NULL;
                    if( member_user_id == req_user_id ){
                        uint32_t reqHandle = pduAttachData.GetHandle();
                        if(reqHandle != 0)
                            pFromConn = CImUserManager::GetInstance()->GetMsgConnByHandle(req_user_id, reqHandle);
                    }
                    pImUser->BroadcastData(pduAttachData.GetPdu(), pduAttachData.GetPduLength(), pFromConn);
                }
			}
		}
		return;
	}


	//CMsgConn* pConn = get_msg_conn(req_user_id);
	CMsgConn* pConn = CImUserManager::GetInstance()->GetMsgConnByHandle(req_user_id, pduAttachData.GetHandle());
    if (pConn) {
		string group_id_url = idtourl(group_id);
		string group_creator_id_url = idtourl(group_creator_id);
		CImPduClientGroupUserListResponse pdu(pConn->GetPduVersion(), group_id_url.c_str(), result, group_name.c_str(), group_avatar.c_str(),
				group_creator_id_url.c_str(), group_type, user_cnt, user_list);
		pdu.SetReserved(pPdu->GetReserved());
		pConn->SendPdu(&pdu);
	}

	if (result)
		return;

	_UpdateGroupMap(group_id, user_cnt, user_list);

	// query group member's online status
	CRouteServConn* pRouteConn = get_route_serv_conn();
	if (pRouteConn) {
		list member_id_list;
		for (uint32_t i = 0; i < user_cnt; i++) {
			if (user_list[i] != req_user_id) {
				member_id_list.push_back(user_list[i]);
			}
		}

		CImPduFriendStatusQuery pdu(2, req_user_id, &member_id_list);
		pRouteConn->SendPdu(&pdu);
	}
}

void CGroupChat::HandleClientGroupMessage(CImPduClientMsgData* pPdu, CMsgConn* pFromConn)
{
	if (pPdu->GetMsgLen() == 0)
		return;

	// send back ACK
	CImPduClientMsgDataAck pduAck(pPdu->GetSeqNo(), pPdu->GetFromIdLen(), pPdu->GetFromIdUrl());
	pduAck.SetReserved(pPdu->GetReserved());
	pFromConn->SendPdu(&pduAck);

	uint32_t from_user_id = pFromConn->GetUserId();
	string to_group_id_url(pPdu->GetToIdUrl(), pPdu->GetToIdLen());
	uint32_t to_group_id = urltoid(to_group_id_url.c_str());
	uint8_t msg_type = pPdu->GetMsgType();
	string msg_data((char*)pPdu->GetMsgData(), pPdu->GetMsgLen());
	log("HandleClientGroupMsg, %d->%d, content: %s\n", from_user_id, to_group_id, msg_data.c_str());

	uint32_t cur_time = time(NULL);
	CImPduMsgData msg_pdu(pPdu->GetSeqNo(), from_user_id, to_group_id, cur_time, msg_type,
			pPdu->GetMsgLen(), pPdu->GetMsgData(), pFromConn->GetClientType(), pPdu->GetAttachLen(), pPdu->GetAttachData());

	// send to DB storage server
	CDBServConn* pDbConn = get_db_serv_conn();
	if (pDbConn) {
		pDbConn->SendPdu(&msg_pdu);
	}

	// send to route server
	CRouteServConn* pRouteConn = get_route_serv_conn();
	if (pRouteConn) {
		pRouteConn->SendPdu(&msg_pdu);
	}

	// send to group members in this server
	group_member_t* group_member = _GetGroupMember(to_group_id);
	if (group_member) {
		pPdu->AddTime();
		group_member_t::iterator it;
		for (it = group_member->begin(); it != group_member->end(); it++) {
			uint32_t member_user_id = *it;
            CImUser* pImUser = CImUserManager::GetInstance()->GetImUserById(member_user_id);
            if (pImUser) {
                pImUser->BroadcastPdu(pPdu, pFromConn);
            }
		}
	} else {
		// DB
        log("this server does not have enough group info\n");
        CPduAttachData pduAttachData(ATTACH_TYPE_HANDLE_AND_PDU, pFromConn->GetHandle(), pPdu->GetLength(), pPdu->GetBuffer());
		CImPduGroupUserListRequest pdu(from_user_id, to_group_id, pduAttachData.GetLength(), pduAttachData.GetBuffer());
        
		pDbConn->SendPdu(&pdu);
	}
}

void CGroupChat::HandleGroupMessage(CImPduMsgData* pPdu)
{
	uint32_t from_user_id = pPdu->GetFromUserId();
	uint32_t to_group_id = pPdu->GetToUserId();
	string msg_data((char*)pPdu->GetMsgData(), pPdu->GetMsgLen());
	log("HandleGroupMsg, %u->%u\n", from_user_id, to_group_id);

    uint32_t seq_no = pPdu->GetRequestId();
    string from_id_url = idtourl(from_user_id);
    string to_id_url = idtourl(to_group_id);
    uint8_t msg_type = pPdu->GetMsgType();
    
    CImPduClientMsgData pdu(seq_no, from_id_url.c_str(), to_id_url.c_str(), pPdu->GetCreateTime(),
                            msg_type, pPdu->GetMsgLen(), pPdu->GetMsgData(),
                            pPdu->GetAttachLen(), pPdu->GetAttachData());
    
	group_member_t* group_member = _GetGroupMember(to_group_id);
	if (group_member)
    {
		group_member_t::iterator it;
		for (it = group_member->begin(); it != group_member->end(); it++) {
			uint32_t member_user_id = *it;
            
            CImUser* pImUser = CImUserManager::GetInstance()->GetImUserById(member_user_id);
            if (pImUser) {
                pImUser->BroadcastPdu(&pdu);
            }
		}
	}
    else
    {
        // DB
        log("this server does not have enough group info\n");
        CPduAttachData pduAttachData(ATTACH_TYPE_HANDLE_AND_PDU, 0, pdu.GetLength(), pdu.GetBuffer());
		CImPduGroupUserListRequest pduLR(from_user_id, to_group_id, pduAttachData.GetLength(), pduAttachData.GetBuffer());
        CDBServConn* pDbConn = get_db_serv_conn();
        if(pDbConn)
            pDbConn->SendPdu(&pduLR);
    }
}

void CGroupChat::HandleClientGroupUnreadMsgCntRequest(CImPduClientGroupUnreadMsgCntRequest* pPdu,
		CMsgConn* pFromConn)
{
	uint32_t req_user_id = pFromConn->GetUserId();
	log("HandleClientGroupUnreadMsgCntReq, user_id=%u\n", req_user_id);

	CDBServConn* pDbConn = get_db_serv_conn();
	if (pDbConn) {
        CDbAttachData attach_data(ATTACH_TYPE_HANDLE, pFromConn->GetHandle(), 0);
		CImPduGroupUnreadMsgCntRequest pdu(req_user_id, pFromConn->GetClientType(),
                            attach_data.GetLength(), attach_data.GetBuffer());
		pdu.SetReserved(pPdu->GetReserved());
		pDbConn->SendPdu(&pdu);
	} else {
		CImPduClientGroupUnreadMsgCntResponse pdu(0);
		pdu.SetReserved(pPdu->GetReserved());
		pFromConn->SendPdu(&pdu);
	}
}

void CGroupChat::HandleGroupUnreadMsgCntResponse(CImPduGroupUnreadMsgCntResponse* pPdu)
{
	uint32_t req_user_id = pPdu->GetReqUserId();
	uint32_t unread_cnt = pPdu->GetGroupUnreadCnt();
	group_unread_cnt_t* unread_list = pPdu->GetGroupUnreadList();
	log("HandleGroupUnreadMsgCntResp, req_user_id=%u, unread_cnt=%u\n", req_user_id, unread_cnt);
    CDbAttachData attach_data(pPdu->GetAttachData(), pPdu->GetAttachLen());

	CMsgConn* pConn = CImUserManager::GetInstance()->GetMsgConnByHandle(req_user_id, attach_data.GetHandle());
	if (pConn) {
		CImPduClientGroupUnreadMsgCntResponse pdu(unread_cnt, unread_list);
		pdu.SetReserved(pPdu->GetReserved());
		pConn->SendPdu(&pdu);
	}
}

void CGroupChat::HandleClientGroupUnreadMsgRequest(CImPduClientGroupUnreadMsgRequest* pPdu, CMsgConn* pFromConn)
{
	uint32_t req_user_id = pFromConn->GetUserId();
	string group_id_url(pPdu->GetGroupIdUrl(), pPdu->GetGroupIdLen());
	uint32_t group_id = urltoid(group_id_url.c_str());
	log("HandleClientGroupUnreadMsgReq, req_user_id=%u, group_id=%u\n", req_user_id, group_id);

	CDBServConn* pDbConn = get_db_serv_conn();
	if (pDbConn) {
        CDbAttachData attach_data(ATTACH_TYPE_HANDLE, pFromConn->GetHandle(), 0);
		CImPduGroupUnreadMsgRequest pdu(req_user_id, group_id, pFromConn->GetClientType(),
                attach_data.GetLength(), attach_data.GetBuffer());
		pdu.SetReserved(pPdu->GetReserved());
		pDbConn->SendPdu(&pdu);
	}
}

void CGroupChat::HandleGroupMsgListResponse(CImPduGroupMsgListResponse* pPdu)
{
	uint32_t req_user_id = pPdu->GetReqUserId();
	uint32_t req_cmd_id = pPdu->GetReqCmdId();
	uint32_t group_id = pPdu->GetGroupId();
	uint32_t msg_cnt = pPdu->GetMsgCnt();
	group_msg_t* msg_list = pPdu->GetMsgList();
	log("HandleGroupMsgListResp, req_user_id=%u, req_cmd_id=%u, group_id=%u, msg_cnt=%u\n",
			req_user_id, req_cmd_id, group_id, msg_cnt);
    CDbAttachData attach_data(pPdu->GetAttachData(), pPdu->GetAttachLen());
	CMsgConn* pMsgConn = CImUserManager::GetInstance()->GetMsgConnByHandle(req_user_id,
                                                                           attach_data.GetHandle());
	if (pMsgConn) {
		uint32_t cmd_id = CID_GROUP_UNREAD_MSG_RESPONSE;

		string group_id_url = idtourl(group_id);
		CImPduClientGroupMsgListResponse pdu(cmd_id, group_id_url.c_str(), msg_cnt, msg_list);
		pdu.SetReserved(pPdu->GetReserved());
		pMsgConn->SendPdu(&pdu);
	}
}

void CGroupChat::HandleClientGroupMsgReadAck(CImPduClientGroupMsgReadAck* pPdu, CMsgConn* pFromConn)
{
	uint32_t req_user_id = pFromConn->GetUserId();
	string group_id_url(pPdu->GetGroupIdUrl(), pPdu->GetGroupIdLen());
	uint32_t group_id = urltoid(group_id_url.c_str());
	log("HandleClientGroupMsgReadAck, req_id=%u, group_id=%u\n", req_user_id, group_id);

	CDBServConn* pDbConn = get_db_serv_conn();
	if (pDbConn) {
		CImPduGroupMsgReadAck pdu(req_user_id, group_id, pFromConn->GetClientType());
		pdu.SetReserved(pPdu->GetReserved());
		pDbConn->SendPdu(&pdu);
	}
}

void CGroupChat::HandleClientGroupCreateTmpGroupRequest(CImPduClientGroupCreateTmpGroupRequest* pPdu, CMsgConn* pFromConn)
{
	uint32_t req_user_id = pFromConn->GetUserId();
	string group_name(pPdu->GetGroupName(), pPdu->GetGroupNameLen());
	string group_avatar(pPdu->GetGroupAvatar(), pPdu->GetGroupAvatarLen());
	uint32_t user_cnt = pPdu->GetUserCnt();
	user_id_t* user_list = pPdu->GetUserList();
	log("HandleClientCreateTmpGroupReq, req_id=%u, group_name=%s, avatar_url=%s, user_cnt=%u\n",
			req_user_id, group_name.c_str(), group_avatar.c_str(), user_cnt);

	CDBServConn* pDbConn = get_db_serv_conn();
	if (pDbConn) {
		list user_id_list;
		for (uint32_t i = 0; i < user_cnt; i++) {
			string user_id_url(user_list[i].id_url, user_list[i].id_len);
			uint32_t user_id = urltoid(user_id_url.c_str());
			user_id_list.push_back(user_id);
		}
        CDbAttachData attach_data(ATTACH_TYPE_HANDLE, pFromConn->GetHandle(), 0);
		CImPduGroupCreateTmpGroupRequest pdu(req_user_id, group_name.c_str(), group_avatar.c_str(),
                    &user_id_list, attach_data.GetLength(), attach_data.GetBuffer());
		pdu.SetReserved(pPdu->GetReserved());
		pDbConn->SendPdu(&pdu);
	} else {
		log("no DB connection\n");
		CImPduClientGroupCreateTmpGroupResponse pdu(1, NULL, group_name.c_str());
		pdu.SetReserved(pPdu->GetReserved());
		pFromConn->SendPdu(&pdu);
	}
}

void CGroupChat::HandleGroupCreateTmpGroupResponse(CImPduGroupCreateTmpGroupResponse* pPdu)
{
	uint32_t req_user_id = pPdu->GetReqUserId();
	uint32_t result = pPdu->GetResult();
	uint32_t group_id = pPdu->GetGroupId();
	string group_name(pPdu->GetGroupName(), pPdu->GetGroupNameLen());
	uint32_t user_cnt = pPdu->GetUserCnt();
	uint32_t* user_list = pPdu->GetUserList();
	log("HandleCreateTmpGroupResp, req_id=%u, result=%u, group_id=%u\n", req_user_id, result, group_id);

	string group_id_url = idtourl(group_id);
	CImPduClientGroupCreateTmpGroupResponse pdu(result, group_id_url.c_str(), group_name.c_str(),
			user_cnt, user_list);
	pdu.SetReserved(pPdu->GetReserved());

    CDbAttachData attach_data(pPdu->GetAttachData(), pPdu->GetAttachLen());
	if (!result) {
		_UpdateGroupMap(group_id, user_cnt, user_list);

		CRouteServConn* pRouteConn = get_route_serv_conn();
		if (pRouteConn) {
			pRouteConn->SendPdu(pPdu);
		}

		// push create tmp group info to other group members
		for (uint32_t i = 0; i < user_cnt; i++) {
			if (user_list[i] != req_user_id) {
				_SendPduToUser(&pdu, user_list[i]);
			}
		}
	}

	_SendPduToUser(&pdu, req_user_id);
}

void CGroupChat::HandleGroupCreateTmpGroupBroadcast(CImPduGroupCreateTmpGroupResponse* pPdu)
{
	uint32_t group_id = pPdu->GetGroupId();
	string group_name(pPdu->GetGroupName(), pPdu->GetGroupNameLen());
	uint32_t user_cnt = pPdu->GetUserCnt();
	uint32_t* user_list = pPdu->GetUserList();
	log("HandleCreateTmpGroupBroadcast, group_id=%u, user_cnt=%u\n", group_id, user_cnt);

	_UpdateGroupMap(group_id, user_cnt, user_list);

	CImPduClientGroupCreateTmpGroupResponse pdu(0, idtourl(group_id), group_name.c_str(), user_cnt, user_list);
	for (uint32_t i = 0; i < user_cnt; i++) {
		_SendPduToUser(&pdu, user_list[i]);
	}
}

void CGroupChat::HandleClientGroupChangeMemberRequest(CImPduClientGroupChangeMemberRequest* pPdu, CMsgConn* pFromConn)
{
    uint32_t change_type = pPdu->GetChangeType();
	uint32_t req_user_id = pFromConn->GetUserId();
	string group_id_url(pPdu->GetGroupId(), pPdu->GetGroupIdLen());
	uint32_t group_id = urltoid(group_id_url.c_str());
	uint32_t user_cnt = pPdu->GetUserCnt();
	user_id_t* user_list = pPdu->GetUserList();
	log("HandleClientChangeMemberReq, change_type=%u, req_id=%u, group_id=%u, user_cnt=%u\n",
			change_type, req_user_id, group_id, user_cnt);

	CDBServConn* pDbConn = get_db_serv_conn();
	if (pDbConn) {
		list user_id_list;
		for (uint32_t i = 0; i < user_cnt; i++) {
			string user_id_url(user_list[i].id_url, user_list[i].id_len);
			uint32_t user_id = urltoid(user_id_url.c_str());
			user_id_list.push_back(user_id);
		}

       CDbAttachData attach_data(ATTACH_TYPE_HANDLE, pFromConn->GetHandle(), 0);
		CImPduGroupChangeMemberRequest pdu(change_type, req_user_id, group_id, &user_id_list,
                                           attach_data.GetLength(), attach_data.GetBuffer());
		pdu.SetReserved(pPdu->GetReserved());
		pDbConn->SendPdu(&pdu);
	} else {
		log("no DB connection\n");
		CImPduClientGroupChangeMemberResponse pdu(change_type, 1, group_id_url.c_str());
		pdu.SetReserved(pPdu->GetReserved());
		pFromConn->SendPdu(&pdu);
	}
}

void CGroupChat::HandleGroupChangeMemberResponse(CImPduGroupChangeMemberResponse* pPdu)
{
	uint32_t change_type = pPdu->GetChangeType();
    uint32_t req_user_id = pPdu->GetReqUserId();
	uint32_t result = pPdu->GetResult();
	uint32_t group_id = pPdu->GetGroupId();
	uint32_t user_cnt = pPdu->GetUserCnt();
	uint32_t* user_list = pPdu->GetUserList();
	log("HandleChangeMemberResp, change_type=%u, req_id=%u, group_id=%u, result=%u\n",
			change_type, req_user_id, group_id, result);
    CDbAttachData attach_data(pPdu->GetAttachData(), pPdu->GetAttachLen());
	string group_id_url = idtourl(group_id);
	CImPduClientGroupChangeMemberResponse pdu(change_type, result, group_id_url.c_str(), user_cnt, user_list);
	pdu.SetReserved(pPdu->GetReserved());

	if (!result) {
		if (change_type == GROUP_MEMBER_ADD_TYPE) {
			_JoinGroup(group_id, user_cnt, user_list);
		} else {
			_QuitGroup(group_id, user_cnt, user_list);
		}

		CRouteServConn* pRouteConn = get_route_serv_conn();
		if (pRouteConn) {
			pRouteConn->SendPdu(pPdu);
		}

		// push join/quit group response to other group member
		group_member_t* member = _GetGroupMember(group_id);
		if (member) {
			for (set::iterator it = member->begin(); it != member->end(); it++) {
				uint32_t user_id = *it;
				if (user_id != req_user_id) {
					_SendPduToUser(&pdu, user_id);
				}
			}
		}

		// push join/quit group response to join/quit user list
		for (uint32_t i = 0; i < user_cnt; i++) {
			uint32_t user_id = user_list[i];
			if (user_id != req_user_id) {
				_SendPduToUser(&pdu, user_id);
			}
		}
	}

	_SendPduToUser(&pdu, req_user_id);
}

void CGroupChat::HandleGroupChangeMemberBroadcast(CImPduGroupChangeMemberResponse* pPdu)
{
	uint32_t change_type = pPdu->GetChangeType();
	uint32_t group_id = pPdu->GetGroupId();
	uint32_t user_cnt = pPdu->GetUserCnt();
	uint32_t* user_list = pPdu->GetUserList();
	log("HandleChangeMemberBroadcast, change_type=%u, group_id=%u, user_cnt=%u\n", change_type, group_id, user_cnt);

	if (change_type == GROUP_MEMBER_ADD_TYPE) {
		_JoinGroup(group_id, user_cnt, user_list);
	} else {
		_QuitGroup(group_id, user_cnt, user_list);
	}

	// push join/quit group response to other group member
	string group_id_url = idtourl(group_id);

	CImPduClientGroupChangeMemberResponse pdu(change_type, 0, group_id_url.c_str(), user_cnt, user_list);
	group_member_t* member = _GetGroupMember(group_id);
	if (member) {
		for (set::iterator it = member->begin(); it != member->end(); it++) {
			uint32_t user_id = *it;
			_SendPduToUser(&pdu, user_id);
		}
	}

	// push join/quit group response to join/quit user list
	for (uint32_t i = 0; i < user_cnt; i++) {
		uint32_t user_id = user_list[i];
		_SendPduToUser(&pdu, user_id);
	}
}

void CGroupChat::HandleGroupChangeMemberNotify(CImPduGroupChangeMemberNotify *pPdu)
{
	uint32_t group_id = pPdu->GetGroupId();
	uint32_t user_cnt = pPdu->GetUserCnt();
	uint32_t* user_list = pPdu->GetUserList();
	log("HandleGroupChangeMemberNotify, group_id=%u, user_cnt=%u\n", group_id, user_cnt);
    
	HandleGroupChangeMemberNotify(group_id, user_cnt, user_list);
}

void CGroupChat::HandleGroupChangeMemberNotify(uint32_t group_id, uint32_t user_cnt,
                                               uint32_t* user_list)
{
    group_member_t* old_group = _GetGroupMember(group_id);
    group_member_t group_tmp;
    if (old_group != NULL) {
        group_tmp = *old_group;
    }
    
    for (uint32_t i = 0; i < user_cnt; i++) {
        group_tmp.insert(user_list[i]);
    }
    
    _UpdateGroupMap(group_id, user_cnt, user_list);

	// push join/quit group response to other group member
	string group_id_url = idtourl(group_id);
    
	CImPduClientGroupChangeMemberNotify pdu( group_id_url.c_str(), user_cnt, user_list);
    for (group_member_t::iterator it = group_tmp.begin(); it != group_tmp.end(); it++) {
        uint32_t user_id = *it;
        _SendPduToUser(&pdu, user_id);
	}
}

void CGroupChat::HandleGroupCreateNormalGroupNotify(CImPduGroupCreateNormalGroupNotify *pPdu)
{
    uint32_t group_id = pPdu->GetGroupId();
	string group_name(pPdu->GetGroupName(), pPdu->GetGroupNameLen());
    string group_avatar(pPdu->GetGroupAvatar(), pPdu->GetGroupAvatarLen());
	uint32_t user_cnt = pPdu->GetUserCnt();
	uint32_t* user_list = pPdu->GetUserList();
	log("HandleGroupCreateNormalGroupNotify, group_id=%u, user_cnt=%u\n", group_id, user_cnt);
    
	HandleGroupCreateNormalGroupNotify(group_id, group_name.c_str(), group_avatar.c_str(),
                                       user_cnt, user_list);
}

void CGroupChat::HandleGroupCreateNormalGroupNotify(uint32_t group_id, const char* group_name,
                                const char* group_avatar, uint32_t user_cnt, uint32_t* user_list)
{
    _UpdateGroupMap(group_id, user_cnt, user_list);
    
	CImPduClientGroupCreateNormalGroupNotify pdu(idtourl(group_id), group_name, group_avatar, user_cnt, user_list);
	for (uint32_t i = 0; i < user_cnt; i++) {
		_SendPduToUser(&pdu, user_list[i]);
	}
}
// caution: update group member every time, can use cache in future
void CGroupChat::_UpdateGroupMap(uint32_t group_id, list* user_list)
{
	if (user_list->size() == 0)
		return;

	group_member_t* group_member = new group_member_t;
	if (!group_member)
		return;

	for (list::iterator it = user_list->begin(); it != user_list->end(); it++) {
		group_member->insert(*it);
	}

	group_map_t::iterator it = m_group_map.find(group_id);
	if (it == m_group_map.end()) {
		m_group_map.insert(make_pair(group_id, group_member));
	} else {
		group_member_t* old_group = it->second;
		delete old_group;

		it->second = group_member;
	}
}

void CGroupChat::_UpdateGroupMap(uint32_t group_id, uint32_t user_cnt, uint32_t* user_list)
{
	list user_id_list;
	for (uint32_t i = 0; i < user_cnt; i++) {
		user_id_list.push_back(user_list[i]);
	}

	_UpdateGroupMap(group_id, &user_id_list);
}

group_member_t* CGroupChat::_GetGroupMember(uint32_t group_id)
{
	group_member_t* group_member = NULL;
	group_map_t::iterator it = m_group_map.find(group_id);
	if (it != m_group_map.end()) {
		group_member = it->second;
	}

	return group_member;
}

void CGroupChat::_JoinGroup(uint32_t group_id, uint32_t user_cnt, uint32_t* user_list)
{
	group_member_t* group_member = _GetGroupMember(group_id);

	if (group_member) {
		for (uint32_t i = 0; i < user_cnt; i++) {
			group_member->insert(user_list[i]);
		}
	}
}

void CGroupChat::_QuitGroup(uint32_t group_id, uint32_t user_cnt, uint32_t* user_list)
{
	group_member_t* group_member = _GetGroupMember(group_id);

	if (group_member) {
		for (uint32_t i = 0; i < user_cnt; i++) {
			group_member->erase(user_list[i]);
		}
	}
}

void CGroupChat::_SendPduToUser(CImPdu* pPdu, uint32_t user_id)
{
    CImUser* pToUser = CImUserManager::GetInstance()->GetImUserById(user_id);
    if(pToUser) {
        pToUser->BroadcastPdu(pPdu);
    }
}

Web Proxy Viewer  |  New URL  |  Original Page