先选对事件
事件用于观察已经到达某个宿主发布点的事实。需要限制道具使用、购买、入场或聊天时,应使用对应的业务 Hook;通知回调的返回值被忽略,不能撤销业务。当前宿主登记 63 项稳定事件。下面目录分别说明字段、发布时机和不能据此推断的结果。
| 想做的事情 | 建议入口 |
|---|---|
| 角色选中后的欢迎公告 | character.bound;允许重连重复触发 |
| 观察权威通关 | dungeon.cleared;此时奖励可能尚未提交 |
| 观察普通副本成长结算成功 | dungeon.settlement_committed;仅此成长事务 |
| 观察购物、交易、拾取、任务提交 | 对应领域的 *_committed / 成功事件;仔细查看范围 |
| 调查业务请求走过了哪个模块 | gameplay.operation.started / .finished;不代表业务成功 |
| 限制操作 | 业务 Hook,在原核心校验与事务前返回决策 |
信封与最小订阅
通知回调收到的第二个参数始终是信封。下面交互目录的示例仅展示 event.data,不是完整信封,也不是发事件 API。
local dnf = require("dnf")
dnf.events.on("character.bound", function(ctx, event)
local character = event.data
if character.channel_id > 0 then
ctx.notice.broadcast({
text = "欢迎勇士 " .. character.id,
scope = "channel",
channel_id = character.channel_id
})
end
end)
此例需要在清单申请、框架授予 notice.broadcast。只读订阅无需额外权限;完整文件见快速上手。不要添加不存在的 dnf.log、计时器或发道具函数。
-- 宿主传入的结构示意,不是插件中要构造的变量
event = {
id = "process-epoch:42", -- 进程内追踪标识
name = "character.bound",
version = 1,
occurred_at_ms = 1793000000000, -- Unix 毫秒
data = { id = "10001", channel_id = 1 }
}
event.id 和副本 run_id 只在相应进程生命周期内有意义,不能用作跨重启发奖幂等键。每次调用独立解码事件表;修改 event 不会回写核心,也不会修改其他回调的输入。
精确名、领域通配与调用顺序
dnf.events.on("chat.message.received", function(ctx, event) end)
dnf.events.on("chat.message.*", function(ctx, event) end)
dnf.events.on("chat.*", function(ctx, event) end)
dnf.events.on("*", function(ctx, event) end)
local catalog = dnf.events.catalog()
assert(catalog["commerce.shop_purchased"] ~= nil)
只能在插件初始化时注册,最多 64 个通知回调。允许稳定事件精确名、覆盖已登记稳定事件的末尾 .* 前缀、*、game.*,以及不超过 160 字节且以 game.game- 开头的诊断精确名。inventory.* 合法,inventory.*.applied、未知领域或拼错的稳定名会拒绝注册。诊断精确名可能通过注册却从未触发。
同一事件按**精确名 → 最具体领域前缀 → 更宽领域前缀 → 全局 ***调用,组内按注册顺序。上面四个订阅会顺次处理同一条 chat.message.received。每插件只入队一次,但所有匹配回调都会执行,共享 10ms / 4 条公告预算。全量订阅可能产生大量通知;生产插件优先使用需要的精确名。
dnf.events.catalog() 返回“名称 → 英文语义说明”的独立副本,不包含本网站的示例字段表。已启用宿主也提供鉴权的 GET /local/plugins/catalog。以实际运行版本返回的目录确认能力,再用本页查询详细结构。
交付、事务与回包边界
通知是尽力交付:每插件队列 64 项,饱和时丢弃,停机或换代也可能失去通知。没有持久化、消费确认或离线补发,热重载不重放历史事件和 server.ready。不能基于通知维护可靠资产账本、执行二次扣费或承诺必达奖励。
committed 说明描述的 owner 事务已经提交。后续 socket 回包、场景投影、邮件派送和其他独立事务可能仍未完成。即使先收到事件、后因网络错误没有收到客户端回包,事件也仍然是真实的提交观察。
operation_applied 可包括成功无操作,例如重复应用已有状态;装备随机强化/锻造失败但已经扣费或损坏装备,也属于已应用结果。它不表示随机结果成功、物品数量变化或客户端确认。前置拒绝和事务回滚不发布这些成功通知。
game.operation.finished / gameplay.operation.finished 的 handler_failed=false 仅说明处理器没有以错误返回。正常业务拒绝也可返回 nil,必须使用领域成功事件判断具体提交。
公共数据结构
字段类型中的 integer 表示 JSON 整数进入 Lua 后为 number;整数身份若契约声明为字符串,必须保留字符串。不要用 tonumber() 转换角色、上架或运行标识。可选字段在 Lua 中为 nil,应先判空;示例省略不适用的可选字段。
| 结构 | 字段与解释 |
|---|---|
Character |
{id: string, channel_id: integer};当前角色快照。脱离会话的活动、离线婚姻变更等可为频道 0,不能直接用于频道公告 |
OwnerOperation |
character, operation, item_id:string, source_list, source_slot, target_list, target_slot;槽位/物品是局部操作元数据,未提供时可能为零,不是完整资产差量 |
DungeonState |
character, dungeon_id, difficulty, run_id:string, room:string, map_id, party:boolean, details?;room 为 X:Y,无可用场景时可能为空串且 map_id 为 0。details 只含当前事件适用字段 |
SocialState |
character, group_id:string, target_id?:string, member_ids?:string[], operation?:string, details?:table;各事件只提供适用字段,不能假设拥有完整成员资料 |
CommerceItem |
{item_id:integer, count:integer, commodity_id?:integer};这里为成功购买通知中的商品行,Cera 可带 commodity_id。购买 Hook 的 Cera 行语义不同,见 Hook 页 |
Character 不是每条事件的顶层统一字段:character.bound/unbound 的 data 本身就是 Character,commerce.trade_committed 则只有双方 ID。使用领域通配时先按 event.name 分支,再读取相应结构。
完整稳定事件目录
所有示例 ID、物品编号和业务值都为示意数据,不能直接作为实际 PVF 的配置依据。筛选目录可查字段与发布时机。
点击事件展开完整字段与数据示例。以下示例均为 event.data,标识使用虚构值。
↗server.ready组件启动完成服务生命周期⌄
应用组件启动后的进程生命周期通知。
触发时机:所有应用组件启动后尽力发布。
事件数据为空表,无业务字段。
- 热重载不补发此事件。
- 订阅建立前或队列繁忙时可能错过;不能把它用作可靠定时任务。
数据示例
{}↗server.stopping服务开始停止服务生命周期⌄
bridge 关闭前的生命周期通知。
触发时机:停机流程关闭 bridge 前尽力发布。
事件数据为空表,无业务字段。
- 停机可能来不及消费,不能依赖此事件持久化内存状态。
数据示例
{}↗game.operation.finished会话任务返回请求观察⌄
已进入会话任务队列的处理函数返回。
触发时机:会话任务处理器返回后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 任务关联角色快照。 |
source | string | 宿主任务来源标识。 |
handler_failed | boolean | 处理器是否返回错误;不是业务结果。 |
- handler_failed=false 不代表业务成功;正常拒绝也可无错误返回。
- 插件公告任务被排除,避免递归。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"source": "upper",
"handler_failed": false
}↗gameplay.operation.started玩法模块开始处理请求观察⌄
已登记的玩法模块处理器即将执行。
触发时机:模块分发选中处理器后、调用前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 当前选中角色。 |
module | string | 宿主登记的模块名。 |
transport | string | 模块接收的传输路径标识。 |
opcode | integer (uint16) | 请求操作码。 |
handler_failed | boolean | 开始通知为 false。 |
- 当前接入 62 个已登记玩法模块,不是原始网络抓包。
- 不暴露请求包体,不能修改或拒绝请求。
- started 的 handler_failed 为 false,无业务成功含义。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"module": "inventory",
"transport": "upper",
"opcode": 27,
"handler_failed": false
}↗gameplay.operation.finished玩法模块处理返回请求观察⌄
已登记玩法模块的处理器已返回。
触发时机:模块处理函数返回时。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 当前角色。 |
module | string | 宿主登记的模块名。 |
transport | string | 传输路径标识。 |
opcode | integer (uint16) | 请求操作码。 |
handler_failed | boolean | 处理器是否以错误返回。 |
- handler_failed=false 也可能是业务被原生规则正常拒绝。
- 用领域成功事件判断事务结果,不从此通知推断扣费、发奖或回包成功。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"module": "inventory",
"transport": "upper",
"opcode": 27,
"handler_failed": false
}↗character.bound角色绑定会话角色与城镇⌄
选中的角色绑定到有效会话。
触发时机:角色绑定时,包含重连。
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 角色标识,保留字符串。 |
channel_id | integer | 会话所属频道。 |
- data 本身就是 Character,没有 data.character。
- 不是首次登录、建角或进城完成;重连会再次触发。
数据示例
{
"id": "10001",
"channel_id": 1
}↗character.unbound角色开始解绑角色与城镇⌄
当前有效角色会话开始解除绑定。
触发时机:角色解绑清理之前取得快照。
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 解绑角色标识。 |
channel_id | integer | 解绑前所属频道。 |
- data 本身就是 Character。
- 不能保证客户端仍在线,也不能把通知当作可靠离线回调。
数据示例
{
"id": "10001",
"channel_id": 1
}↗character.created角色创建提交角色与城镇⌄
新角色记录创建事务已提交。
触发时机:创建事务提交后、响应前,对新记录发布一次。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 新记录的角色 ID 与请求会话频道。 |
name | string | 角色名称。 |
job | string | 仓储角色职业标识。 |
level | integer | 创建后的等级。 |
slot | integer | 角色槽位。 |
- character 指新建角色,不一定是当前已选中角色。
- 不表示客户端已收到角色名单。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"name": "示例勇士",
"job": "swordman",
"level": 1,
"slot": 0
}↗character.deleted角色删除提交角色与城镇⌄
角色记录删除已提交。
触发时机:删除完成后、角色名单刷新前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 被删除角色标识。 |
name | string | 删除前名称。 |
job | string | 删除前职业标识。 |
level | integer | 删除前等级。 |
slot | integer | 原角色槽位。 |
- character 和资料为被删除角色的快照。
- 后续不能据此查询或修改已删除记录。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"name": "示例勇士",
"job": "swordman",
"level": 1,
"slot": 0
}↗town.area_entered城镇区域切换角色与城镇⌄
合法城镇区域切换已接受并完成场景投影发送。
触发时机:城镇位置提交及场景投影发送后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 移动角色。 |
town_id | integer | 城镇编号。 |
area_id | integer | 城镇区域编号。 |
- 重复成功的区域请求可能重复发布;不要用它判断首次到访。
- 发送完成不等于客户端渲染完成。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"town_id": 1,
"area_id": 2
}↗dungeon.entered初始房间进入副本⌄
副本初始房间的对象与掉落状态已提交。
触发时机:开始地图包发送、初始场景状态提交后,按角色发布。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 进入角色。 |
dungeon_id | integer | 副本 ID。 |
difficulty | integer | 请求难度编号。 |
run_id | string | 进程内运行标识,不作持久账本键。 |
room | string | 当前房间 X:Y。 |
map_id | integer | 当前地图 ID;无场景时 0。 |
party | boolean | 是否共享组队副本 owner。 |
- 包含已接入的单人、组队和训练直入路径。
- 不是每次换房通知;进图失败后的退役可另发 exited。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"dungeon_id": 10,
"difficulty": 0,
"run_id": "42",
"room": "0:0",
"map_id": 100,
"party": false
}↗dungeon.room_entered副本房间切换副本⌄
一次真实的副本换房已经提交。
触发时机:换房状态提交后,按实际移动角色发布。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 移动角色。 |
dungeon_id | integer | 副本 ID。 |
difficulty | integer | 难度编号。 |
run_id | string | 运行标识。 |
room | string | 目标房间 X:Y。 |
map_id | integer | 目标地图 ID。 |
party | boolean | 是否共享组队 owner。 |
details.source_room | string | 来源房间 X:Y。 |
details.revisit | boolean | 是否重访目标房间。 |
- 重访旧房间也会发布;重复确认包不冒充新换房。
- details.revisit 不是首次进入整个副本的标记。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"dungeon_id": 10,
"difficulty": 0,
"run_id": "42",
"room": "1:0",
"map_id": 101,
"party": false,
"details": {
"source_room": "0:0",
"revisit": false
}
}↗dungeon.actor_defeated权威战斗对象死亡副本⌄
普通战斗 owner 接受对象死亡。
触发时机:权威死亡判定接受后、可选奖励和场景投影前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 此次接受路径关联角色,不是可靠的最终归属/伤害榜。 |
dungeon_id | integer | 副本 ID。 |
difficulty | integer | 难度。 |
run_id | string | 运行标识。 |
room | string | 当前房间。 |
map_id | integer | 当前地图。 |
party | boolean | 是否组队。 |
details.object_key | integer | 运行时对象键。 |
details.actor_kind | string | 战斗对象分类标识。 |
details.boss | boolean | 此次是否为 Boss 对象死亡。 |
details.room_cleared | boolean | 此次死亡后房间是否清空。 |
details.monster_id | integer | 用于此次掉落判定的怪物模板编号。 |
- 共享世界按对象发布一次,不按每位队员重复发布。
- 不证明掉落、击杀经验或通关奖励已经提交,也不代表覆盖所有特殊对象退休路径。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"dungeon_id": 10,
"difficulty": 0,
"run_id": "42",
"room": "1:0",
"map_id": 101,
"party": true,
"details": {
"object_key": 100,
"actor_kind": "monster",
"boss": false,
"room_cleared": true,
"monster_id": 200
}
}↗dungeon.pickup_committed掉落拾取提交副本⌄
拾取持久化完成,掉落对象已被消费。
触发时机:拾取资产提交及掉落消费后、响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 拾取角色。 |
dungeon_id | integer | 副本 ID。 |
difficulty | integer | 难度。 |
run_id | string | 运行标识。 |
room | string | 发布时当前场景。 |
map_id | integer | 发布时地图。 |
party | boolean | 是否组队。 |
details.object_key | integer | 被消费掉落对象键。 |
details.item_id | integer | 掉落物品模板 ID。 |
details.amount | integer | 掉落数量/金额。 |
details.destination_slot | integer | owner 返回的目标槽。 |
details.gold_after | integer | owner 返回的拾取后金币快照。 |
details.pickup_room | string | 拾取计划所在房间。 |
details.pickup_map_id | integer | 拾取计划所在地图 ID。 |
- 重复拾取收据重放不重复发布。
- details 描述此次局部拾取,不是完整背包快照;金币拾取也可能没有有效目标槽。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"dungeon_id": 10,
"difficulty": 0,
"run_id": "42",
"room": "1:0",
"map_id": 101,
"party": false,
"details": {
"object_key": 300,
"item_id": 400,
"amount": 1,
"destination_slot": 10,
"gold_after": 10000,
"pickup_room": "1:0",
"pickup_map_id": 101
}
}↗dungeon.character_died角色死亡被接受副本⌄
角色死亡状态与死亡状态发送被接受。
触发时机:合法死亡报告推进死亡状态并发送状态后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 死亡角色。 |
dungeon_id | integer | 副本 ID。 |
difficulty | integer | 难度。 |
run_id | string | 运行标识。 |
room | string | 死亡时房间。 |
map_id | integer | 死亡时地图。 |
party | boolean | 是否组队。 |
- 同一死亡状态的重复报告不重复发布。
- 此事件不包含击杀者、伤害明细或损失资产。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"dungeon_id": 10,
"difficulty": 0,
"run_id": "42",
"room": "1:0",
"map_id": 101,
"party": false
}↗dungeon.character_revived角色复活完成副本⌄
复活扣费及响应序列已经提交。
触发时机:owner 完成复活扣费和响应序列后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 复活角色。 |
dungeon_id | integer | 副本 ID。 |
difficulty | integer | 难度。 |
run_id | string | 运行标识。 |
room | string | 当前房间。 |
map_id | integer | 当前地图。 |
party | boolean | 是否组队。 |
details.coin_consumed | boolean | 是否消费复活币。 |
details.free_revive | boolean | 是否免费复活。 |
- 响应重试只发布一次接受的复活。
- coin_consumed 是布尔值,不是消耗数量。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"dungeon_id": 10,
"difficulty": 0,
"run_id": "42",
"room": "1:0",
"map_id": 101,
"party": false,
"details": {
"coin_consumed": true,
"free_revive": false
}
}↗dungeon.exited副本运行退役副本⌄
当前副本运行首次被退役,并保留最后场景和原因。
触发时机:runtime 第一次进入退役边界时。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 关联角色。 |
dungeon_id | integer | 退出副本。 |
difficulty | integer | 难度。 |
run_id | string | 退役运行标识。 |
room | string | 最后可用房间,可能为空。 |
map_id | integer | 最后可用地图,无场景时 0。 |
party | boolean | 是否组队。 |
details.reason | string | 退役原因标识。 |
- 包含返回城镇、运行替换、断线和回滚,不等于通关或成功结算。
- reason 为当前宿主路径标识;不要仅凭字符串猜测资产结果。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"dungeon_id": 10,
"difficulty": 0,
"run_id": "42",
"room": "1:0",
"map_id": 101,
"party": false,
"details": {
"reason": "return_to_town"
}
}↗dungeon.cleared权威通关副本⌄
副本运行权威判定通关。
触发时机:普通 Boss、无 Boss 教学及祭坛已接入的播报入口;共享队伍运行去重。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 该次通关发布关联角色。 |
dungeon_id | integer | 副本 ID。 |
dungeon_name | string | 副本名称。 |
player_name | string | 角色名称。 |
party | boolean | 是否共享组队运行。 |
elapsed_ms | integer | nil | 已知通关用时毫秒;未知为 nil。 |
source | string | 通关发布来源标识。 |
- 奖励可能尚未结算;不是全部攻坚结算的总入口。
- elapsed_ms 未知时为 nil,不应当作 0 秒。
- 自定义通关播报可用 dungeon.clear_announcement Hook,避免与内置公告重复。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"dungeon_id": 10,
"dungeon_name": "示例地下城",
"player_name": "示例勇士",
"party": false,
"elapsed_ms": 90000,
"source": "boss_death"
}↗dungeon.settlement_committed通关成长结算提交副本⌄
本角色通关成长事务已新提交。
触发时机:通关成长事务提交后;收据重放不重复发布。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 结算角色。 |
dungeon_id | integer | 副本 ID。 |
completion_key | string | 核心结算完成标识,仅作观察,不赋予插件资产写入能力。 |
experience | integer (uint32) | 本次提交的经验增量。 |
level | integer | 成长事务后的角色等级。 |
- 不覆盖后续独立翻牌或塔奖励事务。
- experience 是本次成长提交经验增量,不等于经验 Hook 的基础 amount。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"dungeon_id": 10,
"completion_key": "example-completion",
"experience": 1200,
"level": 10
}↗inventory.operation_applied背包操作已应用物品与成长⌄
背包 owner 已应用一项合法操作。
触发时机:显式 owner 成功路径、网络响应发送前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 操作角色。 |
operation | string | owner 操作标识,如 move_itemspace / sort_item;具体值由当前接入 owner 决定。 |
item_id | string | 局部物品模板标识,未提供时为字符串 0。 |
source_list | integer (uint8) | 源列表类型。 |
source_slot | integer (int16) | 源槽位。 |
target_list | integer (uint8) | 目标列表类型。 |
target_slot | integer (int16) | 目标槽位。 |
- 包含成功无操作,拒绝与回滚不发布。
- item_id 为字符串;0 值或槽位 0 不保证代表真实源/目标对象。
- 不提供增减数量、完整奖励或背包差量。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"operation": "move_itemspace",
"item_id": "400",
"source_list": 0,
"source_slot": 10,
"target_list": 0,
"target_slot": 11
}↗equipment.operation_applied装备操作已应用物品与成长⌄
装备 owner 已接受并应用操作结果。
触发时机:合法操作应用或资产事务提交后,响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 操作角色。 |
operation | string | 如 upgrade_item、equipment_regeneration、equipment_socket_open。 |
item_id | string | 局部模板标识,未提供时 0。 |
source_list | integer (uint8) | 源列表。 |
source_slot | integer (int16) | 源槽位。 |
target_list | integer (uint8) | 目标列表。 |
target_slot | integer (int16) | 目标槽位。 |
- 随机强化/锻造失败但成本已扣或装备已损坏也发布,不表示强化成功。
- 可包含成功无操作;拒绝/回滚不发布。
- 没有 UpgradeSucceeded 字段,不要自行从 operation 推断随机结果。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"operation": "upgrade_item",
"item_id": "400",
"source_list": 0,
"source_slot": 10,
"target_list": 0,
"target_slot": 0
}↗skill.operation_applied技能操作已应用物品与成长⌄
技能 owner 已应用解码后的合法操作。
触发时机:技能 owner 成功处理后、响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 操作角色。 |
operation | string | 当前技能 owner 的操作标识。 |
item_id | string | 不适用时 0。 |
source_list | integer | 不适用时 0。 |
source_slot | integer | 不适用时 0。 |
target_list | integer | 不适用时 0。 |
target_slot | integer | 不适用时 0。 |
- 可包含成功无操作;不提供完整技能树、SP/TP 差量。
- 通用物品/槽位字段不适用时为零。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"operation": "buy_skill",
"item_id": "0",
"source_list": 0,
"source_slot": 0,
"target_list": 0,
"target_slot": 0
}↗cargo.operation_applied仓库操作已应用物品与成长⌄
仓库 owner 已应用操作。
触发时机:仓库 owner 成功处理后、响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 操作角色。 |
operation | string | 如 deposit_money、withdraw_money、create_account_cargo。 |
item_id | string | 未提供时 0。 |
source_list | integer | 局部源列表元数据。 |
source_slot | integer | 局部源槽位元数据。 |
target_list | integer | 局部目标列表元数据。 |
target_slot | integer | 局部目标槽位元数据。 |
- 可包含成功无操作;通用字段不等于完整存取金额或仓库差量。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"operation": "deposit_money",
"item_id": "0",
"source_list": 0,
"source_slot": 0,
"target_list": 0,
"target_slot": 0
}↗pet.operation_applied宠物操作已应用物品与成长⌄
宠物 owner 已应用操作。
触发时机:显式宠物成功路径、响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 操作角色。 |
operation | string | 如 seal_creature。 |
item_id | string | 宠物相关模板标识,可能为 0。 |
source_list | integer | 源列表类型。 |
source_slot | integer | 源槽位。 |
target_list | integer | 目标列表类型。 |
target_slot | integer | 目标槽位。 |
- 可包含成功无操作;不包含宠物完整属性或改名正文。
- 未提供的通用目标字段为零。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"operation": "seal_creature",
"item_id": "500",
"source_list": 7,
"source_slot": 1,
"target_list": 0,
"target_slot": 0
}↗craft.operation_applied制作配方提交物品与成长⌄
制作 owner 已成功提交一项已接入配方。
触发时机:配方事务提交后、响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 制作角色。 |
operation | string | 例如 compound_emblems。 |
item_id | string | 局部模板标识,未提供时 0。 |
source_list | integer | 未提供时 0。 |
source_slot | integer | 未提供时 0。 |
target_list | integer | 未提供时 0。 |
target_slot | integer | 未提供时 0。 |
- 不提供完整材料消耗或产物清单。
- 勋章合成等配方结果仍以核心为准,不从此事件另发奖励。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"operation": "compound_emblems",
"item_id": "0",
"source_list": 0,
"source_slot": 0,
"target_list": 0,
"target_slot": 0
}↗quest.accepted接受新任务任务⌄
一代新任务状态已接受并持久化。
触发时机:任务接受持久化后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 接受任务角色。 |
quest_id | integer (uint16) | 任务 ID。 |
progress | integer (int64) | 接受路径为 0,不是完整任务目标列表。 |
- 幂等的重复接受不发布。
- progress 当前接受路径为 0。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"quest_id": 100,
"progress": 0
}↗quest.progressed任务触发进度变化任务⌄
显式任务触发器改变并保存进度。
触发时机:显式触发产生实际变化并持久化后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 任务角色。 |
quest_id | integer (uint16) | 任务 ID。 |
progress | integer (int64) | 本次 owner 返回的进度值。 |
- 未改变状态的触发不发布。
- progress 是该触发器返回值,不是所有任务目标的统一百分比。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"quest_id": 100,
"progress": 3
}↗quest.finished任务结算提交任务⌄
完成任务结算事务已新提交。
触发时机:任务结算事务提交后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 完成任务角色。 |
quest_id | integer (uint16) | 任务 ID。 |
progress | integer (int64) | 当前完成路径为 0。 |
- 收据重放不重复发布。
- 不包含实际任务奖励清单;progress 当前为 0。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"quest_id": 100,
"progress": 0
}↗quest.abandoned放弃任务提交任务⌄
任务放弃结算事务已提交。
触发时机:任务放弃事务提交后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 放弃任务角色。 |
quest_id | integer (uint16) | 任务 ID。 |
progress | integer (int64) | 当前放弃路径为 0。 |
- progress 当前为 0,不表示任务之前没有进度。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"quest_id": 100,
"progress": 0
}↗commerce.shop_purchased商店购买提交商业与交易⌄
NPC、秘密商店或 Cera 商城结账已提交。
触发时机:owner 结账提交后、socket 发布前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 购买角色。 |
source | string | npc / secret / cera。 |
items | CommerceItem[] | 主商品行数组。 |
items[].item_id | integer (uint32) | 实际商品模板 ID。 |
items[].count | integer (uint32) | 实际该行商品数量。 |
items[].commodity_id | integer (uint32) | nil | Cera 商品编号;零值省略。 |
- items 仅主商品,不含额外赠品。
- 这是成功购买通知;Cera 购买 Hook 的请求行只有 commodity_id/count=1,语义不同。
- 不包含价格、余额或原始支付凭据。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"source": "cera",
"items": [
{
"item_id": 400,
"count": 2,
"commodity_id": 1000
}
]
}↗commerce.shop_soldNPC 出售提交商业与交易⌄
向 NPC 出售物品已提交。
触发时机:出售事务提交后、socket 发布前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 出售角色。 |
item_id | integer (uint32) | 出售物品模板 ID。 |
count | integer (uint32) | 实际出售数量。 |
- count 为实际出售量,不提供售价或售后金币余额。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"item_id": 400,
"count": 2
}↗commerce.auction_registered拍卖或金币寄售上架商业与交易⌄
商品拍卖或金币寄售上架已提交。
触发时机:拍卖 owner 上架提交后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 操作角色。 |
source | string | item / gold。 |
listing_id | string | 上架记录 uint64 ID 的字符串。 |
seller_id | string | 卖方角色标识。 |
item_id | integer (int64) | owner 上架模板标识。 |
count | integer (int64) | 商品数量;gold 为 1。 |
- 不提供价格、账号或资产明细。
- source=gold 的 count 当前为 1,并不是寄售金币金额。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"source": "item",
"listing_id": "900000000000001",
"seller_id": "10001",
"item_id": 400,
"count": 2
}↗commerce.auction_cancelled拍卖或寄售取消商业与交易⌄
商品拍卖或金币寄售取消已提交。
触发时机:取消事务提交后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 取消操作角色。 |
source | string | item / gold。 |
listing_id | string | 上架记录 ID。 |
seller_id | string | 卖方角色 ID。 |
item_id | integer (int64) | 上架模板标识。 |
count | integer (int64) | 商品数量;gold 为 1。 |
- 退还邮件可能仍在等待重试,不保证已经收信。
- source=gold 的 count 为 1,不是金币金额。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"source": "item",
"listing_id": "900000000000001",
"seller_id": "10001",
"item_id": 400,
"count": 2
}↗commerce.auction_bid商品拍卖竞价提交商业与交易⌄
商品拍卖的一次新竞价已提交。
触发时机:拍卖竞价 owner 提交后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 出价角色。 |
source | string | 此路径为 item。 |
listing_id | string | 上架记录 ID。 |
seller_id | string | 卖方角色 ID。 |
item_id | integer (int64) | 商品模板。 |
count | integer (int64) | 商品数量。 |
- 仅商品拍卖竞价;退款邮件可能仍待重试。
- 不表示本次出价最终获胜,也不提供竞价金额。
数据示例
{
"character": {
"id": "10002",
"channel_id": 1
},
"source": "item",
"listing_id": "900000000000001",
"seller_id": "10001",
"item_id": 400,
"count": 2
}↗commerce.auction_purchased拍卖直购或寄售购买商业与交易⌄
商品拍卖一口价或金币寄售购买已提交。
触发时机:购买事务提交后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 购买角色。 |
source | string | item / gold。 |
listing_id | string | 上架记录 ID。 |
seller_id | string | 卖方角色 ID。 |
item_id | integer (int64) | 成交模板标识。 |
count | integer (int64) | 成交商品量;gold 为 1。 |
- 邮件发货可能待重试,不是背包到账确认。
- 商品路径优先用 delivery 商品快照;gold 的 count 为 1。
数据示例
{
"character": {
"id": "10002",
"channel_id": 1
},
"source": "item",
"listing_id": "900000000000001",
"seller_id": "10001",
"item_id": 400,
"count": 2
}↗commerce.private_store_opened摊位生效商业与交易⌄
私人商店进入生效状态。
触发时机:摊位激活时。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 开摊角色。 |
seller_id | string | 摊主角色 ID。 |
rows | integer | 摊位商品行数。 |
item_id | integer | nil | 此事件通常省略。 |
count | integer | nil | 此事件通常省略。 |
- 只描述内存状态,不是资产交易提交。
- 相同内容完成开摊的重试不重复发布;item_id/count 不适用并省略。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"seller_id": "10001",
"rows": 2
}↗commerce.private_store_closed摊位关闭商业与交易⌄
一个生效摊位被移除。
触发时机:首次移除当前活动摊位时。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 摊主快照。 |
seller_id | string | 摊主角色 ID。 |
rows | integer | 关闭时摊位行数。 |
item_id | integer | nil | 通常省略。 |
count | integer | nil | 通常省略。 |
- 包含手动、售罄及断线关闭,重复关闭不重复发布。
- 内存状态通知,rows 可为售罄后的 0;item_id/count 通常省略。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"seller_id": "10001",
"rows": 0
}↗commerce.private_store_purchased摊位购买提交商业与交易⌄
私人商店资产交换已新提交。
触发时机:资产交换提交后、投影前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 购买角色。 |
seller_id | string | 摊主角色 ID。 |
rows | integer | 此次成交行数,当前 1。 |
item_id | integer (int64) | nil | 成交物品模板,零值会省略。 |
count | integer (uint32) | nil | 成交数量,零值会省略。 |
- 收据重放不重复发布。
- rows 当前为 1,不是摊位剩余总行数;不提供价格。
数据示例
{
"character": {
"id": "10002",
"channel_id": 1
},
"seller_id": "10001",
"rows": 1,
"item_id": 400,
"count": 2
}↗commerce.trade_committed双角色交易提交商业与交易⌄
双方物品与资产交换已原子提交。
触发时机:新交易提交后、双方投影之前。
| 字段 | 类型 | 说明 |
|---|---|---|
first_character_id | string | 第一方角色 ID。 |
second_character_id | string | 第二方角色 ID。 |
first_item_rows | integer | 第一方出价物品行数。 |
second_item_rows | integer | 第二方出价物品行数。 |
- 无顶层 character 字段,只有双方 ID。
- 条目数不表示物品总数量,也不包含金币值或道具明细。
数据示例
{
"first_character_id": "10001",
"second_character_id": "10002",
"first_item_rows": 1,
"second_item_rows": 2
}↗commerce.package_openedCera 礼包开启提交商业与交易⌄
Cera 礼包消耗和奖励已提交。
触发时机:礼包事务提交后、投影前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 开礼包角色。 |
item_id | integer (uint32) | 礼包源物品模板。 |
reward_rows | integer | 奖励行数。 |
reward_units | integer (uint64) | 奖励总单位数;Lua number 处理极大整数时需留意精度。 |
overflow_mail | boolean | 是否生成背包溢出邮件。 |
- 只覆盖已接入 Cera 礼包路径,非所有罐子/礼包的统一事件。
- overflow_mail=true 表示存在溢出邮件,邮件通知可能尚未送达。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"item_id": 500,
"reward_rows": 2,
"reward_units": 10,
"overflow_mail": false
}↗mail.sent玩家邮件发送提交邮件⌄
玩家发信 owner 已提交。
触发时机:发信 owner 成功提交后、投影前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 发信角色。 |
recipient_id | string | nil | owner 返回的通知收件角色标识;可选。 |
claim_rows | integer | nil | 提取使用字段,发信通常省略。 |
- 不暴露正文、标题或收件人姓名。
- 多收件请求也不应据单一 recipient_id 推断完整收件名单;claim_rows 此路径省略。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"recipient_id": "10002"
}↗mail.claimed非空邮件附件提取邮件⌄
玩家邮箱一次非空提取已提交。
触发时机:邮箱提取提交、产生成功且行数大于 0 的结果后,投影前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 提取角色。 |
claim_rows | integer (uint32) | 非空提取行数。 |
recipient_id | string | nil | 此路径通常省略。 |
- 空提取不发布;不提供附件明细或邮件正文。
- claim_rows 是提取行数,不是物品总数量;recipient_id 通常省略。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"claim_rows": 2
}↗mail.opened邮箱打开快照邮件⌄
邮箱 owner 接受打开请求并生成快照。
触发时机:成功邮箱快照产生后、投影前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 打开邮箱角色。 |
recipient_id | string | nil | 此路径通常省略。 |
claim_rows | integer | nil | 此路径通常省略。 |
- 这是读取观察,不是资产变化或领取成功。
- 重复打开可再次通知,不提供邮件列表或正文。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
}
}↗party.member_joined成员加入队伍队伍与社交⌄
中央队伍 owner 接受新成员加入。
触发时机:中央成员状态接受后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 本次加入角色。 |
group_id | string | 队伍 ID。 |
target_id | string | 加入角色 ID。 |
member_ids | string[] | nil | 当前角色成员名单;空名单可能省略。 |
operation | string | join 或 peer_accept。 |
- 这是队伍内存状态,不是副本入场或资产事务。
- member_ids 为提交后的当前角色名单。
数据示例
{
"character": {
"id": "10002",
"channel_id": 1
},
"group_id": "10",
"target_id": "10002",
"member_ids": [
"10001",
"10002"
],
"operation": "join"
}↗party.member_left成员离开队伍队伍与社交⌄
中央队伍 owner 接受离队或踢人。
触发时机:成员移除接受后、响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 当前路径关联会话角色。 |
group_id | string | owner 返回的队伍标识。 |
target_id | string | 被移除角色 ID。 |
member_ids | string[] | nil | 当前剩余名单。 |
operation | string | leave / kick。 |
- character 在主动离队与踢人路径可分别关联离队者或操作者;以 target_id 判断被移除者。
- 解散后名单为空时 member_ids 可能省略。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"group_id": "10",
"target_id": "10002",
"member_ids": [
"10001"
],
"operation": "kick"
}↗party.leader_changed队长转让队伍与社交⌄
中央队伍 owner 已接受队长转让。
触发时机:队长状态改变后、响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 操作会话角色。 |
group_id | string | 队伍 ID。 |
target_id | string | 新队长角色 ID。 |
member_ids | string[] | nil | 当前成员名单。 |
operation | string | transfer。 |
- target_id 为新队长,character 可为发起转让的旧队长。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"group_id": "10",
"target_id": "10002",
"member_ids": [
"10001",
"10002"
],
"operation": "transfer"
}↗guild.created公会创建提交队伍与社交⌄
公会 registry 与创建扣费已提交。
触发时机:公会创建成功后、响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 创建角色。 |
group_id | string | 公会 ID。 |
operation | string | create。 |
- 不提供公会名称或完整初始名单。
- target_id、member_ids、details 不适用时省略。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"group_id": "50",
"operation": "create"
}↗guild.application_decided公会申请处理队伍与社交⌄
公会申请批准或拒绝已提交。
触发时机:申请决策提交后、响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 处理申请的角色。 |
group_id | string | 公会 ID。 |
target_id | string | 被处理申请的角色 ID。 |
operation | string | approve / deny。 |
- 拒绝申请也是成功提交的决策;检查 operation。
- 不提供申请正文或申请人资料。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"group_id": "50",
"target_id": "10002",
"operation": "approve"
}↗guild.member_left公会成员离开队伍与社交⌄
离开公会或踢人已提交。
触发时机:移除成员提交后、响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 操作角色。 |
group_id | string | 公会 ID。 |
target_id | string | 被移除角色 ID。 |
operation | string | leave / kick。 |
- 以 target_id 判断被移除成员,character 是操作路径关联角色。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"group_id": "50",
"target_id": "10002",
"operation": "kick"
}↗guild.disbanded公会解散提交队伍与社交⌄
公会解散已提交。
触发时机:解散提交后、响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 解散操作角色。 |
group_id | string | 被解散公会 ID。 |
member_ids | string[] | nil | 解散前成员名单。 |
operation | string | disband。 |
- member_ids 是解散前原名单,不是仍在公会的名单。
- 空名单可能省略。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"group_id": "50",
"member_ids": [
"10001",
"10002"
],
"operation": "disband"
}↗wedding.changed婚姻状态提交队伍与社交⌄
婚姻事务提交后,按发生变更的角色发布。
触发时机:婚姻 owner 事务提交后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 发生变更的角色。 |
group_id | string | 记录中的 wedding_id 字符串。 |
target_id | string | 记录中的配偶 ID 字符串,未关联可为 0。 |
operation | string | 原生婚姻操作字节的十进制字符串。 |
details.status | integer | 记录的 wedding_state。 |
details.ring | integer | 记录的 wedding_ring。 |
details.love | integer | 记录的 wedding_love。 |
- 一项双方变更可按角色发布多条。
- 离线角色 channel_id 可为 0;operation 是原生婚姻操作编号字符串,非可调用命令。
数据示例
{
"character": {
"id": "10001",
"channel_id": 0
},
"group_id": "60",
"target_id": "10002",
"operation": "1",
"details": {
"status": 1,
"ring": 1,
"love": 10
}
}↗pvp.room_joined加入 PVP 房间PVP 与攻坚⌄
PVP 房间成员状态已接受。
触发时机:成员加入后、房间状态投影前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 加入角色。 |
group_id | string | 房间 ID。 |
member_ids | string[] | nil | 当前房间角色名单。 |
details.seat | integer | 加入座位。 |
details.created | boolean | 是否为创建房间路径。 |
details.battle_mode | integer | 原生战斗模式编号。 |
- 包含房间创建者和自动匹配;不是开赛通知。
- 当前成员快照不包含角色详细资料。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"group_id": "70",
"member_ids": [
"10001"
],
"details": {
"seat": 0,
"created": true,
"battle_mode": 1
}
}↗pvp.room_left离开 PVP 房间PVP 与攻坚⌄
PVP 房间成员首次被移除。
触发时机:房间有效成员首次进入移除路径时。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 离开角色。 |
group_id | string | 房间 ID。 |
member_ids | string[] | nil | 进入移除路径时的房间名单,含离开者。 |
details.seat | integer | 原座位。 |
details.battle_mode | integer | 原生战斗模式编号。 |
- 包含断线和练习房,重复移除不重复通知。
- 当前发布点在实际移除前,member_ids 包含即将离开的角色,不是剩余名单;空名单省略。
数据示例
{
"character": {
"id": "10002",
"channel_id": 1
},
"group_id": "70",
"member_ids": [
"10001",
"10002"
],
"details": {
"seat": 1,
"battle_mode": 1
}
}↗pvp.match_startedPVP 比赛开始PVP 与攻坚⌄
准备和地图验证完成,比赛开始状态被接受。
触发时机:准备/地图验证后、开始包发送前,每场一次。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 比赛 owner 关联角色。 |
group_id | string | 房间 ID。 |
member_ids | string[] | nil | 参赛房间成员快照。 |
details.map_id | integer | 选中的 PVP 地图 ID。 |
details.battle_mode | integer | 战斗模式编号。 |
- character 为发布路径的 owner 角色,不按每位玩家重复。
- 不保证所有客户端成功收到开始包。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"group_id": "70",
"member_ids": [
"10001",
"10002"
],
"details": {
"map_id": 100,
"battle_mode": 1
}
}↗pvp.match_finishedPVP 终局冻结PVP 与攻坚⌄
PVP 权威终局结果已冻结。
触发时机:权威结果冻结后、奖励持久化前,每场一次。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 终局发布路径关联角色。 |
group_id | string | 房间 ID。 |
member_ids | string[] | nil | 终局时成员快照。 |
details.winner_seat | integer | 胜者座位;255 为平局标记。 |
details.draw | boolean | 是否平局。 |
details.battle_mode | integer | 战斗模式编号。 |
- 不是奖励事务收据;不要根据此事件另发奖励。
- winner_seat=255 表示 draw=true,不是角色 ID。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"group_id": "70",
"member_ids": [
"10001",
"10002"
],
"details": {
"winner_seat": 0,
"draw": false,
"battle_mode": 1
}
}↗raid.created新攻坚实例创建PVP 与攻坚⌄
新的攻坚对象与 owner 已挂接。
触发时机:新实例挂接后、绑定响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 创建路径关联角色。 |
group_id | string | RaidKey 的十进制字符串。 |
member_ids | string[] | nil | 攻坚当前角色名单。 |
details.instance_id | string | 实例 uint64 标识字符串。 |
details.raid_mode | integer (uint8) | 攻坚 owner 模式编号;当前 1 安徒恩、2 卢克、3 超时空,尚未绑定时可为 0。 |
details.single | boolean | 是否单人模式。 |
details.phase | integer | 当前生命周期阶段编号。 |
- 重连恢复不发布为新创建。
- 创建不是开战、扣门票或通关。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"group_id": "80",
"member_ids": [
"10001"
],
"details": {
"instance_id": "900000000000002",
"raid_mode": 0,
"single": false,
"phase": 0
}
}↗raid.started攻坚首次开战PVP 与攻坚⌄
攻坚首次开始状态已经提交。
触发时机:持久化入场扣费后、首次开战状态提交后、响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 开战路径关联角色。 |
group_id | string | RaidKey 字符串。 |
member_ids | string[] | nil | 攻坚成员快照。 |
details.instance_id | string | 实例 ID 字符串。 |
details.raid_mode | integer (uint8) | 当前 1 安徒恩、2 卢克、3 超时空。 |
details.single | boolean | 是否单人模式。 |
details.phase | integer | 生命周期阶段编号。 |
- 每次首次开始一次;重复开战不重复发布。
- 不表示阶段通关、掉落或奖励结算。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"group_id": "80",
"member_ids": [
"10001",
"10002"
],
"details": {
"instance_id": "900000000000002",
"raid_mode": 1,
"single": false,
"phase": 1
}
}↗chat.message.received聊天请求进入策略聊天与好友⌄
结构合法且关联已选角色的聊天请求到达路由策略。
触发时机:转发和喇叭消耗前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 发言角色。 |
mode | integer (uint8) | 原生聊天模式编号。 |
text | string | GBK 解码后的正文快照。 |
item_links | integer | 请求中物品链接计数,不含链接内容。 |
source | string | 进入策略的路径,当前有 town / peer。 |
recipients | integer | 接收阶段为 0。 |
- 此时 recipients=0;收到请求不代表随后允许或转发。
- 通知不能阻断聊天;用 chat.message Hook 返回决策。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"mode": 0,
"text": "大家好",
"item_links": 0,
"source": "town",
"recipients": 0
}↗chat.message.blocked聊天被插件策略拒绝聊天与好友⌄
chat.message 业务 Hook 决策拒绝该请求。
触发时机:策略拒绝后、任何转发或喇叭消耗前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 请求发言角色。 |
mode | integer (uint8) | 聊天模式编号。 |
text | string | 解码正文快照。 |
item_links | integer | 物品链接数。 |
source | string | 策略输入路径标识。 |
recipients | integer | 此阶段为 0。 |
- 不是所有核心聊天失败的汇总;脚本错误回退原规则时也不等于 blocked。
- recipients=0;正文只用于观察。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"mode": 0,
"text": "示例被拒绝文字",
"item_links": 0,
"source": "town",
"recipients": 0
}↗chat.message.forwarded聊天转发已尝试聊天与好友⌄
宿主已尝试进行聊天转发。
触发时机:对应路由执行转发尝试后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 发言角色。 |
mode | integer (uint8) | 聊天模式编号。 |
text | string | 解码正文。 |
item_links | integer | 请求链接数。 |
source | string | 实际路由来源/范围标识,例如 peer、whisper 或广播路径范围。 |
recipients | integer | 宿主受理转发的数量。 |
- recipients 是宿主接受数,不是客户端确认或实际阅读人数。
- source 在该阶段可为具体路由范围,与 received 的入口标识不同。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"mode": 0,
"text": "大家好",
"item_links": 0,
"source": "peer",
"recipients": 1
}↗friend.added好友添加被接受聊天与好友⌄
好友 owner 已成功应用添加操作。
触发时机:好友 owner 成功返回后、成功响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 操作角色。 |
peer_id | string | nil | 解析出的好友角色 ID,空值省略。 |
peer_name | string | 好友角色名称。 |
- 可能包含已有状态的成功无操作,不能推断每次新增了一条关系。
- 不提供账号或好友列表。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"peer_id": "10002",
"peer_name": "示例好友"
}↗friend.removed好友删除被接受聊天与好友⌄
好友 owner 已成功应用移除操作。
触发时机:好友 owner 成功返回后、成功响应前。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 操作角色。 |
peer_id | string | nil | 当前删除路径省略,应允许 nil。 |
peer_name | string | 请求删除的好友名称。 |
- 可含成功无操作;当前删除路径没有 peer_id,只提供目标名称。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"peer_name": "示例好友"
}↗activity.reward_claimed活动新奖励提交活动⌄
已接入的活动 owner 返回了本次新提交奖励。
触发时机:新 MailIDs 产生或旧 onlineevent 非重放领取成功后。
| 字段 | 类型 | 说明 |
|---|---|---|
character | Character | 领奖角色;无会话时 channel_id=0。 |
activity | string | 活动来源标识,或旧 onlineevent 的 EventID。 |
stage | string | 来源对应阶段:位置、档位、累计天数、目标等级、daily:N,period:N 或 StageID。 |
mail_count | integer | 本次新奖励邮件条数;直接发放可能 0。 |
- 收据重放、未获新奖励的请求不当作新领奖。
- 覆盖 attendance_marble、beast_soul、monthly_attendance、weekly_attendance、legacy_levelup、level_aiming、online_pcroom_timepoint 和旧 onlineevent 的 EventID/StageID。
- 旧 onlineevent 可直接发放,mail_count 可为 0;脱离会话的 owner 使 channel_id=0,不能直接频道公告。
- 通知不具备可靠发奖保证,不能据此再次发放同一奖励。
数据示例
{
"character": {
"id": "10001",
"channel_id": 1
},
"activity": "monthly_attendance",
"stage": "3",
"mail_count": 1
}诊断事件:临时排查使用
诊断名由 game. 加现有 logGameEvent 种类构成,例如 game.game-dungeon-cycle-clear-deferred。它们不计入上面的 63 项稳定事件,名称、字段与频率没有稳定业务承诺,与磁盘 packet log 开关独立。
诊断 data 只保留受限数字、布尔值以及 source / reason 字符串(最多 256 字节),可附 channel_id、connection_id;int64/uint64 转字符串。包体、凭据键、错误对象、任意其他字符串不会发布。插件公告来源被排除,以避免递归观察。
game.* 同时会匹配稳定的 game.operation.finished。不能看到诊断词 success、committed 就认定资产已提交。排查完成后改用精确的稳定事件,避免依赖日志名称。
覆盖范围如何确认
当前接线覆盖已登记的玩法模块、显式领域 owner 与文档列出的活动路径;同领域内部所有函数或特殊玩法并不自动变成事件。比如 dungeon.exited 包含断线、替换、回滚,不等于通关;pvp.match_finished 早于奖励持久化;mail.opened 只表示打开快照;dungeon.cleared 当前来自普通 Boss、无 Boss 教学及祭坛播报入口,不宣称覆盖所有攻坚结算。
本页按 dnf/v1 当前源码核对:pkg/dnfext/v1/contracts.go、events_items.go、events_commerce.go、events_world.go、events_gameplay.go 以及 dnfbridge/extensions*.go 的实际发布调用。运行版本的目录若不包含某名称,应先更新配套服务端,再安装依赖该事件的插件。