注意: 此页面上的内容与托管游戏服务器托管 (Clanforge) 相关。如果您使用的是游戏服务器托管 (Multiplay),请参考 游戏服务器托管 (Multiplay) 文档.
服务器查询协议
服务器查询协议 (SQP) 允许客户端使用 UDP/IP 数据包检索有关正在运行的游戏服务器的信息。
客户端通过向服务器发送 ChallengeRequest
来发起查询。作为响应,服务器会发送 ChallengeResponse
,其中包含 ChallengeId
。客户端收到 ChallengeResponse
后,可以继续向服务器查询信息。
以下部分介绍了 SQP 的技术规范,包括 数据类型、请求类型 和 数据包格式。
SQP 支持的游戏服务器状态信息包括
- 服务器名称:游戏服务器的名称。
- 构建 ID:游戏服务器正在运行的游戏镜像的标识符。
- 当前玩家:当前连接的玩家数量。
- 最大玩家:可以加入游戏服务器的最大玩家数量。
- IP 地址:托管游戏服务器的机器的 IP 地址。
- 端口:游戏服务器的端口,客户端可以通过该端口连接到主机上的特定游戏服务器。
- 游戏类型:游戏服务器正在运行的游戏。
- 地图:当前在游戏服务器上加载的游戏地图。
Note: SQP works with the Game Server Hosting game server monitoring process to make sure reports by the game server match the information in Game Server Hosting’s database.
要求
在将 SQP 作为游戏服务器查询协议实现之前,您必须使用所有游戏服务器信息填充游戏客户端端的 ServerInfoData
对象。这将确保游戏服务器报告正确的信息。
参考实现
参考 go-svrquery 以获取 SQP 的示例实现。go-svrquery 是使用各种 查询协议(包括 SQP)与游戏服务器通信的 Golang 客户端。
数据类型
所有服务器查询都包含五种基本类型的数据,这些数据打包成数据流。下表介绍了每种类型。所有类型都是大端字节序。
名称 | 描述 |
---|---|
byte | 一个 8 位字符或一个无符号整数。 |
ushort | 一个 16 位无符号整数。 |
uint | 一个 32 位无符号整数。 |
ulong | 一个 64 位无符号整数。 |
string | 一个可变长度的字节字段,以 UTF-8 编码,并以包含字符串长度的字节为前缀。字符串限制为 255 个字节。 |
请求类型
客户端可以向服务器发出五种类型的请求。下表指定了客户端应为每种请求类型从服务器期望的响应。
请求 | 响应 |
---|---|
ChallengeRequest | 服务器返回一个挑战号,供客户端在查询请求响应中使用。 |
QueryRequest 以及 ServerInfo 块 | 服务器返回有关服务器的基本信息,例如,当前玩家数量、最大玩家数量、游戏类型和构建 ID。 |
数据包类型
下表显示了不同的 SQP 数据包类型。
数据包类型 | 字节值 |
---|---|
ChallengeRequest | 0 |
ChallengeResponse | 0 |
QueryRequest | 1 |
QueryResponse | 1 |
标头
所有 SQP 数据包(无论是请求还是响应)都包含一个标头,其中包含以下数据。
数据 | 类型 | 注释 |
---|---|---|
类型 | byte | 包含数据包类型。请参考 数据包类型。 |
ChallengeToken | uint | ChallengeToken 包含挑战号。QueryRequest 和 QueryResponse 数据包类型需要挑战号。请参考 挑战号。 |
有效负载 | 包含数据包的主体(如果数据包有主体)。 |
挑战号
SQP 使用挑战号(这是一个随机的 32 位整数)来确保发出查询请求的客户端与收到挑战号的客户端相同。
当客户端首次向服务器发送请求时,服务器会随机选择挑战号,并将其包含在数据包标头中。然后,客户端必须在所有后续请求的标头中包含相同的挑战号。
挑战数据包
客户端可以使用挑战数据包检索可用于后续请求的可用的挑战号。
> Note: Challenge packets only have a header. There is no payload.
请求格式
数据 | 注释 |
---|---|
标头 | 请参考 标头。 |
以下代码片段显示了 ChallengeRequest
数据包的示例
[0x00000000] 0x00 '\0' unsigned char
[0x00000001] 0x00 '\0' unsigned char
[0x00000002] 0x00 '\0' unsigned char
[0x00000003] 0x00 '\0' unsigned char
[0x00000004] 0x00 '\0' unsigned char
响应格式
数据 | 注释 |
---|---|
标头 | 请参考 标头。 |
以下代码片段显示了 ChallengeResponse
数据包的示例
[0x00000000] 0x00 '\0' unsigned char
[0x00000001] 0x80 '€' unsigned char
[0x00000002] 0x90 '•' unsigned char
[0x00000003] 0x23 '#' unsigned char
[0x00000004] 0x48 'H' unsigned char
查询数据包
客户端可以发送查询数据包以检索有关服务器的信息。 游戏服务器托管仅要求游戏服务器以ServerInfo
块响应查询。 您也可以使用其他请求类型,但它们对于游戏服务器托管来说并不必要。
块类型
客户端可以使用查询数据包请求四种不同类型的块。 但是,本文档仅包含ServerInfo
块类型,因为它是在游戏服务器托管中唯一支持的块类型。
每个块类型的字节值指示请求的客户端期望的响应块。 当服务器收到查询数据包时,它会检查请求中的RequestedChunks
字段,并使用块类型的字节值执行按位AND
操作。 如果此操作的结果大于零,则服务器知道已请求块类型。
例如,如果RequestedChunks&1 > 0
,则服务器会以ServerInfo
块进行响应。 请参考下面的说明。
> Note: Although there are four types of chunk types available in the SQP protocol, Game Server Hosting only supports the ServerInfo
chunk type.
示例 RequestedChunk | 含义 | 检查 |
---|---|---|
00000001 | ServerInfo | RequestedChunks & 0x01 > 0 |
00000010 | 保留 | RequestedChunks & 0x02 > 0 |
00000100 | 保留 | RequestedChunks & 0x04 > 0 |
00000010 | 保留 | RequestedChunks & 0x08 > 0 |
注意:RequestedChunks
可以同时请求多个块,因此您的实现必须能够对RequestedChunks
值执行正确的按位检查。
请求格式
所有查询请求的请求格式都相同。
> Note: Game Server Hosting only requires a server to respond to ServerInfo
requests. Therefore, all other request types are omitted.
数据 | 类型 | 注释 |
---|---|---|
标头 | 请参考 标头。 | |
版本 | ushort | 包含要使用的SQP版本。 |
RequestedChunks | byte | 包含请求的ChunkTypes 。 请参考 块类型. |
以下代码片段包含QueryRequest
数据包的示例
[0x00000000] 0x01 '\x1' unsigned char
[0x00000001] 0x80 '€' unsigned char
[0x00000002] 0x31 '1' unsigned char
[0x00000003] 0xbe '¾' unsigned char
[0x00000004] 0x18 '\x18' unsigned char
[0x00000005] 0x00 '\0' unsigned char
[0x00000006] 0x01 '\x1' unsigned char
[0x00000007] 0x01 '\x1' unsigned char
响应格式
所有块类型都共享前四个字段(Version
、CurrentPacket
、LastPacket
和PacketLength
)的标准响应格式。 数据包的PacketLength
字段之后的信息根据请求类型而有所不同。
标准响应格式
下表包含所有块类型相同的响应部分。
数据 | 类型 | 注释 |
---|---|---|
标头 | 请参考 标头。 | |
版本 | ushort | 包含要使用的SQP版本。 |
CurrentPacket | byte | 不支持。 该值应始终为 0。 |
LastPacket | byte | 不支持。 该值应始终为 0。 |
PacketLength | ushort | 包含此点之后数据包的长度。 |
ServerInfo 响应格式
数据 | 类型 | 注释 |
---|---|---|
请参考 标准响应格式,了解不同块类型之间不变化的字段。 | ||
ChunkLength | uint | 包含此点之后ServerInfo 块的长度。 |
CurrentPlayers | ushort | 包含服务器上的玩家数量。 |
MaxPlayers | ushort | 包含服务器支持的最大玩家数量。 |
ServerName | string | 包含服务器的名称。 |
GameType | string | 包含服务器上的游戏。 |
BuildId | string | 包含服务器的版本号或构建 ID。 |
Map | string | 包含服务器当前加载的地图。 |
Port | ushort | 包含服务器公开的游戏端口。 |
以下代码片段包含QueryResponse
数据包的示例
[0x00000000] 0x01 '\x1' unsigned char
[0x00000001] 0xc0 'À' unsigned char
[0x00000002] 0x7a 'z' unsigned char
[0x00000003] 0x6c 'l' unsigned char
[0x00000004] 0x3d '=' unsigned char
[0x00000005] 0x00 '\0' unsigned char
[0x00000006] 0x01 '\x1' unsigned char
[0x00000007] 0x00 '\0' unsigned char
[0x00000008] 0x00 '\0' unsigned char
[0x00000009] 0x00 '\0' unsigned char
[0x0000000a] 0x5b '[' unsigned char
[0x0000000b] 0x00 '\0' unsigned char
[0x0000000c] 0x00 '\0' unsigned char
[0x0000000d] 0x00 '\0' unsigned char
[0x0000000e] 0x57 'W' unsigned char
[0x0000000f] 0x00 '\0' unsigned char
[0x00000010] 0x00 '\0' unsigned char
[0x00000011] 0x00 '\0' unsigned char
[0x00000012] 0x10 '\x10' unsigned char
[0x00000013] 0x14 '\x14' unsigned char
[0x00000014] 0x55 'U' unsigned char
[0x00000015] 0x45 'E' unsigned char
[0x00000016] 0x34 '4' unsigned char
[0x00000017] 0x20 ' ' unsigned char
[0x00000018] 0x44 'D' unsigned char
[0x00000019] 0x65 'e' unsigned char
[0x0000001a] 0x64 'd' unsigned char
[0x0000001b] 0x69 'i' unsigned char
[0x0000001c] 0x63 'c' unsigned char
[0x0000001d] 0x61 'a' unsigned char
[0x0000001e] 0x74 't' unsigned char
[0x0000001f] 0x65 'e' unsigned char
[0x00000020] 0x64 'd' unsigned char
[0x00000021] 0x20 ' ' unsigned char
[0x00000022] 0x53 'S' unsigned char
[0x00000023] 0x65 'e' unsigned char
[0x00000024] 0x72 'r' unsigned char
[0x00000025] 0x76 'v' unsigned char
[0x00000026] 0x65 'e' unsigned char
[0x00000027] 0x72 'r' unsigned char
[0x00000028] 0x2e '.' unsigned char
[0x00000029] 0x2f '/' unsigned char
[0x0000002a] 0x53 'S' unsigned char
[0x0000002b] 0x63 'c' unsigned char
[0x0000002c] 0x72 'r' unsigned char
[0x0000002d] 0x69 'i' unsigned char
[0x0000002e] 0x70 'p' unsigned char
[0x0000002f] 0x74 't' unsigned char
[0x00000030] 0x2f '/' unsigned char
[0x00000031] 0x53 'S' unsigned char
[0x00000032] 0x68 'h' unsigned char
[0x00000033] 0x6f 'o' unsigned char
[0x00000034] 0x6f 'o' unsigned char
[0x00000035] 0x74 't' unsigned char
[0x00000036] 0x65 'e' unsigned char
[0x00000037] 0x72 'r' unsigned char
[0x00000038] 0x47 'G' unsigned char
[0x00000039] 0x61 'a' unsigned char
[0x0000003a] 0x6d 'm' unsigned char
[0x0000003b] 0x65 'e' unsigned char
[0x0000003c] 0x2e '.' unsigned char
[0x0000003d] 0x53 'S' unsigned char
[0x0000003e] 0x68 'h' unsigned char
[0x0000003f] 0x6f 'o' unsigned char
[0x00000040] 0x6f 'o' unsigned char
[0x00000041] 0x74 't' unsigned char
[0x00000042] 0x65 'e' unsigned char
[0x00000043] 0x72 'r' unsigned char
[0x00000044] 0x47 'G' unsigned char
[0x00000045] 0x61 'a' unsigned char
[0x00000046] 0x6d 'm' unsigned char
[0x00000047] 0x65 'e' unsigned char
[0x00000048] 0x5f '_' unsigned char
[0x00000049] 0x54 'T' unsigned char
[0x0000004a] 0x65 'e' unsigned char
[0x0000004b] 0x61 'a' unsigned char
[0x0000004c] 0x6d 'm' unsigned char
[0x0000004d] 0x44 'D' unsigned char
[0x0000004e] 0x65 'e' unsigned char
[0x0000004f] 0x61 'a' unsigned char
[0x00000050] 0x74 't' unsigned char
[0x00000051] 0x68 'h' unsigned char
[0x00000052] 0x4d 'M' unsigned char
[0x00000053] 0x61 'a' unsigned char
[0x00000054] 0x74 't' unsigned char
[0x00000055] 0x63 'c' unsigned char
[0x00000056] 0x68 'h' unsigned char
[0x00000057] 0x03 '\x3' unsigned char
[0x00000058] 0x30 '0' unsigned char
[0x00000059] 0x30 '0' unsigned char
[0x0000005a] 0x31 '1' unsigned char
[0x0000005b] 0x08 '\b' unsigned char
[0x0000005c] 0x48 'H' unsigned char
[0x0000005d] 0x69 'i' unsigned char
[0x0000005e] 0x67 'g' unsigned char
[0x0000005f] 0x68 'h' unsigned char
[0x00000060] 0x72 'r' unsigned char
[0x00000061] 0x69 'i' unsigned char
[0x00000062] 0x73 's' unsigned char
[0x00000063] 0x65 'e' unsigned char
[0x00000064] 0x1e '\x1e' unsigned char
[0x00000065] 0x61 'a' unsigned char