Files
2022-10-26 12:25:11 +08:00

194 lines
8.3 KiB
C++

#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<class QueryObject_>
bool DBResult_User_Select(const QueryObject_& query_result, DBUser* db_user);
// CHANGES: f101220.5L, 更改为特定模板函数以方便获取函数调试点
// WARNING: 如果未实现此函数,将发生延迟链接时间错误
template<class QueryObject_>
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<class QueryObject_>
bool DBResult_Char_Update(const QueryObject_& query_result, DBUser* db_user);
private:
typedef STLX_MAP<USERGUID, DBUser*> 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<int>(lifetime_table_.size());
}
}; //end of namespace 'nsQuery'
//==================================================================================================
#endif //DBPROXY_DBQUERY_PROXY_MANAGER_H