Files
mir_server/server/DBServer/DBDataCache.h

335 lines
10 KiB
C
Raw Normal View History

2025-01-09 17:45:40 +08:00
#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: truefalse
* @Remark:
*/
bool CacheData(enActorCacheDataType cdType, CDataPacketReader& packet);
/*
* Comments: Cache数据
* Param bCheckCD: CD
* Param bResp:
* Param INT_PTR nTimeLmt:
* @Return bool: truefalse
* @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: id0
* @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: truefalse
* @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; // 角色数据存盘间隔
};