int32_t COfflineMessageEvent::OnMessageEvent(MessageHeadSS * pMsgHead, IMsgBody* pMsgBody,
		const uint16_t nOptionLen, const void *pOptionData)
{
	if(pMsgBody==NULL || pMsgHead==NULL)
	{
		WRITE_ERROR_LOG("null pointer:{pMsgBody=0x%08x, pMsgHead=0x%08x}\n",pMsgBody,pMsgHead);
		return E_NULLPOINTER;
	}

	COfflineNoti *pOfflineNoti = dynamic_cast<COfflineNoti *>(pMsgBody);
	if(NULL == pOfflineNoti)
	{
		WRITE_ERROR_LOG("null pointer:{pOfflineNoti=0x%08x, nRoleID=%d}\n",pOfflineNoti,pMsgHead->nRoleID,pMsgHead->nRoomID);
		return E_NULLPOINTER;
	}

	WRITE_NOTICE_LOG("oh,shit!recv offline noti{nRoleID=%d}",pOfflineNoti->nRoleID);

	CPlayer *pPlayer = NULL;
	int32_t ret = g_PlayerMgt.GetPlayer(pOfflineNoti->nRoleID, pPlayer);
	if(ret < 0 || pPlayer == NULL)
	{
		WRITE_ERROR_LOG("get player object failed{RoleID=%d, ret=0x%08x}\n",pOfflineNoti->nRoleID, ret);
	}
	else
	{
		RoomID arrRoomID[MaxEnterRoomCount];
		int32_t nRoomCount = 0;
		pPlayer->GetAllEnterRoom(arrRoomID, MaxEnterRoomCount, nRoomCount);
		for(int32_t i = 0; i < nRoomCount; ++i)
		{
			CRoom *pRoom = NULL;
			ret = g_RoomMgt.GetRoom(arrRoomID[i], pRoom);
			if(ret < 0 || pRoom == NULL)
			{
				continue;
			}

			g_RoomMgt.DeletePlayer(arrRoomID[i], pOfflineNoti->nRoleID);
		}

		g_PlayerMgt.DestroyPlayer(pOfflineNoti->nRoleID);
	}

	//销毁相对应的玩家cache数据
	for(int32_t i = 0; i < MaxRoomServerCountPerRoomDispatcher; ++i)
	{
		CPlayerCache *pPlayerCache = NULL;
		int32_t ret = g_PlayerCacheMgt(i)->GetPlayerCache(pOfflineNoti->nRoleID, pPlayerCache);
		if(ret < 0 || pPlayerCache == NULL)
		{
			continue;
		}

		g_PlayerCacheMgt(i)->DestoryPlayerCache(pOfflineNoti->nRoleID);
	}

	return S_OK;
}
int32_t CBuildPlayerDataNoticeMessageEvent::OnMessageEvent(MessageHeadSS * pMsgHead, IMsgBody* pMsgBody,
		const uint16_t nOptionLen, const void *pOptionData)
{
	if(pMsgBody==NULL || pMsgHead==NULL)
	{
		WRITE_ERROR_LOG("null pointer:{pMsgBody=0x%08x, pMsgHead=0x%08x}\n",pMsgBody,pMsgHead);
		return E_NULLPOINTER;
	}

	CBuildPlayerDataNoti *pBuildPlayerDataNotice = dynamic_cast<CBuildPlayerDataNoti *>(pMsgBody);
	if(NULL == pBuildPlayerDataNotice)
	{
		WRITE_ERROR_LOG("pMsgBody transform to class child failed{ret=0x%08x}\n",E_NULLPOINTER);
		return E_NULLPOINTER;
	}

	WRITE_DEBUG_LOG("recv BuildPlayerDataNotice{nPlayerCount=%d}\n",pBuildPlayerDataNotice->nPlayerCount);

	for(int32_t i = 0; i < pBuildPlayerDataNotice->nPlayerCount; ++i)
	{
		CPlayer *pLocalPlayer = NULL;
		PlayerIndex nLocalPlayerIndex = enmInvalidPlayerIndex;
		int32_t ret = g_PlayerMgt.GetPlayer(pBuildPlayerDataNotice->arrRoleID[i], pLocalPlayer, nLocalPlayerIndex);
		//本地roomserver上没有这个玩家
		if(ret < 0 || pLocalPlayer == NULL)
		{
			ret = g_PlayerMgt.CreatePlayer(pBuildPlayerDataNotice->arrRoleID[i], pLocalPlayer, nLocalPlayerIndex);
			if(ret < 0 || pLocalPlayer == NULL)
			{
				WRITE_ERROR_LOG("null pointer:{pLocalPlayer=0x%08x, pMsgHead=0x%08x}\n",pLocalPlayer);
				continue;
			}

			uint32_t nStartPos = pLocalPlayer->GetStartPos();
			uint32_t nEndPos = pLocalPlayer->GetEndPos();

			uint32_t nPlayerDataSize = nEndPos - nStartPos;
			if(nPlayerDataSize >= pBuildPlayerDataNotice->arrPlayerDataSize[i])
			{
				memcpy(((uint8_t *)pLocalPlayer) + nStartPos, pBuildPlayerDataNotice->arrPlayerData[i], pBuildPlayerDataNotice->arrPlayerDataSize[i]);
			}

			RoomID arrRoomID[MaxEnterRoomCount];
			int32_t nEnterRoomCount = 0;
			pLocalPlayer->GetAllEnterRoom(arrRoomID, MaxEnterRoomCount, nEnterRoomCount);
			WRITE_DEBUG_LOG("building player data:{nEnterCount=%d}\n",nEnterRoomCount);
			for(int32_t j = 0; j < nEnterRoomCount; ++j)
			{
				CRoom *pRoom = NULL;
				RoomIndex nRoomIndex = enmInvalidRoomIndex;
				ret = g_RoomMgt.GetRoom(arrRoomID[j], pRoom, nRoomIndex);
				if(ret < 0 || nRoomIndex == enmInvalidRoomIndex)
				{
					WRITE_WARNING_LOG("building player data:but it's not found room object,or room is not rebulid!{nRoleID=%d, nRoomID=%d}\n", pBuildPlayerDataNotice->arrRoleID[i],arrRoomID[j]);
					continue;
				}

				if(pRoom->IsPlayerInRoom(nLocalPlayerIndex)||pRoom->IsRebotPlayerInRoom(pBuildPlayerDataNotice->arrRoleID[i]))
				{
					WRITE_NOTICE_LOG("building player data:player in this room{nRoleID=%d, nRoomID=%d}\n", pBuildPlayerDataNotice->arrRoleID[i], arrRoomID[j]);
					continue;
				}

				//将玩家添加到房间对象中去
				if(pLocalPlayer->IsReboot())
				{
					pRoom->AddRebotPlayer(pBuildPlayerDataNotice->arrRoleID[i]);
				}
				else
				{
					pRoom->AddPlayer(nLocalPlayerIndex, pLocalPlayer->GetVipLevel(), pLocalPlayer->IsHideEnter());
				}
				WRITE_NOTICE_LOG("building player data:player rebulid in room{nRoleID=%d, nRoomID=%d}\n", pBuildPlayerDataNotice->arrRoleID[i],arrRoomID[j]);
			}
		}
		else
		{
			CPlayer stPlayer;
			CPlayer *pRemotePlayer = &stPlayer;

			uint32_t nStartPos = pRemotePlayer->GetStartPos();
			uint32_t nEndPos = pRemotePlayer->GetEndPos();

			uint32_t nPlayerDataSize = nEndPos - nStartPos;
			if(nPlayerDataSize >= pBuildPlayerDataNotice->arrPlayerDataSize[i])
			{
				memcpy(((uint8_t *)pRemotePlayer) + nStartPos, pBuildPlayerDataNotice->arrPlayerData[i], pBuildPlayerDataNotice->arrPlayerDataSize[i]);
			}

			PlayerRoomInfo arrPlayerRoomInfo[MaxEnterRoomCount];
			int32_t nRoomInfoCount = 0;
			pRemotePlayer->GetPlayerRoomInfo(arrPlayerRoomInfo, MaxEnterRoomCount, nRoomInfoCount);

			//只合并目前本地服务器上已有的房间数据
			int32_t nEnterRoomCount = nRoomInfoCount;
			nRoomInfoCount = 0;
			for(int32_t j = 0; j < nEnterRoomCount; ++j)
			{
				CRoom *pRoom = NULL;
				RoomIndex nRoomIndex = enmInvalidRoomIndex;
				ret = g_RoomMgt.GetRoom(arrPlayerRoomInfo[j].nRoomID, pRoom, nRoomIndex);
				if(ret < 0 || pRoom == NULL)
				{
					WRITE_WARNING_LOG("building player data:but it's not found room object,or room is not rebulid!{nRoleID=%d, nRoomID=%d}\n", pBuildPlayerDataNotice->arrRoleID[i],arrPlayerRoomInfo[j].nRoomID);
					continue;
				}
				//将玩家添加到房间对象中去(修改于2012.6.5)
				if(pRoom->IsPlayerInRoom(nLocalPlayerIndex)||pRoom->IsRebotPlayerInRoom(pBuildPlayerDataNotice->arrRoleID[i]))
				{
					WRITE_NOTICE_LOG("building player data:player in this room{nRoleID=%d, nRoomID=%d}\n", pBuildPlayerDataNotice->arrRoleID[i], arrPlayerRoomInfo[j].nRoomID);
					continue;
				}
				if(pRemotePlayer->IsReboot())
				{
					pRoom->AddRebotPlayer(pBuildPlayerDataNotice->arrRoleID[i]);
				}
				else
				{
					pRoom->AddPlayer(nLocalPlayerIndex, pRemotePlayer->GetVipLevel(), pRemotePlayer->IsHideEnter());
				}

				arrPlayerRoomInfo[nRoomInfoCount] = arrPlayerRoomInfo[j];
				++nRoomInfoCount;
				WRITE_NOTICE_LOG("building player data:player rebulid in room{nRoleID=%d, nRoomID=%d}\n", pBuildPlayerDataNotice->arrRoleID[i],arrPlayerRoomInfo[j].nRoomID);
			}
			//合并player
			pLocalPlayer->MergePlayerRoomInfo(arrPlayerRoomInfo, nRoomInfoCount);
		}
	}

	return S_OK;
}
FRAME_HALLSERVER_NAMESPACE_BEGIN

