帖子

加入 QQ 交流群(音游 / 编程)

喜欢本站?打赏作者

宣传Milracle 是一个由 星鸿 开发的 Milthm 二创社区,给玩家提供了在网页上游玩 Milthm 自制谱的渠道,谱面列表中也可以游玩在 PhiZone 上传 Milthm 的自制谱。

宣传Notanote 二周年版本已于 2 月 14 日更新!本次更新包含 5 首新曲,其中有 4 首独占,还有全新的谱面分类方式,详细内容请看 官方视频


日期

Phira API 非官方文档

Phira 有自己的 API,但官方没有相关文档,所以我根据 phira-web 仓库中的代码等信息,写了一篇非官方的文档。本文内容可能会有遗漏和错误的地方,部分内容也未研究清楚,欢迎各位补充。

Phira 有两个 API 链接:https://api.phira.cnhttps://phira.5wyxi.com

# Python 示例

# 获取 ID 为 1000 的谱面的信息
import requests
req = requests.get('https://api.phira.cn/chart/1000')
print(req.json())
// JavaScript 示例

// 获取 ID 为 1000 的谱面的信息
fetch('https://api.phira.cn/chart/1000')
    .then(response => response.json())
    .then(data => console.log(data));

谱面

检索谱面

URL: /chart

参数

参数 说明
uploader int 上传者用户 ID
pageNum integer (default: 30) 每页谱面数量,默认值为 30
page integer (default: 1) 页码,默认值为 1
order string 排序方式
  • 时间顺序: -update
  • 时间倒序: update
  • 评分顺序: -rating
  • 评分倒序: rating
  • 名字顺序: name
  • 名字倒序: -name
division string 分区
  • 常规: regular
  • 整活: troll
  • 纯配置: plain
  • 观赏: visual
tags array[string] 想包含与不想包含的标签,在标签前加负号表示不想包含
search string 搜索
division string 分区
  • 常规: regular
  • 整活: troll
  • 纯配置: plain
  • 观赏: visual
rating array[number] 评分下界与上界,上界在前下界在后

响应

{
    "count": int, // 谱面总数
    "result": [
        {
            "id": int, // 谱面 ID
            "name": string, // 曲名
            "level": string, // 难度,格式为 XX Lv.XX
            "difficulty": float, // 定数,会有浮点数误差,使用时注意四舍五入至十分位
            "charter": string, // 谱师
            "composer": string, // 曲师
            "illustrator": string, // 画师
            "description": string, // 简介
            "ranked": boolean, // 是否计入 rks
            "reviewed": boolean, // 是否通过审核
            "stable": boolean, // 是否上架
            "stableRequest": boolean, // 是否申请上架流程结束
            "illustration": string, // 曲绘文件 URL
            "preview": string, // 预览音频文件 URL
            "file": string, // 谱面文件 URL
            "uploader": int, // 上传者用户 ID
            "tags": [string, string, …], // 标签
            "rating": float, // 评分(1 对应评分 5.00)
            "ratingCount": int, // 评分人数
            "created": string, // 上传时间,格式为 ISO 8601 标准
            "updated": string, // 更新时间,包括非谱面部分,格式为 ISO 8601 标准
            "chartUpdated": string // 谱面更新时间,格式为 ISO 8601 标准
        },
        …
    ]
}

检索特定谱面

URL: /chart/{谱面 ID}

参数

响应

{
    "id": int, // 谱面 ID
    "name": string, // 曲名
    "level": string, // 难度,格式为 XX Lv.XX
    "difficulty": float, // 定数,会有浮点数误差,使用时注意四舍五入至十分位
    "charter": string, // 谱师
    "composer": string, // 曲师
    "illustrator": string, // 画师
    "description": string, // 简介
    "ranked": boolean, // 是否计入 rks
    "reviewed": boolean, // 是否通过审核
    "stable": boolean, // 是否上架
    "stableRequest": boolean, // 是否申请上架流程结束
    "illustration": string, // 曲绘文件 URL
    "preview": string, // 预览音频文件 URL
    "file": string, // 谱面文件 URL
    "uploader": int, // 上传者用户 ID
    "tags": [string, string, …], // 标签
    "rating": float, // 评分(1 对应评分 5.00)
    "ratingCount": int, // 评分人数
    "created": string, // 上传时间,格式为 ISO 8601 标准
    "updated": string, // 更新时间,包括非谱面部分,格式为 ISO 8601 标准
    "chartUpdated": string // 谱面更新时间,格式为 ISO 8601 标准
}

检索多个特定谱面

URL: /chart/multi-get

参数

参数 说明
ids array[number] 谱面 ID

响应

