Skip to content

Releases: askbbtsk/pcl-lite

PCL Lite 1.7.0

Choose a tag to compare

@askbbtsk askbbtsk released this 02 Nov 13:21
1.7.0 正式版:Lunar 页面改成独立登录并能导入令牌,Discord 游玩时长不再归零,启动器公告真的能用了,Windows 用户名默认打码,滚动条重做成随主题的细胶囊。

PCL Lite 1.7.0。

这是自 1.6.4-hotfix-5 以来的第一个正式版。下面按主题把这一路的全部改动列一遍,最后一节是这一版相对上一个预发布(1.7.0-early-3)新增的内容。

一、Lunar 页面:账号独立,且能导入令牌

为什么必须独立

以前 Lunar 页面直接复用 PCL 主页面的登录。选一个账号启动,游戏端会卡在 Connecting... 进不去。

根因不在网络,在令牌身份对不上。Lunar 游戏端拿到 accessToken 会解 JWT,按里面的 aid(应用标识)挑刷新实现;PCL 主页面用的是自己的应用注册,签出来的 aid 三个分支全命中不了,落到最后那条需要 deviceToken 和密钥对的路上 —— PCL 造不出来,刷新失败,界面就永远停在 Connecting...。

现在 Lunar 页面是独立的一套:

主页面 Lunar 页面
应用身份 PCL 自己的 Lunar 的
账号存哪 ProfileService 的档案列表 %LOCALAPPDATA%\PCLLite\Lunar\identities.json
怎么产生 主页面点登录 Lunar 页面点「登录」

没登录时不再偷偷拿 PCL 的登录顶上,而是明确提示去登录。主页面登录、普通账号刷新、离线登录一行没动。

令牌导入

登录页底下多了「使用令牌登录」,粘进去就行,三种凭据自动识别:

粘进去的东西 会发生什么 能续期
Refresh Token 换出整套新令牌,和正常登录完全等价 能,一直有效
Minecraft 令牌 直接用,不换 不能,24 小时后失效
微软 Cookie 走授权码流程换出整套令牌 能

输入框改成了多行可滚动,长令牌不会再被 MaxLength 静默截断。

Cookie 现在认浏览器扩展导出的 cookies.txt:那种文件是 Netscape 格式(7 列、制表符分隔),以前一条规则都不中,整份文件掉进 refresh token 分支去兑换,报错指向完全错误的方向。现在会只取 login.live.com 那部分、同名以更具体的域为准、过期条目丢弃;一条都用不上时直接说「这份 Cookie 已经失效」。

档案列表

  • 匹配键明确成「UUID + 登录方式」:同一个号用设备码登一次、用令牌导入一次,就是两条档案,各自独立
  • 同一个号用同一种方式再登一次,认定是续期,就地替换,不新增条目
  • 启动时自动合并历史遗留的重复条目(先看有没有 Refresh Token,再看到期时间)
  • 每条标出是怎么登进来的:设备代码 / Access Token / Refresh Token / Cookie
  • 登录方式挂在第二行的「正版验证 · xxx」里,不再跟账号名抢位置被省略号吃掉
  • 续期记住了「谁签发的」(RefreshClientId),依次试 PCL Lite / Lunar 启动器 / In-Game Account Switcher,都不是就明说换不了,而不是丢一个 AADSTS70000 让人猜

二、Discord 状态:时长不再莫名归零

设置里那个「应用 ID」输入框删了,改成本项目自己的应用写死在代码里 —— 那个框除了让人填错之外没有任何用处。

时长归零 / 从头开始的几个独立原因都修了:

原因 修法
取内存失败被当成游戏没在跑 只有「进程已退出」才判定没在运行
单次读不到快照就清空起点 连续 15 秒都读不到才算真的退出
起点是「第一次发现游戏在跑的时刻」 改用游戏进程自己的启动时间
管道报「已连接」其实对端已经没了 超过 90 秒没成功发出去过就强制重连
被 Discord 限流一次就断开 30 秒 限流只记错误不断连接;重连间隔 30 秒 → 15 秒

三、启动器公告真的能用了

以前这条链路是死的:公告走 GitHub Releases,而代码里直接返回空列表,设置项选哪一档都没区别。

现在公告来自清单仓库根目录的 notice.json:改文件就等于发一条公告,不用发版。走和更新清单同一套多通道抢答,拉不到 / 文件不存在 / JSON 写坏一律当作没有公告,不影响启动。公告用 id 去重,important: true 的条目在「仅重要」档也会收到。

