335 lines
10 KiB
C
335 lines
10 KiB
C
|
|
#pragma once
|
|||
|
|
#include <map>
|
|||
|
|
|
|||
|
|
class CDBDataCache;
|
|||
|
|
class CActorCacheData;
|
|||
|
|
|
|||
|
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
|
// 角色Cache数据句柄管理器类型定义
|
|||
|
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
|
typedef Handle<UINT> CActorCacheDataHandle;
|
|||
|
|
typedef HandleMgr<CActorCacheData, CActorCacheDataHandle> CActorCacheDataHandleMgr;
|
|||
|
|
|
|||
|
|
class CActorCacheData
|
|||
|
|
{
|
|||
|
|
public:
|
|||
|
|
CActorCacheDataHandle m_handle; // 句柄
|
|||
|
|
CBaseLinkedList<CActorCacheData*>::NodeType* m_node; // 对应于在list中的节点,用于删除时提高效率
|
|||
|
|
unsigned int m_nActorId; // 角色Id
|
|||
|
|
TICKCOUNT m_nNextSaveTick; // 下一次存盘时间
|
|||
|
|
CDataPacket m_sActorCacheData[enCT_Max]; // 角色数据Cache
|
|||
|
|
Uint64 m_sACDDirtyFlag; // 角色数据更新标记。支持最多64中类型
|
|||
|
|
//bool m_sACDDirty[enCT_Max]; // 角色数据Cache脏标记,对每个类型的数据都区分
|
|||
|
|
//bool m_bDirty; // 数据是否需要更新
|
|||
|
|
bool m_bExpired; // 是否过期,如果过期下次RunOne会删除
|
|||
|
|
static const TICKCOUNT s_nExpireTime; // 过期时间
|
|||
|
|
CActorCacheData() : m_handle(0), m_node(0), m_nActorId(0), m_bExpired(false),m_sACDDirtyFlag(0){}
|
|||
|
|
|
|||
|
|
inline void Init(CBufferAllocator &allocator, unsigned int nActorId)
|
|||
|
|
{
|
|||
|
|
for (INT_PTR i = 0; i < enCT_Max; i++)
|
|||
|
|
{
|
|||
|
|
m_sActorCacheData[i].setAllocator(&allocator);
|
|||
|
|
m_sActorCacheData[i].setPosition(0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_nActorId = nActorId;
|
|||
|
|
m_nNextSaveTick = _getTickCount();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//追踪内存情况
|
|||
|
|
INT_PTR Trace()
|
|||
|
|
{
|
|||
|
|
INT_PTR nTotalSize=0;//总内存
|
|||
|
|
for (INT_PTR i = 0; i < enCT_Max; i++)
|
|||
|
|
{
|
|||
|
|
INT_PTR nSize =m_sActorCacheData[i].getMemorySize();
|
|||
|
|
/*
|
|||
|
|
if(nSize >4096)
|
|||
|
|
{
|
|||
|
|
OutputMsg(rmNormal,"Actorid=%d,msgid=%d,size=%d",m_nActorId,(int)i,(int)nSize);
|
|||
|
|
}
|
|||
|
|
*/
|
|||
|
|
nTotalSize += nSize;
|
|||
|
|
}
|
|||
|
|
//OutputMsg(rmNormal,"Actorid=%d,memory=%d",m_nActorId,(int)nTotalSize);
|
|||
|
|
return nTotalSize;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//// 判断数据是否脏
|
|||
|
|
inline bool IsDirty() const {
|
|||
|
|
return m_sACDDirtyFlag != 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
inline bool IsACDDirty(int tp) const {
|
|||
|
|
return (m_sACDDirtyFlag & (Uint64)((1 << tp))) != 0 ? true : false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
inline void SetDirty(int tp, bool bDirty)
|
|||
|
|
{
|
|||
|
|
if (bDirty)
|
|||
|
|
{
|
|||
|
|
m_sACDDirtyFlag |= (Uint64)((1 << tp));
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
m_sACDDirtyFlag &= ~(Uint64)(1 << tp);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
inline void ResetDirty()
|
|||
|
|
{
|
|||
|
|
m_sACDDirtyFlag = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//inline bool IsDirty() const {
|
|||
|
|
// return m_bDirty;
|
|||
|
|
//}
|
|||
|
|
//// 设置数据脏属性
|
|||
|
|
//inline void SetDirty(bool bDirty) {
|
|||
|
|
// m_bDirty = bDirty;
|
|||
|
|
// if (bDirty && IsExpired())
|
|||
|
|
// SetExpired(false);
|
|||
|
|
//}
|
|||
|
|
|
|||
|
|
// 获取句柄
|
|||
|
|
inline CActorCacheDataHandle GetHandle() const { return m_handle; }
|
|||
|
|
// 设置句柄
|
|||
|
|
inline void SetHandle(CActorCacheDataHandle& handle)
|
|||
|
|
{
|
|||
|
|
m_handle = handle;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
// 过期相关的操作
|
|||
|
|
inline bool IsExpired() const { return m_bExpired; }
|
|||
|
|
|
|||
|
|
inline void SetExpired(bool bExpired) {
|
|||
|
|
if (m_bExpired != bExpired)
|
|||
|
|
m_bExpired = bExpired;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
inline bool CheckAndSet(TICKCOUNT nCurrTick)
|
|||
|
|
{
|
|||
|
|
if (nCurrTick >= m_nNextSaveTick)
|
|||
|
|
{
|
|||
|
|
PostponeNextSaveTick();
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void PostponeNextSaveTick();
|
|||
|
|
|
|||
|
|
inline bool operator < (const CActorCacheData& data)
|
|||
|
|
{
|
|||
|
|
return m_nActorId < data.m_nActorId ? true : false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private:
|
|||
|
|
CActorCacheData(const CActorCacheData& rhs)
|
|||
|
|
{
|
|||
|
|
m_nActorId = rhs.m_nActorId;
|
|||
|
|
m_bExpired = false;
|
|||
|
|
ResetDirty();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
|
|||
|
|
class CDBDataClientHandler;
|
|||
|
|
|
|||
|
|
class CDBDataCache
|
|||
|
|
{
|
|||
|
|
friend class CActorCacheData;
|
|||
|
|
|
|||
|
|
public:
|
|||
|
|
CDBDataCache();
|
|||
|
|
virtual ~CDBDataCache(){}
|
|||
|
|
public:
|
|||
|
|
/*
|
|||
|
|
* Comments: 设置DBClient
|
|||
|
|
* Param ILogicDBRequestHost *pHost:
|
|||
|
|
* Param CDBDataClientHandler* handler: DB请求处理器
|
|||
|
|
* @Return void:
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
void SetDBClient(ILogicDBRequestHost* pHost, CDBDataClientHandler* handler);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments: 缓存角色数据
|
|||
|
|
* Param enActorCacheDataType cdType: 缓存数据类型
|
|||
|
|
* Param CDataPacketReader & packet: 缓存数据
|
|||
|
|
* @Return bool: 成功返回true;失败返回false
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
bool CacheData(enActorCacheDataType cdType, CDataPacketReader& packet);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments: 保存Cache数据
|
|||
|
|
* Param bCheckCD: 指定是否检测CD
|
|||
|
|
* Param bResp: 是否回应消息给逻辑服
|
|||
|
|
* Param INT_PTR nTimeLmt: 时间限制
|
|||
|
|
* @Return bool: 成功返回true;失败返回false
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
bool SaveData(bool bCheckCD, bool bResp, INT_PTR nTimeLmt = INT_MAX);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments: 例行处理
|
|||
|
|
* Param nCurrentTick: 当前的Tickount
|
|||
|
|
* @Return void:
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
void RunOne(TICKCOUNT nCurrTick);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments: 角色登录
|
|||
|
|
* Param CDataPacketReader & packet:
|
|||
|
|
* @Return void:
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
void OnActorLogin(CDataPacketReader& packet);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments: 角色退出
|
|||
|
|
* Param
|
|||
|
|
* @Return void:
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
void OnActorLogout(CDataPacketReader& packet);
|
|||
|
|
|
|||
|
|
void SaveAllActorDataImmediately();
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments:追踪内存的使用情况
|
|||
|
|
* @Return void:
|
|||
|
|
*/
|
|||
|
|
void Trace();
|
|||
|
|
|
|||
|
|
protected:
|
|||
|
|
/*
|
|||
|
|
* Comments: 获取角色Id
|
|||
|
|
* Param CDataPacketReader & packet:
|
|||
|
|
* Param INT_PTR nOffset: 角色Id在消息包中的偏移
|
|||
|
|
* @Return unsigned int: 成功返回角色id,失败返回0
|
|||
|
|
* @Remark: 读取数据中的角色id字段,并且不修改packet内容
|
|||
|
|
*/
|
|||
|
|
unsigned int GetActorId(CDataPacketReader& packet, INT_PTR nOffset = 0);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments:立刻保存角色数据
|
|||
|
|
* Param int nActorId:
|
|||
|
|
* Param bool bResp: 是否给逻辑服回应答消息
|
|||
|
|
* @Return bool:
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
bool SaveActorDataImmediately(unsigned int nActorId, bool bResp = true);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments: 移除过期CacheData
|
|||
|
|
* @Return void:
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
void RemoveExpireCache();
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments: 分配一个角色Cache数据节点
|
|||
|
|
* Param int nActorId: 角色Id
|
|||
|
|
* Param CActorCacheDataHandle & handle: 返回分配的ACD节点句柄
|
|||
|
|
* @Return CActorCacheData*: 返回可存储ACD对象节点指针
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
CActorCacheData* AllocActorCacheData(unsigned int nActorId, CActorCacheDataHandle &handle);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments: 根据句柄查询指定ACD节点对象
|
|||
|
|
* Param CActorCacheDataHandle & handle: ACD节点句柄
|
|||
|
|
* @Return CActorCacheData*: 返回对应的ACD对象指针
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
CActorCacheData* GetActorCacheData(const CActorCacheDataHandle& handle);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments: 根据角色Id查找ACD节点对象
|
|||
|
|
* Param int nActorId:
|
|||
|
|
* @Return CActorCacheData*:
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
CActorCacheData* GetActorCacheDataByActorId(unsigned int nActorId);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments: 释放指定句柄的ACD节点对象
|
|||
|
|
* Param CActorCacheDataHandle & handle: ACD节点句柄
|
|||
|
|
* Param , bool updateIndex: 为true表示在释放ACD节点同时更新索引表
|
|||
|
|
* @Return void:
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
void FreeActorCacheData(const CActorCacheDataHandle& handle, bool updateIndex = true);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments: 根据角色缓存数据类型查找对应的消息号
|
|||
|
|
* Param enActorCacheDataType tp:
|
|||
|
|
* @Return jxSrvDef::INTERSRVCMD:
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
jxSrvDef::INTERSRVCMD GetCmdIdByCDT(enActorCacheDataType tp);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* Comments: 保存角色数据
|
|||
|
|
* Param CActorCacheData & data: 角色数据
|
|||
|
|
* Param bool bCheckCD: 是否检测CD
|
|||
|
|
* Param TICKCOUNT nCurrTick: 当前的TickCount
|
|||
|
|
* Param bool bResp: 是否给逻辑服务器会操作结果应答消息
|
|||
|
|
* @Return bool: 成功返回true;失败返回false
|
|||
|
|
* @Remark:
|
|||
|
|
*/
|
|||
|
|
bool SaveActorDataImpl(CActorCacheData& data, bool bCheckCD, TICKCOUNT nCurrTick, bool bResp);
|
|||
|
|
bool SaveActorBasicData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveBagItemData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveEquipItemData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveDepotItemData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SavePetItemData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveOtherGameSetsData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveSkillData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveQuestData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveGuildData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveMiscData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveAchieveData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveScriptData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SavePetData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SavePetSkillData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SavCombatGameInfoData( CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SavCombatRecordData( CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveFriendData( CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SavGamesetData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveActorMailData(CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveAlmirahItemData(CDataPacketReader& packet, bool bResp = true); // 衣橱系统
|
|||
|
|
bool SaveDeathData( CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveDeathDropData( CDataPacketReader& packet, bool bResp = true);
|
|||
|
|
bool SaveConsignData( CDataPacketReader& packet, bool bResp = true);//寄卖
|
|||
|
|
bool SaveStaticCounts( CDataPacketReader& packet, bool bResp = true);//计数器
|
|||
|
|
CLogicDBReqestHandler& GetLogicDBRequestHandler();
|
|||
|
|
|
|||
|
|
private:
|
|||
|
|
typedef bool (CDBDataCache::*SaveHandler)(CDataPacketReader&, bool);
|
|||
|
|
|
|||
|
|
CBufferAllocator m_allocator; // BuffAllocator
|
|||
|
|
ILogicDBRequestHost *m_pHost;
|
|||
|
|
CDBDataClientHandler* m_pClientHandler; // DB请求处理器
|
|||
|
|
CActorCacheDataHandleMgr m_sACDHandleMgr; // 角色Cache数据句柄管理器
|
|||
|
|
std::map<unsigned int, CActorCacheData*> m_sACDIdxTbl; // 角色Cache数据索引表 actorid --> CActorCacheData*
|
|||
|
|
CBaseLinkedList<CActorCacheData*> m_list; // 用于遍历
|
|||
|
|
wylib::container::CLinkedListIterator<CActorCacheData*> m_listIter; // 用于保存上次遍历位置的迭代器
|
|||
|
|
|
|||
|
|
TICKCOUNT m_nNextCheckTime; // 检测更新角色数据定时器
|
|||
|
|
bool m_bHasExpireCache; // 标记是否删除Cache数据
|
|||
|
|
static const TICKCOUNT s_nCheckInterval; // 检测更新角色数据定时器间隔,默认5s检测一次
|
|||
|
|
static const SaveHandler s_aActorCacheHandler[]; // 角色数据Cache处理器表
|
|||
|
|
static const jxSrvDef::INTERSRVCMD s_aCDT2RespSrvCmdID[]; // 角色缓存数据类型到应答消息命令ID映射表
|
|||
|
|
public:
|
|||
|
|
static TICKCOUNT s_nActorCacheSaveInterval; // 角色数据存盘间隔
|
|||
|
|
};
|
|||
|
|
|