跳到主要内容

SA:MP 查询机制

机制概述

SA:MP 查询机制是通过 UDP 数据包传输服务器统计信息的标准协议,可获取服务器名称、玩家延迟、语言设置、在线玩家列表等核心数据。

本文详解该协议工作原理,并指导如何在不依赖官方客户端的情况下实现查询功能。

查询机制

查询是通过 UDP 协议向服务器地址发送的序列化数据包。

您可能会疑惑:"服务器如何区分查询数据包与常规 RakNet 协议数据?" 其原理在于底层 RakNet 套接字层会识别数据包头部的"SAMP"标识(十六进制值:53 41 4D 50),并采用特殊处理流程。查看源码

序列化数据包

传输数据包由以下部分组成:"SAMP" + IP 四元组 + 端口低字节 + 端口高字节 + 操作码

若对 IP 四元组和端口字节的解析方式存在疑问,可参考:IP 地址与端口解析指南

字节长度字段
4"SAMP"
4IP 地址四元组
1端口低 8 位
1端口高 8 位
1操作码

C 语言实现示例

操作码说明

各操作码对应不同查询类型:

  • 0x69 ('i'):基础信息查询
    获取服务器密码状态、在线人数、主机名、游戏模式、语言等核心参数

  • 0x72 ('r'):规则查询
    返回重力值、天气代码、网站链接等自定义规则参数

  • 0x63 ('c'):玩家简表
    获取玩家昵称与得分的快速列表

  • 0x64 ('d'):玩家详情
    包含玩家 ID、昵称、得分、延迟等详细数据

  • 0x78 ('x'):RCON 命令
    远程控制指令通道(需认证)

  • 0x70 ('p'):延迟测试
    通过四字节随机数计算服务器响应时间

响应数据包

如前述,每个操作码将返回特定格式的响应数据。

所有响应数据包前 11 字节为固定包头(与请求包头完全一致),后续字节为具体响应内容:

i, r, c, d, p 响应类型数据表

类型 i 响应

字节键值字节宽度描述
11Password10 表示未设置密码,1 表示已设置密码
12-13Players2当前在线玩家数量
14-15MaxPlayers2服务器最大玩家容量
16-19(strlen)4服务器主机名字符串长度
20 + strlenHostname(strlen)服务器主机名
21-24(strlen)4游戏模式字符串长度
25 + strlenGamemode(strlen)服务器游戏模式
26-29(strlen)4服务器语言字符串长度
30 + strlenLanguage(strlen)服务器使用语言

类型 r 响应

字节键值字节宽度描述
11-12RuleCount2服务器提供的规则数量
13(strlen)1规则名称字符串长度
14 + strlenRulename(strlen)规则名称
15(strlen)1规则值字符串长度
16 + strlenRuleValue(strlen)规则值

(从第 13 字节开始循环,共循环 RuleCount 次)

类型 c 响应

字节键值字节宽度描述
11-12PlayerCount2服务器提供的玩家数量
13(strlen)1玩家昵称字符串长度
14 + strlenPlayerNick(strlen)玩家昵称
15-18Score4玩家分数

(从第 13 字节开始循环,共循环 PlayerCount 次)

类型 d 响应

字节键值字节宽度描述
11-12PlayerCount2服务器提供的玩家数量
13PlayerID1玩家 ID(取值范围 0-255)
14(strlen)1玩家昵称字符串长度
15 + strlenPlayerNick(strlen)玩家昵称
16-19Score4玩家分数
20-23Ping4玩家到服务器的延迟

(从第 13 字节开始循环,共循环 PlayerCount 次)

类型 p 响应

字节键值字节宽度描述
11number 11客户端发送的伪随机序列第一个数字
12number 21伪随机序列第二个数字
13number 31伪随机序列第三个数字
14number 41伪随机序列第四个数字

C 语言实现示例

开源 C 语言库 sampquery-c 实现了完整的查询功能,可作为开发参考:代码仓库