公告只走准实时通道(Contents API / raw 直连 / 反代),跳过 jsDelivr —— 它对 GitHub 路径默认缓存 12 小时,命中缓存时反而最快,会把旧内容顶上来。清单文件(update.json)行为不变。

四、隐私:用户文件夹名打码(默认开)

界面和启动日志里到处是 C:\Users\xxx\AppData\...,随手截图就把 Windows 用户名带出去了。现在 Users 后面那一段统一显示成 *****:

改前:C:\Users\18857\AppData\Roaming\.minecraft
改后:C:\Users\*****\AppData\Roaming\.minecraft
  • 按路径结构打码,不是整串替换,用户名恰好是纯数字时不会牵连版本号和文件大小
  • 所有用户文件夹都打(别人的账号、Public、正斜杠写法一并处理)
  • 固定五个星号,不按名字长度补 —— 星号个数本身也是信息
  • 崩溃报告始终打码,不受开关影响
  • 实例列表左栏、设置 → Java 的路径也都覆盖了

需要看真实路径排查问题时:设置 → 个性化 → 基础 → 取消勾选「界面上的用户文件夹名打码」,立刻生效。

五、界面

  • 滚动条重做(这一版新增,见下)
  • 「新建档案」的方框整块都能点,不再只有中间那个小圆生效
  • 设置 → 启动器 → 游戏选项里那个灰着的「正版验证方式」整行隐藏(代码里被强制成设备代码流,选另一个不改变任何行为)
  • Lunar 页那张卡原来列了 8 行实现细节(含一句早已过时的「好友与社交面板还没做」),改成一句概述 + 「查看完整说明 →」跳仓库里的 docs/LUNAR.md

六、这一版相对 1.7.0-early-3 新增

滚动条改成随主题的细胶囊

原来的原生滚动条又宽又灰,深色主题下尤其扎眼。现在:

  • 平时是一条 4px 半透明细边,鼠标移进这一列就滑出到 8px 并变实
  • 颜色取 ColorBrush3 / ColorBrush4,跟随主题色相,不再是一根灰条
  • 去掉上下箭头按钮,保留 PageUp / PageDown 命中区,点击空白仍可翻页
  • 整列 12px 都是命中区,不用精确压在那 4px 上
  • 横向滚动条单独给模板,保持满宽、同色系
  • 顺带修掉右下角那块白方块:WPF 默认 ScrollViewer 模板在两条滚动条交汇处画了一个 SystemColors.ControlBrush 的矩形,深色界面下就是一块白 —— 重写模板去掉它,PART 名字与默认模板保持一致,ScrollViewerNoMargin / ScrollViewerFullMargin / MyScrollViewer 不受影响

Lunar 上报的启动器版本改为在线查

launcherVersion.semver 以前取本机 Lunar Client.exe 的 FileVersion,没装就 4.0.0。Lunar 服务端只校验下限、下限跟着官方启动器往上涨,这个值迟早过期被 1008 踢掉。

现在走官方启动器自己的更新源:

GET /launcher/metadata/misc?installation_id=<uuid>   → updater.feedUrl + updater.channel
GET <feedUrl>/latest-ow.yml                          → version: x.y.z-ow,剪掉 -ow

结果缓存 6 小时、并发去重,查失败保留上一次的好值;优先级是 在线最新正式版 → 本机 exe FileVersion → 4.0.0。两处 UA 与 /launch 请求体的 launcher_version 一并改用该值。

注意:传给 Genesis 的 --launcherVersion 仍然是 3.3.0,没跟着改。 那是「游戏侧」的参数,只被游戏打日志用;上报服务端的是另一回事。代码里已经改名成 GameLauncherVersion 并写了注释,防止以后又混在一起。

七、其它修复

  • 导入的 Refresh Token 档案刷新一次就变成「设备代码」:McProfile.Clone() 是手写字段清单,漏拷 LoginMethod 与 RefreshClientId,后者还会让下一次续期拿 PCL 的身份去换别人的令牌
  • 更新时并发启动两个更新器导致替换失败
  • AddAccount 应答与页面切换撕裂
  • Lunar 账户库不再跟着物料根目录走
  • 删掉 Lunar 的「回到游戏」按钮:FocusGamePush 在外部进程里被前台锁定挡住,点了没反应

八、更新通道新增 early

给「正式版马上要发了,先放出来给人试」留了个位置:

hotfix(+1) > 正式版(0) > early(-1) > pre(-2) > snapshot(-3) > nightly(-4)

比同号正式版旧(正式版一发出来会再升一次落地,不会被卡住),比 pre 新,同时属于正式版通道 —— 选「稳定版」的用户也收得到。序号写法用 - 隔开:early-1、early-2。

