游戏反作弊系统接入:Part 2
前言
大家好,在上一篇文章中我与大家分享了游戏反作弊系统 EasyAntiCheat 的配置,今天我就来与大家分享一下游戏该如何接入 Easy AntiCheat。本文涵盖的知识点包括:EAC 的工作架构,客户端接口以及服务器接口。好了,咱废话不多说直接开始吧!
反作弊架构
首先给大家介绍一下 EAC 反作弊系统的工作流程,我用 Keynote 给大家画了一个它工作的流程图,如下:
接下来给大家解释一下它的工作流程:
- 首先,EAC 需要在客户端和服务器上分别进行初始化
- 然后要实现一个心跳去定时的检查 EAC 的状态,以免被作弊软件篡改导致服务停止
- 玩家登录游戏服务器后,服务器需要立马给客户的发送一个数据包去验证
- 客户端收到数据包后,验证该数据的完整性
- 客户端验证完整性通过后再发送数据包给服务器,服务器再进行验证
- 当玩家离开服务器后,服务器需要停止给它发送消息,然后客户端停止 EAC 保护
其中步骤3到步骤5我称之为数据通道,通俗的说就是当客户端与服务器建立联系后需要定时的互相发送数据,来确保游戏的数据没有被作弊软件所篡改。
接口说明
根据流程图想必大家都已经了解了 EAC 的工作机制,接下来给大家介绍一下 EAC 主要接口说明,因为 EAC 的接口分为客户端与服务器俩部分,所以我也将分两部分和大家介绍,先来看下客户端吧!
客户端
客户端初始化
EAC 的客户端初始化接口有俩个,一个是 EOS SDK 的初始化接口,另一个是平台初始化接口,分别如下:
代码语言:javascript复制EOS_DECLARE_FUNC(EOS_EResult) EOS_Initialize(const EOS_InitializeOptions* Options);
代码语言:javascript复制★初始化 Epic 在线服务 SDK。在调用SDK中的任何其他函数之前,客户端必须先调用该函数。该函数只能调用一次,并且必须有相应的 EOS_Shutdown 调用。如果SDK初始化成功,则返回EOS_Success。如果该函数已经被调用,则返回 EOS_AlreadyConfigured。如果提供的选项无效,则返回 EOS_InvalidParameters。
EOS_DECLARE_FUNC(EOS_HPlatform) EOS_Platform_Create(const EOS_Platform_Options* Options);
★创建单个 Epic 在线服务平台实例。该平台实例用于访问各种 Epic 在线服务。该函数返回一个不透明的平台实例句柄,并且该句柄必须传递给 EOS_Platform_Release 才能释放该实例。
客户端心跳
初始化完成之后,必须定时调用 EOS_Platform_Tick 来检查服务是否正常运行,此接口在客户端与服务器都需要调用,接口如下:
EOS_DECLARE_FUNC(void) EOS_Platform_Tick(EOS_HPlatform Handle);
为了使SDK提供的服务正常运行,必须经常调用该函数。对于基于刻度的应用程序,通常希望每个刻度调用一次。
客户端违规通知
当 EAC 激活保护模块之后,如果检测到有违规程序正在运行,将通过回调的方式来通知客户端,于是我们需要调用接口 EOS_AntiCheatClient_AddNotifyClientIntegrityViolated 来注册回调。
EOS_AntiCheatClient_AddNotifyClientIntegrityViolated
当必须向本地客户端显示消息时添加回调,通知他们本地完整性违规,这将阻止进一步的在线游戏。
客户端开启会话
当客户端与服务器建立通信后,EAC 客户端就需要与服务器开启一个会话,这里需要用到接口 EOS_AntiCheatClient_BeginSession。
代码语言:javascript复制EOS_DECLARE_FUNC(EOS_EResult) EOS_AntiCheatClient_BeginSession(EOS_HAntiCheatClient Handle, const EOS_AntiCheatClient_BeginSessionOptions* Options);
★开始多人游戏会话。此调用成功返回后,客户端就准备好与游戏服务器或对等点交换反作弊消息。当离开一个游戏会话并连接到另一个游戏会话时,必须通过再次调用 EOS_AntiCheatClient_EndSession 和 EOS_AntiCheatClient_BeginSession 创建新的反作弊会话。
客户端数据通道回调
此接口可以与上面的开启会话接口放在一起调用,即他们的逻辑可以放在一起,譬如先添加 EOS_AntiCheatClient_AddNotifyMessageToServer回调,然后再调用 EOS_AntiCheatClient_BeginSession 接口。
接口定义如下:
代码语言:javascript复制EOS_DECLARE_FUNC(EOS_NotificationId) EOS_AntiCheatClient_AddNotifyMessageToServer(EOS_HAntiCheatClient Handle, const EOS_AntiCheatClient_AddNotifyMessageToServerOptions* Options, void* ClientData, EOS_AntiCheatClient_OnMessageToServerCallback NotificationFn);
★当必须将新消息发送到游戏服务器时发出回调。消息包含不透明的二进制数据,必须使用游戏自己的网络层传输到游戏服务器,然后使用 EOS_AntiCheatServer_ReceiveMessageFromClient 函数传递到服务器反作弊实例。
验证
当客户端收到服务器的消息后,需要调用 EOS_AntiCheatClient_ReceiveMessageFromServer 来验证消息的正确性,接口说明如下:
代码语言:javascript复制EOS_DECLARE_FUNC(EOS_EResult) EOS_AntiCheatClient_ReceiveMessageFromServer(EOS_HAntiCheatClient Handle, const EOS_AntiCheatClient_ReceiveMessageFromServerOptions* Options);
当从游戏服务器收到反作弊消息时调用。
接口返回值说明如下:
- EOS_Success - 成功
- EOS_InvalidParameters - 无效的数据
- EOS_InvalidRequest - 消息内容已损坏且无法处理
- EOS_AntiCheat_InvalidMode - 无效的模式
客户端结束会话
当玩家客户端与服务器断开连接或者客户端关闭的时候需要结束会话,即调用接口 EOS_AntiCheatClient_EndSession,接口定义如下:
代码语言:javascript复制EOS_DECLARE_FUNC(EOS_EResult) EOS_AntiCheatClient_EndSession(EOS_HAntiCheatClient Handle, const EOS_AntiCheatClient_EndSessionOptions* Options);
★通过离开正在进行的会话或完全关闭它来结束多人游戏会话。
服务器
说完了客户端的,接下来再来说说服务器的,首先服务器也需要初始化接口,它与客户端的初始化保持一致,也分为 EOS SDK 初始化和平台初始化。
初始化
EOS_DECLARE_FUNC(EOS_EResult) EOS_Initialize(const EOS_InitializeOptions* Options);
代码语言:javascript复制★初始化 Epic 在线服务 SDK。在调用SDK中的任何其他函数之前,客户端必须先调用该函数。该函数只能调用一次,并且必须有相应的 EOS_Shutdown 调用。如果SDK初始化成功,则返回EOS_Success。如果该函数已经被调用,则返回 EOS_AlreadyConfigured。如果提供的选项无效,则返回 EOS_InvalidParameters。
EOS_DECLARE_FUNC(EOS_HPlatform) EOS_Platform_Create(const EOS_Platform_Options* Options);
★创建单个 Epic 在线服务平台实例。该平台实例用于访问各种 Epic 在线服务。该函数返回一个不透明的平台实例句柄,并且该句柄必须传递给 EOS_Platform_Release 才能释放该实例。
只不过 EOS_Platform_Create 接口需要的参数中可以区分是客户端还是服务器,部分代码见下方:
代码语言:javascript复制EOS_STRUCT(EOS_Platform_Options, (
/** API Version: Set this to EOS_PLATFORM_OPTIONS_API_LATEST. */
int32_t ApiVersion;
/** A reserved field that should always be nulled. */
void* Reserved;
/** The product ID for the running application, found on the dev portal */
const char* ProductId;
/** The sandbox ID for the running application, found on the dev portal */
const char* SandboxId;
/** Set of service permissions associated with the running application */
EOS_Platform_ClientCredentials ClientCredentials;
/** Set this to EOS_FALSE if the application is running as a client with a local user, otherwise set to EOS_TRUE (e.g. for a dedicated game server) */
EOS_Bool bIsServer;
...
)
其中的 bIsServer 参数用来区分是客户端还是服务器。
心跳
与客户端一致。
代码语言:javascript复制EOS_DECLARE_FUNC(void) EOS_Platform_Tick(EOS_HPlatform Handle);
为了使SDK提供的服务正常运行,必须经常调用该函数。对于基于刻度的应用程序,通常希望每个刻度调用一次。
服务器开启会话
当服务器 EAC 初始化成功后,需要开启受保护的游戏会话,接口如下:
代码语言:javascript复制EOS_DECLARE_FUNC(EOS_EResult) EOS_AntiCheatServer_BeginSession(EOS_HAntiCheatServer Handle, const EOS_AntiCheatServer_BeginSessionOptions* Options);
不过需要注意的是,再调用此方法之前,咱们需要先去调用 EOS_AntiCheatServer_AddNotifyMessageToClient 和 EOS_AntiCheatServer_AddNotifyClientActionRequired 俩接口,它们分别是将EAC数据发送给客户端以及注册服务器踢人的通知,具体说明如下:
代码语言:javascript复制EOS_DECLARE_FUNC(EOS_NotificationId) EOS_AntiCheatServer_AddNotifyMessageToClient(EOS_HAntiCheatServer Handle, const EOS_AntiCheatServer_AddNotifyMessageToClientOptions* Options, void* ClientData, EOS_AntiCheatServer_OnMessageToClientCallback NotificationFn);
当必须将新消息分派到连接的客户端时发出回调。消息包含不透明的二进制数据,必须使用游戏自己的网络层传输到正确的客户端,然后使用 EOS_AntiCheatClient_ReceiveMessageFromServer 函数传递到客户端反作弊实例。
代码语言:javascript复制EOS_DECLARE_FUNC(EOS_NotificationId) EOS_AntiCheatServer_AddNotifyClientActionRequired(EOS_HAntiCheatServer Handle, const EOS_AntiCheatServer_AddNotifyClientActionRequiredOptions* Options, void* ClientData, EOS_AntiCheatServer_OnClientActionRequiredCallback NotificationFn);
添加当必须将操作应用于连接的客户端时发出的回调。绑定函数只会在成功调用 EOS_AntiCheatServer_BeginSession 和匹配的 EOS_AntiCheatServer_EndSession 调用之间调用。
结束会话
当执行关服操作时,需要关闭受保护的游戏会话,调用接口如下:
代码语言:javascript复制EOS_DECLARE_FUNC(EOS_EResult) EOS_AntiCheatServer_EndSession(EOS_HAntiCheatServer Handle, const EOS_AntiCheatServer_EndSessionOptions* Options);
结束游戏会话。应在服务器关闭或进入空闲状态时调用。
Client 注册
当客户端会话开启成功后,需要发消息给服务器注册是哪个客户端连上来了,调用接口如下:
代码语言:javascript复制EOS_DECLARE_FUNC(EOS_EResult) EOS_AntiCheatServer_RegisterClient(EOS_HAntiCheatServer Handle, const EOS_AntiCheatServer_RegisterClientOptions* Options);
注册连接的客户端。必须与对 UnregisterClient 的调用配对。该函数只能在成功调用 EOS_AntiCheatServer_BeginSession 和匹配的 EOS_AntiCheatServer_EndSession 调用之间调用。
只有当调用成功后,服务器才会给客户端发送验证消息,也就是我所说的数据通道才会开启,EOS_AntiCheatServer_AddNotifyMessageToClient 回调才会收到消息。
卸载客户端
同理,当玩家离开服务器的时候,玩家的相关信息也需要从受保护的游戏会话中移除,就需要调用接口 EOS_AntiCheatServer_UnregisterClient。
代码语言:javascript复制EOS_DECLARE_FUNC(EOS_EResult) EOS_AntiCheatServer_UnregisterClient(EOS_HAntiCheatServer Handle, const EOS_AntiCheatServer_UnregisterClientOptions* Options);
取消注册已断开连接的客户端。该函数只能在成功调用 EOS_AntiCheatServer_BeginSession 和匹配的 EOS_AntiCheatServer_EndSession 调用之间调用。
验证消息
当服务器收到客户端的消息时,需要调用此接口来验证,接口说明如下:
代码语言:javascript复制EOS_DECLARE_FUNC(EOS_EResult) EOS_AntiCheatServer_ReceiveMessageFromClient(EOS_HAntiCheatServer Handle, const EOS_AntiCheatServer_ReceiveMessageFromClientOptions* Options);
当收到客户端的反作弊消息时调用。该函数只能在成功调用 EOS_AntiCheatServer_BeginSession 和匹配的 EOS_AntiCheatServer_EndSession 调用之间调用。
返回值说明如下:
- EOS_Success - 消息处理成功
- EOS_InvalidParameters - 数据无效
- EOS_InvalidRequest - 消息内容已损坏且无法处理
结尾
OK,本期的分享到此就结束了,在这里需要另外作补充的是,EAC 的保护支持多种网络模型架构,譬如客户端-服务器,点对点,以及局域网。上面我分享的流程主要是应用于客户端以及受信用的服务器架构模型(Trust Server),因为这种类型的架构也是目前来说网络游戏应用的最广范的,如果你们对点对点或者聆听服模型感兴趣,可以自行参考 EAC 的文档,也欢迎大家找我咨询,不过记得请我喝杯咖啡。感谢大家的阅读,下期再见咯。