Skip to content

Releases: november521/mcphone

MCphone NeoForge 1.21.1 v1.10.0

Choose a tag to compare

@github-actions github-actions released this 07 Sep 05:19

MCphone v1.10.0

这一版有两件大的。

一、手机上多了一格「终端」—— 点一下,你自己的存储终端就开出来。 Applied Energistics 2、Refined Storage、Tom's Simple Storage 三家都认,装了哪家就支持哪家,一家都没装的话这一格根本不会出现。手机里还多了个终端卡槽:装一台进去,以后点它就固定开这一台。

二、手机放进副手就挂到画面上。 一直亮着,停在哪一页就显示哪一页;按 Alt 唤出鼠标直接操作它,位置和大小自己摆。

运行环境: Minecraft 1.21.1 · NeoForge 21.1.200 或更高 · 客户端与服务端都需安装
可选: Curios —— 装了多一个手机槽
可选: Waystones(传送石碑)—— 装了多一个「传送石」App
可选: MCEF —— 装了多一个「浏览器」App
可选: NetMusic(网络音乐机)—— 装了唱片仓还收它刻的 CD
可选: Patchouli(教程手册)—— 装了多一个「阅读」App
可选: FTB Quests —— 装了多一个「任务书」App
可选: Applied Energistics 2 / Refined Storage / Tom's Simple Storage —— 装了任意一家就多一个「终端」App
可选: Integrated Dynamics —— 装了多任何东西,只让崩溃报告指认对人

从 1.9.x 升级: 直接替换 jar。存储格式没动——存档、好友、聊天记录、购买记录、App 安装状态、主屏图标位置、手机里的唱片全部原样保留。手机终端卡槽是这一版新加的玩家附件,老存档里它是空的,不需要任何迁移。

⚠ 服务端必须一起换。 这一版新增了一个网络包类型(「终端」那一格要用),而网络包的注册两端必须对称——1.10.0 的客户端进不去 1.9.x 的服务端,反过来也一样。这一条和 1.9.3 不同,那一版是纯客户端改动。

跳过了 1.9.4。 那个版本号做完了但一直没发,它的两件东西都在这一版里,见下面最后一节。


🖥 终端

主屏上多的这一格,干的就是一件事:把你自己那台终端打开

装了哪家 认得的东西
Applied Energistics 2 无线终端、无线合成终端、无线样板访问终端
├ 加装 AE2WTLib(AE2 无线终端) 它那些终端也全认,包括通用终端
Refined Storage 2 无线网格、无线自动合成监视器、便携网格
Tom's Simple Storage 高级无线终端

三家有一家就够。 一家都没装时这一格不上主屏、也不进应用商店——不会让你点到一个没反应的图标。装了哪几家,App 详情页的简介末尾会写出来。

免费。 末影箱那一格卖一个末影箱、传送石那一格卖一个传送石,因为 App 本身就是那件实物的替代品;这一格替代不了什么——它开的是你自己那台终端,没有终端它一格内容都没有。真正的门槛是那台终端,再收一次等于收两遍。

终端卡槽

点开「终端」:卡槽里装了终端就开那一台,卡槽空着就把卡槽界面摆到你面前——格子和背包挨着,拖进去就装好了。按住 Shift 点图标一律开卡槽(想换一台或者取出来走这条)。

它解决的是"身上带着好几台,到底开哪一台":答案从"背包顺序里第一台"变成**"你自己选的那一台"**。

卡槽是加成,不是替代。 终端可以一直留在背包里,卡槽那一页上的「打开终端」照样开得了它。这一条是刻意的:终端一旦被收进手机就不在背包里了,各家自己的快捷键(AE2WTLib 的补货/磁铁/收纳、RS 的打开无线网格)就找不到它——想用那些快捷键的人不装卡槽就是了,代价只是点开之后多按一下。

卡槽里的终端死了不掉,和壁纸、笔记、唱片仓里的唱片一样跟着你走。

范围、耗电、界面,一条都不是我们定的