[
    {
        "id": int, // 谱面 ID
        "name": string, // 曲名
        "level": string, // 难度,格式为 XX Lv.XX
        "difficulty": float, // 定数,会有浮点数误差,使用时注意四舍五入至十分位
        "charter": string, // 谱师
        "composer": string, // 曲师
        "illustrator": string, // 画师
        "description": string, // 简介
        "ranked": boolean, // 是否计入 rks
        "reviewed": boolean, // 是否通过审核
        "stable": boolean, // 是否上架
        "stableRequest": boolean, // 是否申请上架流程结束
        "illustration": string, // 曲绘文件 URL
        "preview": string, // 预览音频文件 URL
        "file": string, // 谱面文件 URL
        "uploader": int, // 上传者用户 ID
        "tags": [string, string, …], // 标签
        "rating": float, // 评分(1 对应评分 5.00)
        "ratingCount": int, // 评分人数
        "created": string, // 上传时间,格式为 ISO 8601 标准
        "updated": string, // 更新时间,包括非谱面部分,格式为 ISO 8601 标准
        "chartUpdated": string // 谱面更新时间,格式为 ISO 8601 标准
    },
    …
]

检索特定谱面的评议情况

URL: /chart/{谱面 ID}/stabilize-status

参数

响应

{
    "stable": boolean, // 是否上架
    "stableRequest": boolean, // 是否申请上架流程结束
    "approvements": [], //
    "denies": [], //
    "history": [ // 评议历史
        {
            "reviewer": int | null, // 评议员用户 ID,若为 null 则代表此对象为评议结果
            "reviewerName": string | null, // 评议员用户名,若为 null 则代表此对象为评议结果
            "reviewerAvatar": string | null, // 评议员头像 URL,若为 null 则代表此对象为评议结果
            "chart": int, // 谱面 ID
            "approve": boolean, // 是否通过了谱面
            "comment": string | null, // 评议员留言
            "time": string // 评议时间,格式为 ISO 8601 标准
        },
        …
    ]
}

活动

检索活动

URL: /event

参数

响应

{
    "count": int, // 活动总数
    "result": [
        {
            "id": int, // 活动数字 ID
            "ids": string // 活动文字 ID
            "creator": int, // 活动创建者用户 ID
            "name": string, // 活动名
            "illustration": string, // 活动封面 URL
            "timeStart": string, // 开始时间,格式为 ISO 8601 标准
            "timeEnd": string, // 结束时间,包括非谱面部分,格式为 ISO 8601 标准
            "locked": boolean // 是否锁定
        },
        …
    ]
}

检索特定活动

URL: /event/{活动 ID}

参数

响应

{
    "id": int, // 活动数字 ID
    "ids": string // 活动文字 ID
    "creator": int, // 活动创建者用户 ID
    "name": string, // 活动名
    "illustration": string, // 活动封面 URL
    "timeStart": string, // 开始时间,格式为 ISO 8601 标准
    "timeEnd": string, // 结束时间,包括非谱面部分修改,格式为 ISO 8601 标准
    "locked": boolean // 是否锁定
}

用户

检索用户

URL: /user

检索特定用户

URL: /user/{用户 ID}

参数

响应

{
    "id": int, // 用户 ID
    "name": string, // 用户名
    "avatar": string, // 头像 URL
    "badges": [string, string, …], // 身份标签,对应网页端用户名颜色
    "language": string, // 语言
    "bio": string | null, // 简介
    "exp": int, // 经验值
    "rks": float, // rks
    "joined": string, // 注册时间,格式为 ISO 8601 标准
    "last_login": string, // 上次登录时间,格式为 ISO 8601 标准
    "roles": int, // 身份组,值为用户所属的所有身份组的对应数字之和。各身份组对应数字如下:
    USER = 0, (普通用户)
    ADMIN = 1, (管理员)
    REVIEWER = 2, (审核员)
    SUPERVISOR = 4, (评议员)
    HEAD_SUPERVISOR = 8, (评议组长)
    HEAD_REVIEWER = 16, (审核组长)
    PECJAM_REVIEWER = 32, (PecJam比赛审核员)
    MODERATOR = 64, (含义未知)
    "banned": boolean, // 是否被封禁
    "login_banned": boolean, // 是否禁止登录
    "follower_count": int, // 粉丝数
    "following_count": int, // 关注数
    "following": boolean // 是否关注
}

检索特定用户状态

URL: /user/{id}/stats

参数

响应

{
    "numRecords": int, // 总游玩次数
    "avgAccuracy": float // 平均准确率
}

游玩记录

检索特定用户的 Best 20

URL: /record/get-pool/{用户 ID}

