Author SHA1 Message Date
copilot-swe-agent[bot]andGlavo 6a8ea72d82 Replace two-level lists with bold section headers in changelog files
continuous-integration/drone/push Build is passing
Agent-Logs-Url: https://github.com/HMCL-dev/HMCL-docs/sessions/85dd9646-e48a-449e-90ed-93535a3be5dd

Co-authored-by: Glavo <20694662+Glavo@users.noreply.github.com>
2026-04-24 12:40:18 +00:00
copilot-swe-agent[bot] 8824bd509d Initial plan 2026-04-24 12:36:31 +00:00
neveler d92735a4e6 修正更新日志中错误将 Copilot 列为贡献者的问题 (#438)
continuous-integration/drone/push Build is passing
2026-04-20 18:53:40 +08:00
neveler e0303cb44a 修复 hits url tag 参数被二次编码的问题 (#452)
continuous-integration/drone/push Build is passing
2026-04-20 11:26:21 +08:00
neveler 8b05643a2f 自动识别 GP / GC 标记并生成对应链接 (#436)
continuous-integration/drone/push Build is passing
2026-04-19 07:25:51 +08:00
Glavo 5101a59793 Add 3.14.0.341 changelog (#454) 2026-04-18 21:36:35 +08:00
Glavo c5c8d64e7e Add 3.13.1 changelog (#453)
continuous-integration/drone/push Build is passing
2026-04-17 20:42:49 +08:00
neveler 0907ca4b6e 优化 document 布局内容 (#423)
continuous-integration/drone/push Build is passing
2026-04-17 07:52:37 +08:00
neveler 493d605495 优化设置页 (#421)
continuous-integration/drone/push Build is passing
2026-04-16 17:31:10 +08:00
neveler f2dbe9e57a 临时禁用磁盘缓存 (#451) 2026-04-16 17:02:19 +08:00
neveler f0a110fc20 添加 kramdown_enhancer 插件 (#435)
continuous-integration/drone/push Build is passing
2026-04-16 15:13:23 +08:00
neveler 0278979106 减少集合列表页的最大列数 (#427)
continuous-integration/drone/push Build is passing
2026-04-13 08:50:00 +08:00
neveler 45e412eafc 移除页脚的 “关注” 字样 (#429) 2026-04-13 08:49:44 +08:00
Glavo e7004603ba Add 3.13.0.340 changelog (#450)
continuous-integration/drone/push Build is passing
2026-04-11 21:04:40 +08:00
Glavo ad5cf6db1a Add 3.13.0.339 changelog (#449)
continuous-integration/drone/push Build is passing
2026-04-08 20:47:41 +08:00
neveler cdadbdb980 Bump nokogiri to 1.19.1 (#426)
continuous-integration/drone/push Build is passing
2026-04-07 16:14:20 +08:00
neveler b996c7d627 优化 offline-skin 文章 (#425) 2026-04-07 16:11:58 +08:00
50 changed files with 1326 additions and 596 deletions
+2 -1
View File
@@ -10,8 +10,9 @@ concurrency:
group: pr-preview
cancel-in-progress: false
env:
GITHUB_PR_NUMBER: ${{ github.event_name == 'issue_comment' && github.event.issue.number || github.event.pull_request.number }}
JEKYLL_ENV: production
ENABLE_WEBP_AUTO_CONVERSION: "true"
GITHUB_PR_NUMBER: ${{ github.event_name == 'issue_comment' && github.event.issue.number || github.event.pull_request.number }}
jobs:
cache-refresh:
if: ${{ !github.event.repository.fork && github.event_name == 'schedule' && github.event.schedule == '0 0 */6 * *' }}
+1 -2
View File
@@ -32,5 +32,4 @@ gem "wdm", "0.2.0", :platforms => [:windows]
gem "http_parser.rb", "0.8.0", :platforms => [:jruby]
# plugin dependencies
gem "nokogiri", "1.18.10"
gem "addressable", "2.8.7"
gem "webp-ffi", "0.4.0" if ENV["ENABLE_WEBP_AUTO_CONVERSION"] == "true" || ENV["DRONE"] == "true"
+1 -1
View File
@@ -5,7 +5,7 @@
- GP-5854: 将 twelvemonkeys 更新至 3.13.1 (by Glavo)
- GP-5855: 将 HelloNBT 更新至 0.3.0 (by Glavo)
- GP-5601: 下载页面折叠快照 Minecraft 版本 (by 辞庐,Copilot,Glavo)
- GP-5601: 下载页面折叠快照 Minecraft 版本 (by 辞庐, Glavo)
- GP-5703: 更新更新渠道选择选项 (by 辞庐, 3gf8jv4dv, Glavo)
- GP-5851: 优化读取 JAR/ZIP 文件时的性能 (by Glavo)
- GP-5860: 更新种子地图、要塞地图、下届要塞地图和末地城地图链接以支持 26.1 (by neveler)
+6
View File
@@ -0,0 +1,6 @@
---
---
[详细版本介绍 (Bilibili)](https://www.bilibili.com/opus/1188905221714083844)
- GP-5928: 支持在 FreeBSD x86-64、Linux Arm64、Linux LoongArch64 和 Linux RISC-V64 平台上启动 Minecraft 26.2-snapshot-1+ (by Glavo)
+12
View File
@@ -0,0 +1,12 @@
---
---
[详细版本介绍 (Bilibili)](https://www.bilibili.com/opus/1190023991956340740)
- GP-5930: 增强对 Vulkan 的支持 (by Glavo, 3gf8jv4dv)
- GP-5931: 支持将新格式快照版本号翻译为文言 (by Glavo)
- GP-5934: 更新游戏内容下载页游戏版本列表至 26.1.2 (by Glavo)
错误修复:
- GP-5935: 修复日志窗口可能意外的显示横向滚动条的问题 (by Glavo)
+14
View File
@@ -0,0 +1,14 @@
---
---
[详细版本介绍 (Bilibili)](https://www.bilibili.com/opus/1192630259688669201)
- GP-5940: 支持更多 Vulkan 渲染器 (by Glavo) [BV1Nhd5B9ENc](https://bilibili.com/video/BV1Nhd5B9ENc)
- GP-5945: 增大自动安装界面加载器名称版本号间距 (by 辞庐)
- GP-5949: 上传微软账户皮肤时校验大小 (by 辞庐)
- GP-5944: 优化菜单分隔符颜色 (by 辞庐,Glavo)
- GP-5946: 隐藏 CurseForge 源中游戏内容的不重要标签 (by 辞庐)
错误修复:
- GP-5943: 修复模组名字过长时下载页面布局异常的问题 (by 辞庐)
+7 -7
View File
@@ -9,10 +9,10 @@
- GP-3490: 修复 OAuth 登录时轮询过于频繁的问题
- GP-3464: 修复在更新日志界面无法拖动启动器窗口的问题
- GP-3503: 使用 Zink 渲染器时禁用 DRI3
- GC-`5fd52bb`: 皮肤缓存不再保存到 .minecraft 目录
- GC-`d5408c3`: 版本特定游戏设置从全局设置复制
- GC-`81b3911`: 修复按 ESC 键时文本框内的值没有保存的问题
- GC-`260f4b6`: 修复输入对话框中 ESC 键不起作用的问题
- GC-`7d12ef6`: 修复内存滑块提示被设备内存进度条覆盖的问题
- GC-`78e15d1`: 修复游戏设置中内存没有实时刷新的问题
- GC-`6f53da1`: 完善模组下载界面
- GC-5fd52bb: 皮肤缓存不再保存到 .minecraft 目录
- GC-d5408c3: 版本特定游戏设置从全局设置复制
- GC-81b3911: 修复按 ESC 键时文本框内的值没有保存的问题
- GC-260f4b6: 修复输入对话框中 ESC 键不起作用的问题
- GC-7d12ef6: 修复内存滑块提示被设备内存进度条覆盖的问题
- GC-78e15d1: 修复游戏设置中内存没有实时刷新的问题
- GC-6f53da1: 完善模组下载界面
+1 -1
View File
@@ -10,6 +10,6 @@
错误修复
- GP-3252: 修复无法补全部分第三方 Minecraft 客户端游戏资源的问题
- GC-`56d20a5`, GC-`397edae`: 修复 Linux 平台调整窗口大小的问题
- GC-56d20a5, GC-397edae: 修复 Linux 平台调整窗口大小的问题
- GP-3531: 修复在 FreeBSD x86-64 平台未正确替换 LWJGL 本地库的问题
- GP-3541: 修复安装 MultiMC 整合包后没有设置图标的问题
+1 -1
View File
@@ -12,4 +12,4 @@
- GP-3594: Java 下载对话框中切换包类型时不应重置版本字段
- GP-3598: 修复使用自定义字体时未正确设置字重的问题
- GP-3602: 修复使用系统 GLFW/OpenAL 时无法启动部分游戏版本的问题
- GC-`ecafc9d`: 修复安装新游戏页面中组件框的高度问题
- GC-ecafc9d: 修复安装新游戏页面中组件框的高度问题
+20 -10
View File
@@ -3,7 +3,8 @@
[详细版本介绍 (Bilibili)](https://www.bilibili.com/opus/1158118032843735049)
- 启动器
**启动器**
- GP-4289: 在添加游戏目录页面选择目录时自动填写名称 (by Dime, 辞庐, Glavo)
- GP-4882: 取消部分控件的连点限制 (by 辞庐)
- GP-5024: 使用副标题显示重启生效提示 (by neveler)
@@ -25,32 +26,41 @@
- GP-5143, GP-5168: 优化对获取账号信息时发生 SSL 异常的处理 (by Xirren, 3gf8jv4dv)
- GP-5182: 支持重置日志字体 (by 辞庐)
- GP-5188: 仅在左键点击时触发 `JFXRippler` 波纹 (by Glavo)
- 实例管理
**实例管理**
- GP-5059: 调整实例管理页面“浏览”菜单中条目的顺序 (by 3gf8jv4dv)
- GP-5137: 允许重命名实例时使用原名 (by mineDiamond)
- GP-5174: 优化存在大量实例的情况下的实例列表性能 (by Glavo)
- 模组管理
**模组管理**
- GP-4832: 支持更新选中的模组 (by ZZZank)
- GP-5016: 刷新模组列表不滚动到顶部 (by OrzMiku)
- 世界管理
**世界管理**
- GP-4823: 优化世界管理界面和世界信息界面 (by mineDiamond, 3gf8jv4dv)
- GP-5162: 优化存在大量数据包的情况下数据包管理页面的性能 (by mineDiamond)
- GP-5224: 优化存在大量世界的情况下世界管理页面的性能 (by Glavo)
- 整合包
**整合包**
- GP-4897: 导出整合包时隐藏系统资源文件 (by Calboot)
- GP-5119: 安装 Modrinth 整合包时下载图标 (by Glavo)
- 账户
**账户**
- GP-4794: 优化微软登录页面 (by 辞庐, 3gf8jv4dv)
- 下载
**下载**
- GP-5026: 限制访问 CurseForge/Modrinth 时的并发数 (by Burning_TNT)
- GP-5180: 在资源包下载页面中隐藏不必要的标签 (by Glavo)
- GP-5160: 优化下载页面中来自 Modrinth 的内容标签显示 (by ENC_Euphony)
- GP-5211: 优化下载页面图标缓存功能 (by Glavo)
- 联机
**联机**
- GP-4929: 将陶瓦联机更新至 0.4.1 (by Burning_TNT)
- 本地化
**本地化**
- 优化软件文案,修订翻译 (by 3gf8jv4dv)
- 错误修复
**错误修复**
- GP-5034: 修复下载光影时对话框的标题文字错误的问题 (by Wulian233)
- GP-5043: 修复导出整合包有关以及 NBT 文件查看有关的界面样式及深色模式问题 (by Calboot)
- GP-5064: 修复弹出菜单在 HiDPI 显示器上播放动画过程中内容 Y 轴方向缩放异常的问题 (by Glavo)
+18 -9
View File
@@ -3,7 +3,8 @@
[详细版本介绍 (Bilibili)](https://www.bilibili.com/opus/1169614354625069063)
- 启动器
**启动器**
- GP-5391: 将 XZ for Java 更新至 1.11 (by Glavo)
- GP-5390: 将 TwelveMonkeys 更新至 3.13.0 (by Glavo)
- GP-5392: 将 Gradle Shadow 插件更新至 9.3.1 (by Glavo)
@@ -17,24 +18,30 @@
- GP-5462: 未安装实例时点击主页“开始游戏”按钮不选择不支持当前平台的版本 (by 辞庐, Glavo)
- GP-5467: 自动展开 NBT 查看器中部分子标签 (by Calboot)
- GP-5527: 增加弹窗图标与内容间距 (by 辞庐)
- 游戏设置
**游戏设置**
- GP-4975: 调整渲染器名称 (by Chen Meng)
- 模组管理
**模组管理**
- GP-5029: 优化检查模组更新功能 (by Burning_TNT)
- GP-5196: 使用 Forge/Quilt 加载器时模组管理页面应当扫描子文件夹 (by Wulian233)
- GP-5296: 扫描模组子目录时忽略 `.connector` 文件夹 (by 辞庐)
- 世界管理
**世界管理**
- GP-5215: 优化世界管理与世界信息页面 (by mineDiamond, 3gf8jv4dv, Glavo)
- 账户
**账户**
- GP-5330, GP-5531, GP-5538: 优化微软登录流程,更新微软账户登录对话框 (by 辞庐, 3gf8jv4dv, Glavo)
- 下载
**下载**
- GP-4792: 优化 Fabric API / Quilt API 安装提示 (by 辞庐, 3gf8jv4dv)
- GP-5090: 支持 Legacy Fabric 自动安装 (by 辞庐)
- GP-5250: Modrinth 默认不获取更新日志 (by Calboot)
- GP-5304: 取消游戏下载页面中高版本游戏对 Windows 7/8/8.1 的不兼容提示 (by 辞庐)
- GP-5394: Java 下载页面支持选择多个 Java 版本下载 (by NoClassDefFoundError, Glavo)
- GP-5465, GP-5474: 优化下载页面条目中标签的展示方式 (by Glavo)
- 外观
**外观**
- GP-5279: 更新下载页面条目样式 (by Glavo)
- GP-5283, GP-5317, GP-5319: 优化深色模式支持 (by Glavo)
- GP-5292, GP-5398: 更新文本输入框的右键菜单样式 (by 辞庐)
@@ -46,9 +53,11 @@
- GP-5422: 优化日志窗口无日志行的背景色 (by 辞庐)
- GP-5456: 优化工具栏按钮图标 (by Glavo)
- GP-5481: 优化设置页面检查更新设置项的样式 (by Glavo)
- 本地化
**本地化**
- 优化软件文案,修订简繁英翻译,清理过时翻译 (by 3gf8jv4dv)
- 错误修复
**错误修复**
- GP-5012: 修复 Modrinth 模组依赖已经被删除的条目时无法加载版本列表的问题 (by Burning_TNT)
- GP-5195: 修复导出 Modrinth 整合包时勾选“包含启动器”选项时导出的整合包不是 ZIP 格式的问题 (by 辞庐)
- GP-5245: 修复主页公告阴影被裁切的问题 (by 辞庐)
+6 -3
View File
@@ -3,10 +3,13 @@
[详细版本介绍 (Bilibili)](https://www.bilibili.com/opus/1188175055790538753)
- 启动器
**启动器**
- GP-5870, GP-5873, GP-5874, GP-5882: 优化 Minecraft 26.1 性能 (by Glavo, 3gf8jv4dv) [BV1mPXSBEEBx](https://www.bilibili.com/video/BV1mPXSBEEBx)
- GP-5892: 优化对 26w14a 愚人节版本的支持,更新模组下载页游戏版本列表至 26.1.1 (by Glavo)
- 世界管理
**世界管理**
- GP-5860: 种子地图、要塞地图、下届要塞地图和末地城地图支持 26.1 (by Glavo,neveler)
- 错误修复
**错误修复**
- GP-5910: 修复无法为 Minecraft 26.1.1 从官方源安装 NeoForge 的问题 (by Glavo, Burning_TNT)
+73
View File
@@ -0,0 +1,73 @@
---
---
[详细版本介绍 (Bilibili)](https://www.bilibili.com/opus/1192242668981190663)
**启动器**
- GP-5851: 将 kala-compress 更新至 1.27.1-3 (by Glavo)
- GP-5854: 将 twelvemonkeys 更新至 3.13.1 (by Glavo)
- GP-5883: 将 XZ for Java 更新至 1.12 (by Glavo)
- GP-4716: 优化 Java 信息识别功能 (by Glavo)
- GP-5316: 更新 AMD 显卡信息数据 (by 辞庐, Glavo)
- GP-5518: 在 Wine 环境中启动时发出警告 (by Damon Lu)
- GP-5667: 优化 NBT 读取功能 (by Glavo)
- GP-5660: 在游戏进程结束后禁用“结束游戏进程”与“导出游戏运行栈”按钮 (by 辞庐)
- GP-5694: 为游戏崩溃界面导出和启动器日志导出添加加载指示器 (by 辞庐)
- GP-5702: 优化标签的展示逻辑 (by 辞庐)
- GP-5703: 更新更新渠道选择选项 (by 辞庐, 3gf8jv4dv, Glavo)
- GP-5730: 支持通过版本 json 安装实例 (by 辞庐, Glavo)
- GP-5738: 为在临时目录中启动 HMCL 时弹出的提示对话框添加 5 秒倒计时 (by 辞庐)
- GP-5879: 安装模组时检查文件是否已存在 (by 辞庐)
- GP-5880: 优化手动更新 URL (by Xirren)
- GP-5923: 优化原理图管理和世界界面中部分输入框的校验方式 (by 辞庐)
- GP-5928: 支持在 FreeBSD x86-64、Linux Arm64、Linux LoongArch64 和 Linux RISC-V64 平台上启动 Minecraft 26.2-snapshot-1+ (by Glavo)
**游戏设置**
- GP-5813: 将“不适用于当前系统的选项”的系统支持信息移到子标题 (by Damon Lu)
- GP-5930, GP-5940: 支持设置 Vulkan 的渲染器 (by Glavo, 3gf8jv4dv) [BV1Nhd5B9ENc](https://www.bilibili.com/video/BV1Nhd5B9ENc)
**账户**
- GP-5949: 上传微软账户皮肤时校验图片尺寸 (by 辞庐)
**整合包**
- GP-5786, GP-5837: 安装 CurseForge 整合包时下载图标 (by Calboot)
**外观**
- GP-5484: 支持加载 SVG 图片 (by Glavo)
- GP-5775: 为自定义颜色选择对话框添加确认和取消按钮 (by mineDiamond, Glavo)
- GP-5829: 更新内存状态栏样式 (by Glavo)
- GP-5830: 在颜色选择器中隐藏透明度值 (by neveler)
- GP-5832, GP-5836: 为弹窗添加圆角 (by neveler)
- GP-5861: 优化“关于”页面组件间距 (by neveler)
- GP-5905: 优化组合框样式 (by Wulian233)
- GP-5917: 优化组合框展开图标 (by 辞庐, Glavo)
- GP-5924: 优化 Java 下载弹窗旋转指示器样式 (by 辞庐)
- GP-5925: 优化添加认证服务器 http 警告颜色 (by 辞庐)
- GP-5944: 优化菜单分隔符颜色 (by 辞庐, Glavo)
- GP-5945: 增大自动安装界面加载器名称和版本号之间的间距 (by 辞庐)
**下载**
- GP-5601, GP-5899: 下载页面折叠快照 Minecraft 版本 (by 辞庐, Glavo, Calboot)
- GP-5781: 支持设置游戏内容默认下载源 (by Calboot, Glavo, 3gf8jv4dv)
- GP-5859: 增强 Java 下载功能可靠性 (by Glavo)
- GP-5872: 优化下载页面依赖项展示 (by 辞庐)
- GP-5934: 更新游戏内容下载页游戏版本列表至 26.1.2 (by Glavo)
- GP-5946: 隐藏 CurseForge 源中游戏内容的不重要标签 (by 辞庐)
**本地化**
- GP-5931: 支持将新格式快照版本号翻译为文言 (by Glavo)
- 优化软件文案,修订翻译 (by 3gf8jv4dv)
**错误修复**
- GP-5301: 修复清理游戏资源/库操作在 JavaFX 线程运行的问题 (by 辞庐)
- GP-5609: 修复涟漪无法完整覆盖大型控件的问题 (by 辞庐)
- GP-5688: 修复 Alex 模型皮肤 3D 预览手臂背后有一列侧面的异常像素的问题 (by 辞庐)
- GP-5877: 修复弹窗过程中模糊 (by 辞庐)
- GP-5888: 修复模组管理页面对于 1.20.1+NeoForge 实例会将部分 Forge 模组识别为 `MixinExtras` 的问题 (by Calboot)
- GP-5911: 修复多次打开微软登录弹窗后报错的问题 (by Glavo)
- GP-5914: 修复导入整合包界面箭头颜色错误的问题 (by Calboot)
- GP-5915: 修复长按标题栏中部分按钮时可以拖动窗口的问题 (by 辞庐)
- GP-5922: 修复安装整合包时部分任务未正确归类的问题 (by 辞庐)
- GP-5935: 修复日志窗口中可能显示横向滚动条的问题 (by Glavo)
- GP-5943: 修复模组名字过长时下载页面布局异常的问题 (by 辞庐)
+8 -8
View File
@@ -52,21 +52,21 @@
- GP-3490: 修复 OAuth 登录时轮询过于频繁的问题
- GP-3464: 修复在更新日志界面无法拖动启动器窗口的问题
- GP-3503: 使用 Zink 渲染器时禁用 DRI3
- GC-`5fd52bb`: 皮肤缓存不再保存到 .minecraft 目录
- GC-`81b3911`: 修复按 ESC 键时文本框内的值没有保存的问题
- GC-`260f4b6`: 修复输入对话框中 ESC 键不起作用的问题
- GC-`7d12ef6`: 修复内存滑块提示被设备内存进度条覆盖的问题
- GC-`78e15d1`: 修复游戏设置中内存没有实时刷新的问题
- GC-`6f53da1`: 完善模组下载界面
- GC-5fd52bb: 皮肤缓存不再保存到 .minecraft 目录
- GC-81b3911: 修复按 ESC 键时文本框内的值没有保存的问题
- GC-260f4b6: 修复输入对话框中 ESC 键不起作用的问题
- GC-7d12ef6: 修复内存滑块提示被设备内存进度条覆盖的问题
- GC-78e15d1: 修复游戏设置中内存没有实时刷新的问题
- GC-6f53da1: 完善模组下载界面
- GP-3252: 修复无法补全部分第三方 Minecraft 客户端游戏资源的问题
- GC-`56d20a5`, GC-`397edae`: 修复 Linux 平台调整窗口大小的问题
- GC-56d20a5, GC-397edae: 修复 Linux 平台调整窗口大小的问题
- GP-3531: 修复在 FreeBSD x86-64 平台未正确替换 LWJGL 本地库的问题
- GP-3541: 修复安装 MultiMC 整合包后没有设置版本图标的问题
- GP-3549: 修复 macOS 平台 HMCLauncher.sh 不会显示 Java 下载页面的问题
- GP-3594: Java 下载对话框中切换包类型时不应重置版本字段
- GP-3598: 修复使用自定义字体时未正确设置字重的问题
- GP-3602: 修复使用系统 GLFW/OpenAL 时无法启动部分游戏版本的问题
- GC-`ecafc9d`: 修复安装新游戏页面中组件框的高度问题
- GC-ecafc9d: 修复安装新游戏页面中组件框的高度问题
- GP-3618: 修复无法识别 Intel64 架构的问题
- GP-3626: 修复离线账户选择 Steve/Alex 皮肤时模型错误的问题
- GP-3622: 修复在非官方支持的平台上 Minecraft 1.21 与 Sodium 不兼容的问题
+4 -2
View File
@@ -1,8 +1,10 @@
---
---
- 启动器
**启动器**
- GP-4262: 更新 AMD 显卡信息 (by Glavo)
- GP-4274: 更新 chunkbase 种子地图链接 (by Wulian233)
- 错误修复:
**错误修复:**
- GP-4174: 修复无法从 BMCLAPI 下载部分 NeoForge 所需文件的问题 (by 辞庐)
+12 -6
View File
@@ -3,24 +3,30 @@
版本介绍: [cv43005407](https://www.bilibili.com/opus/1111270122956259346)
- 启动器
**启动器**
- GP-4422: 弃用 Java 11 支持 (by Glavo)
- GP-4164: 支持通过环境变量强制使用 GPU 渲染和控制动画帧率 (by Glavo)
- GP-4179: 在 `./.hmcl/java` 中搜索 Java (by Glavo)
- GP-4365: 修复首次打开子页面时切换动画丢失的问题 (by Glavo)
- GP-4439: 更新模组和整合包数据 (by Glavo)
- GP-4414: 检测到配置文件由高版本启动器创建时禁止保存配置文件 (by Glavo)
- 游戏管理
**游戏管理**
- GP-4224: 支持在 Windows 7/8/8.1 上使用软渲染器 (by Glavo)
- 下载
**下载**
- GP-4170: 模组下载列表翻页后自动回到顶部 (by 辞庐)
- GP-4171: 支持加载 WebP 图标,解决部分模组/整合包图标无法加载的问题 (by Glavo)
- 外观
**外观**
- GP-4185: 新增内存显示条禁用样式 (by OrzMiku)
- 本地化
**本地化**
- GP-4376: 将“版本”重命名为“实例” (by 3gf8jv4dv)
- 优化软件文案,完善英语、西班牙语、俄语翻译
- 错误修复
**错误修复**
- GP-4121: 修复多次启动游戏时内存泄露的问题 (by roj234)
- GP-4066: 修复游戏版本列表错误地过滤掉部分版本的问题 (by Wulian233)
- GP-4152: 修复导入异常格式的数据包时启动器崩溃的问题 (by Glavo)
+4 -2
View File
@@ -3,9 +3,11 @@
版本介绍: [cv43162536](https://www.bilibili.com/opus/1116529228834144258)
- 游戏管理
**游戏管理**
- GP-4515: 优化 Java 自动选择规则 (by Glavo)
- 错误修复
**错误修复**
- GP-4508: 修复使用 JavaFX 25 时游戏下载界面布局错误的问题 (by Glavo)
- GP-4465: 修复启用代理身份认证且未设置密码时启动器崩溃的问题 (by Glavo)
- GP-4466: 修复滚动切换游戏实例/账户功能 (by Glavo)
+4 -2
View File
@@ -3,10 +3,12 @@
版本介绍: [cv43348716](https://www.bilibili.com/opus/1123235936240402439)
- 启动器
**启动器**
- GP-4223: 在“设置 > 通用”添加“提前预览 HMCL 版本”选项 (by Glavo)<br>
详情请见完整更新日志: [cv43348716](https://www.bilibili.com/opus/1123235936240402439)
- GP-4088: 当离线账户名称超过 16 字符时弹出警告 (by ShulkerSakura)
- 下载
**下载**
- GP-4120: 更新 unlisted-versions-of-minecraft 镜像源地址 (by 8Mi_Yile)
- GP-4626: 更新模组下载页游戏版本列表至 1.21.10 (by Glavo)
+6 -3
View File
@@ -3,10 +3,13 @@
详细版本介绍: [cv43648491](https://www.bilibili.com/opus/1132495430464045104)
- 启动器
**启动器**
- GP-4742: 更新 Chunkbase 种子地图链接 (by Wulian233)
- 联机
**联机**
- GP-4723: 将陶瓦联机更新至 0.3.13 (by Burning_TNT)
- GP-4735: 在不支持的平台上打开陶瓦联机页面时弹出提示 (by Glavo)
- 错误修复
**错误修复**
- GP-4736: 修复 FreeBSD x86-64 平台上错误的将所有版本视作未经测试的版本的问题 (by Glavo)
+6 -3
View File
@@ -3,16 +3,19 @@
详细版本介绍: [cv43836292](https://www.bilibili.com/opus/1138359439513878544)
- 下载
**下载**
- GP-4767: 添加对 25w45a_unobfuscated 的支持 (by Glavo)
- GP-4782: 添加对 25w46a_unobfuscated 的支持 (by Glavo)
- GP-4829: 添加对 1.21.11-pre1/2_unobfuscated 的支持 (by mineDiamond)
- GP-4841: 更新 HMCL 元数据链接 (by Glavo)
- 联机
**联机**
- GP-4816: 更新陶瓦联机用户须知 (by Glavo)
- GP-4838: 将陶瓦联机更新至 0.3.14 (by Burning_TNT)
- 错误修复
**错误修复**
- GP-4795: 修复初次打开部分页面时页面闪烁的问题 (by Glavo)
- GP-4808: 修复 Windows 下全局设置中本地库路径路径分隔符显示错误的问题 (by 辞庐)
+8 -4
View File
@@ -3,7 +3,8 @@
详细版本介绍: [cv43836921](https://www.bilibili.com/opus/1138376365938049027)
- 启动器
**启动器**
- GP-4703, GP-4743: 优化更新日志展示功能 (by Glavo)
- GP-4696: 在外链按钮上添加 tooltip (by neveler)
- GP-4749: 恢复对 JavaFX 14 的兼容性 (by Glavo)
@@ -15,16 +16,19 @@
- GP-4612: 增强解析数据包/资源包元数据的能力 (by mineDiamond)
- GP-4826: 从首页打开子页面时打开默认标签页 (by Glavo)
- GP-4845: 更新 amdgpu.ids (by 辞庐)
- 外观/动画
**外观/动画**
- GP-4780, GP-4790, GP-4803, GP-4815: 优化界面动画效果 (by Glavo)
- GP-4698: 被打包为 `.app` 文件时使用 `.app` 文件内置的 Dock 栏图标 (by 风花AnemoFlower)
- GP-4779: 预加载页面以减少动画卡顿 (by Glavo)
- GP-4762: 在 macOS 平台使用系统默认最小化动画 (by Damon Lu)
- GP-4809: 在更多页面上启用平滑滚动 (by Glavo)
- 本地化
**本地化**
- GP-4709: 本地化下载速度显示 (by Glavo)
- 优化软件文案,修订翻译 (by 3gf8jv4dv, Glavo)
- 错误修复
**错误修复**
- GP-4775: 修复无法获取部分远古版本版本号的问题 (by Glavo)
- GP-4783: 修复模组管理页面点击搜索按钮后未聚焦到搜索栏的问题 (by mineDiamond)
- GP-4805: 修复复制实例时使用非法实例 ID 启动器行为异常的问题 (by Haowei Wen)
+4 -2
View File
@@ -3,10 +3,12 @@
[详细版本介绍 (Bilibili)](https://www.bilibili.com/opus/1148470393780043777)
- 启动器
**启动器**
- GP-4886: 优化对 Linux MIPS64el 平台的支持 (by Glavo)
- GP-4917: 支持 Minecraft 新版本号规则 (by Glavo)
- 错误修复
**错误修复**
- GP-4850: 修复 `FetchTask` 未设置 User-Agent 的问题 (by Glavo)
- GP-4913: 修复游戏进程结束时点击日志窗口的“结束游戏进程”按钮会导致启动器无响应的问题 (by Glavo)
- GP-4981: 修复从 BMCLAPI 下载部分旧文件时校验失败的问题 (by Glavo)
+16 -8
View File
@@ -3,20 +3,25 @@
[详细版本介绍 (Bilibili)](https://www.bilibili.com/opus/1148770448825122832)
- 启动器
**启动器**
- GP-4837: 实验性支持阿拉伯语 (by Hommam-Prom)
- GP-4911, GP-4963: 添加对 1.21.11_unobfuscated 及其预发布版的支持 (by mineDiamond)
- GP-4927: 在 macOS 平台上导出启动脚本时支持导出 `.command` 文件 (by WhatDamon)
- GP-5019: 使用子标题注解“提前预览 HMCL 版本”选项 (by neveler)
- GP-5008: 优化反馈页面 (by Glavo)
- 游戏设置
**游戏设置**
- GP-4144: 添加输出游戏调试日志选项 (by 辞庐)
- 实例管理
**实例管理**
- GP-4475: 添加资源包管理功能 (by 辞庐)
- GP-4872: 添加快速进入世界功能 (by mineDiamond)
- 账户管理
**账户管理**
- GP-4932: 在主页右键点击账户按钮时弹出快速切换账户菜单 (by zimzaza4)
- 外观
**外观**
- GP-4835: 更新至 Material Design 3 颜色系统 (by Glavo)
- 支持深色模式 (by Glavo, Wulian233, neveler)
- GP-4854: 更新表格控件的样式 (by Calboot)
@@ -24,13 +29,16 @@
- GP-4915: 在 `HintPane` 提示框中为图标和文本添加间距 (by neveler)
- GP-4951: 更新选择框下拉菜单滚动条样式 (by Glavo)
- GP-4964: 更新表格中复选框的样式 (by Glavo)
- 下载
**下载**
- GP-4856: 优化下载源选择逻辑 (by Glavo)
- GP-4990: 支持下载 Java 25 (by OrzMiku)
- 联机
**联机**
- GP-4869: 在陶瓦联机页面向非中国内地用户添加提示框 (by Glavo)
- GP-4916: 在陶瓦联机界面启动游戏时禁用离线皮肤功能 (by Glavo)
- 错误修复
**错误修复**
- GP-4857: 修复惯性滚动可能导致弹出菜单错位的问题 (by Glavo)
- GP-4871: 修复修改主题色后 `JFXCheckBox` 颜色不会及时变化的问题 (by Glavo)
- GP-4874: 修复 `JFXRadioButton` 在 Windows 平台上中心圆点偏移的问题 (by Glavo)
+4 -2
View File
@@ -3,11 +3,13 @@
[详细版本介绍 (Bilibili)](https://www.bilibili.com/opus/1157751599072804904)
- 启动器
**启动器**
- GP-5046: 禁用日志窗口的平滑滚动效果 (by Glavo)
- GP-5052: 优化列表的平滑滚动效果 (by Glavo)
- GP-5110: 更新 NeoForge 版本号规则 (by 辞庐)
- 错误修复
**错误修复**
- GP-5128: 修复使用 BMCLAPI 下载源时选择 `Liteloader` 版本时可能报错的问题 (by Wulian233)
- GP-5125: 修复未正确归类 NeoForge alpha 版本的问题 (by 辞庐)
- GP-5220: 修复 CurseForge 源无法搜索到内容的问题 (by Glavo)
+2 -4
View File
@@ -9,6 +9,7 @@
# data_dir: _data
# includes_dir: _includes
# cache_dir: .jekyll-cache
disable_disk_cache: true
sass:
# sass_dir: _sass
# minimal-mistakes
@@ -105,10 +106,7 @@ defaults:
path: ""
values:
layout: document
read_time: false
author_profile: false
share: false
comments: false
show_date: true
sidebar:
nav: docs
hits: true
-15
View File
@@ -1,15 +0,0 @@
note:
title: 注意
class_name: notice--info
tip:
title: 提示
class_name: notice--success
important:
title: 重要
class_name: notice--primary
warning:
title: 警告
class_name: notice--warning
caution:
title: 谨慎
class_name: notice--danger
+16 -16
View File
@@ -5,24 +5,18 @@ appearance_color:
- light
- dark
- auto
appearance_skin_light:
appearance_color_switcher:
type: radio
default: default
default: enable
options:
- default
- air
- aqua
- contrast
- dark
- dirt
- neon
- mint
- plum
- sunrise
- catppuccin_latte
- catppuccin_mocha
appearance_skin_dark:
type: radio
- enable
- disable
appearance_skin:
type: multi-radio
children:
light:
default: default
dark:
default: dark
options:
- default
@@ -37,3 +31,9 @@ appearance_skin_dark:
- sunrise
- catppuccin_latte
- catppuccin_mocha
miscellaneous_hits:
type: radio
default: enable
options:
- enable
- disable
+2
View File
@@ -0,0 +1,2 @@
zh:
follow_label: false
+18 -21
View File
@@ -8,59 +8,56 @@ contributors:
- TyMxy
---
# 离线模式下更换皮肤
**注意:**
> 使用 Steve、Alex、本地皮肤图片文件: 可能无法加入多人联机,其他玩家可能看不到您的皮肤
> [!NOTE]
> 使用 Steve、Alex、本地皮肤图片文件: 可能无法加入多人联机,其他玩家可能看不到您的皮肤\
> 使用 LittleSkin、Blessing Skin 服务器: 多人联机下和您使用 **相同方式** 的玩家可以看到您的皮肤, 其他玩家不可以
打开HMCL, 进入 **账号列表** , 点击下图离线账号的【上传皮肤】红框处:
打开 HMCL 进入**账户列表**,点击下图离线模式账户的 `上传/编辑皮肤` 按钮(红框处)。
![](/assets/img/docs/offline-skin/img1_1.png)
![](/assets/img/docs/offline-skin/img1_2.png)
> 默认: 使用默认随机的皮肤显示
>
> Steve: 使用Steve (史蒂夫) 皮肤显示
>
> Alex: 使用Alex (艾利克斯) 皮肤显示
>
> [本地皮肤图片文件](#本地皮肤图片文件)、[LittleSkin](#littleskin)、[Blessing Skin 服务器](#blessing-skin-服务器): 请见下文↓
- `默认` 使用默认随机的皮肤显示
- `Steve` 使用 Steve(史蒂夫)皮肤显示
- `Alex` 使用 Alex(艾利克斯)皮肤显示
- [本地皮肤图片文件](#本地皮肤图片文件)
- [LittleSkin](#littleskin)
- [Blessing Skin 服务器](#blessing-skin-服务器)
## 本地皮肤图片文件
点击 **本地皮肤图片文件** , 设置 **皮肤/披风**皮肤图片 路径, 点击 **确认**, 即可
选中本地皮肤图片文件后,根据需求分别设置皮肤与披风的资源路径然后点击确认即可。
![](/assets/img/docs/offline-skin/img2.png)
## LittleSkin
首先您需要一个LittleSkin的账号, [注册](https://mcskin.littleservice.cn/auth/register)并[登录](https://mcskin.littleservice.cn/auth/login)
首先您需要一个 LittleSkin 的账户,[注册](https://mcskin.littleservice.cn/auth/register)并[登录](https://mcskin.littleservice.cn/auth/login)。
然后前往 [角色管理](https://mcskin.littleservice.cn/user/player), 查看您的角色名, 如果没有, 请点击 **添加新角色** 进行添加
然后前往[角色管理](https://mcskin.littleservice.cn/user/player),查看您的角色名,如果没有可以点击添加新角色按钮进行添加。
你可在 [我的衣柜](https://mcskin.littleservice.cn/user/closet) 修改此账户名的皮肤与披风
你可在[我的衣柜](https://mcskin.littleservice.cn/user/closet)修改此账户名的皮肤与披风。
![](/assets/img/docs/offline-skin/img3_1.png)
在HMCL中创建的离线账户的 账户名 **必须**和角色名相等, 如果不相等, 请 **重新在HMCL中创建离线账户**
角色名必须与 HMCL 中离线模式账户的角色名一致。如不一致,请在 HMCL 中切换至对应的离线模式账户,或新建与角色名匹配的离线模式账户。
![](/assets/img/docs/offline-skin/img3_2.png)
确认相等后, 点击 **LittleSkin** 即可同步在LittleSkin上此账户名的皮肤
确认离线模式账户的角色名一致后,点击 **LittleSkin** 即可同步在 LittleSkin 上的皮肤。
![](/assets/img/docs/offline-skin/img3_3.png)
## Blessing Skin 服务器
**Blessing Skin 服务器, 进入 **角色管理** , 查看角色名 , 确认 **角色名** 和 **HMCL中创建的离线账号角色名** 相同, 如果不相等, **请重新在HMCL中创建离线账户**
进入角色管理核对角色名与 HMCL 中离线模式账户的角色名是否一致。如不一致,请在 HMCL 中切换至对应的离线模式账户,或新建与角色名匹配的离线模式账户。
你可在 我的衣柜 修改此账户名的皮肤与披风
你可在我的衣柜修改此账户名的皮肤与披风。
![](/assets/img/docs/offline-skin/img4_1.png)
进入 **配置生成**, 按下图找到 `CustomSkinLoader` 中的网址, 复制到HMCL中即可同步在Blessing Skin 服务器上此账户名的皮肤
进入配置生成并按下图找到 `CustomSkinLoader` 中的网址,复制到 HMCL 中即可同步在 Blessing Skin 服务器上此账户名的皮肤。
![](/assets/img/docs/offline-skin/img4_2.png)
+9 -8
View File
@@ -2,12 +2,13 @@
layout: single
---
{% if jekyll.environment == 'production' and page.hits %}
<img src="https://hits.zkitefly.eu.org/?tag={{ page.url | absolute_url | url_encode }}" alt="Hits" decoding="async">
{% endif %}
<div class="notice--info">
<p>本文由 {{ page.author | default: '未署名用户' }} 创建{% if page.contributors %},并由 {{ page.contributors | join: ' ' }} 编辑{% endif %}。</p>
</div>
{{ content }}
{% if page.author or page.contributors or jekyll.environment == 'production' and page.hits %}
<script src="{{ '/assets/js/meta.js' | relative_url }}"></script>
<script>
{%- if page.author %}appendMeta("{{ page.author }}", "fas fa-user-pen");{% endif -%}
{%- for contributor in page.contributors %}appendMeta("{{ contributor }}", "fas fa-user-pen");{% endfor -%}
{%- if jekyll.environment == 'production' and page.hits %}hits({{ page.url | absolute_url | jsonify }});{% endif -%}
</script>
{% endif %}
+40 -31
View File
@@ -1,46 +1,55 @@
---
layout: document
layout: single
---
{% for group in page.data %}
{% capture notice %}
## {{ group.title }}
{%- for group in page.data %}
<h2 id="{{ group.title }}">{{ group.title }}</h2>
{% for pair in group.settings %}
{% assign name = pair[0] %}
{% assign value = pair[1] %}
{% assign setting = site.data.settings[name] %}
{% if setting.type == 'radio' %}
<div class="notice">
<ul class="task-list">
<li><strong>{{ value.title }}</strong></li>
<li>{{ value.description }}</li>
<h3 id="{{ name }}">{{ value.title }}</h3>
{% if value.description %}<p>{{ value.description }}</p>{% endif %}
{% if setting.type == 'radio' %}
{% for option in setting.options %}
<li class="task-list-item">
<input type="radio" class="task-list-item-checkbox" name="{{ name }}" value="{{ option }}" id="{{ name }}_{{ option }}"{% if setting.default == option %} checked{% endif %}><label for="{{ name }}_{{ option }}">{{ value.options[option] }}</label>
</li>
<label>
<input type="radio"{% if setting.default == option %} checked{% endif %} class="setting-item" name="{{ name }}" value="{{ option }}">
{{ value.options[option] }}
</label>
{% endfor %}
</ul>
{% elsif setting.type == 'multi-radio' %}
<table class="setting-multi-radio">
<thead>
<tr>
<th>{{ value.title }}</th>
{% for item in setting.children %}
{% capture item_name %}{{ item[0] }}{% endcapture %}
<th>{{ value.children[item_name] }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for option in setting.options %}
<tr>
<th>{{ value.options[option] }}</th>
{% for item in setting.children %}
<td><input class="setting-item"{% if item[1].default == option %} checked{% endif %} type="radio" name="{{ name }}.{{ item[0] }}" value="{{ option }}"></td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</div>
{% endfor %}
{% endfor %}
<script>
settings.onChange("{{ name }}", function (newValue, oldValue) {
var list = document.getElementsByName("{{ name }}");
for (var i = 0; i < list.length; i++) {
list[i].checked = list[i].value === newValue;
list[i].onchange = function () {
if (this.checked) {
settings.set(this.name, this.value);
for (const settingItem of document.getElementsByClassName("setting-item")) {
settingItem.addEventListener("change", ({ target }) => settings.set(target.name, target.value));
settings.onChange(settingItem.name, (value) => settingItem.type === "radio" && (settingItem.checked = settingItem.value === value));
}
}
}
});
</script>
{% endif %}
{% endfor %}
{% endcapture %}
{{ notice | markdownify }}
{% endfor %}
<style>.notice label input { display: inline }</style>
-48
View File
@@ -1,48 +0,0 @@
require "nokogiri"
Jekyll::Hooks.register [:pages, :documents], :post_convert do |doc|
next unless doc.output_ext == ".html"
site = doc.site
next unless site.data["plugins"]
alert_type = site.data["plugins"]["auto_alert"]
next unless alert_type
fragment = Nokogiri::HTML::DocumentFragment.parse(doc.content)
# 遍历 HTML 中的所有 blockquote 标签
fragment.css("blockquote").each do |item|
# 找出第一个子节点,用于判断是否含有 [!type] 标记
first_child = item.at_css("*:first-child")
next unless first_child
next unless first_child.name == "p"
inner_html = first_child.inner_html.downcase
# 遍历所有 alert 类型
alert_type.each do |type, data|
prefix = "[!#{type}]"
prefix_with_newline = "#{prefix}\n"
# 情况一:完整匹配 [!type] 形式 <p>[!NOTE]</p>
if inner_html == prefix
# 将 alert 类型对应的 class 加入 blockquote
item["class"] = [item["class"], data["class_name"]].compact.join(" ")
# 将 <p> 替换为 <div> 并插入标题
first_child.name = "div"
first_child.inner_html = "<strong>#{data["title"]}</strong>"
break
# 情况二:段落以 [!type]\n 开头 <p>[!NOTE]\n\n other content</p>
elsif inner_html.start_with? prefix_with_newline
# 将 alert 类型对应的 class 加入 blockquote
item["class"] = [item["class"], data["class_name"]].compact.join(" ")
# 在原段落前插入标题 <div><strong>提示</strong></div><p>[!NOTE]\n\n other content</p>
first_child.add_previous_sibling "<div><strong>#{data["title"]}</strong></div>"
# 移除段落内容开头的 [!type]\n <div><strong>提示</strong></div><p>\n other content</p>
first_child.inner_html = first_child.inner_html[prefix_with_newline.length..-1] || ""
break
end
end
end
doc.content = fragment.to_html
end
-30
View File
@@ -1,30 +0,0 @@
require "nokogiri"
require "addressable/uri"
Jekyll::Hooks.register [:pages, :documents], :post_convert do |doc|
next unless doc.output_ext == ".html"
site = doc.site
liquid_context = Liquid::Context.new({}, {}, { site: site })
process_uri = lambda do |path|
uri = Addressable::URI.parse(path)
if uri&.path
uri.path = Liquid::Template.parse("{% link #{uri.path[1..]} %}").render!(liquid_context)
end
uri.to_s
end
fragment = Nokogiri::HTML::DocumentFragment.parse(doc.content)
fragment.css("[src^=\"/assets/\"],[src^=\"/\"][src$=\".md\"],[src^=\"/\"][src*=\".md#\"]").each do |item|
if item["src"]
item["src"] = process_uri.call(item["src"])
end
end
fragment.css("[href^=\"/assets/\"],[href^=\"/\"][href$=\".md\"],[href^=\"/\"][href*=\".md#\"]").each do |item|
if item["href"]
item["href"] = process_uri.call(item["href"])
end
end
doc.content = fragment.to_html
end
+195
View File
@@ -0,0 +1,195 @@
begin
require "webp-ffi"
rescue LoadError; end
module KramdownEnhancer
GITHUB_LINK_REGEX = /\b(GP-\d+|GC-[0-9a-f]{7})\b/
BLOCKQUOTE_TYPES = {
note: "notice--info",
tip: "notice--success",
important: "notice--primary",
warning: "notice--warning",
caution: "notice--danger",
}
class << self
def webp
@webp ||= {}
end
def file
@file ||= {}
end
def baseurl
@baseurl
end
def baseurl=(input)
@baseurl =
if input.is_a?(String) && !input.empty?
str = input.start_with?("/") ? input : "/#{input}"
str.chomp("/")
else
""
end
end
end
class WebpFile < Jekyll::StaticFile
def write(dest)
true
end
end
module Html
def convert_a(el, indent)
if el.attr["href"].is_a?(String) && !el.options[:relative]
el.attr["href"] = relative_url(el.attr["href"])
el.options[:relative] = true
end
super
end
def convert_img(el, indent)
if el.attr["src"].is_a?(String) && !el.options[:relative]
src = el.attr["src"]
el.attr["src"] = relative_url(src)
el.options[:relative] = true
if KramdownEnhancer.webp[src] && !el.options[:webp] && !el.options[:picture]
webp_src = KramdownEnhancer.webp[src]
pic = Kramdown::Element.new(:html_element, "picture")
pic.children << Kramdown::Element.new(:html_element, "source", { "srcset" => relative_url(webp_src), "type" => "image/webp" })
el.options[:picture] = true
el.options[:webp] = true
pic.children << el
return convert_html_element(pic, indent)
end
end
super
end
def convert_blockquote(el, indent)
p = el.children.first
return super if p&.type != :p || p.children.empty?
first = p.children.first
return super unless first&.type == :text
text = first.value.downcase
KramdownEnhancer::BLOCKQUOTE_TYPES.each do |type, class_name|
prefix = "[!#{type}]"
prefix_with_newline = "#{prefix}\n"
# case A: <p>[!NOTE]</p>
if text == prefix
el.attr["class"] = [el.attr["class"], class_name].compact.join(" ")
p.children.shift
break
# case B: <p>[!NOTE]\n some text</p>
elsif text.start_with?(prefix_with_newline)
el.attr["class"] = [el.attr["class"], class_name].compact.join(" ")
first.value = first.value[prefix_with_newline.length..-1] || ""
break
end
end
super
end
def convert_html_element(el, indent)
unless el.options[:relative]
if el.value == "a" && el.attr["href"].is_a?(String)
el.attr["href"] = relative_url(el.attr["href"])
el.options[:relative] = true
elsif el.value == "img" && el.attr["src"].is_a?(String)
src = el.attr["src"]
el.attr["src"] = relative_url(el.attr["src"])
el.options[:relative] = true
if KramdownEnhancer.webp[src] && !el.options[:webp] && !el.options[:picture]
webp_src = KramdownEnhancer.webp[src]
pic = Kramdown::Element.new(:html_element, "picture")
pic.children << Kramdown::Element.new(:html_element, "source", { "srcset" => relative_url(webp_src), "type" => "image/webp" })
el.options[:webp] = true
pic.children << el
return convert_html_element(pic, indent)
end
elsif el.value == "picture"
el.children.each do |child|
child.options[:picture] = true
end
end
end
super(el, indent)
end
def convert_text(el, indent)
return super(el, indent) unless !el.options[:github_link] && KramdownEnhancer::GITHUB_LINK_REGEX.match?(el.value)
list = el.value.split(KramdownEnhancer::GITHUB_LINK_REGEX)
el.type = :html_element
el.value = "span"
el.children = list.reject(&:empty?).map do |item|
if KramdownEnhancer::GITHUB_LINK_REGEX.match(item)
href =
if item.start_with?("GP-")
"https://github.com/HMCL-dev/HMCL/pull/#{item[3..]}"
else
"https://github.com/HMCL-dev/HMCL/commit/#{item[3..]}"
end
link = Kramdown::Element.new(:a, nil, {"href": href, "target": "_blank"})
link.children = [Kramdown::Element.new(:text, item, nil, :github_link => true)]
link
else
Kramdown::Element.new(:text, item, nil, :github_link => true)
end
end
convert_html_element(el, indent)
end
private
def relative_url(input)
if input.is_a?(String) && input.start_with?("/")
input = input.start_with?("/") ? input : "/#{input}"
uri = Addressable::URI.parse(input)
if uri
if uri.path.length > 1
file = KramdownEnhancer.file[uri.path[1..]]
uri.path = file.url if file
end
uri.path = "#{KramdownEnhancer.baseurl}#{uri.path}"
return uri.to_s
end
end
input
end
end
end
Jekyll::Hooks.register :site, :post_read do |site|
KramdownEnhancer.baseurl = site.config["baseurl"]
webp_list = []
webp_enabled = defined?(WebP)
site.each_site_file do |file|
KramdownEnhancer.file[file.relative_path] = file
if file.is_a?(Jekyll::StaticFile)
url = "#{file.url}.webp"
source = "#{file.path}.webp"
destination = File.join(site.dest, url)
if File.exist?(source)
KramdownEnhancer.webp[file.url] = url
elsif webp_enabled && %w[.png .jpg .jpeg .tif .tiff].include?(file.extname.downcase)
FileUtils.mkdir_p(File.dirname(destination))
WebP.encode(file.path, destination)
webp_list.push(KramdownEnhancer::WebpFile.new(site, site.dest, File.dirname(url), File.basename(url)))
KramdownEnhancer.webp[file.url] = url
end
end
end
site.static_files.concat(webp_list)
Kramdown::Converter::Html.prepend(KramdownEnhancer::Html)
end
+58 -5
View File
@@ -1,4 +1,40 @@
@import "minimal-mistakes";
/* Copyright comment */
@import "minimal-mistakes/copyright";
/* Variables */
@import "minimal-mistakes/variables";
/* Mixins and functions */
@import "minimal-mistakes/vendor/breakpoint/breakpoint";
@include breakpoint-set("to ems", true);
@import "minimal-mistakes/vendor/magnific-popup/magnific-popup"; // Magnific Popup
@import "minimal-mistakes/vendor/susy/susy";
@import "minimal-mistakes/mixins";
/* Core CSS */
@import "minimal-mistakes/reset";
@import "minimal-mistakes/base";
@import "minimal-mistakes/forms";
@import "minimal-mistakes/tables";
@import "minimal-mistakes/animations";
/* Components */
@import "minimal-mistakes/buttons";
@import "minimal-mistakes/notices";
@import "minimal-mistakes/masthead";
@import "minimal-mistakes/navigation";
@import "minimal-mistakes/footer";
@import "minimal-mistakes/search";
@import "minimal-mistakes/syntax";
/* Utility classes */
@import "minimal-mistakes/utilities";
/* Layout specific */
@import "minimal-mistakes/page";
@import "minimal-mistakes-plus/archive";
@import "minimal-mistakes/sidebar";
@import "minimal-mistakes/print";
blockquote {
margin-inline: 0;
@@ -11,10 +47,27 @@ blockquote {
word-break: break-word;
}
.task-list-item label {
display: inline
}
.m0 {
margin: 0 !important;
}
table.setting-multi-radio td {
border: 0;
text-align: center;
border-left: 1px solid mix(#000, $border-color, 25%);
}
input[type="radio"] {
width: 0;
margin: 0;
margin-inline-end: 1em;
font-family: var(--fa-family-classic);
}
input[type="radio"]::before {
content: "\f111";
}
input[type="radio"]:checked::before {
content: "\f192";
}
+398
View File
@@ -0,0 +1,398 @@
/* ==========================================================================
ARCHIVE
========================================================================== */
.archive {
margin-top: 1em;
margin-bottom: 2em;
@include breakpoint($large) {
float: inline-end;
width: calc(100% - #{$right-sidebar-width-narrow});
padding-inline-end: $right-sidebar-width-narrow;
}
@include breakpoint($x-large) {
width: calc(100% - #{$right-sidebar-width});
padding-inline-end: $right-sidebar-width;
}
}
.archive__item {
position: relative;
a {
position: relative;
z-index: 10;
}
a[rel="permalink"] {
position: static;
}
}
.archive__subtitle {
margin: 1.414em 0 0.5em;
padding-bottom: 0.5em;
font-size: $type-size-5;
color: $muted-text-color;
border-bottom: 1px solid $border-color;
+ .list__item .archive__item-title {
margin-top: 0.5em;
}
}
.archive__item-title {
margin-bottom: 0.25em;
font-family: $sans-serif-narrow;
line-height: initial;
overflow: hidden;
text-overflow: ellipsis;
a[rel="permalink"]::before {
content: '';
position: absolute;
inset: 0;
}
a + a {
opacity: 0.5;
}
}
/* remove border*/
.page__content {
.archive__item-title {
margin-top: 1em;
border-bottom: none;
}
}
.archive__item-excerpt {
margin-top: 0;
font-size: $type-size-6;
& + p {
text-indent: 0;
}
a {
position: relative;
}
}
.archive__item-teaser {
position: relative;
border-radius: $border-radius;
overflow: hidden;
img {
width: 100%;
}
}
.archive__item-caption {
position: absolute;
bottom: 0;
inset-inline-end: 0;
margin: 0 auto;
padding: 2px 5px;
color: #fff;
font-family: $caption-font-family;
font-size: $type-size-8;
background: #000;
text-align: end;
z-index: 5;
opacity: 0.5;
border-radius: $border-radius 0 0 0;
@include breakpoint($large) {
padding: 5px 10px;
}
a {
color: #fff;
text-decoration: none;
}
}
/*
List view
========================================================================== */
.list__item {
.page__meta {
margin: 0 0 4px;
font-size: 0.6em;
}
}
/*
Grid view
========================================================================== */
.archive {
.grid__wrapper {
/* extend grid elements to the right */
@include breakpoint($large) {
margin-inline-end: -1 * $right-sidebar-width-narrow;
}
@include breakpoint($x-large) {
margin-inline-end: -1 * $right-sidebar-width;
}
}
}
.grid__item {
margin-bottom: 2em;
@include breakpoint($small) {
float: inline-start;
width: span(5 of 10);
&:nth-child(2n + 1) {
clear: both;
margin-inline-start: 0;
}
&:nth-child(2n + 2) {
clear: none;
margin-inline-start: gutter(of 10);
}
}
.page__meta {
margin: 0 0 4px;
font-size: 0.6em;
}
.page__meta-sep {
display: block;
&::before {
display: none;
}
}
.archive__item-title {
margin-top: 0.5em;
font-size: $type-size-5;
}
.archive__item-excerpt {
font-size: $type-size-6;
}
.archive__item-teaser {
@include breakpoint($small) {
max-height: 200px;
}
@include breakpoint($medium) {
max-height: 120px;
}
}
}
/*
Features
========================================================================== */
.feature__wrapper {
@include clearfix();
margin-bottom: 2em;
border-bottom: 1px solid $border-color;
.archive__item-title {
margin-bottom: 0;
}
}
.feature__item {
position: relative;
margin-bottom: 2em;
font-size: 1.125em;
@include breakpoint($small) {
float: inline-start;
margin-bottom: 0;
width: span(4 of 12);
&:nth-child(3n + 1) {
clear: both;
margin-inline-start: 0;
}
&:nth-child(3n + 2) {
clear: none;
margin-inline-start: gutter(of 12);
}
&:nth-child(3n + 3) {
clear: none;
margin-inline-start: gutter(of 12);
}
.feature__item-teaser {
max-height: 200px;
overflow: hidden;
}
}
.archive__item-body {
padding-inline: gutter(1 of 12);
}
a.btn::before {
content: '';
position: absolute;
inset: 0;
}
&--left, &--right {
position: relative;
margin-inline: 0;
width: 100%;
clear: both;
font-size: 1.125em;
a.btn::before {
content: '';
position: absolute;
inset: 0;
}
.archive__item-teaser {
margin-bottom: 2em;
}
}
&--left {
float: inline-start;
.archive__item {
float: inline-start;
}
@include breakpoint($small) {
.archive__item-teaser {
float: inline-start;
width: span(5 of 12);
}
.archive__item-body {
float: inline-end;
width: span(7 of 12);
padding-inline-start: gutter(0.5 of 12);
padding-inline-end: gutter(1 of 12);
}
}
}
&--right {
float: inline-end;
.archive__item {
float: inline-end;
}
@include breakpoint($small) {
text-align: end;
.archive__item-teaser {
float: inline-end;
width: span(5 of 12);
}
.archive__item-body {
float: inline-start;
width: span(7 of 12);
padding-inline-start: gutter(1 of 12);
padding-inline-end: gutter(0.5 of 12);
}
}
}
&--center {
position: relative;
float: inline-start;
margin-inline: 0;
width: 100%;
clear: both;
font-size: 1.125em;
.archive__item {
float: inline-start;
width: 100%;
}
.archive__item-teaser {
margin-bottom: 2em;
}
a.btn::before {
content: '';
position: absolute;
inset: 0;
}
@include breakpoint($small) {
text-align: center;
.archive__item-teaser {
margin: 0 auto;
width: span(5 of 12);
}
.archive__item-body {
margin: 0 auto;
width: span(7 of 12);
}
}
}
}
/* Place inside an archive layout */
.archive {
.feature__wrapper {
.archive__item-title {
margin-top: 0.25em;
font-size: 1em;
}
}
.feature__item,
.feature__item--left,
.feature__item--center,
.feature__item--right {
font-size: 1em;
}
}
/*
Wide Pages
========================================================================== */
.wide {
.archive {
@include breakpoint($large) {
padding-inline-end: 0;
}
@include breakpoint($x-large) {
padding-inline-end: 0;
}
}
}
/* Place inside a single layout */
.layout--single {
.feature__wrapper {
display: inline-block;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 KiB

+40
View File
@@ -0,0 +1,40 @@
(() => {
const pageTitle = document.getElementById("page-title");
if (pageTitle === null) return;
const header = pageTitle.parentElement;
let metas = header.getElementsByClassName("page__meta")[0];
if (metas === null) {
metas = document.createElement("div");
element.className = "page__meta";
header.append(element);
}
window.appendMeta = (text, icon) => {
if (metas.children.length > 0) {
const sep = document.createElement("span");
sep.className = "page__meta-sep";
metas.append(sep);
}
const meta = document.createElement("span");
if (icon !== undefined) {
const metaIcon = document.createElement("i");
metaIcon.className = icon;
meta.append(metaIcon, " ");
}
meta.append(text.trim());
metas.append(meta);
};
window.hits = (tag) => {
if (settings.get("miscellaneous_hits") === "disable") return;
const hitsUrl = new URL("https://hits.zkitefly.eu.org");
hitsUrl.searchParams.set("tag", tag);
fetch(hitsUrl, { method: "HEAD" }).then((response) => {
if (response.status !== 200) return;
const { headers } = response;
const total = headers.get("X-Total-Hits");
const today = headers.get("X-Today-Hits");
if (total !== null && today !== null) {
appendMeta(today + " / " + total, "far fa-eye");
}
});
};
})();
+27 -67
View File
@@ -1,76 +1,36 @@
---
layout: null
---
(function (global) {
var PREFIX = "HMCL_DOCS_SETTINGS_";
var data = {};
var events = {};
var config = /*{%comment%}*/{}/*{%endcomment%}*//**{{'/'}}{{ site.data.settings | jsonify }}/**/;
global.addEventListener("storage", function (event) {
if (!event.key) return;
if (event.key.indexOf(PREFIX) !== 0) return;
var handlers = events[event.key];
if (!handlers) return;
var newValue = event.newValue;
var oldValue = event.oldValue;
if (oldValue === newValue) return;
data[event.key] = newValue;
for (var i = 0; i < handlers.length; i++) {
if (typeof handlers[i] === "function") {
handlers[i](newValue, oldValue);
}
}
});
var settings = {
set: function (key, value) {
if (config[key] === undefined) return;
var strKey = (PREFIX + key).toUpperCase();
var newValue = value + "";
data[strKey] = newValue;
localStorage.setItem(strKey, newValue);
var handlers = events[strKey];
if (!handlers) return;
for (var i = 0; i < handlers.length; i++) {
if (typeof handlers[i] === "function") {
handlers[i](newValue);
(function () {
const PREFIX = "HMCL_DOCS_SETTINGS_", data = {}, bus = new EventTarget(), configs = /*{%comment%}*/{}/*{%endcomment%}*/ /**{{'/'}}{{ site.data.settings | jsonify }}/**/;
window.addEventListener("storage", ({ key, newValue }) => key !== null && key.startsWith(PREFIX) && newValue !== data[key] && bus.dispatchEvent(new CustomEvent(key, { detail: (data[key] = newValue) })));
for (const [key, config] of Object.entries(configs)) {
if (config.children === undefined) continue;
for (const [childKey, child] of Object.entries(config.children)) {
configs[`${key}.${childKey}`] = { ...config, ...child };
}
}
const formatKey = (key) => PREFIX + key.toUpperCase().replaceAll(".", "_");
window.settings = {
set(key, value) {
const name = formatKey(key);
localStorage.setItem(name, (data[name] = String(value)));
bus.dispatchEvent(new CustomEvent(name, { detail: data[name] }));
},
get: function (key, defaultValue) {
if (config[key] === undefined) return;
var strKey = (PREFIX + key).toUpperCase();
data.hasOwnProperty(strKey) || (data[strKey] = localStorage.getItem(strKey));
if (typeof defaultValue === "string" && data[strKey] === null) {
return defaultValue;
}
return data[strKey];
get(key) {
const name = formatKey(key);
if (data[name] !== undefined) return data[name];
const value = localStorage.getItem(name);
if (value !== null) return data[name] = value;
const config = configs[key];
if (config === undefined || typeof config.default !== "string") return null;
return config.default;
},
refresh: function (key) {
if (config[key] === undefined) return;
settings.set(key, settings.get(key, config[key].default));
onChange(key, handler) {
const value = this.get(key);
if (value === null) return;
handler(value);
bus.addEventListener(formatKey(key), (event) => handler(event.detail));
},
onChange: function (key, handler) {
if (config[key] === undefined) return;
if (typeof handler !== "function") return;
var strKey = (PREFIX + key).toUpperCase();
if (config[key].type === "radio") {
handler(settings.get(key, config[key].default));
}
if (!events[strKey]) {
events[strKey] = [handler];
} else {
events[strKey].push(handler);
}
}
};
global.settings = settings;
})(window);
})();
+14 -6
View File
@@ -4,11 +4,14 @@ layout: null
window.addEventListener("DOMContentLoaded", function () {
var skinLink = document.getElementById("skin");
var darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)");
function applySkin(skin) {
skinLink.href = "{{ '/assets/css/skins/' | relative_url }}" + skin + ".css";
}
function applyDarkSkin() {
skinLink.href = "{{ '/assets/css/skins/' | relative_url }}" + settings.get("appearance_skin_dark", "dark") + ".css";
applySkin(settings.get("appearance_skin.dark"));
}
function applyLightSkin() {
skinLink.href = "{{ '/assets/css/skins/' | relative_url }}" + settings.get("appearance_skin_light", "default") + ".css";
applySkin(settings.get("appearance_skin.light"));
}
function autoSchemeHandler() {
if (darkModeQuery.matches) {
@@ -61,10 +64,15 @@ window.addEventListener("DOMContentLoaded", function () {
}
}
settings.onChange("appearance_color", applyTheme);
settings.onChange("appearance_skin_dark", function () {
settings.refresh("appearance_color");
settings.onChange("appearance_skin.dark", function () {
applyTheme(settings.get("appearance_color"));
});
settings.onChange("appearance_skin_light", function () {
settings.refresh("appearance_color");
settings.onChange("appearance_skin.light", function () {
applyTheme(settings.get("appearance_color"));
});
settings.onChange("appearance_color_switcher", function (value) {
if (modeSwitcher !== null) {
modeSwitcher.style.display = value === "enable" ? "" : "none";
}
});
});
+1 -1
View File
@@ -23,7 +23,7 @@ title: 新手导航
{% for group in site.data.navigation.docs -%}
## {{ group.title }}
{% for item in group.children -%}
1. [{{ item.title }}]({{ item.url | relative_url }})
1. [{{ item.title }}]({{ item.url }})
{%- if item.description %}\
{{ item.description }}
{%- endif %}
+19 -18
View File
@@ -12,9 +12,18 @@ data:
light: 亮色
dark: 暗色
auto: 自动
appearance_skin_light:
title: 亮色皮肤
description: 亮色模式下应用的皮肤。
appearance_color_switcher:
title: 颜色模式快捷开关
description: 用于快捷切换站点主题颜色模式的开关,位于页面右上角。
options:
enable: 启用
disable: 禁用
appearance_skin:
title: 皮肤
description: 各颜色模式下应用的皮肤。
children:
light: 亮色
dark: 暗色
options:
default: 默认 (Default)
air: 天空 (Air)
@@ -28,20 +37,12 @@ data:
sunrise: 日出 (Sunrise)
catppuccin_latte: Catppuccin Latte
catppuccin_mocha: Catppuccin Mocha
appearance_skin_dark:
title: 暗色皮肤
description: 暗色模式下应用的皮肤。
- title: 杂项
settings:
miscellaneous_hits:
title: 访问统计服务
description: 用于统计页面访问量的服务。
options:
default: 默认 (Default)
air: 天空 (Air)
aqua: 水蓝 (Aque)
contrast: 高对比 (Contrast)
dark: 暗色 (Dark)
dirt: 泥土 (Dirt)
neon: 霓虹 (Neno)
mint: 薄荷 (Mint)
plum: 梅紫 (Plum)
sunrise: 日出 (Sunrise)
catppuccin_latte: Catppuccin Latte
catppuccin_mocha: Catppuccin Mocha
enable: 启用
disable: 禁用
---