会话接口

用于处理基于会话的匹配的接口。

阅读时间31分钟

Epic在线服务 (EOS)让玩家能够通过 会话接口 建立、寻找在线游戏服务并与之发生交互。会话可能较短,例如在开始游戏之前填充特定数量的玩家槽位,游戏结束之后便解散;会话也可能较长,例如在多个地图或关卡的循环比赛中持续保持对游戏的跟踪。会话接口还负责管理游戏专属的数据,此数据为后端服务的搜索和匹配功能提供支持。有关匹配的注意事项,请参阅下文匹配相关的安全注意事项。本文还介绍了会话接口相关的一些定义和标题。完整列表请参见会话接口 API 参考文档。

通过平台接口函数 EOS_Platform_GetSessionsInterface 获取 EOS_HSessions 句柄,即可使用会话接口。所有会话接口函数均需将此句柄作为首个参数。必须确保 EOS_HPlatform 句柄会更新(tick),以便在请求完成时触发正确回调。请参阅基于C#的EOS SDK文档,了解有关Ticking的更多信息。

激活会话

激活会话是会话接口所有功能的核心。一个应用程序同时可拥有多个激活会话,每个皆由专属的本地名称识别。举例而言:本地好友之间可以建立名为“派对”的会话,组队与其他队伍进行比赛;也可以建立名为“游戏”的会话,其中包含部分或所有好友,以及当前进行比赛中的其他玩家。在每个参与玩家的系统上,每个会话都拥有其自身的 EOS_HActiveSession 柄。玩家创建会话、通过在线搜索或邀请加入会话后,玩家的机器上便会形成一个激活会话。激活会话存在于本地,不再需要它时,本地应用程序必须将其销毁。如主机未能进行此操作,后端服务将延迟会话的销毁,可能使其他玩家在在线搜索中错误找到不存在的会话。

要获取激活会话高级信息(类型为 EOS_ActiveSession_Info )的副本,包括其名称、创建或加入会话的本地用户的ID、其当前状态、对会话细节的引用(指向 EOS_SessionDetails_Info 的常量指针),以及任何用户定义的数据属性,必须以初始化如下的一个 EOS_Sessions_CopyActiveSessionHandleOptions 来调用本地函数 EOS_Sessions_CopyActiveSessionHandle ,以获得激活会话柄(类型为 EOS_HActiveSession ):

属性
ApiVersionEOS_SESSIONS_COPYACTIVESESSIONHANDLE_API_LATEST
SessionName要获取会话柄的会话的名称

可以用此柄调用 EOS_ActiveSession_CopyInfo 。还需要根据以下信息初始化并传入一个 EOS_ActiveSession_CopyInfoOptions

属性
ApiVersionEOS_ACTIVESESSION_COPYINFO_API_LATEST

此函数也在本地运行,在成功时将形成会话 EOS_ActiveSession_Info 数据的副本。不再需要时,必须通过 EOS_ActiveSession_Info_Release 来释放副本。

会话细节

本地创建、或通过搜索/邀请/其他玩家状态数据发现的激活会话将保存一个称为 EOS_SessionDetails_Info 的内部数据结构。此结构包含会话的基本细节:

  • 会话ID

  • 主机地址

  • 会话中开放槽位的数量

结构还包含指向另一个结构 EOS_SessionDetails_Settings 的指针。此结构提供了会话状态的更多详情,其中包括:

  • 称为 桶ID 的顶级过滤条件。其为每个游戏专属,常见格式是“GameMode:Region:MapName”

  • 会话所允许的连接总数

  • 进行中加入设置

  • 隐私设置

会话细节

如果你拥有一个 EOS_ActiveSession_Info 数据结构,便能通过它的 SessionDetails 变量来访问该会话的 EOS_SessionDetails_Info 。如否,可以使用一个 EOS_HSessionDetails 柄来调用 EOS_SessionDetails_CopyInfo ,获取 EOS_SessionDetails_Info 数据的副本。用一个包含以下信息的 EOS_SessionDetails_CopyInfoOptions 结构调用 EOS_SessionDetails_CopyInfo

属性
ApiVersionEOS_SESSIONDETAILS_COPYINFO_API_LATEST

在成功时,这将返回会话 EOS_SessionDetails_Info 的一个副本,其包含会话的ID、主机的地址,以及会话中开放槽位的数量。不再需要此信息时,调用 EOS_SessionDetails_Info_Release 来释放。

创建会话

会话的创建分为两步。

首先用 EOS_Sessions_CreateSessionModification 函数在本地建立会话的初始状态与设置。还需要传入一个拥有以下信息的 EOS_Sessions_CreateSessionModificationOptions 结构:

