游戏开发后端【免费下载链接】OpenFrontIOOnline browser-based RTS game项目地址https://gitcode.com/gh_mirrors/op/OpenFrontIO点击查看免费下载导读OpenFrontIO 是一款开源在线浏览器端即时战略游戏RTS本文基于 docs/API.md 整理其面向第三方站点的公共 HTTP API 全貌你可以用它拉取指定时间范围内的比赛元数据与完整对局记录、查询玩家的会话与个人战绩、同步 7 天内被删除的玩家 ID 以做数据合规清理也可以让玩家通过「身份令牌」向你的站点证明其 OpenFront 账号归属并消费部落排行榜、部落统计与部落会话数据。读完本文你将掌握每个端点的参数约束、分页机制Content-Range 与 keyset 游标、响应字段含义以及部落加权胜场weighted wins的完整计算公式。一、接口总览与通用约定公共 API 的基础地址为https://api.openfront.io全部返回 JSON。从仓库结构看公开数据接口对应着服务端对局归档src/server/Archive.ts、部落数据src/client/ClanApi.ts与身份令牌src/client/components/IdentityTokenCard.ts等模块客户端侧还有对应的类型定义src/core/ApiSchemas.ts、src/core/ClanApiSchemas.ts可对照参考。使用前需要记住三个通用约定时间戳一律使用 ISO 8601 格式例如2025-10-25T00:00:00Z。公开数据不含敏感身份公开玩家 IDpublic player id会在游戏记录中剥离用于隐私保护详见下文 Get Game Info 的说明。分页有两种风格比赛元数据列表使用limit/offsetContent-Range响应头玩家会话与个人游戏历史使用 keyset 游标cursor/nextCursor部落会话则使用page/limit。二、Games比赛元数据与对局详情2.1 按时间范围列出比赛元数据GET https://api.openfront.io/public/games获取在指定时间范围内开始的所有比赛的 ID 与基础元数据结果按开始时间排序并分页。硬性约束务必遵守最大时间跨度2 天单次请求最多返回1000 场比赛查询参数参数必填取值说明start是ISO 8601 时间戳时间范围起点end是ISO 8601 时间戳时间范围终点type否Private/Public/Singleplayer游戏类型mode否Free For All/Team游戏模式rankedType否unranked/1v1/2v2排位类型playerTeams否如Duos玩家组队配置limit否默认 50最大 1000返回条数offset否整数分页偏移量示例请求curl https://api.openfront.io/public/games?start2025-10-25T00:00:00Zend2025-10-26T23:59:59ZtypePublicmodeTeamrankedTypeunrankedlimit10offset5响应示例[ { game: ABSgwin6, start: 2025-10-25T00:00:10.526Z, end: 2025-10-25T00:19:45.187Z, type: Public, mode: Team, difficulty: Medium, numPlayers: 6, maxPlayers: 8, lobbyFillTime: 45000, playerTeams: Duos, rankedType: unranked } ]分页提示响应包含Content-Range响应头格式形如games 5-15/399即本次返回的是第 515 条、总共 399 条——这是判断是否还有下一页以及计算偏移量的依据。从服务端实现看每场对局在结束后会通过 src/server/Archive.ts 中的archive(gameRecord)以POST {jwtIssuer}/game/{gameID}写入归档存储并附x-api-key做服务间鉴权readGameRecord()则负责按gameId读回完整对局记录读取前会用ID.safeParse校验 ID 合法性。公共/public/games端点即为这套归档数据的公开只读视图。2.2 获取单场比赛详情GET https://api.openfront.io/public/game/:gameId检索指定比赛的详细信息。查询参数参数说明turns设为false可剔除回合数据、显著减小响应体积默认包含示例# 完整对局数据 curl https://api.openfront.io/public/game/ABSgwin6 # 不含回合数据 curl https://api.openfront.io/public/game/ABSgwin6?turnsfalse隐私说明为保护玩家隐私公开的游戏记录中会剥离公开玩家 ID。若你的应用需要以「玩家」维度反查对局应改走下文 Players 一组的端点以玩家为入口查询其参与过的游戏。三、Players玩家信息、会话与战绩3.1 获取玩家信息GET https://api.openfront.io/public/player/:playerId检索指定玩家的资料与统计信息。curl https://api.openfront.io/public/player/HabCsQYR3.2 获取玩家会话列表Keyset 游标分页GET https://api.openfront.io/public/player/:playerId/sessions返回该玩家参与过的比赛及其客户端 ID会话 ID最新比赛在前每页 100 条使用与「获取玩家比赛」相同的 keyset游标分页。查询参数参数说明filter模式桶取ffa/team/hvn/ranked之一省略表示全部模式type游戏类型取public/private/singleplayer之一省略表示全部类型。filter与type正交可同时使用start/endISO 8601 时间限定比赛开始时间含边界可单独给出其一start必须早于endcursor不透明续传令牌直接把上一次响应中的nextCursor原样传入即可取下一页不要自行构造或解析它。游标与其签发时的过滤条件绑定修改任何其他参数都必须丢弃游标、从头开始响应示例{ results: [ { gameId: abc123, gameStart: 2026-05-17T21:04:00.000Z, gameEnd: 2026-05-17T21:24:34.000Z, gameType: Public, gameMode: Team, gameRankedType: unranked, clientId: client-session-id, username: alice, clanTag: ABC, hasWon: true } ], nextCursor: opaque-token }边界语义重要nextCursor为null表示没有更多会话。已知玩家但无任何会话时返回空的results数组返回 404 才表示该玩家 ID 不存在。做数据清洗时应区分这两种情况。curl https://api.openfront.io/public/player/HabCsQYR/sessions3.3 获取玩家比赛历史Keyset 游标分页GET https://api.openfront.io/public/player/:playerId/games获取玩家个人比赛历史最新在前。注意此端点使用 keyset游标分页而不是其他地方使用的page/limit方案——不要把上一组端点的分页习惯带到这里。查询参数参数说明filter模式桶ffa/team/hvn/ranked省略为全部type游戏类型public/private/singleplayer省略为全部与filter正交可组合cursor不透明续传令牌原样回传上一响应的nextCursor不可构造或解析响应示例{ results: [ { gameId: abc123, start: 2026-05-17T21:04:00.000Z, durationSeconds: 1234, map: World, mode: Team, type: Public, playerTeams: Duos, rankedType: unranked, result: victory, totalPlayers: 8, username: alice, clanTag: ABC } ], nextCursor: opaque-token }字段语义result取值victory胜利/defeat失败/incomplete没有记录的胜者。playerTeams、totalPlayers、clanTag可能为null。nextCursor为null表示没有更多比赛。username/clanTag反映的是该玩家在那场比赛中所用的身份可能随改名或部落变动而不同不要把它当作玩家当前身份。curl https://api.openfront.io/public/player/HabCsQYR/games?filterteamtypepublic3.4 近期被删除的玩家合规同步GET https://api.openfront.io/public/players/recently-deleted列出最近 7 天内被删除玩家的公开 ID最新在前。如果你的服务收集了玩家数据请每日轮询本端点并把已删除的玩家从你的数据中移除以满足账号删除的合规要求。查询参数参数说明sinceISO 8601 时间戳只返回该时间之后被删除的玩家必须位于最近 7 天内同步机制传入since上次同步的deletedAt或你上次轮询的时间即可只拉取更新的删除记录。删除记录最多只保留 7 天若since早于 7 天会返回400。错过窗口的补救如果漏掉了某个时间段可改为核对——任何现在对/public/player/:playerId返回404的玩家都应从你的数据中删除。curl https://api.openfront.io/public/players/recently-deleted?since2026-09-14T00:00:00Z响应示例[ { publicId: HabCsQYR, deletedAt: 2026-09-14T08:12:33.000Z } ]四、验证账号归属Identity Tokens身份令牌第三方站点可以让玩家证明自己拥有某个 OpenFront 账号用于账号关联、绑定或成就同步等场景。流程为玩家在你的站点下选择账户设置 → 关联到第三方站点Account settings → Link to a third-party site生成一个令牌并粘贴到你的站点你校验令牌、把返回的publicId与你的用户绑定一次然后丢弃该令牌。令牌安全模型务必理解令牌只对生成它的那个站点有效JWT 的aud声明就是你的域名有效期10 分钟令牌除玩家的公开 ID 外不携带任何身份信息不能用于登录 OpenFront。当前支持的站点ofstats.io、trackerfront.io。如需新增你的站点请向 OpenFront 团队申请站点由管理后台托管无需重新部署新站点会在几分钟内出现在游戏中。在客户端侧对应实现是 src/client/components/IdentityTokenCard.ts组件通过getIdentityTokenAudiences()拉取站点列表无站点时组件不渲染玩家选择站点后点击生成调用createIdentityToken铸造令牌令牌只保存在内存中每次点击都会重新铸造并有 10 分钟过期定时器expiryTimer。测试用例 tests/client/components/IdentityTokenCard.test.ts 验证了两个站点ofstats.io与trackerfront.io的展示与按选中站点铸造令牌的行为。4.1 方式一调用校验端点推荐POST https://api.openfront.io/public/identity_token/validate请求体JSON字段说明token玩家粘贴的令牌audience你的站点例如ofstats.iocurl -X POST https://api.openfront.io/public/identity_token/validate \ -H Content-Type: application/json \ -d {token: eyJ..., audience: ofstats.io}成功响应{ publicId: T8pcWNuC, expiresAt: 2026-09-25T03:36:56.000Z }令牌无效、已过期或为其他站点生成时返回400。4.2 方式二自行验证 JWT令牌是EdDSA 签名的 JWT。你可以从https://api.openfront.io/.well-known/jwks.json获取公钥并校验签名然后检查以下声明声明期望值isshttps://api.openfront.ioaud你自己的域名typidentityexp未过期玩家的公开 ID 即sub声明。示例载荷{ typ: identity, sub: T8pcWNuC, iat: 1790306816, exp: 1790307416, iss: https://api.openfront.io, aud: ofstats.io }对照仓库可以确认这套 JWT 体系与登录态令牌一脉相承src/core/ApiSchemas.ts 中的TokenPayloadSchema定义了sub经 base64url 解码校验的 UUID并transform回 UUID、iat、iss、aud、exp、role等字段结构服务端 JWT 签发与校验逻辑集中在 src/server/jwt.ts。身份令牌正是复用了同一套 EdDSA 签名与 JWKS 发布机制只是将typ限定为identity且不放任何登录能力。五、Clans部落排行榜、统计与会话5.1 部落排行榜加权胜场GET https://api.openfront.io/public/clans/leaderboard按加权胜场weighted wins展示前 100 名部落。加权胜场具有30 天半衰期用于让近期胜利占据更高权重。客户端实现可参考 src/client/ClanApi.ts 中的fetchClanLeaderboard()直接请求/public/clans/leaderboard响应结构由 src/core/ClanApiSchemas.ts 中的ClanLeaderboardEntrySchema含weightedWins数值字段定义。加权胜场完整计算公式FUNCTION calculateScore(session: ClanSession, decay: NUMBER 1) → NUMBER // 1. Calculate average team size avgTeamSize ← session.totalPlayerCount ÷ session.numTeams // 2. Determine how much the clan contributed to their team // (clan players divided by average players per team) clanMemberRatio ← session.clanPlayerCount ÷ avgTeamSize // 3. Apply decay factor (e.g., for older sessions) weightedValue ← clanMemberRatio × decay // 4. Calculate match difficulty based on number of teams // More teams → harder to win → higher reward for victory // Uses square root to avoid extreme scaling difficulty ← MAX(1, √(session.numTeams - 1)) // 5. Return final score: // - Win: reward is multiplied by difficulty // - Loss: penalty is divided by difficulty (less punishment in harder matches) IF session.hasWon THEN RETURN weightedValue × difficulty ELSE RETURN weightedValue ÷ difficulty END IF END FUNCTION算法要点解读平均队伍规模totalPlayerCount ÷ numTeams作为「每个队伍里应该有多少人」的基准。部落贡献比clanPlayerCount ÷ avgTeamSize衡量该部落玩家在其队伍中占的比重——人越多的部落赢下一场单场得分被稀释得越多。时间衰减decay默认 1对更早的会话按 30 天半衰期打折即「越新越值钱」。难度系数MAX(1, √(numTeams - 1))。队伍越多越难赢因此胜利奖励越高用平方根防止极端放大。胜负不对称胜利时得分 weightedValue × difficulty失败时扣分 weightedValue ÷ difficulty——即越难的对局里失败惩罚越小鼓励强队去打高难度对局。5.2 部落统计GET https://openfront.io/public/clan/:clanTag展示指定部落在选定时间范围内的综合战绩。不传时间范围时展示从 2025 年 11 月初开始的终身统计lifetime stats。核心指标总场次、胜场、负场与胜率胜负比与加权胜负比并按以下维度细分队伍类型如 2 队、3 队、双人、三人等对局中的队伍数量2 队、5 队、20 队等。注意本端点的统计不应用衰减因此其中的加权胜场与排行榜leaderboard中的加权胜场数值不同——排行榜面向「谁最近最强」本端点面向「一段时间的整体表现」。查询参数参数说明startISO 8601 时间戳可选endISO 8601 时间戳可选curl https://api.openfront.io/public/clan/UN?start2025-11-15T00:00:00Z end2025-11-18T23:59:59Z5.3 部落会话GET https://api.openfront.io/public/clan/:clanTag/sessions部落会话clan session的定义任何带有该部落标签的玩家出现在一场公开团队游戏中即产生一条会话。不传start/end时展示终身会话自 2025 年 11 月初起。查询参数参数说明startISO 8601 时间戳可选endISO 8601 时间戳可选page页码范围 1–200默认 1limit每页条数范围 1–50默认 20响应结构{ results: [ ... ], total: 150, page: 1, limit: 20 }结果按比赛开始时间排序最新在前。注意本端点使用的是page/limit分页最大 200 页与玩家侧端点的 keyset 游标分页不同。curl https://api.openfront.io/public/clan/UN/sessions?start2025-11-15T00:00:00Zend2025-11-18T23:59:59Zlimit10page1六、实战建议与注意事项综合以上端点给第三方接入方几条可落地的实践建议按需选择分页风格/public/games用Content-Range头判断翻页部落会话用page/limit玩家会话与个人历史用 keysetcursor。对玩家历史这类「实时追加、可能并发更新」的数据keyset 游标比 offset 更稳定不会因新数据插入而跳页或重复。善用turnsfalse拉取整场对局做回放或统计时若不需要逐回合数据务必传turnsfalse可大幅减小响应体积与传输耗时。坚持每日合规同步把/public/players/recently-deleted纳入每日定时任务cron记录上次同步的deletedAt作为since一旦错过 7 天窗口改用 404 核对兜底保证删除请求及时落实。身份令牌一次性使用拿到publicId并完成绑定后立即丢弃令牌不要持久化10 分钟有效期与aud绑定意味着令牌必须在玩家操作窗口内完成校验。理解两份加权胜场的差异排行榜强调「近期难度」统计端点强调「全量无衰减」做展示时不要把两者混为一谈。若想深入理解这些接口背后的实现可继续阅读 src/server/Archive.ts对局归档与读取、src/client/ClanApi.ts部落数据客户端调用、src/core/ClanApiSchemas.ts部落响应 schema以及 src/client/components/IdentityTokenCard.ts身份令牌前端交互。赞分享游戏开发后端【免费下载链接】OpenFrontIOOnline browser-based RTS game项目地址https://gitcode.com/gh_mirrors/op/OpenFrontIO点击查看免费下载相关推荐Win11DebloatWindows 11终极瘦身指南让你的电脑重获新生 Win11DebloatWindows 11终极瘦身指南让你的电脑重获新生 Windows 11虽然界面美观但预装了太多你不需要的应用和功能系统变桌面应用CLISegmenTron代码结构详解核心模块与自定义模型开发入门SegmenTron代码结构详解核心模块与自定义模型开发入门 SegmenTron是一个功能强大的语义分割开源项目支持PointRend、Fast_SCNNNotepad--深度解析国产跨平台文本编辑器的10个专业级使用技巧Notepad 深度解析国产跨平台文本编辑器的10个专业级使用技巧 Notepad 是一款由中国开发者打造的跨平台文本编辑器支持Windows、Linux和桌面应用上一篇彻底解决表单重置难题jQuery Validation Plugin状态清除完全指南下一篇提升Knockout.js组件质量测试覆盖率工具全攻略创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?