这一格只做一件事:挑出你要开的那一台,然后按它自己的方式打开。所以:

  • 你在 AE2 / RS / Tom's 里的进度,自动就是你在这一格里的进度——插了增幅卡、绑了哪个网络、跨不跨维度,全按对方的规则来
  • 开不了的时候说话的也是它们(AE2 的 Device is not linked.、Tom's 的"终端不可达"之类),我们不在前面加自己的检查。加了的话两套规则迟早对不上,而对不上的表现是"手机上说不行、手里拿着又能开"

⚠ Tom's 的基础无线终端开不了,这不是 bug

那把终端的设计就是"瞄准范围内的终端方块右键",它压根没有"隔空打开"这回事(open() 的方法体是一句 return)。从手机上点它,字节码层面就是什么都不会发生。

所以这一版把它挡在外面:放不进卡槽,背包里带着它点「终端」会跳过并告诉你原因——比点了没反应强。要隔空开,用高级无线终端。


📱 副手 HUD:手机挂在画面上

手机拿在副手里就自动挂到 HUD 上,一直亮着,停在哪一页就显示哪一页——边走边看聊天、边挖矿边看任务书,不用一次次开机。

按 Alt 唤出鼠标就能直接操作它:翻页、点 App、在输入框里打字都行。按住的这段时间人走不动(原版界面一开就不吃移动键),松开回到走路。

挂着的和 Alt 里的是同一部手机,不是两块屏:你在 Alt 里翻到第三页,松手之后 HUD 上还是第三页。

手机挂在 Curios 饰品栏里时副手是空的,那种情况另给一个 G 键手动叫出来。两个键都能在「选项 → 按键设置 → MCphone」里改。

位置和大小自己摆。「设置 → 副手 HUD」里可以开关、调大小与位置;也能就地摆——拖边框或状态栏挪位置,滚轮缩放。

F1 藏 HUD 的时候它也跟着藏。

开关、大小、位置都是客户端设置,存在 config/mcphone-client.toml 里,跟着这台电脑走。


原本要发在 1.9.4 的两件

界面大小那两个加减键的符号对齐了。 原来画的是 (U+2212)和 +(ASCII)两个字符,各自在行高里的落点根本不是一回事:横着差一两像素,竖着差一整档,两个键并排摆着一眼就看得出来。改成画出来的两根杠,两个键的横杠现在逐像素相同,加号只是多一根竖的。顺带也不再受字体和资源包影响。

给附属作者堵了"踩裁剪"那个坑的三条路。 附属在自己的页面里调 graphics().enableScissor 而不是本体给的 PhoneCanvas.clipped只在界面倍数不是 100% 时才现形——附属作者在 100% 下怎么测都是好的,玩家却怪到附属头上。这一版:警告从 clipped 挪到了 graphics() 的文档上(该被提醒的正是只用 graphics() 的那个人)、AddonApiExamples 补了一个用 clipped 写的可滚动列表例子、本体在附属页面画完之后自检裁剪栈,脏了替它收掉并留一条日志(附属开了裁剪没关的话,这一帧之后整个游戏界面都会被切在它那个框里,而 GL 的 scissor 是跨帧的)。


给开发者

「终端」那三家的接入写在 docs/terminal-integration.md查实过的 API 入口表(全是 javap 出来的,不是抄文档)、每一家那条"错了不报错"的坑、许可表、测试清单,以及想再加一家要做什么。加一家的代价是 feature/terminal/integration/ 下一个包加一行 isLoaded

这一格原来是个独立附属(november521/mcphone-terminal,只发过 v0.3.0),这一版并了进来。理由:本体自己早就在做同一件事——传送石靠 Waystones、任务书靠 FTB Quests、阅读靠 Patchouli、浏览器靠 MCEF,"装了 X 就多一格"在这个仓库里的既定形态就是内建 App 加可选依赖。那个仓库已归档,v0.3.0 的 Release 留着不删。

MCphone Forge 1.20.1 v0.11.0

Choose a tag to compare

@github-actions github-actions released this 07 Sep 02:30

MCphone Forge 1.20.1 v0.11.0

这一版把 1.21.1 那一支 1.9.0 ~ 1.9.3 的四个小版本一次搬了过来。 上一版(0.10.2)
跟到的是那边的 1.8.19,此后那一支加了图片消息、每个 App 一个快捷键、界面大小这几样,
现在两支又对齐了。

运行环境: Minecraft 1.20.1 · Forge 47.4.0 或更高 · 客户端与服务端都需安装
可选联动一个没变:Curios、Waystones + Balm、MCEF、NetMusic、Patchouli、GuideME、FTB Quests。


⚠️ 先说清楚这一版验到哪儿

别把它当成熟版本用,而且这一版欠的比上一版多。

代码、专用服务端启动、两道构建期校验都是绿的,断言测试从 6 个加到 10 个
122,377 条全过;但新搬来的这五样一个像素都没在真游戏里看过

验了什么 怎么验的
存档格式(含老存档兼容)的往返 ChatMessageCodecTest,38 条断言
图片那三个包与会话摘要的线格式往返、上限两侧 ChatImagePacketTest,47 条断言
GIF 拆帧(局部帧、透明索引、隔行、延迟众数、抽稀) GifDecodeTest,33 条断言
压图、透明底、自动降档、按内容去重 ImageEncodeTest,55 条断言
服务端能起来、新配置项被吃下 runServerDone (7.338s)!,零 ERROR
声明的 Forge 下限(47.4.0)仍然编得过 ./gradlew compileJava -Pforge_version=47.4.0

完全没验的:发图与表情的界面、GIF 在别人手机上动起来、快捷键绑定与冲突提示、
界面大小那一页、相机的模糊闪光。

这台开发机没有显示环境,runClient 跑不起来——上面那几样全是要点着看的东西。
开个新存档试,别拿主力存档。 碰到问题请带上 logs/latest.log 开 issue。

多人游戏要两端都升。 这一版在聊天通道中间插了三个包,通道的协议号跟着 +1,
0.10.2 的客户端连 0.11.0 的服务端会被直接拒绝(这是刻意的:让它连上去只会解错包)。


📱 这一版多了什么

💬 美西螈能发图和表情了

输入栏左边多了一个「+」,点开有图片表情两项。

  • 图片就是相册:相机拍的、按 F2 截的都在里面,点一张就发出去。
    也可以直接把图片文件拖进游戏窗口——正开着会话时拖进来就是发给他。
  • 表情是你自己的表情包,放在 config/mcphone/stickers/,跟着客户端走。
    拖进窗口导入(一次能拖一整包),或者点那一页右上角的「打开文件夹」丢进去。
  • GIF 是动的。 拆成帧、拼成一张图传过去,播放在客户端。太大的自动降一档帧尺寸、
    再不行隔帧抽稀(至多 36 帧),实在塞不下就退回去发第一帧。
  • 收到的图点一下放大,右上角能存进相册(存的是原始文件)。
  • 发之前会压:长边 512 像素,体积由服主定上限(默认 512 KB)。

每对会话只留最近 20 张图,更早的图片消息还在记录里,显示成「已过期」——
不删那一行,是因为删掉之后聊天记录会凭空少几句。文字消息仍是每对 100 条。

⌨️ 每个 App 一个快捷键

「设置 → App 管理器 → 点开某个 App → 快捷键」,按一个键就绑上,
以后在世界里按它直接开机并进这个 App。

  • 键盘和鼠标键都能绑,包括侧键、中键、右键。左键除外,它是"算了"。
  • 支持组合键(Ctrl / Shift / Alt,可以叠)。触发要求完全一致:
    绑了 Ctrl+K,光按 K 不开,Ctrl+Shift+K 也不开。
  • 撞了车不拦你,但会先说一声——那一行变成「再按一次强制」并写明被谁占了。
  • 绑在鼠标键上的 App 打开时不会顺带挥手或用一次物品

存在 config/mcphone-client.tomlappHotkeys 里。

📐 界面大小

「设置 → 界面大小」把整个手机放大或缩小,75%–300%,拖那条或者点 − + 一档 25%。
原版的 GUI 缩放是全局的,这一项只管手机。

「贴合清晰倍数」默认开着:字是位图,GUI 缩放 × 界面大小 是整数时像素才方正,
所以档位自动对齐到 1/GUI缩放。关掉能拖到任意值,代价是笔画时粗时细。
窗口放不下时自动夹回去,配置里的数不动。

🗂 App 管理器重做

每个 App 一页:图标、名字、作者、版本、介绍、它是哪个模组给的
声明的前置与联动模组装没装。卸载要点两次,系统 App 的卸载键是灰的并写明原因。

这一页也是每个 App 自己开关的去处——第一个这样的开关是快捷键,第二个是下面这个。

📷 相机的快门闪光可以换成模糊

「设置 → App 管理器 → 相机 → 快门闪光」,在白闪模糊之间换。
白闪在夜里会把屏幕顶到全白,模糊那一版只是糊一下再收回来,亮度不变。
两种都不会进照片。存在 config/mcphone-client.tomlcameraSoftFlash 里。

🔧 顺带修的

  • 设置里四个页面滚不动:壁纸、App 管理器、App 详情、关于,
    内容超出一屏就再也看不见。
  • 相册与壁纸页多了「打开文件夹」,直接用系统的文件管理器开那个目录;
    壁纸那一页点过之后会盯着目录,拖进去的图切回游戏就看得见。
  • 动态图标的 partialTick 一直是 0,附属模组做不了平滑动画。

🖥 服主须知

存档的 serverconfig/mcphone-server.toml 多了两项(升级后自动补进去,不必手加):

默认 说明
allowChatImages true 关掉后图片键不再显示,服务端也拒收上传的图。已经发过的图不删
chatImageMaxKb 512 一张图最多多少 KB(64–768)

图片占多少硬盘chatImageMaxKb × 20(每对会话最多留 20 张不同的图)。
默认就是每对好友封顶 10 MB。这是最坏情况:Minecraft 的截图大片是天空与地形,
512 长边压出来常常只有 1 KB。图片按内容存,同一张表情反复发只占一份。

图存在世界存档的 mcphone/chat-images/ 下,做备份时别漏。
服务器启动时会扫一遍,删掉没有任何消息认领的孤儿文件。

这一支没有配置界面(Forge 1.20.1 没有内置的),这两项要手改文件。
手机自己那几项——字体配色、界面大小、快门闪光、快捷键——都在「设置」里点得到,
那是模组自己画的界面,不受影响。


🔧 与 1.21.1 那一支的差别

老的三条不变(唱片判定按 RecordItem 类判、没有配置界面、传送石按"拿着传送石"计价)。
这一版新增的差别玩家都感觉不到,逐条记在 docs/PORTING.md
「第七刀」一节里。挑两条值得知道的:

模糊闪光是自己拼的后处理链。 1.20.1 的 PostChain 没有 setUniform
所以这一支自带一份只声明中转贴图的链定义,两个 pass 用公开的 addPass 加进去,
着色器程序仍是原版那支。画出来是同一个效果,半径一样跟着时间收。

带上限的编解码补齐了发的那一侧。 1.21 那边 ByteBufCodecs.list(上限) 是收发
两侧都拦的;1.20.1 没有那套组合子,这一支原先九处只拦了收的那一侧。漏掉发的那一侧
不是少一道保险——超量的包会照发,由收方解码时抛,而那等于断开连接,症状是
"对方莫名其妙掉线"而错在发的那一端。现在两侧都拦,收进了一个 core/net/Wire

组合键在这边要自己数修饰键。 Forge 只有单数的 getActiveModifier()
它按 Ctrl → Shift → Alt 返回第一个按住的——照直译过来,Ctrl+Shift+K 会被认成
Ctrl,而且编译、绑定都正常,只有按下去不响应。这边逐个问,行为与那一支一致。


🙏 第三方

jar 里嵌着 JavaMP3(MIT,用于音乐 App 解码 mp3),
许可证全文见 jar 内的 THIRD-PARTY.txt

MCphone NeoForge 1.21.1 v1.9.3

Choose a tag to compare

@github-actions github-actions released this 06 Sep 17:00

MCphone v1.9.3

手机可以自己调大小了 —— 「设置 → 界面大小」,75% 到 300%,不用去动全局的 GUI 缩放。 换肤表里最后七个空位也补齐了,44 个位现在一张不缺。

运行环境: Minecraft 1.21.1 · NeoForge 21.1.200 或更高 · 客户端与服务端都需安装
可选: Curios —— 装了多一个手机槽
可选: Waystones(传送石碑)—— 装了多一个「传送石」App
可选: MCEF —— 装了多一个「浏览器」App
可选: NetMusic(网络音乐机)—— 装了唱片仓还收它刻的 CD
可选: Patchouli(教程手册)—— 装了多一个「阅读」App
可选: FTB Quests —— 装了多一个「任务书」App
可选: Integrated Dynamics —— 装了多任何东西,只让崩溃报告指认对人

从 1.9.x 升级: 直接替换 jar。这一版改的全在客户端,没动网络包,也没动任何存储格式——存档、好友、聊天记录、购买记录、App 安装状态、主屏图标位置、手机里的唱片全部原样保留。

服务端可以晚一步换。 网络包的注册版本仍是 1,包的种类也一个没变。


📐 界面大小

「设置 → 界面大小」多了一页:拖那条,或者点 − +,范围 75%–300%,默认 100%。改的时候整个手机(连同这一页自己)就在跟着变,所以不需要另做预览。

为什么不用原版的 GUI 缩放。 那一项是全局的:为了看清手机把它调大,聊天框、物品栏、所有界面都跟着变大。4K 屏配 GUI 缩放 2 时手机小得像块邮票,而调大 GUI 缩放又会让别的东西全都变笨重——这一档只管手机。

「贴合清晰倍数」默认开着。 字是位图、按最近邻画,所以每个像素方不方正只看一个乘积:GUI 缩放 × 界面大小。是整数就横平竖直,不是整数就有的列占两像素、有的占三像素,细线时粗时细。开着的时候档位自动对齐到 1/GUI缩放——缩放 2 是 100/150/200…,缩放 3 是 100/133/166…,缩放 4 是 100/125/150…,− + 一次正好走一档。关掉就能拖到任意值,代价就是上面那点不匀。

窗口放不下时自动夹回去,但配置里的数不动——窗口是随时会变的,一次临时的小窗口不该把你的设置永久改小;被夹着的时候那一页会写一行「窗口放不下,实际 xxx%」。

放大是整体缩放,不是重排布局:手机里所有东西的相对位置一点不变。这也是客户端设置,存在 config/mcphone-client.tomluiScale / uiScaleSnap 里,跟着这台电脑走。

🎨 换肤表补满:44 个位一张不缺

这一版补上最后七张自带图:

  • 浏览器工具条上的后退 / 前进 / 刷新。它们此前画的是 ◀ ▶ ↻ 三个字符,是整套界面里最后三处"没上贴图"的地方
  • 滑条那四件:槽、已填充、滑块、两端的 − + 键底。槽与填充带九宫格元数据(border: 2),拉伸时两端的圆头不会跟着抻长

同时给资源包开了七个新位browser/backbrowser/forwardbrowser/reloadsettings/slider_tracksettings/slider_fillsettings/slider_knobsettings/step_button)。滑条那四件刻意起的是通用名字:以后别的滑条也会用同一组,画一次就够。尺寸与替换规则见 README 的换肤表。