int32_t CBuildPlayerDataMessageEvent::OnMessageEvent(MessageHeadSS * pMsgHead, IMsgBody* pMsgBody,
		const uint16_t nOptionLen, const void *pOptionData)
{
	if(pMsgBody == NULL || pMsgHead == NULL)
	{
		WRITE_ERROR_LOG("null pointer:{pMsgHead=0x%08x, pMsgBody=0x%08x}\n", pMsgHead, pMsgBody);
		return E_NULLPOINTER;
	}
	CBuildPlayerDataNoti *pNoti = dynamic_cast<CBuildPlayerDataNoti *>(pMsgBody);
	if(pNoti == NULL)
	{
		WRITE_ERROR_LOG("null pointer:pMsgBody transform to CBuildPlayerDataNoti class failed!{nMessageID=0x%08x, nSourceID=%d}\n",
				pMsgHead->nMessageID, pMsgHead->nSourceID);
		return E_NULLPOINTER;
	}

	WRITE_DEBUG_LOG("got build player data message notify!{nPlayerCount=%d}\n", pNoti->nPlayerCount);


	// build the player data
	for(int32_t i = 0; i < pNoti->nPlayerCount; ++i)
	{
		CPlayer* pLocalPlayer = NULL;
		int32_t ret = g_PlayerMgt.GetPlayer(pNoti->arrRoleID[i], pLocalPlayer);
		if(ret < 0 || pLocalPlayer == NULL)
		{
			// build a local player by player cache
			ret = g_PlayerMgt.CreatePlayer(pNoti->arrRoleID[i], pLocalPlayer);
			uint32_t nCount = g_PlayerMgt.GetRealPlayerCount();
			g_PlayerMgt.SetRealPlayerCount(++nCount);
			if(ret < 0 || pLocalPlayer == NULL)
			{
				WRITE_ERROR_LOG("build player:create player error!{ret=0x%08x}", ret);
				continue;
			}

			uint32_t nStartPos = pLocalPlayer->GetStartPos();
			uint32_t nEndPos = pLocalPlayer->GetEndPos();

			uint32_t nPlayerDataSize = nEndPos - nStartPos;
			if(nPlayerDataSize >= pNoti->arrPlayerDataSize[i])
			{
				memcpy(((uint8_t *)pLocalPlayer) + nStartPos, pNoti->arrPlayerData[i],
						pNoti->arrPlayerDataSize[i]);

				// verify if correctly built, print out!
				char szPlayer[MaxUpdateDataSize] = {0};
				uint32_t offset = 0;
				sprintf(szPlayer + offset, "built player!{nRoleID=%d, strRoleName=%s, nAccountID=%d, "
						"nVipLevel=%d, nUserLevel=%d, nPlayerGender=%d, nCurRoomCount=%d, ",
						pLocalPlayer->GetRoleID(), pLocalPlayer->GetRoleName(), pLocalPlayer->GetAccountID(),
						pLocalPlayer->GetVipLevel(), pLocalPlayer->GetUserLevel(), pLocalPlayer->GetPlayerGender(),
						pLocalPlayer->GetCurEnterRoomCount());
				offset = (uint32_t) strlen(szPlayer);
				if(pLocalPlayer->GetCurEnterRoomCount() > 0)
				{
					sprintf(szPlayer + offset, "{");
					offset = (uint32_t) strlen(szPlayer);

					PlayerRoomInfo arrPlayerRoomInfo[MaxEnterRoomCount];
					int32_t nActualCount = 0;
					pLocalPlayer->GetPlayerRoomInfo(arrPlayerRoomInfo, MaxEnterRoomCount, nActualCount);
					for(int32_t i = 0; i < nActualCount; ++i)
					{
						char* fmt = NULL;
						if(i < nActualCount - 1)
							fmt = "{nServerID=%d, nRoomID=%d, nPlayerState=%d}, ";
						else
							fmt = "{nServerID=%d, nRoomID=%d, nPlayerState=%d}}, ";

						sprintf(szPlayer + offset, fmt, arrPlayerRoomInfo[i].nServerID,
								arrPlayerRoomInfo[i].nRoomID, arrPlayerRoomInfo[i].nPlayerState);
						offset = (uint32_t) strlen(szPlayer);
					}
				}
				sprintf(szPlayer + offset, "nLoginTime=%ld, nTunnelIndex=%d, nServerID=%d, nOnlineTime=%lu, "
						"nLeftMoney=%d, nExperience=%d, nLastVersion=%d, nIsRobot=%d, nAdminCount=%d, ",
						pLocalPlayer->GetLoginTime(), pLocalPlayer->GetConnInfo().nTunnelIndex, pLocalPlayer->GetConnInfo().nServerID,
						pLocalPlayer->GetOnlineTime(),pLocalPlayer->GetLeftMoney(), pLocalPlayer->GetExperience(),
						pLocalPlayer->GetLastVersion(), (int32_t)pLocalPlayer->IsRobot(), pLocalPlayer->GetPlayerAdminCount());
				offset = (uint32_t) strlen(szPlayer);
				if(pLocalPlayer->GetPlayerAdminCount() > 0)
				{
					sprintf(szPlayer + offset, "{");
					offset = (uint32_t) strlen(szPlayer);

					RoomID arrRoomIDS[MaxBeAdminPerPlayer];
					int32_t nActualCount = 0;
					pLocalPlayer->GetAllAdminRoom(arrRoomIDS, MaxBeAdminPerPlayer, nActualCount);
					for(int32_t i = 0; i < nActualCount; ++i)
					{
						char* fmt = NULL;
						if(i < nActualCount - 1)
							fmt = "{nRoomID=%d, nRoleRank=%d}, ";
						else
							fmt = "{nRoomID=%d, nRoleRank=%d}}, ";

						sprintf(szPlayer + offset, fmt, arrRoomIDS[i], pLocalPlayer->GetAdminRoleRank(arrRoomIDS[i]));
						offset = (uint32_t) strlen(szPlayer);
					}
				}

				sprintf(szPlayer + offset, "nIdentityType=%u, nPlayerState=%d, nCurNewPlayerRoomCount=%u}\n",
						pLocalPlayer->GetIdentityType(), pLocalPlayer->GetPlayerState(), pLocalPlayer->GetNewPlayerRoomCount());
				offset = (uint32_t) strlen(szPlayer);

				WRITE_DEBUG_LOG("%s", szPlayer);
			}
			else
			{
				continue;
			}

			// build room player list
			RoomID arrRoomID[MaxEnterRoomCount];
			int32_t nEnterRoomCount = 0;
			pLocalPlayer->GetAllEnterRoom(arrRoomID, MaxEnterRoomCount, nEnterRoomCount);
			for(int32_t j = 0; j < nEnterRoomCount; ++j)
			{
				CRoom *pRoom = NULL;
				ret = g_RoomMgt.GetRoom(arrRoomID[j], pRoom);
				if(ret < 0 || pRoom == NULL)
				{
					WRITE_ERROR_LOG("building player data, failed to find room object!{nRoomID=%d}\n",
							arrRoomID[j]);
					continue;
				}

				if(pRoom->IsPlayerInRoom(pNoti->arrRoleID[i]))
				{
					WRITE_ERROR_LOG("building player data, the player should not in this room!{nRoleID=%d, nRoomID=%d}\n",
							pNoti->arrRoleID[i], arrRoomID[j]);
					continue;
				}

				//将玩家添加到房间对象中去
				pRoom->AddPlayer(pNoti->arrRoleID[i]);

			}
		}
	}


	return S_OK;
}