Skip to content

谜题后端

对于较为复杂的交互型题目,通常需要自定义后端逻辑。每个谜题都可以配置一段服务器 JavaScript 脚本,用于自定义 API、自定义评测、提示购买钩子等场景。

快速开始

  1. 在单个谜题配置页面的 [额外配置-后端脚本] 一节,将 [启用状态] 设置为开启。

  2. [脚本源码] 中填写以下示例代码:

    js
    export function test(ctx) {
      return { code: 'ok', ctx };
    }
  3. [公开函数] 中将自动列出导出的函数,选择 test 以将其暴露为自定义 API。

  4. 为测试队伍解锁这个题目,此时队伍内成员可以直接通过 API 请求该函数。

    GET /api/puzzles/[id]/backend/test

    得到以下结果。

    json
    {"code":0,"data":{"code":"ok","ctx":{...}}}}

调用入口

目前支持在自定义 API、自定义评测、提示购买钩子三种场景下调用谜题后端。只有在开启了对应题目的后端脚本功能时,脚本相关的配置项才会可用。

只有导出的函数才能被直接调用,建议使用以下两种导出方法。

js
export function test(ctx) {}
export const test = ctx => {};

自定义 API

[额外配置-后端脚本-公开函数] 中可以选择任意个暴露为自定义 API 的导出函数。

玩家登录且所在队伍有权访问该题时,可以直接通过 HTTP 请求公开函数。

GET  /api/puzzles/[id]/backend/[function]
POST /api/puzzles/[id]/backend/[function]

上下文将提供 HTTP 请求信息。在调用成功时,响应体的 code 固定为 0data 为被调函数的返回值,要求必须可序列化为 JSON。

自定义评测

[答案提交-评测规则] 中可以设置某条规则的 [评测方式][评测函数],并填写要调用的导出函数。

在玩家提交答案后,运行这条评测规则时,将调用该函数。调用与本次提交共用数据库事务,函数失败会使本次判题失败并回滚事务内修改。

上下文将提供提交信息。被调函数可以返回 undefined,代表该函数未处理这次提交,评测机将继续匹配之后的规则;或者返回一个评测结果对象。

ts
type JudgeResult = {
  action?: 'fail' | 'correct' | 'milestone' | 'start_game' | 'easter_egg' | 'finish_game' | number;
  result?: string;
  answer?: string;
  ignored?: boolean;
  triggers?: string[];
};

评测函数作为一个匹配规则,返回评测结果的 action 将实际生效。也就是说 correct 会使提交解出本题,start_game 会使队伍开始比赛,finish_game 会使队伍完成比赛,fail 会使队伍受到错误惩罚。同时,trigger 也会像普通的触发器配置一样写入队伍状态。

如果 ignored 设置为 true,那么这条提交不会计入提交次数,不会增加冷却惩罚的时间,也不会拒绝用户重复提交答案,但是仍然会显示在提交记录中。评测故障的提交自动记为 ignored

为了防止状态混乱,评测期间不能调用 $this.submission.add$this.solve

提示购买钩子

[提示编辑-预设提示] 中可以在某个提示的 [解锁调用函数] 填写要调用的导出函数。

在玩家解锁这条提示时,后端实际解锁前,将调用该函数。

上下文将提供提示和购买信息。被调函数返回值会被忽略,调用过程中失败会阻止本次购买。

API 参考

谜题后端提供了多种工作函数,可以修改队伍部分状态,存储各种信息等,实现复杂后端逻辑。

对于调用上下文和提供的工具函数,请参考谜题后端 - API 参考

示例

// TODO //