换肤文档里还补了一条以前没写清的规矩:贴图改不了颜色,状态只能靠亮度或透明度——悬停、点不动这类状态,没贴图时是换颜色画的,有了贴图那个颜色就再也看不见。所以模组在有贴图时改用别的表达(整张提亮、整张压暗、或者把高亮块画在贴图底下),画贴图的人不必自己去表达这些状态。

🧩 给附属模组作者

PhoneCanvas 新增 clipped(x, y, w, h, Runnable) ——做可滚动列表、长文本时用它来裁剪。

如果你的页面自己调过 canvas.graphics().enableScissor(...),请改用它。 原版那句收窗口坐标、而且不看 PoseStack,玩家一旦把界面调离 100%,你的裁剪框就会停在没缩放时的位置和大小上,文字被切掉一块——而且只在非 100% 时出现,很难查到自己头上。clipped 替你把矩形过一遍当前的变换矩阵,缩放几层都对,body 抛异常也会把裁剪收回去。

其余什么都不用改:PhoneCanvas 给的坐标和送进 mouseClicked / mouseScrolled 的鼠标坐标两边一起换算过了。详见 docs/addon-api.md

MCphone NeoForge 1.21.1 v1.9.2

Choose a tag to compare

@github-actions github-actions released this 06 Sep 15:10