九、许可协议打包进 exe

以前 csproj 里写的是 <Content Include="LICENCE" />,而仓库里的文件叫 LICENSE 且放在仓库根目录,那个配置项一直指向不存在的文件。现在改成嵌入资源(PCL.LICENSE),协议正文编进程序集,单文件产物照旧只有一个 exe。

校验

SHA-256(签名后):BA810B25B7DFFAD4791CC6572C6B4E585CD36362A1BF867D7795B10F58961B8C

大小:19,394,856 字节

签名:Valid(PCL Lite,DigiCert 时间戳)

已知问题

  • Cookie 登录仍然没有在「真实且未过期的会话」下跑通过一次。格式识别(含 cookies.txt)已经补齐,但手上那份导出里的 MSPAuth / MSPProf 都是 Disabled(登出状态留下的),验证不到最后一步。真遇到回 login_required,先在浏览器里重新登一次 login.live.com 再导出
  • 令牌导入的账号 24 小时后必须重新导入,这是微软定的,没有绕法
  • 之前被误标成「设备代码」的旧档案,数据上已经还原不出原始登录方式了,需要删掉后用同一个 Refresh Token 重新导入一次
  • Lunar 的独立登录走的是 Lunar 自己的 Azure 应用注册,授权记录会记在 Lunar 名下(account.microsoft.com 的「应用权限」里看到的是 Lunar Client,不是 PCL);Lunar 单方面改那个注册会让这条路直接失效,PCL 无法自救
  • 反代(ghproxy 之类)如果自己带缓存,理论上也可能返回旧公告。遇到「改了没生效」先等一两分钟再试

更早的分步说明

1.7.0 一路发过若干预发布版,每一步的细节都在各自的发布说明里:snapshot → snapshot-2 → snapshot-3 → snapshot-4 → snapshot-5 → pre-1 → pre-2 → pre-3 → pre-4 → early-1 → early-2 → early-3。

PCL Lite 1.7.0-early-3

Choose a tag to compare

@askbbtsk askbbtsk released this 01 Nov 23:07
1.7.0-early-3:补上漏掉的打码 —— 实例列表和 Java 列表里的路径之前还是真名。

PCL Lite 1.7.0-early-3。

抢先体验版:1.7.0 正式发布之前先放出来的那一份。四个更新通道(稳定版 / 预览版 / 快照版 / 始终最新)都能收到它。

修了什么

1.7.0-early-2 的用户文件夹名打码漏了两处,因为这两处的路径是直接赋给控件的,没走本地化文本那条路:

  • 实例选择左栏:每个文件夹下面那行路径(C:\Users\xxx\AppData\Roaming\.minecraft 之类)还是真名
  • 设置 → Java:每个 Java 的副标题(安装目录)还是真名

现在两处都打码了,效果和别的地方一致:

改前:C:\Users\18857\AppData\Roaming\.minecraft
改后:C:\Users\*****\AppData\Roaming\.minecraft

其余行为不变:默认开着,固定五个星号,只换 Users 后面那一段,崩溃报告始终打码。

有问题就关掉

设置 → 个性化 → 基础 → 取消勾选「界面上的用户文件夹名打码」,立刻生效,不用重启。

校验

SHA-256(签名后):F725FD8E6B4A67D7B305E8DCA41912351C3B51D5F895470D51DB939DDFF4EEF5

大小:19,384,104 字节

签名:Valid(PCL Lite,DigiCert 时间戳)

已知问题

  • Cookie 登录仍然没有在「真实且未过期的会话」下跑通过一次。格式识别(含浏览器扩展导出的 cookies.txt)已经补齐,但手上那份导出里的 MSPAuth / MSPProf 都是 Disabled(登出状态留下的),验证不到最后一步
  • 令牌导入的账号 24 小时后必须重新导入,这是微软定的,没有绕法
  • 之前被误标成「设备代码」的旧档案,数据上已经还原不出原始登录方式了,需要删掉后用同一个 Refresh Token 重新导入一次

PCL Lite 1.7.0-early-2

Choose a tag to compare

@askbbtsk askbbtsk released this 01 Nov 22:59
1.7.0-early-2:界面和启动日志里的 Windows 用户名默认打码成 *****,截图发出去不会带出你自己的用户名。

PCL Lite 1.7.0-early-2。

抢先体验版:1.7.0 正式发布之前先放出来的那一份。四个更新通道(稳定版 / 预览版 / 快照版 / 始终最新)都能收到它。

改了什么

用户文件夹名打码(默认开)

界面和启动日志里到处是 C:\Users\xxx\AppData\... 这种路径,随手截个图就把 Windows 用户名带出去了。这一版把 Users 后面那一段统一显示成 *****:

改前:C:\Users\18857\AppData\Roaming\.minecraft
改后:C:\Users\*****\AppData\Roaming\.minecraft

几个细节:

  • 按路径结构打码,不是整串替换。只换 Users 路径段紧跟的那一段,其余字符一个不动 —— 用户名恰好是纯数字时,日志里的版本号、文件大小不会被牵连
  • 所有用户文件夹都打:别人的账号、C:\Users\Public、正斜杠写法 C:/Users/... 一并处理
  • 固定五个星号,不按名字长度补 —— 星号个数等于名字长度,本身就是一条信息
  • 崩溃报告始终打码,不受下面那个开关影响(那是要发给别人看的)

有问题就关掉

打码会影响显示,如果你需要看真实路径排查问题,或者觉得哪里打过头了:

设置 → 个性化 → 基础 → 取消勾选「界面上的用户文件夹名打码」

立刻生效,不用重启。只影响显示,不会改动磁盘上任何文件夹或文件。

校验

SHA-256(签名后):B48E4FB8D6237AA5E3DF76B0F7F684C9115D2B97D454EB9BD09485C26B908EEC

大小:19,384,104 字节

签名:Valid(PCL Lite,DigiCert 时间戳)

已知问题

  • Cookie 登录仍然没有在「真实且未过期的会话」下跑通过一次。格式识别(含浏览器扩展导出的 cookies.txt)已经补齐,但手上那份导出里的 MSPAuth / MSPProf 都是 Disabled(登出状态留下的),验证不到最后一步
  • 令牌导入的账号 24 小时后必须重新导入,这是微软定的,没有绕法
  • 之前被误标成「设备代码」的旧档案,数据上已经还原不出原始登录方式了,需要删掉后用同一个 Refresh Token 重新导入一次

PCL Lite 1.7.0-early-1

Choose a tag to compare

@askbbtsk askbbtsk released this 01 Nov 14:31
1.7.0-early-1:代码和 1.7.0-pre-4 一模一样,只是改用 early 号段发布 —— 默认「稳定版」通道的用户现在也能提前拿到 1.7.0 了。

PCL Lite 1.7.0-early-1。

抢先体验版:1.7.0 正式发布之前先放出来的那一份。四个更新通道(稳定版 / 预览版 / 快照版 / 始终最新)都能收到它。

和 1.7.0-pre-4 有什么不同

功能上没有任何不同,代码完全一致。 唯一的区别是版本号:pre-4 只有把更新通道切到「预览」及更激进的用户能收到,early-1 属于正式版通道,装完默认设置的人也能提前用上。

具体改了什么见 1.7.0-pre-4 的发布说明,一句话概括是两件事:

  • 新增 early 号段(就是这一版用的这个)
  • 许可协议正文打包进 exe,单文件产物照旧只有一个文件

early 的位置

hotfix(+1) > 正式版(0) > early(-1) > pre(-2) > snapshot(-3) > nightly(-4)
  • 比同号正式版旧:1.7.0-early-1 < 1.7.0,正式版一发出来,抢先版用户会再升一次落地,不会被卡住
  • 比 pre 新:1.7.0-early-1 > 1.7.0-pre-9,它已经是「即将发布的那份正式版」,不是预览阶段
  • 属于正式版通道:选「稳定版」的用户也收得到,不用切到激进通道

序号写法照旧,用 - 隔开:early-1、early-2。

校验

SHA-256(签名后):AEC3E7421B55B3EE63534B7013681F34BB4051FDC3AA73116090F03C95AFD10A

大小:19,380,008 字节

签名:Valid(PCL Lite,DigiCert 时间戳)

已知问题

  • Cookie 登录仍然没有在「真实且未过期的会话」下跑通过一次。格式识别(含浏览器扩展导出的 cookies.txt)已经补齐,但手上那份导出里的 MSPAuth / MSPProf 都是 Disabled(登出状态留下的),验证不到最后一步
  • 令牌导入的账号 24 小时后必须重新导入,这是微软定的,没有绕法
  • 之前被误标成「设备代码」的旧档案,数据上已经还原不出原始登录方式了,需要删掉后用同一个 Refresh Token 重新导入一次

PCL Lite 1.7.0-snapshot-4

Pre-release

Choose a tag to compare

@askbbtsk askbbtsk released this 01 Nov 12:57
1.7.0-snapshot-4:Discord 状态的应用 ID 固定内置不再可改,游玩时长不再莫名归零;启动器公告改由 service 仓库的 notice.json 下发,改文件即生效。

