Files
mir_server/server/LogicServer/base/OfflineCenterUserMgr.cpp
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

674 lines
18 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "../base/Container.hpp"
#define MARRYBLESSNUM 10
//////////////////////////////////////////////////////////////
//为某个玩家添加离线信息
COfflineCenterUser * COfflineCenterUserMgr::AddCenterOffLineUser(unsigned int nActorId,bool &isExist)
{
COfflineCenterUser * pUser = GetUserByActorId(nActorId);
if(pUser ==NULL) //如果找不到这个玩家
{
isExist =false;
pUser = m_FixedSizeAllocator.allocObject();
if(pUser)
{
new (pUser)COfflineCenterUser();
pUser->nActorId = nActorId;
m_actoridMap.insert( std::make_pair(nActorId, pUser) );
}
return pUser;
}
else
{
isExist =true;
return pUser;
}
}
//移除所有离线玩家信息TODO优化添加一个freelist存储之
void COfflineCenterUserMgr::RemoveAllUser()
{
CLogicEngine *logic = GetLogicServer()->GetLogicEngine();
OfflineUserMap::iterator iter = m_actoridMap.begin(),itEnd = m_actoridMap.end();
while(iter !=itEnd )
{
COfflineCenterUser * pUser = iter->second;
if(pUser)
{
//释放物品的内存
for(INT_PTR i=0; i< CEquipVessel::EquipmentCount; i++)
{
CUserItem *pItem = pUser->m_Equips[i];
if(pItem)
{
logic->DestroyUserItem(pItem); //销毁
pUser->m_Equips[i]= NULL;
}
}
//释放其他内存
pUser->m_Skilldata.clear();
pUser->m_nStrengths.clear();
pUser->m_NewTitleDataList.clear();
pUser->m_Almirah.clear();
//析构
pUser->~COfflineCenterUser();
m_FixedSizeAllocator.freeObject(pUser);
}
iter ++;
}
m_actoridMap.clear(); //清掉
}
//装载玩家的其他信息
void COfflineCenterUserMgr::OnLoadCenterActorData(unsigned int nActorId, CDataPacketReader &reader)
{
ActorOfflineMsg msg;
if (reader.getAvaliableLength() < sizeof(ActorOfflineMsg))
{
auto iter = m_noticeMap.find(nActorId);
if (iter != m_noticeMap.end())
{
m_noticeMap.erase(iter);
}
}
reader >> msg;
COfflineCenterUser * pUser= GetUserByActorId(nActorId);
if(pUser ==NULL)
{
OutputMsg(rmError,_T("%s,actorid=%d, not exist"),__FUNCTION__,nActorId);
return;
}
memcpy(pUser,&msg,sizeof(msg));
pUser->name[sizeof(pUser->name) -1] =0; //防止数据出错
pUser->sGuildName[sizeof(pUser->sGuildName) -1] =0; //防止数据出错
CLogicEngine *pEngineer = GetLogicServer()->GetLogicEngine();
// 加载装备数据
int nCount =0;
{
CUserItem userItem;
reader >> nCount; //装备的数目
for (INT_PTR i=0 ; i < nCount; i++ )
{
userItem << reader;
if (CUserItem *pUerItem = pEngineer->CopyAllocUserItem(false,&userItem))
{
INT_PTR nPos =-1;
const CStdItem *pStdItem = GetLogicServer()->GetDataProvider()->GetStdItemProvider().GetStdItem(pUerItem->wItemId);
if ( !pStdItem )
{
OutputMsg(rmError,_T("actorID=%d的玩家item=%d,装备非法"),nActorId,pUerItem->wItemId);
pEngineer->DestroyUserItem(pUerItem); //出错则删除内存防止泄露
continue;
}
else
{
nPos = CEquipVessel::GetItemTakeOnPosition((Item::ItemType)pStdItem->m_btType,pUerItem->btHandPos);
if(nPos <0)
{
OutputMsg(rmError,_T("actorID=%d的玩家nPos=%d,location=%d,itemId=%d,guid=%lld,装备位置非法"),nActorId,nPos,pUerItem->btHandPos,pUerItem->wItemId,pUerItem->series);
pEngineer->DestroyUserItem(pUerItem); //出错则删除内存防止泄露
pUerItem = NULL;
continue;
}
if(nPos >=0 && pUser->m_Equips[nPos] ==NULL)
{
pUser->m_Equips[nPos] = pUerItem;
}
else
{
OutputMsg(rmError,_T("actorID=%u的玩家nPos=%d已经有装备了"),nActorId,nPos);
pEngineer->DestroyUserItem(pUerItem); //出错则删除内存防止泄露
pUerItem = NULL;
}
}
}
}
}
// 加载技能数据
{
CSkillSubSystem::SKILLDATA data;
reader >> nCount;
CSkillProvider *pSkillProvider = GetLogicServer()->GetDataProvider()->GetSkillProvider();
for(INT_PTR i=0; i < nCount; i++)
{
reader.readBuf(&data,sizeof(ONESKILLDBDATA) );
data.bEvent =0;
data.bMjMask =0;
const OneSkillData *pConfig = pSkillProvider->GetSkillData(data.nSkillID);
if(pConfig ==NULL) continue;
data.bIsPassive = ((pConfig->nSkillType == stPassiveSkill)?1:0);
data.bPriority = pConfig->bPriority;
data.nSkillType = pConfig->nSkillType;
pUser->m_Skilldata.push_back(data);
}
}
// 加载强化信息
{
reader >> nCount;
for(INT_PTR i=0; i < nCount; i++)
{
int nType = 0;
StrengthInfo it;
reader >> nType >>it.nId >> it.nLv;
if(it.nId > 0)
pUser->m_nStrengths[nType].push_back(it);
}
}
// 加载称号信息
{
reader >> nCount;
for(INT_PTR i=0; i < nCount; i++)
{
unsigned int nValue = 0, nTime = 0;
reader >> nValue >> nTime;
WORD wId = LOWORD(nValue);
CNewTitleSystem::NEWTITLEDATA newTitleData;
newTitleData.wId = wId;
newTitleData.nRemainTime = nTime;
pUser->m_NewTitleDataList.push_back(newTitleData);
}
}
// 加载时装信息
{
reader >> nCount;
CAlmirahItem oneItem;
for(INT_PTR i=0; i < nCount; i++)
{
reader >> oneItem.nModelId;
reader >> oneItem.nLv;
reader >> oneItem.btTakeOn;
pUser->m_Almirah.push_back(oneItem);
}
}
// 加载神魔
{
reader >> nCount;
GhostData oneItem;
for(INT_PTR i=0; i < nCount; i++)
{
reader >> oneItem.nId;
reader >> oneItem.nLv;
reader >> oneItem.nBless;
pUser->m_ghost.push_back(oneItem);
}
}
// 加载圣物兵魂
{
reader >> nCount;
for(INT_PTR i = 0; i < nCount; i++)
{
SoulWeaponNetData oneItem;
oneItem.nId = i + 1;
reader >> oneItem.nLorderId >> oneItem.nStarId >> oneItem.nLvId;
reader.readString(oneItem.cBestAttr);
oneItem.cBestAttr[sizeof(oneItem.cBestAttr)-1] = 0;
pUser->vSoulWeapon.push_back(oneItem);
}
}
// 通知玩家
auto it = m_noticeMap.find(nActorId);
if (it != m_noticeMap.end())
{
auto& vec = it->second;
for (size_t i = 0; i < vec.size(); i++)
{
auto func = vec[i];
func(pUser);
}
m_noticeMap.erase(it);
}
}
//加载某个离线玩家信息
void COfflineCenterUserMgr::LoadCenterUser(unsigned nActorId, unsigned nViewerId, int nsys,int ncmd)
{
if(nActorId ==0) return;
//如果这个玩家已经装载了,那么不再装载
bool isExist;
//如果已经存在这样的一个用户的话就不需要装载了
// AddCenterOffLineUser(nActorId,isExist);
if (nViewerId) m_noticeMap[nActorId].push_back(std::bind(&COfflineCenterUserMgr::viewCenterByOfflineUser, this, std::placeholders::_1, nViewerId, nsys,ncmd));
// if(isExist) return;
//向Center服务器发数据数据包
CLocalCrossClient* pCSClient = GetLogicServer()->GetCrossClient();
if (pCSClient->connected())
{
CDataPacket& DataPacket = pCSClient->allocProtoPacket(jxInterSrvComm::CrossServerProto::cGetActorOfflineData);
int nServerId = GetLogicServer()->GetCrossServerId();
DataPacket << nServerId;
DataPacket << (unsigned int) nActorId; //去装载跨服玩家的离线数据
GetLogicServer()->GetCrossClient()->flushProtoPacket(DataPacket);
}
}
//移除某个离线玩家信息TODO优化添加一个freelist存储之
void COfflineCenterUserMgr::RemoveUser(unsigned int nActorID)
{
OfflineUserMap::iterator iter = m_actoridMap.find(nActorID);
if (iter == m_actoridMap.end())
{
return;
}
COfflineCenterUser *pUser = iter->second;
if (pUser)
{
CLogicEngine *logic = GetLogicServer()->GetLogicEngine();
//释放物品的内存
for(INT_PTR i=0; i< CEquipVessel::EquipmentCount; i++)
{
CUserItem *pItem = pUser->m_Equips[i];
if(pItem)
{
logic->DestroyUserItem(pItem); //销毁
pUser->m_Equips[i]= NULL;
}
}
//释放其他内存
pUser->m_Skilldata.clear();
pUser->m_nStrengths.clear();
pUser->m_NewTitleDataList.clear();
pUser->m_Almirah.clear();
//析构
pUser->~COfflineCenterUser();
m_FixedSizeAllocator.freeObject(pUser);
}
m_actoridMap.erase(iter);
}
void COfflineCenterUserMgr::viewCenterByOfflineUser(COfflineCenterUser *pUser, unsigned int nActorId, int nsys,int ncmd)
{
CActor *pActor = GetGlobalLogicEngine()->GetEntityMgr()->GetEntityPtrByActorID(nActorId);
if (!pActor) return;
CActorPacket pack;
CDataPacket & data = pActor->AllocPacket(pack);
data << (BYTE) nsys << (BYTE) ncmd;
// 基本数据
viewCenterOfflineUserData(pUser, data);
pack.flush();
}
void COfflineCenterUserMgr::viewCenterOfflineUserData(COfflineCenterUser *pUser, CDataPacket& data)
{
if(!pUser) return;
data << (unsigned int)pUser->nActorId;
data.writeString(pUser->name);
data << (BYTE)pUser->nVocation;
data << (BYTE)pUser->nCircle;
data << (unsigned int)pUser->nLevel;
data << (BYTE)pUser->nSex;
// 装备数据
INT_PTR nEquipCount = 0;
INT_PTR nPosBegin = data.getPosition();
data << (BYTE)nEquipCount;
for(INT_PTR i=0; i<itMaxEquipPos; i++)
{
if (CUserItem* pUserItem = pUser->m_Equips[i])
{
data << (BYTE)i;
*pUserItem >> data;
nEquipCount++;
}
}
INT_PTR nPosEnd = data.getPosition();
data.setPosition(nPosBegin);
data << (BYTE)nEquipCount;
data.setPosition(nPosEnd);
// 技能数据
INT_PTR nSkillCount = 0;
nPosBegin = data.getPosition();
data << (BYTE)pUser->m_Skilldata.size();
for (INT_PTR i = 0 ; i < pUser->m_Skilldata.size(); i++)
{
CSkillSubSystem::SKILLDATA& skillData = pUser->m_Skilldata[i];
const OneSkillData * pSkill =GetLogicServer()->GetDataProvider()->GetSkillProvider()->GetSkillData(skillData.nSkillID);
if (pSkill->boIsDelete) continue;
data << (WORD)skillData.nSkillID << (BYTE)skillData.nLevel;
data << (BYTE)(!skillData.nIsClosed);//技能是否激活可用
nSkillCount++;
}
nPosEnd = data.getPosition();
data.setPosition(nPosBegin);
data << (BYTE)nSkillCount;
data.setPosition(nPosEnd);
// 属性数据
INT_PTR nSize = sizeof(CActorOfflineProperty);
data << (WORD)nSize;
data.writeBuf(&pUser->actordata,nSize);
// 工会名
data.writeString(pUser->sGuildName);
// 强化信息
typedef std::map<int, std::vector<StrengthInfo> >::iterator strongMapIter;
data <<(BYTE)(pUser->m_nStrengths.size());
for(strongMapIter it = pUser->m_nStrengths.begin(); it != pUser->m_nStrengths.end(); it++)
{
std::vector<StrengthInfo>& v_list = it->second;
data <<(BYTE)(it->first);
data <<(BYTE)(v_list.size());
for(int i = 0; i < v_list.size(); i++)
{
StrengthInfo& info = v_list[i];
data<<(BYTE)(info.nId);
data<<(int)(info.nLv);
}
}
// 称号信息
INT_PTR nDataCount = pUser->m_NewTitleDataList.size();
data << int(nDataCount);
for (int i=0; i<nDataCount;i++)
{
CNewTitleSystem::NEWTITLEDATA& newTitleData = pUser->m_NewTitleDataList[i];
data << (unsigned int)newTitleData.wId;
int nLastTime = newTitleData.nRemainTime - GetGlobalLogicEngine()->getMiniDateTime();
nLastTime = nLastTime > 0 ? nLastTime : 0;
data << (unsigned int)nLastTime;
}
// 时装信息
nDataCount = (byte)pUser->m_Almirah.size();
data << (byte)nDataCount;
for (INT_PTR i = 0; i < nDataCount; i++)
{
CAlmirahItem & oneItem = pUser->m_Almirah[i];
data << (int)oneItem.nModelId;
data << (BYTE)oneItem.btTakeOn;
data << (int)oneItem.nLv;
}
nDataCount = (byte)pUser->m_ghost.size();
data << (byte)nDataCount;
for (INT_PTR i = 0; i < nDataCount; i++)
{
GhostData & oneItem = pUser->m_ghost[i];
data << (BYTE)oneItem.nId;
data << (int)oneItem.nLv;
data << (int)oneItem.nBless;
}
nDataCount = (BYTE)pUser->vSoulWeapon.size();
data << (BYTE)nDataCount;
for (INT_PTR i = 0; i < nDataCount; i++)
{
SoulWeaponNetData & oneItem = pUser->vSoulWeapon[i];
data << (BYTE)oneItem.nId;
data << (int)oneItem.nLorderId;
data << (int)oneItem.nStarId;
data << (int)oneItem.nLvId;
data.writeString(oneItem.cBestAttr);
}
}
//查看离线玩家的资料
void COfflineCenterUserMgr::ViewCenterOffLineActor(CActor *pActor, unsigned int nActorId, int nsys,int ncmd)
{
if (pActor == NULL || nActorId == 0) return;
// 再从离线玩家找
if(COfflineCenterUser *pUser = GetUserByActorId(nActorId))
{
viewCenterByOfflineUser(pUser, pActor->GetId(), nsys, ncmd);
}
else
{
// 最后只能从数据库找
LoadCenterUser(nActorId, pActor->GetId(), nsys, ncmd);
}
return;
}
//////////////////////////////////////////////////////////////
void COfflineCenterUserMgr::OnCenterReturnData(CDataPacketReader& reader)
{
// unsigned int nActorID=0;
// if(size < sizeof(int)*2 + sizeof(nActorID) + sizeof(nErrorCode))
// return ; //数据格式错误
// reader >> nActorID;
// // 查询数据不成功
// OnLoadCenterActorData(nActorID,reader);
}
void COfflineCenterUserMgr::SetCenterOfflineUserData(CDataPacketReader& data)
{
unsigned int nActorId = 0;
data >> nActorId;
bool isExist;
//如果已经存在这样的一个用户的话就不需要装载了
COfflineCenterUser *pUser = AddCenterOffLineUser(nActorId,isExist);
if(pUser) {
data.readString(pUser->name, sizeof(pUser->name));
BYTE nVocation = 0;
BYTE nCircle = 0;
unsigned int nLevel = 0;
BYTE nSex = 0;
data >> nVocation;
data >> nCircle;
data >> nLevel;
data >> nSex;
pUser->nVocation = nVocation;
pUser->nCircle = nCircle;
pUser->nLevel = nLevel;
pUser->nSex = nSex;
// 装备数据
BYTE nEquipCount = 0;
data >> nEquipCount;
CUserItem userItem;
CLogicEngine *pEngineer = GetLogicServer()->GetLogicEngine();
for(INT_PTR i=0; i<nEquipCount; i++)
{
BYTE k = 0;
data >> k;
userItem << data;
if (CUserItem *pUerItem = pEngineer->CopyAllocUserItem(false,&userItem))
{
INT_PTR nPos =-1;
const CStdItem *pStdItem = GetLogicServer()->GetDataProvider()->GetStdItemProvider().GetStdItem(pUerItem->wItemId);
if ( !pStdItem )
{
OutputMsg(rmError,_T("actorID=%d的玩家item=%d,装备非法"),nActorId,pUerItem->wItemId);
pEngineer->DestroyUserItem(pUerItem); //出错则删除内存防止泄露
continue;
}
else
{
nPos = CEquipVessel::GetItemTakeOnPosition((Item::ItemType)pStdItem->m_btType,pUerItem->btHandPos);
if(nPos <0)
{
OutputMsg(rmError,_T("actorID=%d的玩家nPos=%d,location=%d,itemId=%d,guid=%lld,装备位置非法"),nActorId,nPos,pUerItem->btHandPos,pUerItem->wItemId,pUerItem->series);
pEngineer->DestroyUserItem(pUerItem); //出错则删除内存防止泄露
pUerItem = NULL;
continue;
}
if(nPos >=0 && pUser->m_Equips[nPos] ==NULL)
{
pUser->m_Equips[nPos] = pUerItem;
}
else
{
OutputMsg(rmError,_T("actorID=%u的玩家nPos=%d已经有装备了"),nActorId,nPos);
pEngineer->DestroyUserItem(pUerItem); //出错则删除内存防止泄露
pUerItem = NULL;
}
}
}
}
pUser->m_Skilldata.clear();
// 技能数据
BYTE nSkillCount = 0;
data >> nSkillCount;
CSkillProvider *pSkillProvider = GetLogicServer()->GetDataProvider()->GetSkillProvider();
for (INT_PTR i = 0 ; i < nSkillCount; i++)
{
WORD nSkillID = 0;
BYTE nLevel = 0;
BYTE nIsClosed = 0;
data >> nSkillID >> nLevel>> nIsClosed;
CSkillSubSystem::SKILLDATA data;
data.nSkillID = nSkillID;
data.nLevel = nLevel;
data.nIsClosed = nIsClosed;
data.bEvent =0;
data.bMjMask =0;
const OneSkillData *pConfig = pSkillProvider->GetSkillData(data.nSkillID);
if(pConfig ==NULL) continue;
data.bIsPassive = ((pConfig->nSkillType == stPassiveSkill)?1:0);
data.bPriority = pConfig->bPriority;
data.nSkillType = pConfig->nSkillType;
pUser->m_Skilldata.push_back(data);
}
// 属性数据
WORD nSize = sizeof(CActorOfflineProperty);
data >> nSize;
data.readBuf(&pUser->actordata,nSize);
// 工会名
data.readString(pUser->sGuildName,sizeof(pUser->sGuildName));
// 强化信息
// 加载强化信息
{
pUser->m_nStrengths.clear();
BYTE nCount = 0;
data >> nCount;
int nLv = 0;
BYTE nid = 0;
for(INT_PTR i=0; i < nCount; i++)
{
BYTE nType = 0;
BYTE nNum = 0;
data >> nType >> nNum;
for(int j = 0; j < nNum; j++) {
data >> nid >> nLv;
StrengthInfo it;
it.nId = nid;
it.nLv = nLv;
if(it.nId > 0)
pUser->m_nStrengths[nType].push_back(it);
}
}
}
// 加载称号信息
{
pUser->m_NewTitleDataList.clear();
int nCount = 0;
data >> nCount;
for(INT_PTR i=0; i < nCount; i++)
{
unsigned int wId = 0, nTime = 0;
data >> wId >> nTime;
CNewTitleSystem::NEWTITLEDATA newTitleData;
newTitleData.wId = wId;
newTitleData.nRemainTime = nTime;
pUser->m_NewTitleDataList.push_back(newTitleData);
}
}
// 加载时装信息
{
pUser->m_Almirah.clear();
BYTE nCount = 0;
data >> nCount;
for(INT_PTR i=0; i < nCount; i++)
{
int nModelId = 0, nLv = 0;
BYTE btTakeOn = 0;
data >> nModelId >> btTakeOn >> nLv;
CAlmirahItem oneItem;
oneItem.nModelId = nModelId;
oneItem.nLv = nLv;
oneItem.btTakeOn = btTakeOn;
pUser->m_Almirah.push_back(oneItem);
}
}
// 加载神魔
{
pUser->m_ghost.clear();
BYTE nCount = 0;
data >> nCount;
for(INT_PTR i=0; i < nCount; i++)
{
BYTE nId = 0;
int nLv = 0, nBless = 0;
data >> nId >> nLv >> nBless;
GhostData oneItem;
oneItem.nId = nId;
oneItem.nLv = nLv;
oneItem.nBless = nBless;
pUser->m_ghost.push_back(oneItem);
}
}
// 加载圣物兵魂
{
pUser->vSoulWeapon.clear();
BYTE nCount = 0;
data >> nCount;
for(INT_PTR i = 0; i < nCount; i++)
{
BYTE nId = 0;
int nLorderId = 0, nStarId = 0,nLvId = 0;
SoulWeaponNetData oneItem;
data >> nId >> nLorderId >> nStarId >> nLvId;
oneItem.nId = nId;
oneItem.nLorderId = nLorderId;
oneItem.nStarId = nStarId;
oneItem.nLvId = nLvId;
data.readString(oneItem.cBestAttr, sizeof(oneItem.cBestAttr));
oneItem.cBestAttr[sizeof(oneItem.cBestAttr)-1] = 0;
pUser->vSoulWeapon.push_back(oneItem);
}
}
}
}