MCphone v1.9.2

每个 App 都能绑一个快捷键了 —— 在世界里按一下,直接开机并进那个 App。 相机的快门白闪也可以换成「模糊一下」,界面贴图补齐了一大批。

运行环境: Minecraft 1.21.1 · NeoForge 21.1.200 或更高 · 客户端与服务端都需安装
可选: Curios —— 装了多一个手机槽
可选: Waystones(传送石碑)—— 装了多一个「传送石」App
可选: MCEF —— 装了多一个「浏览器」App
可选: NetMusic(网络音乐机)—— 装了唱片仓还收它刻的 CD
可选: Patchouli(教程手册)—— 装了多一个「阅读」App
可选: FTB Quests —— 装了多一个「任务书」App
可选: Integrated Dynamics —— 装了多任何东西,只让崩溃报告指认对人

从 1.9.x 升级: 直接替换 jar。这一版改的全在客户端,没动网络包,也没动任何存储格式——存档、好友、聊天记录(含图片)、购买记录、App 安装状态、主屏图标位置、手机里的唱片全部原样保留。

服务端可以晚一步换。 网络包的注册版本仍是 1,包的种类也一个没变,客户端 1.9.2 连 1.9.1 的服务端照常能用。


⌨ 每个 App 一个快捷键

「设置 → App 管理器 → 点开某个 App」里多了一行快捷键:点一下,然后按你想用的那个键——以后在世界里按它就直接开机并进这个 App,不必再「开机 → 找图标 → 点开」。

默认未指定,每个 App 各绑各的。绑过的键会写在管理器列表那一行的右边,一眼扫得完谁绑了什么。

键盘、鼠标键都行,包括鼠标侧键(4/5)、中键、右键——和原版「按键设置」里能绑的范围一样。左键除外,它在等键时是"算了":左键是你在手机里点东西的那只手,绑上去的话每挖一次方块都会开一次手机。绑在鼠标键上的 App 打开时不会顺带挥手或用一次物品

支持组合键:按住 Ctrl / Shift / Alt 再按主键,可以叠(Ctrl+Shift+K),鼠标键同样可以。触发要求完全一致:绑了 Ctrl+K,光按 K 不开,按 Ctrl+Shift+K 也不开——否则两个 App 分别绑这两个组合时,后者会连着前者一起响。Mac 上的 Command 就是这里的 Ctrl。

ESC 是清除,与原版「按键设置」里的意思一致,不用学第二套。

撞了车不拦你,但会先说一声。 一个组合已经被别的 App、或者被原版/别的模组的键位占着时,那一行会变成「再按一次强制」并写出被谁占的;再按同一个组合就照绑,之后那一行一直带个 ⚠。要说这一声是因为这套快捷键不出现在原版的按键设置界面里——真让「按 E 同时开背包和手机」默默发生,你日后查不出是谁干的。

顺带一提,加修饰键并不等于避开冲突:原版键位判要不要响应时不看你有没有按住修饰键,所以 Ctrl+E 照样连带开背包。真按下去时手机会把那条键位攒的点击倒掉,不至于等你关掉手机再补开一次背包。

绑定是客户端设置,存在 config/mcphone-client.tomlappHotkeys 里,跟着这台电脑走,换服务器、换存档都在。手机已经开着时按这些键不会切换 App:那时候你多半正在手机里打字。

附属模组不用做任何事,绑定按 App id 走,内建与附属一视同仁。

📷 快门闪光可以换成「模糊一下」

「设置 → App 管理器 → 相机」里多一行快门闪光,在白闪模糊之间点着换,默认还是白闪。

白闪是照相机的老习惯,但夜里或在暗处拍照时它会把整个屏幕顶到全白,眼睛得缓几秒;模糊那一版只是把画面糊一下再收回来,同样交代了"拍下来了",亮度不变。两种都不会进照片——闪光是抓完图之后才开始的。

模糊借的是原版菜单背景那条后处理链,不额外带着色器文件,半径跟着时间收,所以是化开又收回去,不是硬切一块糊画面。它不受你的「菜单背景模糊度」设置影响——把那一项调成 0 的人,这里照样看得到模糊。

🎨 界面贴图补了十八张

状态栏、主屏拖动时的空槽、两颗页码点、翻页提示条、商店的可点与不可点按钮底、浏览器的面板与工具条、阅读的搜索栏 / 标签 / 收藏与未收藏两颗星,加上聊天的两种气泡、输入栏底、消息通知底与未读角标——这些位以前只有兜底纯色,现在模组自带。资源包放同路径的图仍然照常覆盖。

气泡这类会被拉伸的底,圆角不再抻变形。 在 PNG 旁边放一份同名的 .png.mcmeta,内容 {"mcphone_skin": {"border": 3}},这张图就改走九宫格:四角按源图上那 3 个像素原样画,只有四条边和中间被拉伸,气泡多宽多高四个角都一样大。border 大于源图短边的一半时忽略,退回整张拉伸;不写这份元数据的老资源包什么都不用改。模组自带的两种气泡与输入栏用的就是这份元数据。

给资源包作者新开了三个位browser/backbrowser/forwardbrowser/reload(浏览器工具条上的后退 / 前进 / 刷新,建议 22×18)。模组暂时没有自带图,缺图时照旧画 ◀ ▶ ↻ 三个字符。

换肤文档里也补了一条以前没写清的规矩:贴图改不了颜色,状态只能靠亮度或透明度。悬停、点不动这类状态,没有贴图时是换一个颜色画的;一旦这个位上有了贴图,那个颜色就再也看不见。所以模组在有贴图时改用别的表达——导航键与商店按钮悬停是整张提亮,浏览器那三个键点不动时是整张压暗,音乐键与聊天的「+」把高亮块画在贴图底下。画贴图时不必自己去表达这些状态。

MCphone NeoForge 1.21.1 v1.9.1

Choose a tag to compare

@github-actions github-actions released this 06 Sep 11:58

MCphone v1.9.1

设置里那四个页面终于能滚了 —— 在此之前,超出一屏的内容不是"待会儿再看",是永远看不到。

运行环境: Minecraft 1.21.1 · NeoForge 21.1.200 或更高 · 客户端与服务端都需安装
可选: Curios —— 装了多一个手机槽
可选: Waystones(传送石碑)—— 装了多一个「传送石」App
可选: MCEF —— 装了多一个「浏览器」App
可选: NetMusic(网络音乐机)—— 装了唱片仓还收它刻的 CD
可选: Patchouli(教程手册)—— 装了多一个「阅读」App
可选: FTB Quests —— 装了多一个「任务书」App
可选: Integrated Dynamics —— 装了多任何东西,只让崩溃报告指认对人

