主题集成
Finder API
主题模板可以通过 steamFinder 读取 Steam 数据。Finder 主要读取后台预热好的缓存,失败或超时时返回 null,模板需要判空。
可用方法
| 方法 | 返回类型 | 说明 |
|---|---|---|
steamFinder.getProfile() |
SteamProfile |
用户资料 |
steamFinder.getRecentGames(limit) |
List<RecentGame> |
最近游玩 |
steamFinder.getOwnedGames(page, size) |
ListResult<OwnedGame> |
游戏库分页 |
steamFinder.getStats() |
SteamStats |
游戏统计 |
steamFinder.getBadges() |
BadgeInfo |
徽章信息 |
游戏对象字段
游戏库和最近游玩共享 OwnedGame 字段,最近游玩额外包含最近两周时长、成就和库外标识。
| 字段 | 说明 |
|---|---|
appId |
Steam AppID |
name |
游戏名称,列表优先使用 GetItems 返回的本地化名称 |
playtimeForever / playtimeFormatted |
总游玩时长分钟数 / 格式化文本 |
imgIconUrl / iconUrl |
Steam 原始图标 hash / 拼接并套用 CDN 后的图标 URL |
rtimeLastPlayed / lastPlayedFormatted |
最后游玩时间戳 / 格式化日期 |
realHeaderImage / headerImageUrl |
Steam 原始真实封面 / 套用 CDN 后的展示封面 |
delisted |
GetItems 明确返回 visible=false 时为 true,表示当前地区或状态下商店不可见 |
playtime2Weeks / playtime2WeeksFormatted |
仅最近游玩:最近两周时长 |
achievementProgressText / achievementsLocked |
仅最近游玩:成就进度文本 / 成就是否不可用 |
inLibrary |
仅最近游玩:是否存在于当前游戏库缓存,false 表示库外游戏 |
headerImageUrl 可能为 null,主题必须准备占位图。它为 null 不一定代表不可用,只有 delisted=true 才显示「不可用」标识。
示例代码
用户资料
<th:block th:with="profile=${steamFinder.getProfile()}">
<div th:if="${profile != null}">
<img th:src="${profile.summary?.avatarFull}" alt="头像">
<span th:text="${profile.summary?.personaName}">用户名</span>
<span th:text="${profile.statusText}">在线状态</span>
<span th:text="'等级 ' + ${profile.steamLevel}">等级</span>
</div>
</th:block>
最近游玩
<th:block th:with="recentGames=${steamFinder.getRecentGames(5)}, phImg='/themes/your-theme/assets/game-placeholder.png'">
<div th:if="${recentGames != null}" th:each="game : ${recentGames}">
<img th:src="${game.headerImageUrl != null ? game.headerImageUrl : phImg}" th:alt="${game.name}">
<span th:text="${game.name}">游戏名</span>
<span th:text="${game.playtime2WeeksFormatted}">2h 0m</span>
<span th:if="${game.delisted}">不可用</span>
<span th:if="${game.inLibrary != null and !game.inLibrary}">库外</span>
<span th:if="${game.achievementProgressText != null}" th:text="${game.achievementProgressText}">15/30</span>
</div>
</th:block>
游戏库分页
<th:block th:with="gameList=${steamFinder.getOwnedGames(1, 12)}, phImg='/themes/your-theme/assets/game-placeholder.png'">
<div th:if="${gameList != null}">
<div th:each="game : ${gameList.items}">
<img th:src="${game.headerImageUrl != null ? game.headerImageUrl : phImg}" th:alt="${game.name}">
<span th:text="${game.name}">游戏名</span>
<span th:text="${game.playtimeFormatted}">总时长</span>
<span th:if="${game.delisted}">不可用</span>
</div>
<span th:text="'第 ' + ${gameList.page} + ' 页,共 ' + ${gameList.totalPages} + ' 页'"></span>
</div>
</th:block>
徽章
<th:block th:with="badges=${steamFinder.getBadges()}">
<div th:if="${badges != null}">
<span th:text="${badges.playerLevel}">等级</span>
<span th:text="${badges.totalBadges}">徽章数</span>
<div th:each="badge : ${badges.badges}">
<img th:if="${badge.imageUrl != null}" th:src="${badge.imageUrl}" th:alt="${badge.displayName}">
<span th:text="${badge.displayName}">徽章</span>
</div>
</div>
</th:block>
/steam 页面模板变量
插件内置 /steam 页面会传入这些变量:
| 变量 | 类型 | 说明 |
|---|---|---|
title |
String |
页面标题 |
games |
UrlContextListResult<OwnedGame> |
游戏库列表,带分页 URL |
gamesLimit |
int |
游戏库总数量限制 |
recentGamesLimit |
int |
最近游玩显示数量 |
enableGameLink |
boolean |
是否启用商店链接 |
showHeatmap |
boolean |
是否显示热力图 |
heatmapDays |
int |
热力图显示天数 |
heatmapColorTheme |
String |
热力图主题 |
heatmapShowLegend |
boolean |
是否显示图例 |
echartsUrl |
String |
ECharts 脚本地址 |
REST API
公开 REST API 基础路径:/apis/api.steam.timxs.com/v1alpha1。
| 接口 | 方法 | 说明 |
|---|---|---|
/profile |
GET | 用户资料 |
/games?page=1&size=20&sortBy=playtime_forever |
GET | 游戏库分页,size 最大 100 |
/recent?limit=5 |
GET | 最近游玩,limit 最大 20 |
/stats |
GET | 统计数据 |
/achievements/{appid} |
GET | 单个游戏成就进度 |
/badges |
GET | 徽章信息 |
/game-detail/{appId}?lang=schinese |
GET | 游戏卡片详情 |
/heatmap/records?startDate=&endDate= |
GET | 每日游戏时长记录 |
/games 和 /recent 在未配置或 service 返回 empty 时会返回空分页/空数组,而不是空 body。Finder API 失败时仍返回 null。
缓存与性能
Finder API 日常读取后台预热好的缓存,不直接等待 Steam API。刚启动、刚刷新缓存或后台持续失败时,缓存为空可能返回 null。
最近游玩成就进度在后台刷新最近游玩缓存时补全,并随列表缓存返回;页面访问缓存时不会逐个游戏重新请求成就 API。
页面列表的更新由「活跃信息刷新间隔」和「库藏信息刷新间隔」控制。「缓存过期时间」只用于游戏卡片详情等按需查询。