属性
ApiVersionEOS_SESSIONS_CREATESESSIONMODIFICATION_API_LATEST
SessionName会话的名称。在此用户创建的会话中,每个会话的名称必须独一无二
BucketId用于会话搜索的游戏专属顶层过滤信息。应使用最静态、最粗略的设置对此条件进行设置,常见格式为“GameMode:Region:MapName”。
MaxPlayers任意时间中会话所允许的最大玩家数
LocalUserId与会话关联的用户ID
bPresenceEnabled此会话是否与本地用户的状态信息相关(详情请见状态接口
SessionId可选项。设置此值以覆盖创建过程中定期分配给该会话的唯一ID。你可以用此方法来设置与其他开发人员标识符关联的值。这样,就不必向会话添加附加属性,并且要求会话公开发布通知以查找私有会话。该值必须在应用程序的生态系统内具有全局惟一性。如果不这样做,将会导致 'EOS_Sessions_SessionAlreadyExists' 错误。
bSanctionsEnabled此会话是否应该强制阻止受惩罚用户加入会话。这会阻止用户对 JoinRegisterPlayers 的调用,使这些用户无法成功加入。详情请参见惩罚接口文档。

如果 EOS_Sessions_CreateSessionModification 调用成功,其将返回 EOS_Success ,你提供的默认 EOS_HSessionModification 将包含一个有效柄。

然后继续修改会话的初始设置(参见[修改会话]章节),直到完成需要的所有修改。之后可以用一个初始化如下的 EOS_Sessions_UpdateSessionOptions 结构来调用 EOS_Sessions_UpdateSession ,完成创建流程:

属性
ApiVersionEOS_SESSIONS_UPDATESESSION_API_LATEST
SessionModificationHandle你要创建或更新会话的柄( EOS_HSessionModification

EOS_Sessions_UpdateSession 为异步,完成时将用一个 EOS_Sessions_UpdateSessionCallbackInfo 数据结构调用你的委托(类型为 EOS_Sessions_OnUpdateSessionCallback )。在成功时,你提供的本地名称将与来自服务器的可搜索、独特ID字符串进行配对。

玩家细节

你可以从活动会话检索以下玩家数据:

  • 注册玩家总数。
  • 每个注册玩家的产品用户ID(PUID)。

访问注册玩家总数

你可以调用 EOS_ActiveSession_GetRegisteredPlayerCount ,获取与活动会话关联的注册玩家总数。为此,请调用 EOS_ActiveSession_GetRegisteredPlayerCount ,其中带有包含以下信息的 ActiveSessionGetRegisteredPlayerCountOptions 结构:

属性
ApiVersionEOS_ACTIVESESSION_GETREGISTEREDPLAYERCOUNT_API_LATEST

访问每个注册玩家的产品用户ID

你可以在活动会话的注册玩家中迭代,获取每个注册玩家的产品用户ID(PUID)。为此,请调用 EOS_ActiveSession_GetRegisteredPlayerByIndex ,其中带有包含以下信息的 ActiveSessionGetRegisteredPlayerByIndexOptions 结构:

属性
ApiVersionEOS_ACTIVESESSION_GETREGISTEREDPLAYERBYINDEX_API_LATEST
PlayerIndex要检索的注册玩家的索引。

成功后,这会返回活动会话的指定索引处玩家的产品用户ID(PUID)。

修改会话

要修改现有的会话,首先使用一个指向默认 EOS_HSessionModification 对象的指针以及初始化如下的一个 EOS_Sessions_UpdateSessionModificationOptions 结构来调用 EOS_Sessions_UpdateSessionModification

属性
ApiVersionEOS_SESSIONS_UPDATESESSIONMODIFICATION_API_LATEST
SessionName你希望修改的会话名称

如果此调用成功,其将返回 EOS_Success ,修改将被应用到本地会话,你提供的 EOS_HSessionModification 将为有效柄。如你是会话拥有者,可以使用此柄来调用 EOS_Sessions_UpdateSession ,将本地进行的修改应用到会话的后端服务版本。此函数可用于新会话(尚未在服务器上创建的会话)和之前已存在的会话。以下函数将修改会话的不同方面:

函数效果
EOS_SessionModification_SetHostAddress 此函数修改包含到达服务器所需数据的字符串。主机地址并不一定必须是IP地址;套接字ID、URL或其他类型皆可。
EOS_SessionModification_SetBucketId桶ID(BucketId)是主要搜索条件,包含所有搜索中必需的游戏专属信息。举例而言,“GameMode:Region:MapName”之类的格式可以用于构建桶ID。
EOS_SessionModification_SetMaxPlayers此函数用于设置会话中所允许的最大玩家数。
EOS_SessionModification_SetJoinInProgressAllowed 你可以用此函数允许或禁止玩家加入已开始的游戏(参见[开始和结束游戏]章节了解详情)。
EOS_SessionModification_SetPermissionLevel 此函数可以将会话的隐私设置改为以下项:
  • EOS_OSPF_PublicAdvertised :会话将对所有玩家可见,将显示在搜索中。
  • EOS_OSPF_JoinViaPresence : 只有能够访问创建用户状态信息(此信息包含会话ID)的玩家才能找到此会话。
  • EOS_OSPF_InviteOnly : 只有受邀请的玩家才能找到此会话。
EOS_SessionModification_AddAttribute将一个自定义属性(类型为 EOS_SessionDetails_AttributeData )添加到会话。请参见[自定义属性]章节了解详情。
EOS_SessionModification_RemoveAttribute从会话中移除一个自定义属性。请参见[自定义属性]章节了解详情。

如果你是会话的拥有者,在本地修改会话之后可以在后端设备上更新会话。要执行此操作,用包含以下信息的 EOS_Sessions_UpdateSessionOptions 调用 EOS_Sessions_UpdateSession

属性
ApiVersionEOS_SESSIONS_UPDATESESSION_API_LATEST
SessionModificationHandle你希望服务器创建或更新会话的柄(EOS_HSessionModification

完成时,此操作将用一个 EOS_Sessions_UpdateSessionCallbackInfo 数据结构调用你的回调函数(类型为 EOS_Sessions_OnUpdateSessionCallback )。

自定义属性

会话能够包含用户定义的数据(其称为 attributes )。每个属性都拥有一个名称,用作一个字符串键、一个值、一个识别值类型的枚举变量,以及一个可视性设置。当前支持以下变量类型:

EOS_ESessionAttributeType值类型
EOS_SAT_BOOLEANEOS_Bool
EOS_SAT_INT64int64_t
EOS_SAT_DOUBLEdouble
EOS_SAT_STRINGconst char* (非空结尾的UTF8字符串)

以下可视性类型可用:

EOS_ESessionAttributeAdvertisementType可视性
EOS_SAAT_DontAdvertise其他用户不可见
EOS_SAAT_Advertise用户可见

访问属性

用一个有效 EOS_HSessionDetails 柄和包含以下信息的一个 EOS_SessionDetails_CopySessionAttributeByIndexOptions 来调用 EOS_SessionDetails_GetSessionAttributeCount ,即可找到会话拥有的属性数量:

属性
ApiVersionEOS_SESSIONDETAILS_GETSESSIONATTRIBUTECOUNT_API_LATEST

要获取属性的副本,用一个有效 EOS_HSessionDetails 柄和一个初始化如下的 EOS_SessionDetails_CopySessionAttributeByIndexOptions 来调用 EOS_SessionDetails_CopySessionAttributeByIndex

属性
ApiVersionEOS_SESSIONDETAILS_COPYSESSIONATTRIBUTEBYINDEX_API_LATEST
AttrIndex要复制属性的索引

在成功时,将返回 EOS_Success ,你的输出参数将包含 EOS_SessionDetails_Attribute 结构(对应请求的属性索引)的副本。此结构把属性的值和类型包含在一个 EOS_Sessions_AttributeData 数据结构中,把其可视性包含在一个 EOS_ESessionAttributeAdvertisementType 枚举值中。不再需要此数据时,使用 EOS_SessionDetails_Attribute_Release 将其释放。

添加属性

用以下信息填充 EOS_Sessions_AttributeData 数据结构,设置需要进行添加或修改的属性:

属性
ApiVersionEOS_SESSIONS_SESSIONATTRIBUTEDATA_API_LATEST
Key属性的名称
Value属性的值、或字符串的指针
ValueType描述 Value 的一个 EOS_ESessionAttributeType

将此数据准备好后,调用 EOS_SessionModification_AddAttribute 来添加属性。必须提供 EOS_HSessionModification 柄和一个初始化如下的 EOS_SessionModification_AddAttributeOptions

属性
ApiVersionEOS_SESSIONMODIFICATION_ADDATTRIBUTE_API_LATEST
SessionAttribute指向 EOS_Sessions_AttributeData 的一个常量指针,包含希望进行的修改
AdvertisementType一个 EOS_ESessionAttributeAdvertisementType,说明此属性是否应为公开可见

你在会话中最多可以保存 EOS_SESSIONMODIFICATION_MAX_SESSION_ATTRIBUTES (当前为64)个属性,每个属性的命名最长为 EOS_SESSIONMODIFICATION_MAX_SESSION_ATTRIBUTE_LENGTH (当前为32)个字符。

此函数只设置你需要添加或更新的属性。其不会实际添加或更新属性,或以任何方式与会话交互。如此[章节]前文所述,你仍然需要调用 EOS_Sessions_UpdateSession

移除属性

要移除属性,用会话的 EOS_HSessionModification 柄以及一个包含以下信息的 EOS_SessionModification_RemoveAttributeOptions 来调用 EOS_SessionModification_RemoveAttribute

属性
ApiVersionEOS_SESSIONMODIFICATION_REMOVEATTRIBUTE_API_LATEST
Key你希望移除的属性的名称(键)

此函数只在你需要移除特定属性时建立。其不会实际移除属性,或以任何方式与会话交互。如此[章节]前文所述,你仍然需要调用 EOS_Sessions_UpdateSession

邀请玩家至会话

要邀请另一个玩家加入激活会话,会话的[注册]成员可以用包含以下数据的 EOS_Sessions_SendInviteOptions 结构来调用 EOS_Sessions_SendInvite

属性
ApiVersionEOS_SESSIONS_SENDINVITE_API_LATEST
SessionName玩家被邀请加入的会话的名称
LocalUserId发送邀请的本地用户
TargetUserId被邀请的远程用户

服务器处理邀请请求后,将以包含结果代码的一个 EOS_Sessions_SendInviteCallbackInfo 结构来运行你的回调(类型为 EOS_Sessions_OnSendInviteCallback )。如在发送邀请的过程中没有出现错误,则此结果说明成功;成功并不意味着远程用户已接受(甚至已看到)邀请。

关于Epic Games启动程序的邀请功能,请确保将你的部署映射到你的构件中。

邀请到达时,远程用户将接收到邀请通知,负载将提供被邀请用户的ID,以及邀请资深的ID。接收到邀请后,使用 EOS_Sessions_CopySessionHandleByInviteId 从邀请获取 EOS_HSessionDetails 柄。你可以使用此柄来访问相关会话的[会话细节]数据,或接受/拒绝邀请。柄使用完毕后,调用 EOS_SessionDetails_Release 将其释放。

为接收此通知,你必须使用 EOS_Sessions_AddNotifySessionInviteReceived 注册一个回调。此操作只需执行一次(通常在启动时执行),之后每次收到邀请时便会运行你的回调。你不再需要通知时,调用 EOS_Sessions_RemoveNotifySessionInviteReceived 来移除回调。

接受邀请

会话接口不含接受邀请的专属功能。你可以用从邀请获取的 EOS_HSessionDetails 柄(标准方法)来[加入]会话。要请求所有待定邀请的列表,用初始化如下的 EOS_Sessions_QueryInvitesOptions 数据结构来调用 EOS_Sessions_QueryInvites

属性
ApiVersionEOS_SESSIONS_QUERYINVITES_API_LATEST
LocalUserId正在请求其邀请的本地用户

此操作为异步。完成时,其将以一个 EOS_Sessions_QueryInvitesCallbackInfo 数据结构来调用你的回调函数(类型为 EOS_Sessions_OnQueryInvitesCallback )。在成功时,EOS会将所有用户的待定邀请缓存到本地。你可以使用 EOS_Sessions_GetInviteCount 来确定缓存中邀请的数量。传入一个带以下信息的 EOS_Sessions_GetInviteCountOptions 结构:

属性
ApiVersionEOS_SESSIONS_GETINVITECOUNT_API_LATEST
LocalUserId拥有缓存邀请的本地用户

此函数在本地运行,将返回一个 uint32_t ,其代表当前缓存中的邀请数量。要获取任意缓存邀请的ID,用包含以下信息的一个 EOS_Sessions_GetInviteIdByIndexOptions 来调用 EOS_Sessions_GetInviteIdByIndex

属性
ApiVersionEOS_SESSIONS_GETINVITEIDBYINDEX_API_LATEST
LocalUserId拥有缓存邀请的本地用户
Index要获取ID的邀请的缓存索引

EOS_Sessions_GetInviteIdByIndex 返回 EOS_Success ,你传给它的输出参数将包含邀请的ID(一个非空结尾的字符串)以及该字符串的长度。

邀请ID字符串的最大长度为 EOS_SESSIONS_INVITEID_MAX_LENGTH (当前为64)。

如[上文]所述,EOS_Sessions_CopySessionHandleByInviteId 函数将提供一个 EOS_HSession 柄,它使你能够访问相关会话的[会话细节]数据。你可以选择接受邀请[加入]会话、无视邀请、或[拒绝]邀请。EOS_HSession 柄使用完毕后,调用 EOS_SessionDetails_Release 将其释放。

拒绝邀请

要拒绝邀请,请用初始化如下的一个 EOS_Sessions_RejectInviteOptions 来调用 EOS_Sessions_RejectInvite

属性
ApiVersionEOS_SESSIONS_REJECTINVITE
LocalUserId拒绝邀请的本地用户
InviteId邀请的ID

完成时,你将收到对 EOS_Sessions_OnRejectInviteCallback 回调函数的调用,并带有一个说明成功或失败的 EOS_Sessions_RejectInviteCallbackInfo 数据结构。成功拒绝邀请后,会将其从系统中永久删除。

发现远程会话

要找到远程会话,需要配置搜索、执行搜索,再检查结果。

配置搜索

要开始搜索,先调用 EOS_Sessions_CreateSessionSearch 来创建一个搜索柄。传入一个 EOS_Sessions_CreateSessionSearchOptions 结构,初始化如下:

属性
ApiVersionEOS_SESSIONS_CREATESESSIONSEARCH_API_LATEST
MaxSearchResults要返回的搜索结果的最大数量

此函数在本地运行,成功时将填充默认搜索柄(类型为 EOS_HSessionSearch )。下一步是配置柄以你需要的条件来进行特定搜索。EOS提供了3种方法来搜索会话:

  • 会话ID: 找到拥有已知ID的单一会话

  • 用户ID: 找到已知用户的所有会话(当前仅限于本地用户)

  • 属性数据: 找到与用户定义的过滤条件相匹配的所有会话

配置会话ID

如果希望了解特定会话的服务器端ID,请用搜索柄和一个初始化如下的 EOS_SessionSearch_SetSessionIdOptions 来调用 EOS_SessionSearch_SetSessionId

属性
ApiVersionEOS_SESSIONSEARCH_SETSESSIONID_API_LATEST
SessionId希望找到的会话的ID

配置会话ID搜索只需要这一步。和其他搜索方法不同,这永远不会返回一个以上的结果。

只有标记为 EOS_OSPF_PublicAdvertisedEOS_OSPF_JoinViaPresence 的会话可以用此方法发现。

配置用户ID

要找到涉及已知用户的所有会话,用搜索柄和包含以下信息的一个 EOS_SessionSearch_SetTargetUserIdOptions 来调用 EOS_SessionSearch_SetTargetUserId

属性
ApiVersionEOS_SESSIONSEARCH_SETTARGETUSERID_API_LATEST
TargetUserId要在会话中寻找的用户ID

这是配置用户ID搜索所需的唯一一步。必须是已登录的本地用户。

该应用程序只能找到本地身份验证用户或在公共会话中注册的远程用户。

配置属性数据

寻找会话最有效的方式是基于一组搜索参数进行搜索,这些参数将用作过滤器。一些参数可以对用户公开,例如让用户选择特定的游戏类型或地图;而其他的参数也可能为隐藏,例如用玩家的预期水平来搜索水平相当的对手进行比赛。此搜索方法可接受多个参数,只会找到所有参数均验证通过的会话。要设置搜索参数,用搜索柄以及包含以下信息的一个 EOS_SessionSearch_SetParameterOptions 来调用 EOS_SessionSearch_SetParameter

属性
ApiVersionEOS_SESSIONSEARCH_SETPARAMETER_API_LATEST
Parameter与会话相关的[属性]进行对比的一个键和一个值
ComparisonOp要进行的对比类型

可以多次调用此函数来设置多个过滤条件,满足所有过滤条件的会话才会显示在搜索结果中。下表列出了可以使用的对比类型、它们使用的值类型,以及通过必须满足的条件:

ComparisonOp可接受的值类型成功条件
EOS_CO_EQUAL所有属性等于搜索值
EOS_CO_NOTEQUAL所有属性不等于搜索值
EOS_CO_GREATERTHAN数字类型属性大于搜索值
EOS_CO_GREATERTHANOREQUAL数字类型属性大于或等于搜索值
EOS_CO_LESSTHAN数字类型属性小于等于搜索值
EOS_CO_LESSTHANOREQUAL数字类型属性小于或等于搜索值
EOS_CO_DISTANCE数字类型并非过滤;属性基于其与搜索值或 Abs(AttributeValue - SearchValue) 的距离来排序
EOS_CO_ANYOF字符串属性与分号间隔列表中的任意成员匹配(例如“This;OrThis;MaybeThis”)
EOS_CO_NOTANYOF字符串属性与分号间隔列表中的任意成员不匹配(例如“NotThis;OrThisEither”)

执行搜索

要执行搜索,请使用搜索句柄以及一个 EOS_SessionSearch_FindOptions 结构(初始化如下)来调用 EOS_SessionSearch_Find

这是一个异步操作。其完成时,你的回调函数(类型为 EOS_SessionSearch_OnFindCallback)将接收到一个 EOS_SessionSearch_FindCallbackInfo 结构,其将告知搜索成功或失败。成功完成后,你可以从EOS缓存中获取搜索结果的副本。

EOS支持平行运行多个 EOS_SessionSearch_Find 操作。

提示 :你可以按属性 EOS_SESSIONS_SEARCH_MINSLOTSAVAILABLE 搜索,查找未满(仍有插槽可用)的会话。将值类型设置为 int64_t ,并使用 EOS_CO_GREATERTHANOREQUAL 比较运算符,以将值设置为至少 1 。这会从结果中排除已满会话。

检查搜索结果

对于给定的 EOS_HSessionSearch 句柄和 EOS_SessionSearch_CopySearchResultByIndexEOS_SessionSearch_GetSearchResultCount 会通过单独的 EOS_HSessionDetails 句柄逐个返回会话细节。

成功完成搜索后,用搜索柄和 EOS_SessionSearch_GetSearchResultCount 来获取搜索返回的结果数量。之后可以调用 EOS_SessionSearch_CopySearchResultByIndex 来获取与该索引处[激活会话]相关的 EOS_HSessionDetails 柄副本。此柄提供对[会话细节]数据的访问,可以将此数据用于将会话的相关信息对本地用户显示、或确定是否使用你自己的游戏逻辑来[加入]会话。不再需要时,必须用 EOS_SessionDetails_ReleaseEOS_HSessionDetails 柄释放。

加入会话

如拥有有效 EOS_HSessionDetails 柄,可以调用 EOS_Sessions_JoinSession 并提供一个带以下信息的 EOS_Sessions_JoinSessionOptions 结构来加入现有的会话:

属性
ApiVersionEOS_SESSIONS_JOINSESSION_API_LATEST
SessionName本地系统用于引用会话的专属名称
SessionHandle希望加入的会话的 EOS_HSessionDetails
LocalUserId加入会话的本地用户
bPresenceEnabled此会话是否与本地用户的状态信息相关(详情请见状态接口

操作完成时,你的回调函数(类型为 EOS_Sessions_OnJoinSessionCallback )将接收一条表明成功或失败的 EOS_Sessions_JoinSessionCallbackInfo 。如操作成功,EOS将在加入客户端系统时创建一个激活会话。因为这个新会话为本地拥有,不再需要时加入的用户将负责[销毁]。

注册玩家

玩家加入会话后,会话拥有者负责将玩家注册到会话。这使得后端服务能够了解玩家的数量,以便在会话满时停止公开宣传会话。EOS将通过 EOS_Sessions_RegisterPlayers 函数立即接受多个玩家的注册。用一个包含以下数据的 EOS_Sessions_RegisterPlayersOptions 结构从拥有客户端调用此函数:

属性
ApiVersionEOS_SESSIONS_REGISTERPLAYERS_API_LATEST
SessionName会话的本地名
PlayersToRegister加入玩家的ID数组
PlayersToRegisterCountPlayersToRegister 中元素的数量

完成时,你的回调(类型为 EOS_Sessions_OnRegisterPlayersCallback)将读取一个 EOS_Sessions_RegisterPlayersCallbackInfo 参数并执行。此参数包含以下数据:

属性
ResultCode表示成功或失败的结果代码
Registered Players成功注册的玩家列表
Registered Players Count注册玩家数量
Sanctioned Players因为惩罚而无法注册的玩家列表
Sanctioned Players Count因为惩罚而无法注册的玩家数量

如调用成功,新注册的玩家将能够访问部分会话管理功能(例如邀请其他玩家加入会话)。注意,当一个或多个受惩罚玩家被拒绝注册时,不会返回错误; 必须手动检查 SanctionedPlayers 列表 。请参见执行惩罚了解详情。玩家加入会话时EOS不会提供通知,因此在加入时你必须通知拥有者,或为拥有者提供一种方式来检测玩家已成功加入会话。

当用户注册了公共可见会话(配置为 EOS_ospf_PublicAdvertisedEOS_ospf_JoinViaPresence 的会话)后,其他用户可以使用 EOS_SessionSearch_SetTargetUserId 找到会话。

离开会话

会话接口不含离开会话的专属功能。要离开会话,须通过标准方法,使用其本地名称来[销毁]本地会话。

取消玩家注册

玩家离开会话后,会话的拥有者负责取消玩家注册。这使得服务器可以清理出玩家槽位,以便之后的玩家加入。EOS可以通过 EOS_Sessions_UnregisterPlayers 函数立即取消多个玩家的注册。用一个包含以下数据的 EOS_Sessions_UnregisterPlayersOptions 结构从所属客户端调用此函数:

属性
ApiVersionEOS_SESSIONS_UNREGISTERPLAYERS_API_LATEST
SessionName会话的本地名
PlayersToUnregister离开玩家的ID数组
PlayersToUnregisterCountPlayersToUnregister 中元素的数量

完成时,你的回调(类型为 EOS_Sessions_OnUnregisterPlayersCallback)将随一个 EOS_Sessions_UnregisterPlayersCallbackInfo 参数运行。此参数将说明成功或失败。如调用成功,玩家在原始注册时后端服务将调用这些玩家所获得的会话管理功能。举例而言,未注册会话的玩家无法邀请其他玩家加入。EOS不会提供玩家离开会话的通知,因此你在离开会话时必须通知拥有者,或提供一种方式让拥有者能够检测玩家已离开游戏或断线。

会话不支持主机迁移。如果会话拥有者离开或失去网络连接,会话将被孤立,其他任何人都无法在后端管理该会话。

开始和结束游戏

玩家可以声明本地激活会话的比赛已开始或结束。如该会话映射到本地玩家拥有的后端服务上的会话,后端版本也将开始或结束游戏。进行游戏时,如该会话禁用了 过程中加入(Join in Progress) (参加[修改会话]中的章节来了解详情),后端服务将自动拒绝加入会话的尝试。虽然开始会话通常意味着比赛已开始,但此功能的具体用法仍然是由开发者自行决定。

要开始游戏,用一个初始化如下的 EOS_Sessions_StartSessionOptions 来调用 EOS_Sessions_StartSession

属性
ApiVersionEOS_SESSIONS_STARTSESSION_API_LATEST
SessionName会话的本地名

操作完成时,你的回调(类型为 EOS_Sessions_OnStartSessionCallback )将随一个 EOS_Sessions_StartSessionCallbackInfo 数据结构运行,此结构说明成功或失败。如操作成功,会话则视为“进行中”,直到用包含以下信息的一个 EOS_Sessions_EndSessionOptions 调用 EOS_Sessions_EndSession 结束游戏:

属性
ApiVersionEOS_SESSIONS_ENDSESSION_API_LATEST
SessionName会话的本地名

完成时,你的 EOS_Sessions_OnEndSessionCallback 函数将接收一个调用,并以一个 EOS_Sessions_EndSessionCallbackInfo 数据结构来说明成功或失败。在成功时,会话不再被视为“进行中”,将会再次允许玩家加入。结束会话不会移除玩家或销毁会话;其会返回开始之前的状态并保持可用,并且能够再次开始。如果希望销毁会话,则不需要先调用 EOS_Sessions_EndSession

销毁会话

不再需要会话时,必须使用 EOS_Sessions_DestroySession 进行销毁。用包含以下信息的一个 EOS_Sessions_DestroySessionOptions 数据结构调用此函数:

属性
ApiVersionEOS_SESSIONS_DESTROYSESSION_API_LATEST
SessionName要销毁的会话的名称

销毁操作完成时,你将收到一个类型为 EOS_Sessions_OnDestroySessionCallback 的回调,并带一个 EOS_Sessions_DestroySessionCallbackInfo 数据结构。成功销毁后,会话将不复存在,其名称将能重新使用。然而由于系统的异步性质,在调用 EOS_Sessions_DestroySession 之后,后端服务销毁会话之前,玩家可以提出请求。在此情况下,开始销毁操作之后你可能会接收到加入会话的请求。此时必须拒绝这些玩家的加入请求或关闭网络,防止其加入无法使用的会话。

在远程客户端上镜像会话管理

通过会话接口,会话拥有者(创建会话的用户)可以管理会话的状态,因为其存在于后端服务上。会话的生命周期以创建为开始,销毁为结束。在这两个事件之间,会话接口可以修改会话、变更其隐私设置、发送邀请、在玩家渐入和离开时注册/取消注册,以及开始/进行/结束比赛。会话的生命周期并非一成不变。举例而言,会话可以随时修改其数据,并能开始和结束多场比赛。

整体而言,只有会话拥有者能对后端服务上的会话数据进行修改。但是,[加入]会话的远程客户端将拥有会话的本地视图,而此视图不会自动获取关于后端版本的数据更新。镜像以下函数调用,让远程客户端可以将本地视图与后端会话同步(这并非必需操作,但会有所帮助):

  • EOS_Sessions_StartSession

  • EOS_Sessions_EndSession

  • EOS_Sessions_RegisterPlayers

  • EOS_Sessions_UnregisterPlayers

这些函数将修改远程客户端(非拥有者客户端)上会话的本地状态,而不影响后端服务的版本。

执行惩罚

如果你用了EOS的惩罚功能,那么你可以在当玩家加入或注册会话时,强制执行惩罚。请参见惩罚接口文档,了解有关惩罚机制的更多详情。

受到惩罚的玩家无法加入或注册启用了惩罚机制的会话。这也包括由玩家创建的启用了惩罚机制的会话;如果他们是受惩罚玩家,同样不能加入这些会话。

惩罚通过会话接口强制执行。在创建会话时,会根据 EOS_Sessions_CreateSessionModificationOptions 结构体中的 bSanctionsEnabled 的值来判断是否启用惩罚。如果 bSanctionsEnabled 为真,那么所创建的会话就会启用惩罚。请参见创建会话以获得更多信息。

如果玩家受到了 RESTRICT_GAME_ACCESS 类型的惩罚,反作弊系统会将他们从游戏的多人游戏会话中自动踢出。请参见反作弊文档了解详情。

EOS_Sessions_JoinSession函数不会把被标为 RESTRICT_MATCHMAKING 的玩家加入到会话中,并且会在玩家尝试加入时返回 EOS_Sessions_PlayerSanctioned 错误。然而,可支持多人玩家的函数 EOS_Sessions_RegisterPlayers 不同于 EOS_Sessions_JoinSession ,它不会在受惩罚玩家(1个或多个)尝试注册会话时返回错误。相反,你必须检查响应对象,来确定所有玩家是否都注册了。如果会话启用了惩罚,所有受到惩罚并且无法注册的玩家,都会出现在回调信息 EOS_Sessions_RegisterPlayersCallbackInfoSanctionedPlayers 成员中。请参见玩家注册了解详情。

使用限制

用户可以通过“会话”接口来主持、寻找会话,或者与在线游戏会话互动。会话可以很短暂,比如在游戏开始前填满一定数量的玩家空白,然后在游戏结束后解散。也可以比较长,比如跟踪某个在多张地图/关卡上循环进行的游戏。会话接口还能管理特定的游戏数据,支持后端服务搜索和匹配功能。

有关节流限制、使用配额和最佳实践的一般信息,请参阅服务使用限制

以下是影响会话的一些限制:

功能限制
当前在线玩家每个会话1000
会话属性每个会话100
属性名称长度1000个字符

使用会话接口的用户交互必须遵守以下限制:

功能限制每项部署限制
创建会话每分钟30次请求每分钟每1个CCU 30次请求
删除会话每分钟30次请求每分钟每1个CCU 30次请求
更新会话每分钟30次请求每分钟每1个CCU 30次请求
添加或移除玩家每分钟100次请求每分钟每1个CCU 30次请求
开始或停止会话每分钟30次请求每分钟每1个CCU 30次请求
邀请用户每分钟100次请求每分钟每1个CCU 30次请求
过滤会话每分钟30次请求每分钟每1个CCU 30次请求

此外,还存在一些与用户有关的频率相关的限制。请注意以下限制,避免出现瓶颈:

功能用户限制
单个用户同时可以加入的最大数量的会话16

匹配相关的安全注意事项

匹配(Matchmaking) 功能要求你采取一组信息,例如玩家标识符或服务器IP地址,然后将数据广播给其他潜在玩家。通常情况下,会话数据包括:

  1. 一个 主机IP地址(Host IP Address) ,通过 EOS_SessionModification_SetHostAddress 设置或由EOS服务自动检测。尝试加入游戏时,必须存在该地址信息。

  2. 所有注册了会话的玩家的 EOS产品用户ID

  3. 所有使用 EOS_SessionModification_AddAttribute 添加到会话的自定义属性。这些可以是开发者设置的任何东西。

匹配会获取游戏数据并创建一个可搜索的索引,所以在创建会话时,你应当始终留意哪些数据是暴露的。对于采用专用服务器的游戏来说,你需要暴露服务器的IP地址;而对于点对点会话来说,你可以暴露终端用户的IP地址。

注意 :如果你对暴露主机IP地址有安全顾虑,你可以使用 EOS_SessionModification_SetHostAddress ,将主机地址设置为其他内容。例如如果你使用P2P接口,则设置为P2P的套接字ID。

当你创建一个会话时,你可以使用 EOS_SessionModification_SetPermissionLevel 为该会话指定一个 权限级别 。会话有3种安全级别。

安全级别说明
EOS_OSPF_PublicAdvertised任何客户端都可以在搜索结果中获得会话,而无需知道会话ID;只要会话没有开始或者会话允许中途加入,就可以读取会话信息。对客户端/玩家来说,只要能够访问唯一会话ID,就能查看会话信息,即使该会话不可加入。
EOS_OSPF_JoinViaPresence所有能够访问唯一会话ID的客户端/玩家都可以查看会话信息(通常,这类信息通过存在数据共享,但也可以通过其他方式共享)。
EOS_OSPF_InviteOnly只有被会话现有成员明确邀请的玩家才能查看会话信息。

最佳实践

  • 请确保你的会话的暴露范围被设置成最低限度。

  • 假如会话属性不应被暴露给所有正在寻找该会话的人,则请不要将信息添加到会话属性中。

  • 如果你需要使用JoinViaPresence,请确保隐藏会话ID,不让玩家/用户看到。如果它被暴露,那么它将允许会话数据被访问。

  • 如果你的游戏不支持JoinInProgress,请确保服务器采用EOS_Sessions_StartSession来启动会话,以便当游戏开始后,从之后的搜索中删除该会话。

常见问题解答

问:为什么我找不到刚创建的服务器?
答:索引编制需要两秒钟来刷新,因此你可能无法立即找到你的服务器。

问:为什么我看不到与同事或好友相同的服务器列表?
答:为确保任何两个人不会同时获得相同的服务器列表,匹配有两秒钟延迟。这种有意的抖动可避免会影响服务器效率的竞争条件。

问:我想查看我的游戏中设置的会话。我如何才能查看我的游戏中的所有会话?
答:你可以在开发人员门户中找到你的游戏中的会话列表。登录开发人员门户(在dev.epicgames.com/portal),并在左侧边栏中的 产品(Products) 分段下选择你的产品。转至 游戏服务(Game Services) > 多人游戏(MULTIPLAYER) > 匹配(Matchmaking)