#本机网关协议
插件与 GameHub 客户端之间的接口规范。这是整个生态的地基 —— 只要遵守这份协议, 插件用什么语言、什么方式采集事件都可以。
网关只监听 127.0.0.1:43002,不绑外部网卡,事件不出本机。
兼容性承诺:这份协议与现有 Gamehub 客户端保持一致。 已经在市场上的插件不用改一个字节就能配本平台的客户端使用,反之亦然。
#1. 提交事件
POST http://127.0.0.1:43002/v1/events
Content-Type: application/json
{
"source": "7dtd",
"eventKey": "7dtd.player_hurt",
"commandId": "player-hurt",
"occurredAt": "2026-09-10T04:00:00.0000000Z",
"sessionId": "7dtd-3f8a9c1e",
"eventId": "c91b7d20",
"matchValue": null,
"data": { "damage": 23, "health": 61, "maxHealth": 100 }
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
source |
string | ✅ | 与 manifest 里的 yokonex.source 一致 |
eventKey |
string | ✅ | 必须是 manifest 里声明过的某一条 |
commandId |
string | ✅ | 优先用网关下发的映射,见第 2 节 |
occurredAt |
string | ✅ | ISO-8601 UTC。事件发生的时刻,不是发送的时刻 |
sessionId |
string | 一次游戏会话内保持不变,排错时用来串联 | |
eventId |
string | 唯一 id,网关用它去重 | |
matchValue |
string | 同一 eventKey 下的细分维度(比如武器名),预留 | |
data |
object | 任意附加信息,客户端会展示;未来用于强度分级 |
响应
| 状态码 | 含义 |
|---|---|
200 |
已接收(不代表设备一定动了 —— 用户可能禁用了这个事件) |
400 |
字段不合法 |
404 |
网关不认识这个 source |
429 |
触发网关侧限流 |
occurredAt 为什么必须是发生时刻:网关会丢弃过期事件。如果你填的是发送时刻,
积压的事件在恢复时会被当成"刚刚发生"全部执行 —— 设备会为几秒前的事情连续动作。
#2. 拉取用户配置
GET http://127.0.0.1:43002/v1/game-integrations/<source>/adapter-config
{
"enabled": true,
"endpoint": "ws://127.0.0.1:43002/7dtd",
"mappings": {
"7dtd.player_hurt": "player-hurt",
"7dtd.player_death": "player-death"
}
}
建议每 5 秒拉一次,并严格遵守下面四条:
| 情况 | 插件该怎么做 |
|---|---|
enabled 为 false |
用户关掉了联动,不发送任何事件 |
mappings 里有这个 eventKey |
用它给的 commandId(用户改过绑定) |
mappings 非空但没这个 key |
用户禁用了这个事件,不发 |
| 返回 404 | 网关还不认识这个 source,回落到 manifest 里的默认 commandId |
最后一条很重要:它让插件在客户端还没收录你的游戏时就能用,用户不必干等。
#3. WebSocket 通道(可选)
事件量大、或者需要接收网关下行消息时,可以用 adapter-config 返回的 endpoint:
ws://127.0.0.1:43002/<source>
上行消息体与 HTTP 的 POST /v1/events 完全相同,一条消息一个 JSON 对象。
HTTP 和 WebSocket 二选一即可。HTTP 更简单、更容易调试,推荐先用 HTTP; 只有在每秒几十条事件的场景下 WebSocket 才有明显优势。
#4. 插件侧必须实现的三道闸门
协议本身不限制你发多快,但设备接的是人的身体,所以这三件事必须由插件做:
#4.1 每事件冷却
尸潮里「玩家受伤」每秒能触发十几次。没有冷却,设备会被刷成近乎常通。
| 事件类型 | 建议冷却 |
|---|---|
| 高频(受伤、击杀、命中) | 1.0 ~ 1.5 秒 |
| 中频(流血、击晕、体力耗尽) | 4 ~ 12 秒 |
| 低频(感染、中毒、濒死) | 15 ~ 30 秒 |
| 罕见(血月、升级、通关) | 2 ~ 10 秒 |
冷却要在入队时计,不是发送成功时计。 否则网关掉线期间会攒下一批同类事件, 恢复的瞬间集中放电。
#4.2 全局限流
单事件冷却不够 —— 十种事件各自不超频,加起来照样能刷满。 再加一道总闸门:10 秒窗口内最多 10~15 条。
#4.3 过期丢弃
入队时记时间戳,出队时超过 3 秒就直接丢掉。
#5. 工程要求
游戏线程绝不做 IO。 事件采集回调里只做「取数据 + 入队」, HTTP/WS 全部在后台线程,超时设短(建议 500~800ms)。 网关没开、崩了、卡了,游戏都不能掉一帧。
失败要静默。 网关不可达时只在日志里留一条警告,不要弹窗、不要重试风暴、 不要因为发不出去就阻塞游戏逻辑。
参考实现:yokonex-7dtd 插件的 GatewayClient.cs ——
优先级队列、三道闸门、后台线程、断线降级,一共两百多行,可以直接照抄结构。