从 1.9.0 升级: 直接替换 jar。这一版只改了客户端画界面的部分,没动网络包,也没动任何存储格式——存档、好友、聊天记录(含图片)、购买记录、App 安装状态、主屏图标位置、手机里的唱片全部原样保留。

服务端可以晚一步换。 网络包的注册版本仍是 1,包的种类也一个没变,所以客户端 1.9.1 连 1.9.0 的服务端照常能用。当然两边一致最省心。


🖱 病根:那四页压根没有"滚动"这个概念

不是滚轮没接上。feature/settings/ 下的页面里一个 scrollOffset 字段都没有,溢出的处理清一色是同一句:

if (y + rowH > bottom) break;   // 画不下就不画,也没有别的路能看到

手机屏幕的内容区只有 120×176,一屏放得下八行左右。于是:

页面 原来的上限 你因此看不到什么
App 管理器 8 行 纯本体就注册 11 个 App,默认安装下就有 3 个 App 在管理器里根本不存在。这一页还是 1.9.0 刚重做的
更换壁纸 2 行 × 2 列 = 4 张 第 5 张起看不见。而那个目录正是你自己往里丢图的地方,丢满是迟早的事——你只会以为那张图没被认出来
关于 画到底补个 联动模组列表被截断。这一页存在的理由就是回答"我怎么没有这个功能",答案恰好被截在 后面
App 详情 静默丢行 描述是附属自己写的、长度不由我们定;放不下时前置/联动那几行直接不画,你看不到自己缺的是哪个前置

壁纸页的注释里其实早写着「这一页的网格没有翻页,放不下的壁纸就是永远看不见」——当时拿它当论据去论证「打开文件夹」为什么要挤在标题行里,等于把 bug 写成了设计理由。那段注释一并改了。

🔧 怎么修的

没有发明第三套滚动。 项目里本来就有两套,照抄:

  • 等高列表用行索引NotesList 那套):App 管理器、壁纸网格(按行滚)
  • 长短不一的内容流用像素 + enableScissorChatConversation 那套):关于、App 详情

两套都把"一屏放得下几行"留到渲染时才算,再夹紧 offset——删一张壁纸、卸一个 App 之后列表会变短,不夹就会停在一片空白上。

关于页因此从静态类改成了实例(滚动是状态)。App 详情页的头部与卸载键不跟着滚:那个键得一直够得着。

两页没动:设置列表(5 项)和字体颜色(6 个预设)目前放得下十行,加了也是 maxScroll 恒为 0。等哪天加到溢出,按同一套补上即可。

MCphone NeoForge 1.21.1 v1.9.0

Choose a tag to compare

@github-actions github-actions released this 06 Sep 08:50

MCphone v1.9.0

美西螈能发照片和表情了 —— 输入栏左边一个「+」,图片与表情各一页,点一下就到对方手机上 从拍照到发出去、到对方点开看大图、再存回自己相册,中间不再需要任何别的模组或外部工具。

运行环境: Minecraft 1.21.1 · NeoForge 21.1.200 或更高 · 客户端与服务端都需安装
可选: Curios —— 装了多一个手机槽
可选: Waystones(传送石碑)—— 装了多一个「传送石」App
可选: MCEF —— 装了多一个「浏览器」App
可选: NetMusic(网络音乐机)—— 装了唱片仓还收它刻的 CD
可选: Patchouli(教程手册)—— 装了多一个「阅读」App
可选: FTB Quests —— 装了多一个「任务书」App
可选: Integrated Dynamics —— 装了多任何东西,只让崩溃报告指认对人

从 1.8.x(含 1.8.20)升级: 直接替换 jar。存档、好友关系、聊天记录、购买记录、App 安装状态、主屏图标位置、手机里的唱片全部原样保留。

聊天记录的存档格式动了,但两边都兼容:老存档照常读;新版本写下的文字消息仍是老格式,所以万一要把模组降回 1.8.x,文字聊天记录一条都不会丢(只有图片消息那几条读不出来)。这一点有断言测试守着,见 docs/ChatMessageCodecTest.java

服务端必须一起换。 图片走的是新增的网络包,也存在服务端;客户端新、服务端旧的话,那个图片键点了不会有任何反应。


➕ 输入栏左边那个「+」

点开是一张小菜单:图片表情

为什么是「+」而不是直接一个图片键:能发的东西不止一种,每多一种就在输入栏挤一个键的话,那条栏很快就没地方打字了。菜单是按枚举画出来的,往后再多一种(分享物品、发个坐标)只要加一项,高度、悬停、点击分派都不用改。

📷 图片 —— 从相册挑一张

「图片」点开就是相册的网格——相机 App 拍的、按 F2 随手截的,都在里面,点一张就发出去了。

也可以直接把图片文件拖进游戏窗口。 正开着会话时拖进来,等同于选了这张图发出去。从相册选图的前提是那张图已经在截图目录里,而想发的常常是刚从别处存下来的一张——拖进来一步到位。

😀 表情 —— 自己的表情包,导进来就能一直用

「表情」那一页盯着 config/mcphone/stickers/,那就是你自己的表情包。它跟着客户端走,换服务器、换存档都在,与书架收藏同一个道理。

导入两条路,都不弹系统窗口

  • 把图片拖进游戏窗口 —— 表情页开着时,拖进来是"收进目录"而不是"发出去",而且一次能拖一整包,全收
  • 点右上角「打开文件夹」 —— 用系统自己的文件管理器打开那个目录,你想丢多少丢多少

(不做 Java 的文件选择器是有理由的:那要初始化 AWT,而 AWT 在 macOS 上要和游戏抢主线程,是有名的崩溃源。)

导入之后点一下就发。同一张表情反复发,服务器上只存一份——图片是按内容存的(文件名是"会话键 + 图片字节"的哈希),第二次发连写盘都省了,也只占"每对会话 20 张"里的一个名额。表情就是靠这一条才发得起,它天生要被反复发。

png / jpg / jpeg / gif / bmp 都收,GIF 是动的(见下一节)。

收到的图直接就看得见,不是一行"[图片]"要你再点。点一下放大,铺满整块屏幕;再点一下(或者按导航栏的返回)收回去。手机屏幕只有 120×200,消息里那张最宽 80 像素出头——认得出是什么,看不清写了什么,所以放大这一手是必须有的。

图片不套气泡。 文字消息有气泡底,图片没有:真实的聊天软件里图片就是图片本身,谁发的靠左右对齐看得出来。套一层等于在图周围多画一圈没有意义的色块,而这块屏幕只有 120 宽,那一圈还要从图身上扣——现在那 6 个像素还给图了。

放大之后右上角有「保存」,存进相册(也就是截图目录)。存的是收到的原始 PNG 字节,不是屏幕上那张贴图——贴图是解码放大过的像素,从它反推不回原文件。存完立刻出现在相册里,也就能再转发给别人。

会话列表那一行显示成「[图片]」。这句话是客户端说的、不是服务端说的:服务端把那条消息原样发下来,显示成哪国语言由看的人的客户端决定——服主的服务端是英文的、玩家的客户端是中文的,这种事天天发生。

