// ==UserScript== // @name Steam 游戏库展示 // @namespace steam-game-library-viewer // @author Github: SmallRob,SteamID: Healer007 // @version 2.11.44 // @description 在 Steam 商店/社区页面增加中央游戏库模态面板(橱窗/个人展柜/时长/洞察/家庭组/系列分类/绝版/愿望单/PS会免/Epic赠送/年度大作/锁区/DLC收藏,支持卡片/横版封面/列表三种视图)和右侧个人信息面板侧滑栏(概览/洞察/社交/勋章/设置)。 // v2.11.44 修复(部分游戏小图标无法获取,如 app 4292950):Steam 社区小图标 CDN 路径已迁移——新游戏(含未发售)的社区图标不再发布到旧路径 cdn.{cloudflare,akamai}.steamstatic.com/steamcommunity/public/images/apps/{appid}/{hash}.jpg(实测 404),仅存在于新路径 shared.{fastly,akamai}.steamstatic.com/community_assets/images/apps/{appid}/{hash}.jpg;且此类新游戏常无任何商店封面资产(capsule_sm_120/header 全 404),社区图标是唯一可用图,旧代码"旧路径+capsule_sm_120 单级兜底"全链路失败。实测新路径对老游戏同样可用(TF2/440 新旧均 200)=超集。修复:①getGameIconUrl 有 hash 时主用 shared.fastly community_assets 新路径,并接入 icon:appid 成功缓存(getPosterGood kind='icon');②新增 communityIconChainUrls 统一图标回退链(新路径 fastly/akamai → 旧路径 cloudflare/akamai → capsule_sm_120 四 CDN 含 store_item_assets);③新增 _sglvIconFallback 页面级回退函数(对齐封面 _sglvPosterFallback 三段式:成功缓存→链式回退→header.jpg 兜底→隐藏),onload 记录成功 URL 避免重复试错;④_applyGameIcon 改走统一链;⑤替换 6 处硬编码内联 onerror(展柜近期游玩/SGIS 近期时间线/SGIS 入库时间线/愿望单列表/时长 Top20/全局搜索缩略图)为 _sglvIconFallback,消除散落的旧路径三元式与单级 capsule_sm_120 兜底,iconUrl 构造统一收敛到 getGameIconUrl;⑥hotfix(SGIS 概览页"用户档案获取失败: getGameIconUrl is not defined"→次日再报"getGameIconUrl is not a function"):getGameIconUrl 定义于主面板渲染子闭包,SGIS 为兄弟闭包不可直接引用(与 v2.11.38 xpPercent 同类作用域事故,ReferenceError 被 renderProfile 外层 catch 误报为档案获取失败)——SGIS 顶部 v2.4.1 别名块补 const getGameIconUrl = SGLV_API.getGameIconUrl 桥接;首版桥接遗漏关键一步:SGLV_API 此前从未导出过 getGameIconUrl(8830 行含 getGameIconUrl 的对象字面量实为收藏库桥 CollectionHost,非 SGLV_API——所有 SGLV_API 成员均为 17079+ 的逐条直接赋值),别名把 undefined 固化进 const → 渲染时报 not a function;本版补 SGLV_API.getGameIconUrl = getGameIconUrl 导出(17089 导出块,先于 SGIS 求值),并新增"导出存在+先于 SGIS 段+别名存在+调用后置"四重哨兵防回归;全局搜索 buildSearchItem 的 typeof getGameIconUrl 守卫因作用域恒假(缩略图 capsule 兜底从未接通)同步改 SGLV_API 真接通。 // v2.11.43 修复(参考 steam-family-game-analysis v2.10 购买动态的购买者归属):GetSharedLibraryApps 的 owner_steamids 按入库顺序排列——末位=最新入库者(购买者),首位=最早购入者(该启发式经 family-analysis v1.56+ 生产验证)。家人后买一款自己已拥有的游戏时,共拥游戏 owners=[我,家人],rt_time_acquired 是家人的购买时间——2.11.42 的许可页校准依赖许可页可达,若许可页抓取失败/超 50 页上限/未命中该 app,家人购买仍会以"当天 07:59"出现在个人入库动态。本版引入 owners 末位归属,不依赖许可页即可正确归属:①新增 isMyAcquisitionEvent 纯函数(owners 末位===我 → rt_time_acquired 是我的购买事件;独占拥有恒真;非我的游戏恒假;无 owners 回退路径视为自己);②个人入库动态:非我的购买事件且无许可页校准日期 → 直接不展示("不是我的购买不出现在个人入库动态中"),有校准日期则展示在我的真实购买日期;③buildCalibratedAcquiredMap 同规则清理:非我的购买事件且无校准日期的游戏从入库时间映射移除(热力图/频率分析/趋势时间线/排序补齐不再按家人的购买日期计数);④fetchAllGames 主库路径:同类游戏 acquiredTime 清零(趋势图年度柱/"今年入库"KPI 回退到 lastPlayed 估算口径,不再错误计入家人购买日);⑤家庭组入库动态新增购买者显示——条目名称下方显示"成员名 购入"(steamIdtoName[owners 末位],名称映射缺失时经 getAccessToken+fetchFamilyInfo 拉取并持久化,失败仅显示时间),对齐 family-analysis 购买动态表的购买者列;⑥家庭组入库 footer 注明"购买者=最新入库成员";⑦测试新增 F 组 isMyAcquisitionEvent 6 场景 + 购买者接线哨兵 G 组 6 项 + H 组执行级回归 2 项(真实执行 buildFamilyTimeline/buildPersonalTimeline 全链路,stub 注入依赖,专门拦截"源码哨兵查不出的运行时 ReferenceError")——sglv-license-time.test.js 共 39 组断言;⑧hotfix:buildFamilyTimeline 的 purchaserName 首版引用了未声明的 owners 局部变量(该函数循环内原本无此声明),家庭组入库动态加载即抛 "owners is not defined"——已补声明并注入式验证 H1 能复现拦截该错误。 // v2.11.42 修复(参考 steam-friend-manager crossVerifyLicenses):家庭组共拥游戏入库时间被家人的新入库刷新——GetSharedLibraryApps 的 rt_time_acquired 是每个 app 的单一时间戳,家庭成员新入库一款自己已拥有的游戏时该时间被刷成家人的入库时间,个人入库动态/入库趋势/热力图等"我的入库"语境把旧游戏统计到家人的入库日期上(当天展示并未购买的共拥游戏)。修复:①新增个人许可页抓取模块(parseLicenseDate/parseLicenseRows/fetchPersonalLicenseMap:store.steampowered.com/account/licenses 首屏+AjaxLoadMoreLicenses 分页,24h 会话级缓存,未登录/失败静默降级保留家庭组时间;许可页仅列本人许可,appid 命中即为"我的游戏" ground truth,日级精度);②新增 licenseCorrectionsFor 纯函数——许可页日期与 rt_time_acquired 不同日才覆盖为许可页日期(秒),同日保留家庭组时间(保留真实时刻);③新增 buildCalibratedAcquiredMap 统一出口,接入 5 个"我的入库"消费点:个人入库动态(buildPersonalTimeline,条目加 licenseCorrected 标记)/入库趋势时间线/入库频率分析/入库排序补齐/入库热力图;④fetchAllGames 主库路径(趋势图年度柱/今年入库 KPI/SGIS 面板数据源)合并家庭组数据后同样校准 acquiredTime;⑤家庭组入库动态(buildFamilyTimeline)保持原始 rt_time_acquired 不校准——家庭组入库页含个人已拥有的共拥游戏为既定正确行为,仅修正其 footer 与状态注释中过时的"排除个人已拥有"虚假声明;⑥个人入库动态渲染:校准条目仅日级精度不再显示伪 HH:MM 时刻,footer 附加"N 款已按个人许可页校准";⑦新增 test/sglv-license-time.test.js 25 组断言(日期解析 3 格式/DOM 行解析契约 shim/校准规则 6 场景/消费点接线哨兵 7 项/许可页网络模块 stub 4 场景:缓存生效+分页合并+网络失败不写负缓存+并发去重)。 // v2.11.40 主题层抽象:①CSS_SGIS_OVERRIDE(无条件紫色覆盖层)重构为典雅紫主题层 CSS_THEME_PURPLE(内容零改动,默认主题零视觉回归),从 CSS_INLINE 移除;②新增经典蓝主题层 CSS_THEME_BLUE(scripts/gen-sglv-theme-blue.js 生成:紫层镜像色值映射 #a78bfa→#66c0f4 等 + 主脚本 CSS 常量/共享库原生紫色规则蓝色瘦身覆盖,Part B 120 条 + Part C 163 条,紫色残留自检 0);③SGLV_THEMES 注册表 + applySglvTheme 动态注入(