参数

参数 说明
player integer 用户 ID

响应

{
    "bestPool": [
        {
            "id": int, // 游玩记录 ID
            "player": int, // 玩家 ID
            "chart": int, // 谱面 ID
            "score": int, // 分数
            "accuracy": float, // 准确率
            "perfect": int, // Perfect 数
            "good": int, // Good 数
            "bad": int, // Bad 数
            "miss": int, // Miss 数
            "speed": float, // 硫流速
            "max_combo": int, // 最大连击数
            "best": boolean, // 含义未知
            "best_std": boolean, // 含义未知
            "mods": int, // 含义未知
            "full_combo": boolean, // 是否全连
            "time": string, // 游玩时间,格式为 ISO 8601 标准
            "std": float, // 无暇度(打击偏移),单位为秒
            "std_score": float, // 无暇度(分数)
        },
        …
    ]
}

检索特定游玩记录

URL: /record/{id}

参数

响应

{
    "id": int, // 游玩记录 ID
    "player": int, // 玩家 ID
    "chart": int, // 谱面 ID
    "score": int, // 分数
    "accuracy": float, // 准确率
    "perfect": int, // Perfect 数
    "good": int, // Good 数
    "bad": int, // Bad 数
    "miss": int, // Miss 数
    "speed": float, // 硫流速
    "max_combo": int, // 最大连击数
    "best": boolean, // 含义未知
    "best_std": boolean, // 含义未知
    "mods": int, // 含义未知
    "full_combo": boolean, // 是否全连
    "time": string, // 游玩时间,格式为 ISO 8601 标准
    "std": float, // 无暇度(打击偏移),单位为秒
    "std_score": float // 无暇度(分数)
}

检索多个特定游玩记录

URL: /record/multi-get

参数

参数 说明
ids array[number] 游玩记录 ID

响应

[
    {
        "id": int, // 游玩记录 ID
        "player": int, // 玩家 ID
        "chart": int, // 谱面 ID
        "score": int, // 分数
        "accuracy": float, // 准确率
        "perfect": int, // Perfect 数
        "good": int, // Good 数
        "bad": int, // Bad 数
        "miss": int, // Miss 数
        "speed": float, // 硫流速
        "max_combo": int, // 最大连击数
        "best": boolean, // 含义未知
        "best_std": boolean, // 含义未知
        "mods": int, // 含义未知
        "full_combo": boolean, // 是否全连
        "time": string, // 游玩时间,格式为 ISO 8601 标准
        "std": float, // 无暇度(打击偏移),单位为秒
        "std_score": float, // 无暇度(分数)
        "playerName": null, // 用处未知
        "playerAvatar": null, // 用处未知
        "playerBadges": null // 用处未知
    },
    …
]

检索特定谱面的游玩记录

URL: /record/query/{谱面 ID}

参数

参数 说明
pageNum integer (default: 30) 每页游玩记录数量减一的值,默认值为 30,最小值为 4,最大值为 30
page integer (default: 1) 页码,默认值为 1

响应

{
    "count": int, // 总游玩记录数
    [
        {
            "id": int, // 游玩记录 ID
            "player": int, // 玩家 ID
            "chart": int, // 谱面 ID
            "score": int, // 分数
            "accuracy": float, // 准确率
            "perfect": int, // Perfect 数
            "good": int, // Good 数
            "bad": int, // Bad 数
            "miss": int, // Miss 数
            "speed": float, // 硫流速
            "max_combo": int, // 最大连击数
            "best": boolean, // 含义未知
            "best_std": boolean, // 含义未知
            "mods": int, // 含义未知
            "full_combo": boolean, // 是否全连
            "time": string, // 游玩时间,格式为 ISO 8601 标准
            "std": float, // 无暇度(打击偏移),单位为秒
            "std_score": float, // 无暇度(分数)
            "playerName": null, // 用处未知
            "playerAvatar": null, // 用处未知
            "playerBadges": null // 用处未知
        },
        …
    ]
}

检索特定用户的 Best 20

URL: /record/get-pool/{用户 ID}

参数

无。

响应

{
    "bestPool": [
        {
            "record": int, // 游玩记录 ID
            "chart": int, // 谱面 ID
            "rks": float, // 单曲 rks
        },
        …
    ]
}

其他

获取文件

URL: /file/{文件 ID}

参数

响应

文件

成员列表

URL: /staff

参数

响应

{
    "admin": [number, number, …], // 管理员
    "headReviewers": [number, number, …], // 审核组长
    "reviewers": [number, number, …], // 审核员
    "headSupervisors": [number, number, …], // 评议组长
    "supervisors": [number, number, …], // 评议员
}