对方不在线也能发,与文字消息完全一样:图存进世界存档,他下次上线就看得见。

🎞 动图

拖一张 GIF 表情进来,发出去在对方手机上就是动的。

怎么传的:客户端把 GIF 拆成帧,拼成一张 PNG(所有帧排成方阵)发出去,消息里多带"几帧、每帧停多久"。这样一来上面所有的机制一个都不用改——还是一张 PNG、还是同一个体积上限、还是按内容去重(同一张动图表情反复发仍然只存一份)、服务端仍然不必解码任何图片。收件人也只上传一张贴图,播放就是按时间挑一个子矩形画出来,一张动图和一张静态图的开销几乎一样。

不转发原始 GIF 字节,是因为压不动:源文件常有一两百 KB,超了上限就得重新编码,而重编 GIF 要重新量化调色板,画质掉得比缩成 PNG 还厉害。

塞不下就一档档退:先降一帧的尺寸(160 → 128 → 96),再隔帧抽稀(每两帧、每三帧取一帧,剩下的每帧就多停几倍时间,不然会播成快进)。帧数封顶 36。抽到不成动画(少于 6 帧)就不硬撑了,退回去发第一帧——一张清楚的静态表情,好过一团看不出在动什么的马赛克。

拆帧不是"逐帧读出来"那么简单:GIF 的每一帧存的是与上一帧的差,可能只有画面的一小块,画完还要按 disposal 决定这一块留着、擦成透明、还是还原成上一帧。所以是自己铺一张画布一帧帧盖上去,每盖完拍一张快照(见 GifCodec)。

每帧不同的停留时间会被拉匀:取出现次数最多的那个值。GIF 允许逐帧不同,但把一串延迟塞进每条聊天消息会让消息本身胖一圈,而表情几乎都是匀速的。

表情页的格子里是第一帧,不动——一屏几十张同时动只会让人眼花。会话里才动。

动图存进相册的是第一帧:相册是给截图用的,那里躺一张雪碧图,别的软件都读不了。

📂 相册与壁纸页多了「打开文件夹」

点一下,用系统自己的文件管理器打开对应目录。要往相册里放几张图、想把刚存下来的那张翻出来发给别人、或者往 wallpapers/ 里丢一张壁纸,不必再自己一层层去找——表情那一页早就有这个键了,另外两页没有,是个疏漏。

目录不存在时先建出来再开:玩家点它的时候,相册与壁纸目录多半正是空的,而"路径不存在"这句话对他一点用都没有。

壁纸那一页还多一手:点过之后开始盯着目录,每秒重扫一次。不然这个键只完成一半——你点开文件夹、拖一张 PNG 进去、切回游戏,而这一页只在进来的时候扫过一次,那张图要退出去再进来才认,多半会以为没放成功。只在点过之后才盯:那是玩家说出"我要往里放东西"的唯一时刻。

两页的位置都是标题行右边,不另占一行。壁纸那一页尤其不能占:它的网格没有翻页,多一行正好把两行挤成一行,能选的壁纸从四张掉到两张。挤不下时截掉的是标题——玩家正是点着「更换壁纸」进来的,标题只是复述一遍,而这个键是这一页唯一的新功能。

🗜 发之前会先压

截图是全屏分辨率的,一张 1920×1080 的 PNG 常有两三 MB。原样发上去有两个问题:原版对客户端发给服务端的包有 32767 字节的硬上限,根本发不动;而且服主要替所有人存那么大的文件。

所以客户端先压:长边压到 512 像素,体积由服主定上限chatImageMaxKb,默认 512 KB),再切片按序发上去,服务端拼回来。

512 是照着"放大之后要多清楚"定的:消息里那张最宽 80 个 GUI 像素,只按它算 256 都嫌多;但图是点得开的,放大后铺满 112×170 个 GUI 像素,在 4 倍缩放下就是 448×680 个真实像素——到那儿 384 还要拉伸一点,512 则是原尺寸出头。

体积上限为什么交给服主:它直接换成硬盘(每对好友 = 上限 × 20 张)。一台十个人的私服和一台两百人的公服,愿意为聊天记录付的硬盘差着两个数量级,而这件事只有服主知道。客户端读到的是服主那一份——服务端配置会在玩家连上来时同步过来。

压完仍然超上限的(雨天、树叶、粒子这类噪点多的截图,PNG 压不动)会自动降一档尺寸重压(384 → 320 → 256 → 192);实在压不下来会在动作栏上告诉你换一张,而不是静悄悄地什么都没发生。实测一张纯随机噪点的 1920×1080:默认 512 KB 下原样发出去(512×288),把上限调到 128 KB 就会自动降到 256×144。而 Minecraft 真实截图那种大片天空与地形,512 长边压出来只有 1 KB,两个上限下都一样。

透明底保得住。 留不留 alpha 通道是按图判的:表情几乎全是透明底的 PNG,一律按不透明编码的话,透明的地方会变成纯黑——表情页里看着好好的,发出去带一圈黑框。截图没有透明像素,仍然不留那个通道,这条路上每个字节都要过网络。

一张只解码一次。 降档重压时不重新读盘解码——那是整条路上最贵的一步,一张 4096 的 PNG 解一遍就是一秒出头,四档各解一遍等于让玩家干等三四秒。读盘、解码、缩到最大那一档只做一次,往下几档都从那一张再缩(降档是为了压体积,不是为了更清楚,而 512→384 只有 0.75 倍,一次插值就够)。实测 2048 的噪点图从 1.27 秒降到 0.28 秒,4096 的从 3.58 秒降到 0.90 秒。

同一张只压一次。 压出来的结果只取决于文件内容,所以按"文件 + 改动时间 + 大小"把最近 8 张记住。表情天生要反复发同一张,第二次起直接拿现成的字节走——压缩那一段是 0 毫秒。

一次只发一张,点快了的排队。 同时只允许一次上传:压缩是异步的,两次上传交错着发上去,而服务端按"片号必须连续"收,交错的结果是两张都发不成。但"这会儿不能发"不等于"当你没点过"——冷却期里点的那几张排着(至多 4 张),闸一开自己走。发送期间那个「+」画得淡一些(意思是上一张还在路上,你照样能点),排满了才真的点不动。

🚫 为什么不走图床

同类的聊天模组多半是另一条路:图片传到公网图床(uguu.se 之类),聊天里发一串
[[CICode,url=...]],收到的人按 URL 去下载。那条路有一个我们给不起的好处——不需要服务端
任何服务器都能用;也有三个我们不愿付的代价:

  • 图离开了游戏。传上去的是玩家的截图,落在一个谁都能读的公网地址上;那类模组的说明里
    通常直接写着"请勿发送敏感或私密内容"
  • 链接会过期(常见的免费图床是几小时)。聊天记录还在,图全成了死链——而我们这边过期的是
    像素、消息还在,且保留的是最近 20 张而不是三小时
  • 多一个必须能连上的第三方。图床挂了、或者玩家的网络到不了它,发不了也看不了;而 MCphone
    只依赖玩家此刻已经连着的那台服务器