PCL Lite 1.7.0-snapshot-4。

快照版,只有选了「快照」或更激进通道的用户会收到。稳定版通道请继续用 1.6.4-hotfix-5。

改了什么

一、Discord 应用 ID 不再可改

设置里那个「应用 ID」输入框删了,改成本项目自己的应用写死在代码里。

那个框除了让人填错之外没有任何用处:填成别人的应用,状态卡片上显示的就是别人的应用名和图标;填错一个字符就整条链路连不上,而用户根本无从判断是自己填错了还是 Discord 没开。现在不给改,也就没有「填错了」这种状态。

老配置里残留的那一项会被当作未知键忽略,不用手动清理。

二、游玩时长不再莫名归零

这一版把「时长卡住 / 从头开始」的几个独立原因都修了:

原因 表现 修法
取内存失败被当成游戏没在跑 时长忽然归零 只有「进程已退出」才判定没在运行,取内存失败只放弃那一项数据
单次读不到快照就清空起点 时长从头开始 连续 15 秒都读不到才算真的退出
起点是「第一次发现游戏在跑的时刻」 一旦被清就永远对不上 改用游戏进程自己的启动时间,怎么重算都是同一个值
管道报「已连接」其实对端已经没了 状态停在最后一帧不动 超过 90 秒没成功发出去过任何东西就强制重连
被 Discord 限流一次就断开 30 秒 状态空白一阵又回来 限流只记错误不断连接;重连间隔也从 30 秒降到 15 秒

三、启动器公告真的能用了

以前这条链路是死的:公告走 GitHub Releases,而代码里直接返回空列表,所以「启动器公告」那个设置项选哪一档都没区别。

现在公告来自清单仓库根目录的一个独立文件:

https://raw.githubusercontent.com/bedkillerspacex-boop/Pcl-Lite-service/main/notice.json
  • 改这个文件就等于发一条公告,不用发版,客户端每次启动拉一次
  • 走的是和更新清单同一套多通道抢答,raw 拉不到会自动换 jsDelivr 或反代
  • 拉不到、文件不存在、JSON 写坏,一律当作没有公告,不影响启动、不弹错误
  • 公告用 id 去重,看过的人不会再被弹第二次
  • important: true 的条目,「仅重要」档的用户也会收到(这个档位以前没有实际过滤逻辑,现在有了)

字段说明直接写在文件里的 _字段说明 那一项。

校验

SHA-256(签名后):5BAA1FD3C9D928E18546C756BB916A9B349D083BA98B1D9A667B60C44B9BAB35

大小:19,373,864 字节

已知问题

  • Cookie 登录那条路仍然没在真实登录态下验证过。代码路径是通的(授权码 + prompt=none),
    但手上没有一份真实可用的 Cookie 去实测,可能会回 login_required。真遇到了就先用
    Refresh Token 或设备码,别在 Cookie 上耗时间
  • 令牌导入的账号 24 小时后必须重新导入,这是微软定的,没有绕法
  • 公告文件刚建好,content 是空的,所以这一版不会弹任何公告

PCL Lite 1.7.0-snapshot-3

Pre-release

Choose a tag to compare

@askbbtsk askbbtsk released this 01 Nov 12:12
1.7.0-snapshot-3:账号列表不再把登录方式挤在名字后面被省略号吃掉,改挂到「正版验证」后面;同一个号可以用不同方式各占一条档案。

PCL Lite 1.7.0-snapshot-3。

快照版,只有选了「快照」或更激进通道的用户会收到。稳定版通道请继续用 1.6.4-hotfix-5。

改了什么

一、登录方式不再跟账号名抢位置

上一版把登录方式拼成「账号名(设备代码)」,名字本来就长,加上后缀必然超宽:

Bed_Spacekiller_(设备…

方法名被省略号吃掉了,等于没标。现在挂在第二行的灰色信息里:

Bed_Spacekiller_
正版验证 · 设备代码

跟着「正版验证」一起灰,视觉上是一体的。账号详情页用的是同一份拼接逻辑,两处显示一致。

二、同一个号可以用多种方式各占一条档案

规则明确成一句话:匹配键是「UUID + 登录方式」。

场景 结果
同一个号,用设备码登一次、用令牌导入一次 两条档案,各自独立,互不覆盖
同一个号,用同一种方式再登一次 认定是续期,就地替换,档案位置和 ID 都不变,不新增条目

保留多条是有意的:不同方式的令牌寿命和续期能力完全不一样(Refresh Token 能一直续、Minecraft 令牌 24 小时就废),混成一条反而说不清自己手上这条还能用多久。

顺带修了个会让它失效的 bug:续期回来的结果里 LoginMethod 是空的,旧代码会把它归一化成 device 再去匹配 —— 一个 Cookie 档案续期时找不到自己,凭空多出一条 device 档案。现在结果没带登录方式就退回按 UUID 找第一条,宁可命中一个已有槽位,也不新增重复项。

校验

SHA-256(签名后):AC5DBFD28EFEDD69F42F83FC11DFB11B62F4EF148B30399F7360D10AD2D23459

大小:19,373,352 字节

已知问题

  • Cookie 登录那条路仍然没在真实登录态下验证过。代码路径是通的(授权码 + prompt=none),
    但手上没有一份真实可用的 Cookie 去实测,可能会回 login_required。真遇到了就先用
    Refresh Token 或设备码,别在 Cookie 上耗时间
  • 令牌导入的账号 24 小时后必须重新导入,这是微软定的,没有绕法

PCL Lite 1.7.0-snapshot-2

Pre-release

Choose a tag to compare

@askbbtsk askbbtsk released this 01 Nov 10:39
1.7.0-snapshot-2:账号能直接导入令牌了 —— 粘 Refresh Token、Minecraft 令牌或 Cookie 就能登,重复的正版档案也会自动合并成一条。

PCL Lite 1.7.0-snapshot-2。

快照版,只有选了「快照」或更激进通道的用户会收到。稳定版通道请继续用 1.6.4-hotfix-5。

改了什么

一、登录多了「粘贴凭据」这条路

以前只能走设备码:打开 microsoft.com/link、输码、选账号。现在登录页底下多了一个
「使用令牌登录」,粘进去就行,三种凭据自动识别:

粘进去的东西 会发生什么 能续期
Refresh Token 换出整套新令牌,和正常登录完全等价 能,一直有效
Minecraft 令牌 直接用,不换 不能,24 小时后失效
微软 Cookie 走授权码流程换出整套令牌 能

输入框改成了多行、可滚动,长令牌不会再被截断(以前 MaxLength 是 1000,
一段 refresh token 经常一千多字符,粘进去被静默切掉尾巴,报错还看不出原因)。

二、续期记住了「谁签发的」

Refresh Token 是绑死在签发它的 Azure 应用上的。以前不管哪来的令牌,续期都拿 PCL 自己的
身份去换,微软直接回 AADSTS70000(令牌是发给别的客户端的),档案就废了。

现在档案里记一个 RefreshClientId,续期时用同一个身份换。依次试三个已知签发方:

  • PCL Lite 自己
  • Lunar 启动器(4358653d-…)
  • In-Game Account Switcher(54fd49e4-…)

三个都不是,就明确告诉你「这个令牌换不了」,而不是丢一个错误码让人猜。

三、重复的正版档案自动合并

同一个号反复登录会一直往下堆新条目,列表里出现好几个一模一样的名字。根因是合并时
只比 UUID,不看登录方式 —— 同一个号用设备码登一次、用令牌导入一次,就成了两条。

现在按「UUID + 登录方式」判断,同号同方式只留一条。留哪条:先看有没有 Refresh Token
(有才续得下去),再看到期时间。反过来只看时间的话,一条快过期的令牌档案会把能续期的挤掉。

启动时自动跑一次,历史遗留的重复条目会自己消失。

档案列表里现在也会标出这条是怎么登进来的:设备代码 / Access Token / Refresh Token / Cookie。

四、Lunar 页面

  • 账号下拉框每一项改成两行:上面账号名,下面 UUID。同名的号一眼分不清,UUID 才是一对一能对上的
  • 支持「Minecraft 令牌导入」的 Lunar 身份账号:能启动,但 24 小时后要重新导入(这种账号没有 refreshToken)
  • 令牌过期又续不了,现在直接报错说清楚,不再拿个死令牌进游戏卡在 Connecting...
  • 令牌不是 Lunar 应用签的(aid 对不上),日志里会警告,省得一路走到卡住才让人猜
  • 左边栏的账号信息跟着选中项刷新,以前右边换完号左边还写着上一个
  • 老配置里的 pcl:<ProfileId> 前缀和 1.5.0 之前的裸 localId 会被归一化,不会再出现「选中的账号没了」

怎么用

进登录页,点最下面那行「使用令牌登录」,粘进去,回车。

三种凭据里 Refresh Token 最省事:一次粘进去能一直用,效果和正常登录一样。

校验

SHA-256(签名后):BC7388195B9906E4D2996181F58AC81C5C591DACBB87FD11E007C0F2D8ADA994

大小:19,373,352 字节

已知问题

  • Cookie 那条路还没在真实登录态下验证过。代码路径是通的(授权码 + prompt=none),
    但手上没有一份真实可用的 Cookie 去实测,可能会回 login_required。真遇到了就先用
    Refresh Token 或设备码,别在 Cookie 上耗时间
  • 令牌导入的账号 24 小时后必须重新导入,这是微软定的,没有绕法

1.7.0-snapshot

1.7.0-snapshot Pre-release
Pre-release

Choose a tag to compare

@askbbtsk askbbtsk released this 01 Nov 04:51
1.7.0-snapshot:Lunar 页面的账号改成独立登录 —— 在本页点「登录」用 Lunar 的应用身份授权一次,产出的令牌游戏端才认,不再卡 Connecting...

PCL Lite 1.7.0-snapshot。

快照版,只有选了「快照」或更激进通道的用户会收到。稳定版通道请继续用 1.6.4-hotfix-5。

问题

Lunar 页面以前直接复用 PCL 主页面的登录。选一个 PCL 账号启动,游戏端会卡在
Connecting...,进不去。

根因不在网络,在令牌身份对不上。Lunar 游戏端拿到 accessToken 后会解 JWT,
按里面的 aid(应用标识)选刷新实现:

oPe = e => {
  let { aid: t } = decodeJwt(e.accessToken);
  return t === LunarAppId ? SV          // 标准 OAuth,能刷
       : t === XboxLiveAppId ? iPe      // 走不通,见下
       : wV;                            // SISU,需要 deviceToken 和密钥对
}

PCL 主页面登录用的是 PCL 自己的应用注册,签出来的 refreshToken 的 aid 是 PCL 的。
三个分支全命中不了,落到 wV(SISU),那条路要 deviceToken、密钥对、还要过区域封禁
和年龄验证 —— PCL 造不出来,于是刷新失败,界面永远停在 Connecting...。

顺带说一句:iPe 那个分支其实是死代码。它比的是 16 位无横线的应用标识,
而真实令牌里 aid 是 36 位带横线的标准 UUID 形式,decodeJwt 不做归一化,
永远不相等。所以这条路不用再试了。

改了什么

Lunar 页面的账号现在是独立的一套,和主页面互不相通。

主页面 Lunar 页面
应用身份 PCL 自己的 Lunar 的
账号存哪 ProfileService 的档案列表 %LOCALAPPDATA%\PCLLite\Lunar\identities.json
怎么产生 主页面点登录 Lunar 页面点「登录」
互相可见 看不到 Lunar 的 看不到 PCL 的

具体改动:

  • 新增 LunarIdentityStore:多账号存储,只写 PCL 自己的目录,不碰 ~/.lunarclient
  • 账号下拉框第一组从「PCL 账号」换成「Lunar 身份账号」,不再读 ProfileService
  • 账号行右侧新增「登录」按钮:走设备码流程,用 Lunar 的应用身份授权,
    产出的 refreshToken 的 aid 就是 Lunar 的,游戏端认得出来
  • 没登录时不再偷偷拿 PCL 的登录顶上,而是明确提示去登录
  • 续期改成两级:优先用账户库里那份 refreshToken 配 Lunar 的应用身份刷新(刷新后
    连新的 refreshToken 一起写回,微软每次都轮换);账户库里没有才退回用 PCL 登录兜底

主页面登录、普通账号刷新、离线登录一行没动,还是原来的应用注册。

怎么用

  1. 进 Lunar 页面,账号行右侧点「登录」
  2. 按提示打开 microsoft.com/link 输入设备码,选账号
  3. 登录完自动选中,直接启动

登录一次之后就一直有效,之后启动不再弹。

校验

SHA-256(签名后):C8EE6EBBB35D72092C98CED89126F43E71190FDFC654551CC259BF50FBC232B9

大小:19,346,216 字节

已知代价

这个登录走的是 Lunar 自己的 Azure 应用注册,所以:

  • 授权记录会记在 Lunar 名下,在 account.microsoft.com 的「应用权限」里看到的是
    Lunar Client,不是 PCL
  • Lunar 单方面改那个应用注册(关公共客户端、删应用)会让这条路直接失效,
    PCL 无法自救

这是让游戏端认令牌的唯一办法,没有别的绕法。

PCL Lite 1.7.0-pre-4

PCL Lite 1.7.0-pre-4 Pre-release
Pre-release

Choose a tag to compare

@askbbtsk askbbtsk released this 01 Nov 14:19
1.7.0-pre-4:新增 early(抢先体验版)后缀,排在同号正式版下面、pre 上面,稳定版通道也能收到;许可协议正文终于打包进 exe 了。

PCL Lite 1.7.0-pre-4。

预览版,只有选了「预览」「快照」或更激进通道的用户会收到。稳定版通道请继续用 1.6.4-hotfix-5。

改了什么

一、新增 early:抢先体验版

给「正式版马上要发了,先放出来给人试」这种情况留了个位置。它夹在正式版和 pre 之间:

hotfix(+1) > 正式版(0) > early(-1) > pre(-2) > snapshot(-3) > nightly(-4)

两条性质:

  • 比同号正式版旧。1.7.0-early-1 < 1.7.0,所以正式版一发出来,抢先版用户会再升一次落到正式版上,不会被卡住
  • 比 pre 新。它是即将发布的那份正式版,比预览阶段更靠后,1.7.0-early-1 > 1.7.0-pre-9

它同时属于正式版通道 —— 选「稳定版」的用户也会收到。这正是「抢先体验」的意思:不用切到激进通道就能提前拿到。

序号写法照旧:early-1、early-2,用 - 隔开。

二、许可协议打包进 exe

以前 csproj 里写的是 <Content Include="LICENCE" />,而仓库里的文件叫 LICENSE、还放在仓库根目录(项目目录的上一级)—— 那个配置项一直指向不存在的文件,等于空转。发出去的 exe 里一份协议都没有。

现在改成嵌入资源(PCL.LICENSE),协议正文编进程序集:

  • 单文件产物照旧只有一个 exe,不多带一个附件
  • 仓库根目录那份 LICENSE 改了内容,重新编译就会带上,不会两边各一份、慢慢走样

校验

SHA-256(签名后):BFFD6CB038C07F1FC5097D163B1D1BA9727988D7225F6D5083C5E3B4B8B5159E

大小:19,380,008 字节

已知问题

  • Cookie 登录仍然没有在「真实且未过期的会话」下跑通过一次。格式识别已经补齐,但手上那份导出里的 MSPAuth / MSPProf 都是 Disabled(登出状态留下的),验证不到最后一步
  • 令牌导入的账号 24 小时后必须重新导入,这是微软定的,没有绕法

PCL Lite 1.7.0-pre-3

PCL Lite 1.7.0-pre-3 Pre-release
Pre-release

Choose a tag to compare

@askbbtsk askbbtsk released this 01 Nov 14:05
1.7.0-pre-3:修导入的 Refresh Token 档案刷新一次就变成「设备代码」——续期时复制档案漏拷了登录方式和签发者。

PCL Lite 1.7.0-pre-3。

预览版,只有选了「预览」「快照」或更激进通道的用户会收到。稳定版通道请继续用 1.6.4-hotfix-5。

改了什么

导入的 Refresh Token 档案不再变回「设备代码」

现象:用 Refresh Token 登录成功,账号列表里却标着「正版验证 · 设备代码」。令牌本身是好的,游戏也能正常启动,只是标签错了 —— 但错的不只是标签。

根因在 McProfile.Clone():它是手写的字段清单,漏了两个字段。

续期时档案是「复制一份、就地替换」,于是:

  • LoginMethod 没被复制 → 变成空串 → 归一化时按老档案兜底成 device → 显示「设备代码」
  • RefreshClientId 也没被复制 → 签发者被清空 → 下一次续期会拿 PCL 自己的身份去换别人的令牌,微软直接回 AADSTS70000

第二个才是真问题。第一个只是让你早点发现它。

修了两处:

  1. Clone() 补齐 LoginMethod 与 RefreshClientId,并加了注释说明「这是手写清单,加字段记得同步」
  2. ApplyAuthenticationResult 里改用原档案的登录方式兜底,而不是刚克隆出来的那份 —— 就算以后再漏字段,也不会静默把登录方式抹掉

已经标错的档案需要手动清一下

这个修复只保证「以后不再标错」,已经变成「设备代码」的旧档案不会自己恢复 —— 它们和真正的设备码档案在数据上已经长得一模一样了,没法区分。

建议:把重复的那几条删掉,用同一个 Refresh Token 重新导入一次。这次进去之后就会一直是「Refresh Token」,不会再变。

校验

SHA-256(签名后):CAC8D443E702ACE5D10F12A374933AB57BFA0ADFB1EF5C996A1FE68029F70003

大小:19,375,912 字节

已知问题

  • Cookie 登录仍然没有在「真实且未过期的会话」下跑通过一次。格式识别已经补齐,但手上那份导出里的 MSPAuth / MSPProf 都是 Disabled(登出状态留下的),验证不到最后一步
  • 令牌导入的账号 24 小时后必须重新导入,这是微软定的,没有绕法