#pragma once #ifndef DBPROXY_DBQUERY_PROXY_MANAGER_H #define DBPROXY_DBQUERY_PROXY_MANAGER_H #include "./DBQueryProxyNode.h" class QueryForUser; class QueryForCharTransaction; class Query_User_Select; class Query_User_Select_Inventory; class Query_User_Select_PetList; // class Query_Warehouse_Select; class Query_Char_Update; class Query_Char_Update_Inventory; namespace nsQuery { class DBQueryProxyManager; }; //end of namespace //================================================================================================== // @history // |10.04.15|waverix|created, // |支持可靠的用户数据数据库同步与生命周期管理 namespace nsQuery { ; //================================================================================================== class DBQueryProxyManager { public: enum eRequestResult { eReqResult_Success = 0, eReqResult_Failed , //未知 eReqResult_Transaction , //事务锁 eReqResult_Loaded , //已加载 }; enum eConnectResult { eConnectResult_Error = 0, eConnectResult_Create, eConnectResult_Reuse, eConnectResult_PendingReuse, eConnectResult_Pending, }; enum eEnterGameResult { eEnterGameResult_Fail = 0, eEnterGameResult_Enterable, eEnterGameResult_Pending, }; // NOTE: f101020.5L enum eFindResult { eFindResult_NotFound = 0, eFindResult_Service, eFindResult_Pending, }; static void CreateInstance(); static void DestroyInstance(); static DBQueryProxyManager* Instance(); int GetPendingUsers() const; // (NOTE) (f100423.3L) (WAVERIX) 支持同步容错机制 // 快速重新连接请求应该是待处理进程 \ // 游戏服务器是否有惰性请求 // returns = { 0, 1, 2, 3, 4 }; // 0 : error, reuse_db_user == NULL, send ~_CHARLISTREQ_NAK // 1 : success, reuse_db_user == NULL, 需要创建用户和连续过程 // 2 : success, reuse_db_user != NULL, 重用数据库用户 // 3 : success, reuse_db_user != NULL, 从提取的挂起重用数据库用户. // 4 : success, reuse_db_user == NULL, db 用户处于挂起状态。 调用者,数据包处理程序, // 由于退出挂起状态后发生了惰性事件,因此应该是非行为 eConnectResult EnterConnectPendingProcess(DBUser** reuse_db_user, const MSG_AD_CHARINFO_CHARLISTREQ_SYN* recv_msg, ChildServerSession* server_session); eEnterGameResult EnterGamePendingProcess(DBUser* db_user, DBCharacter* db_character, ChildServerSession* server_session); // NOTE: f101020.5L, 此方法考虑待定用户支持查找用户功能 // 换句话说,先在 DBUserManager 中查找,然后在 PendingUser 中查找 eFindResult FindUserWithPendings(USERGUID user_guid, DBUser** find_db_user) const; // NOTE: f101020.5L, 此方法考虑待定用户支持查找用户功能 // 换句话说,先在 DBUserManager 中查找,然后在 PendingUser 中查找 eFindResult FindUserWithPendings(USERGUID user_guid, CHARGUID char_guid, DBUser** find_db_user, DBCharacter** find_db_character) const; // 如果结果为空,则未找到登录账号,\ // 创建与用户 guid 相关的 DBUser。 // 如果结果不为空,则在待处理列表中查找用户 \ // 这是同步的最新数据,在pending list中删除隐式可以使用的对象 DBUser* MoveUserFromPendings(USERGUID user_guid); bool MoveUserToPendings(DBUser* db_user); // 在 db 用户从 DBUserManager 的表中提取后调用 MoveUserToPendings bool DisconnectUser(DBUser* db_user, bool extract_from_user_table); //bool ChangePendingControl(DBUser* db_user, bool enabled, // DBQueryProxyUserNode::eRequest transaction); void Update(); // bool SendUserInfoToAgentOnAllCharacterLoaded(DBUser* db_user); // (f100731.5L) 替换“SendAllDataToGameServer”功能 // 支持选中字符的数据控件. bool SendCharInfoToGameOnAllCharDataLoaded(DBUser* db_user, DBCharacter* db_character); // //---------------------------------------------------------------------------------------------- // S_User_Select + S_User_Select_Inventory + S_CharacterState_Select // S_Warehouse_Select // (f100729.3L) 添加以支持所有加载的序列过程 //(警告)没有规则检查例程 eRequestResult Request_User_Select_All(DBUser* db_user); // f101004.4L, 添加支持拆分T_Inventory查询后的部分设备查询 eRequestResult Request_Char_Data_Equipment(DBUser* db_user, DBCharacter* db_character); // (f100731.2L) 添加以支持字符的所有加载序列过程 // (WARNING) 没有规则检查例程 eRequestResult Request_Char_Data_All(DBUser* db_user, DBCharacter* db_character); eRequestResult Request_User_Select(DBUser* db_user, DBQueryProxyUserNode::eTransaction transaction); // 如果在 DBUserManager 中找不到就调用它,应该更新待处理列表的数据库用户 eRequestResult DBResult_User_Select(USERGUID user_guid, const QueryForUser& result_base, DBQueryProxyUserNode::eTransaction transaction); // NOTE: r100928.3L // CHANGES: f101220.5L, 更改为特定模板函数以方便获取函数调试点 // WARNING: 如果未实现此函数,将发生延迟链接时间错误 template bool DBResult_User_Select(const QueryObject_& query_result, DBUser* db_user); // CHANGES: f101220.5L, 更改为特定模板函数以方便获取函数调试点 // WARNING: 如果未实现此函数,将发生延迟链接时间错误 template bool DBResult_User_Update(const QueryObject_& query_result, DBUser* db_user); //---------------------------------------------------------------------------------------------- // S_Warehouse_Update eRequestResult Request_User_Update(DBUser* db_user, DBQueryProxyUserNode::eTransaction transaction); //---------------------------------------------------------------------------------------------- eRequestResult Request_Char_Create(const Query_Char_Create& query_result, DBUser* db_user); bool DBResult_Char_Create(const Query_Char_Create& query_result, DBUser* db_user, RC::eCHAR_CREATE_RESULT rc); //---------------------------------------------------------------------------------------------- eRequestResult Request_Char_Transaction(DBUser* db_user, DBCharacter* db_character, ProxyCommand::eCommand transaction); eRequestResult DBResult_Char_Transaction(USERGUID user_guid, CHARGUID char_guid, const QueryForCharTransaction& query_result); bool DBResult_Char_Transaction(const QueryForCharTransaction& query_result, DBUser* db_user, DBCharacter* db_character); //---------------------------------------------------------------------------------------------- // S_Char_Update + S_Char_Update_Inventory + S_CharacterState_Update eRequestResult Request_Char_Update(DBUser* db_user, DBCharacter* db_character, DBQueryProxyCharNode::eTransaction transaction); // 如果在 DBUserManager 中找不到就调用它,应该更新待处理列表的数据库用户 eRequestResult DBResult_Char_Update(USERGUID user_guid, CHARGUID char_guid, DBQueryProxyCharNode::eTransaction transaction); // CHANGES: f101220.5L, 更改为特定模板函数,方便获取函数调试点 // WARNING: 如果未实现此功能,将发生延迟链接时间错误 template bool DBResult_Char_Update(const QueryObject_& query_result, DBUser* db_user); private: typedef STLX_MAP LifetimeTable; DBQueryProxyManager(); ~DBQueryProxyManager(); bool SendPendingConnectionResult(DBUser* db_user); bool UpdateQueryTransaction(DBUser* db_user); // fields ... LifetimeTable lifetime_table_; // static DBQueryProxyManager* db_query_proxy_manager_s; }; }; //end of namespace 'nsQuery' //================================================================================================== // implementation namespace nsQuery { ; inline DBQueryProxyManager* DBQueryProxyManager::Instance() { return db_query_proxy_manager_s; } inline int DBQueryProxyManager::GetPendingUsers() const { return static_cast(lifetime_table_.size()); } }; //end of namespace 'nsQuery' //================================================================================================== #endif //DBPROXY_DBQUERY_PROXY_MANAGER_H