我们本来就要服务端(好友关系、离线消息都在那儿),所以把图留在服务器里是顺理成章的,
换来的是隐私、持久、以及"只有会话双方要得到"的访问控制。

⏳ 每对会话只留最近 20 张【不同的】图

图片是留在存档里的,不像传送那样做完就完了。所以有一道上限:每对会话保留最近 20 张不同图的像素,再往前的图片消息留着那一行,但显示成「已过期」

数的是"不同的图"而不是"图片消息":同一张表情发二十次只占一个名额,因为它在硬盘上本来就只有一份。挤掉谁按"最久没再发过"算——刚刚还在发的那张表情永远是新的。

为什么不把整条消息删掉:删掉之后聊天记录会凭空少几句,而少的是什么谁也想不起来。显示成「已过期」至少说清了这里本来有张图。

文字消息不受这条限制,仍然是每对会话 100 条。

🖼 像素是"看到了才去要"的

一条消息里只有图片的 id,不含像素。玩家翻到哪一张,客户端才去要哪一张——一个会话最多 100 条消息,一进去就全下载等于几百 KB 的突发流量,而他多半只看得见最后两三张。

要的时候是攒一批一次要(至多 4 张):服务端对拉取类的包有 500 毫秒限流,一次一张地要,一屏三张图要一秒半才凑齐。要过没回音的会隔 6 秒再要一次——包可能正好撞上限流被丢掉,而客户端无从知道。

自己刚发出去的那张不会再下回来:上传的那几个字节直接进客户端缓存,回声一到就用上了。

贴图缓存最多 24 张,超出按最久没显示的逐出并归还显存;手机一关全部释放。

🔒 服主那一头

新增一个配置项serverconfig/mcphone-server.toml):

默认 关掉之后
allowChatImages true 输入栏那个图片键不再显示,服务端也拒收上传的图。已经发过的图不删,仍然看得见
chatImageMaxKb 512 一张图最多多少 KB(64–768)。客户端按它压、服务端按它收,直接决定硬盘

硬盘怎么算chatImageMaxKb × 20(每对会话至多 20 张不同的图)。默认 512 KB 就是每对常聊的好友封顶 10 MB,200 对是 2 GB 上限——那是最坏情况,正常截图离它很远(真实截图压出来只有 1 KB 量级)。嫌大就把这个数调小:客户端会自动降一档尺寸重压,动图先掉帧再退成静态图,功能不坏,只是画质让路。

图片存在世界存档的 mcphone/chat-images/,一张一个文件——不放进聊天记录那份 SavedData 里,是因为那份东西整份常驻内存、每次保存整份重写,而图片只在有人正好翻到那条消息时才被读一次。

服务器启动时扫一遍孤儿文件:图写完了、消息还没落盘就崩了的话,那个文件再没人认领。一次崩溃留一两个文件不算什么,但服务器会崩很多次,而没人会记得去清。

几道闸,都在服务端:

  • 发图片每人 2 秒一张RequestThrottle)。这不是"防手快",是防有人拿聊天当上传通道;被拦下时会明说"缓一下",不静默丢弃
  • 只有好友之间能发,与文字消息同一道校验,手机也得在身上
  • 要一张图时校验的是"这张图出现在你和他的那段记录里"——知道 id 也要不走别人的图
  • 服务端不解码图片(解码是客户端的事),但会看一眼文件头是不是 PNG、它自己声明的宽高在不在上限之内。真正的解码防线在客户端,用的是纯 Java 的 ImageIO 而不是原生解码器——那段字节是别的玩家发来的
  • 越界的宽高一律夹到合法区间而不是抛异常:抛的话,伪造客户端发一个宽 20 亿的包就能让收件人掉线,挨罚的是无辜的那一方

写盘与读盘都在后台线程,主线程只做校验与落消息。

🧱 顺带整理的几处

  • 消息正文抽成了 MessageBody(文本 / 图片各一个实现,种类登记在 MessageKind)。再加一种消息——分享物品、发个坐标——只要写一个实现类、在那张表上登记一行,存档、网络包、会话列表预览、通知横幅全都自动认得它,已有的两种一个字节都不用动
  • 读图、缩图、上传贴图收进 ImageCodec 一份。相册读的是硬盘上的截图,美西螈读的是网络上来的字节,中间那几步(逐级减半缩放、ARGB→ABGR、尺寸要在 register 之前取)一模一样,而每一步都有不写下来就会踩的坑
  • 照片网格收进 PhotoGridPainter 一份,相册与"选一张发给好友"那一页共用:格子多宽、几列、缓存要顶到多大,都是"改一处必须同时改另一处"的数
  • 照片网格与目录扫描又抽出一层ImageFolder(一个"装着图的目录":扫描、缩略图、LRU、导入、删除)现在同时给相册和表情用,两页共用一份实现;「挑一张发出去」那一页也是同一个类的两个实例,只是盯着不同的目录
  • 新增换肤位 chat/attach.png(9×9,缺图时画 + 字符)

给服主

这一版新增两个配置项allowChatImageschatImageMaxKb)、新增三个网络包(上传一片、要图、发图),新增一个存档目录mcphone/chat-images/)。聊天记录的格式向前向后都兼容,见开头那一段。服务端与客户端必须同时更新。

MCphone NeoForge 1.21.1 v1.8.20

Choose a tag to compare

@github-actions github-actions released this 05 Sep 12:57

MCphone v1.8.20

这一版只补账。 1.8.1 到 1.8.19 十九个补丁版从来没有过发版说明——发版说明一个文件对应一个
次版本,而 v1.8.0.md 是 1.8.0 发布当天写的,之后一路走到 1.8.19,玩家在 Modrinth 与 CurseForge
上只看得到一行 tag 标题。其中还夹着「新建世界开手机一片空白」这种真会撞上的 bug。这里一次写全。

代码与 1.8.19 一模一样,差别只有版本号本身。装着 1.8.19 的不必更新;这个 tag 存在的
唯一理由,是让下面这些字有地方发出去。

运行环境: Minecraft 1.21.1 · NeoForge 21.1.200 或更高 · 客户端与服务端都需安装
可选: Curios —— 装了多一个手机槽
可选: Waystones(传送石碑)—— 装了多一个「传送石」App
可选: MCEF —— 装了多一个「浏览器」App
可选: NetMusic(网络音乐机)—— 装了唱片仓还收它刻的 CD
可选: Patchouli(教程手册)、沉浸工程、GuideME —— 各自往「阅读」里添几本书
可选: FTB Quests —— 装了多一个「任务书」App
可选: Integrated Dynamics —— 装了多任何东西,只让崩溃报告指认对人

