LyraGameInstance.h 分析
1. 类声明与宏
UCLASS(MinimalAPI, Config = Game)
class ULyraGameInstance : public UCommonGameInstance
- 分析: 该类继承自
UCommonGameInstance,这是 Lyra 项目对 UE 原生UGameInstance的扩展基类,提供了更多通用功能(如用户管理)。MinimalAPI使得只有该类的主要函数被导出给其他模块,有助于编译时间。Config = Game表示该类的配置属性(如果有)将存储在DefaultGame.ini等配置文件中。
2. 构造函数
UE_API ULyraGameInstance(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
- 分析: 标准的构造函数。在 Lyra 项目中,它主要用于调用父类构造函数,并在
Init函数中进行实际的初始化工作。
3. 成员函数:GetPrimaryPlayerController
UE_API ALyraPlayerController* GetPrimaryPlayerController() const;
- 分析: 此函数用于获取游戏的主玩家控制器。在多人游戏中,通常指第一个本地玩家控制器。
- 在 Lyra 项目中的应用: 任何需要获取主玩家控制器以执行输入、生成角色、更新用户界面等操作的代码都可能调用此函数。它是连接游戏实例和具体玩家操作的桥梁。
4. 成员函数:CanJoinRequestedSession
UE_API virtual bool CanJoinRequestedSession() const override;
- 分析: 重写自父类,用于判断当前实例(或玩家)是否可以加入一个请求的游戏会话。
- 在 Lyra 项目中的应用: 在尝试加入一个在线多人会话或服务器之前,框架会调用此函数进行检查。代码中的初始实现总是返回
true,但这为后续开发留下了扩展点,例如可以在这里检查玩家的网络连接状态、是否已登录、DLC 是否已加载等条件,以决定是否允许加入会话。
5. 成员函数:HandlerUserInitialized
UE_API virtual void HandlerUserInitialized(const UCommonUserInfo* UserInfo, bool bSuccess, FText Error, ECommonUserPrivilege RequestedPrivilege, ECommonUserOnlineContext OnlineContext) override;
- 分析: 重写自父类,当用户(玩家)初始化过程(通常是登录过程)完成时,会回调此函数。
- 在 Lyra 项目中的应用: 这是用户登录流程的关键节点。当玩家成功登录后(例如,通过了平台的认证),此函数会被调用。在 Lyra 中,它利用这个机会让对应的
ULyraLocalPlayer从磁盘加载该玩家的个人设置(如音频设置、图形设置、控制设置等),确保每个用户的偏好都能在游戏开始时被正确应用。
6. 成员函数:ReceivedNetworkEncryptionToken
UE_API virtual void ReceivedNetworkEncryptionToken(const FString& EncryptionToken, const FOnEncryptionKeyResponse& Delegate) override;
- 分析: 重写自父类。当作为客户端的游戏实例从服务器接收到一个加密令牌时,引擎会调用此函数。客户端需要根据此令牌提供相应的加密密钥,并通过调用传入的
Delegate来响应。 - 在 Lyra 项目中的应用: 这是 Lyra 实现网络通信加密的关键环节。它处理两种模式:
- DTLS 加密: 使用证书和指纹进行更安全的加密连接,常用于测试或更高级的安全需求。
- 简单调试加密: 使用硬编码的
DebugTestEncryptionKey。这是项目的主要演示模式,展示了如何建立加密连接,但绝对不应用于生产环境。
7. 成员函数:ReceivedNetworkEncryptionAck
UE_API virtual void ReceivedNetworkEncryptionAck(const FOnEncryptionKeyResponse& Delegate) override;
- 分析: 重写自父类。当服务器确认了客户端的加密设置后,客户端会收到一个 ACK(确认),此时引擎会调用此函数。客户端需要再次提供加密数据(对于 DTLS,这次需要提供服务器的证书指纹)以完成握手。
- 在 Lyra 项目中的应用: 这是加密握手流程的第二步。它确保了客户端拥有验证服务器身份所需的信息(指纹),从而建立双向的、可信的加密通道。同样,它支持 DTLS 和简单调试两种模式。
8. 成员函数:Init
UE_API virtual void Init() override;
- 分析: 重写自父类,在游戏实例创建后、游戏正式开始前被调用。
- 在 Lyra 项目中的应用: 这是整个游戏初始化的核心入口。它做了几件关键事情:
- 注册初始化状态: 通过
UGameFrameworkComponentManager注册了从Spawned到GameplayReady等一系列初始化状态。这套状态机系统用于有序地管理游戏框架组件(如玩家状态、武器组件等)的初始化流程,确保依赖关系正确。 - 初始化调试密钥: 准备了一个固定的、不安全的加密密钥
DebugTestEncryptionKey用于测试。 - 绑定会话旅行事件: 将
OnPreClientTravelToSession函数绑定到会话子系统的OnPreClientTravelEvent上。
- 注册初始化状态: 通过
9. 成员函数:Shutdown
UE_API virtual void Shutdown() override;
- 分析: 重写自父类,在游戏实例即将被销毁、游戏结束时调用。
- 在 Lyra 项目中的应用: 执行清理工作,例如移除在
Init中绑定的事件监听器,防止在游戏关闭过程中产生不必要的回调。
10. 成员函数:OnPreClientTravelToSession
UE_API void OnPreClientTravelToSession(FString& URL);
- 分析: 这是一个自定义的回调函数,当客户端即将旅行(连接)到一个新的会话(服务器)时被调用。
- 在 Lyra 项目中的应用: 它的主要作用是在启用加密测试 (
Lyra::bTestEncryption) 时,向连接的 URL 中添加一个EncryptionToken查询参数。这个令牌(在 DTLS 模式下是玩家的唯一 ID,否则是固定值 “1”)会被发送到服务器,服务器端的ReceivedNetworkEncryptionToken函数会使用这个令牌来协商或查找对应的加密密钥。这是客户端主动发起加密握手的第一步。
11. 成员变量:DebugTestEncryptionKey
TArray<uint8> DebugTestEncryptionKey;
- 分析: 一个字节数组,用于存储加密算法(如 AES256)所使用的密钥。
- 在 Lyra 项目中的应用: 这是整个调试加密系统的核心。在
Init中被初始化为一个固定的序列[0, 1, 2, ..., 31]。在ReceivedNetworkEncryptionToken和ReceivedNetworkEncryptionAck中,无论传入的令牌是什么,只要不使用 DTLS,最终都会将这个硬编码的密钥设置到响应中。这意味着客户端和服务器使用的是同一个固定的密钥,这非常不安全,但非常适合在开发阶段快速测试和验证网络加密管道的功能是否正常工作。
总结
ULyraGameInstance 在 Lyra 项目中扮演着游戏大脑的角色,其成员主要围绕以下几个核心应用:
- 游戏框架初始化: 通过
Init和组件管理器,建立了一套严谨的初始化状态机,确保所有游戏系统按正确顺序启动。 - 用户生命周期管理: 通过
HandlerUserInitialized,将用户登录成功与加载个人设置关联起来,提供个性化的游戏体验。 - 网络会话与连接: 通过
CanJoinRequestedSession和OnPreClientTravelToSession管理会话的加入和旅行过程。 - 网络通信安全(测试/演示): 最重要的功能之一。提供了一套完整的、可配置的(通过控制台变量)网络加密演示方案。它同时实现了简单的静态密钥加密和更复杂的 DTLS 证书加密,为开发者提供了学习和集成安全网络通信的宝贵范例。所有加密相关的成员函数和变量都服务于这个目的。
这个类清晰地展示了如何在 UE5 中构建一个功能齐全、可扩展的多人游戏实例,特别是在处理用户状态和网络安全方面。
6755

被折叠的 条评论
为什么被折叠?