从 1.8.0 升级: 直接替换 jar。存档、好友关系、聊天记录、购买记录、App 安装状态、主屏图标位置、
手机里的唱片全部原样保留——这十九个补丁版没动过任何存储格式。


📌 1.8.1 → 1.8.19,这些日子里发生了什么

修的

  • 新建世界开手机有几率一片空白,一个 App 都没有(1.8.19)。成因在 SPI 扫描那句
    ServiceLoader.load(service):单参那个重载用的是当前线程的 context classloader,而扫描
    是从 FMLClientSetupEvent 触发的,跑在 modloading-worker 线程上;那个线程的 TCCL 是从
    "碰巧创建这个 worker 的线程"复制来的,而 worker 是按需惰性创建的——赶上一个看不见
    META-INF/services 的,这一轮一个服务都扫不到,还不报错。这正好解释了"有几率"和"难复现"。
    现在传本模组自己的类加载器,与线程无关。顺带补了第二道:原先是进门就落锁,只要有一轮
    扫空,整局就再也不重扫,玩家重进世界都治不好、只能重启游戏;现在扫出东西了才落锁
  • 「任务书」那一格不再因为一次异常就永久点不开(1.8.11)。抛出来的多半是 FTB 自己界面里
    一时的问题(某个任务图标坏了、档案正好重载到一半),而原来的写法会把那一格从此禁用
  • 模组装齐的玩家进商店「联动App」页不再是空的(1.8.17)。这是 1.8.13 ~ 1.8.16 把内建 App
    改成联动声明时带出的回归

加的

  • 「阅读」分成书架与书城两页,行右端的 ☆ 管收藏,收藏落在 config/mcphone/reader/shelf.json(1.8.2、1.8.3)
  • 外部手册白名单,为不用 Patchouli 的手册留一条路;沉浸工程的工程师手册第一个进来(1.8.4、1.8.5)
  • GuideME 书源:AE2 与现代化工艺的手册自动进书城(1.8.9)
  • 「任务书」App:主屏一格直接开 FTB 任务书,不用再让它占着快捷栏(1.8.10)
  • 商店的「联动App」页说得出缺的是哪个模组(1.8.12)

改的

  • 接口分出**「联动模组」与硬前置两层**(1.8.6):阅读、任务书、浏览器、传送石依次改成联动声明,
    缺了对方只是少那一格,而不是整个手机起不来(1.8.7、1.8.13、1.8.15、1.8.16)
  • 「阅读」换上新画的书图标,旧那张归了「任务书」(1.8.1、1.8.18)
  • 发版时同时发到 Modrinth 与 CurseForge,不再只发一边

以后不会再这样

补丁版发出去时,说明跟着一起发:规矩记在 gradle.properties 的版本号那一段里,与"什么时候升
哪一位"写在同一处——那是发版前必然会看的地方。攒到下一版一起补,就是这一版存在的原因。

MCphone NeoForge 1.21.1 v1.8.19

Choose a tag to compare

@github-actions github-actions released this 04 Sep 15:35

Full Changelog: v1.8.18...v1.8.19

MCphone Forge 1.20.1 v0.10.2

Choose a tag to compare

@github-actions github-actions released this 29 Aug 09:40

MCphone Forge 1.20.1 v0.10.2

这是 MCphone 移植到 Minecraft 1.20.1 + Forge 的第一个发布版本。 1.21.1 那一支的功能已经全部搬过来了 —— 14 个 App、七个模组联动、三十多个网络包,一样不缺。

运行环境: Minecraft 1.20.1 · Forge 47.4.0 或更高 · 客户端与服务端都需安装
可选: Curios —— 装了多一个手机槽,手机能挂腰上
可选: Waystones(传送石碑)+ Balm —— 装了多一个「传送石」App
可选: MCEF —— 装了多一个「浏览器」App
可选: NetMusic(网络音乐机)—— 装了唱片仓还收它刻的 CD
可选: Patchouli(教程手册)—— 装了「阅读」里多它那批手册
可选: GuideME —— 同上,AE2 那批手册
可选: FTB Quests —— 装了多一个「任务书」App
可选: Integrated Dynamics —— 装了多任何东西(这一支上它是预防性的,见下)


⚠️ 先说清楚这一版验到哪儿

别把它当成熟版本用。 这一支的代码、专用服务端启动、两道构建期校验都是绿的,
6 个断言测试 122,204 条全过;但界面这一层只在真游戏里点过一部分

验过了 传送石(开界面 + 真的传送成功)、书城列书、缺 MCEF 时浏览器正确隐藏、开机与主屏
还没验 聊天、记事本、音乐、相册、相机、应用商店、末影箱、设置、时钟、天气、任务书
完全没验 浏览器真正打开网页(要装 MCEF)、NetMusic 的 CD、FTB 任务书

三十多个网络包是一次性挂上通道的,序号分配与两端握手目前只在专用服务端上"看着对"。
开个新存档试,别拿主力存档。 碰到问题请带上 logs/latest.log 开 issue。

1.0.0 留给"每个 App 都在游戏里点过"之后。

📱 这一支有什么

与 1.21.1 那一支功能等价:

  • 开机:右键手机,或用快捷键(手上、背包、饰品槽都找得到)
  • 14 个 App:设置、应用商店、聊天、相机、相册、音乐、末影箱、记事本、传送石、浏览器、时钟、天气、阅读、任务书
  • 壁纸、设备名、字体配色、好友与聊天记录、笔记、已购 App 都随存档走

🔧 与 1.21.1 那一支的差别

绝大多数是看不见的(网络层、玩家数据、注册表在两个版本上是完全不同的 API),
但有两处玩家能感觉到

唱片判定变严了。 1.21 那边查的是 JUKEBOX_PLAYABLE 数据组件,所以别的模组、
甚至只靠 json 定义的唱片它都认得。1.20.1 上没有那个组件,曲长与音效直接挂在
RecordItem 这个类上,只能按类型判 —— 别的模组若没继承 RecordItem 而是自己
实现一套,这边就认不出来
。这是 1.20.1 的天花板,不是偷懒。

配置界面还没有。 1.21 那边挂的是 NeoForge 自带的配置界面,Forge 1.20.1 没有内置的。
配置文件本身照常工作(config/mcphone-client.toml 与存档里的 mcphone-server.toml),
只是暂时得手改。

📝 版本号说明

刻意不追 1.21.1 那一支的 1.8.x。 玩家看版本号判断的是"这一支有多完整",
两支功能不等价的时候用同一个号等于骗人。这一支从 0.1.0(骨架)走到 0.10.2,
号段是它自己的。

🙏 第三方

jar 里嵌着 JavaMP3(MIT,用于音乐 App 解码 mp3),
许可证全文见 jar 内的 THIRD-PARTY.txt

MCphone NeoForge 1.21.1 v1.8.18

Choose a tag to compare

@github-actions github-actions released this 27 Aug 06:31