补充打包方式

This commit is contained in:
NianGao Dev
2026-08-16 23:46:36 +08:00
parent 0a87efb9c3
commit db81873409
7 changed files with 174 additions and 14 deletions

View File

@@ -2,6 +2,9 @@
; 年糕历险记 —— Windows 安装脚本(NSIS 3,简体中文)
; 用法:makensis /DVERSION=1.0.0 scripts/installer.nsi
; 产物:年糕历险记-Setup-v1.0.0.exe(构建与发布.md §8)
; 特性:简体中文向导、可选安装目录、
; 快捷方式选项(组件页:桌面 / 开始菜单,默认勾选)、
; 安装完成后可选立即运行(完成页,默认勾选)、开始菜单卸载、卸载保留存档。
!include "MUI2.nsh"
@@ -24,12 +27,27 @@ InstallDirRegKey HKCU "${UNINSTALL_KEY}" "InstallLocation"
RequestExecutionLevel user
SetCompressor /SOLID lzma
!define MUI_ABORTWARNING
!define MUI_FINISHPAGE_RUN "$INSTDIR\${PRODUCT_EXE}"
!define MUI_FINISHPAGE_RUN_TEXT "运行${PRODUCT_NAME}"
; 安装器 exe 自身的版本信息
VIProductVersion "${VERSION}.0"
VIAddVersionKey "ProductName" "${PRODUCT_NAME}"
VIAddVersionKey "FileDescription" "${PRODUCT_NAME} 安装程序"
VIAddVersionKey "FileVersion" "${VERSION}"
VIAddVersionKey "ProductVersion" "${VERSION}"
VIAddVersionKey "CompanyName" "${PRODUCT_PUBLISHER}"
VIAddVersionKey "LegalCopyright" "Copyright (C) ${PRODUCT_PUBLISHER}"
; ---- 页面(全中文)----
!define MUI_ABORTWARNING
; 安装器/卸载器图标:游戏 logo(make_icon.ps1 从素材包 pack.png 生成多尺寸 icon.ico,
; 构建与发布.md §8「安装器图标」规范:安装包必须与游戏本体同图标)
!define MUI_ICON "..\cmd\client\icon.ico"
!define MUI_UNICON "..\cmd\client\icon.ico"
; 完成页「安装完成后运行」复选框(默认勾选)
!define MUI_FINISHPAGE_RUN "$INSTDIR\${PRODUCT_EXE}"
!define MUI_FINISHPAGE_RUN_TEXT "安装完成后运行${PRODUCT_NAME}"
; ---- 页面(全中文):欢迎 → 组件(快捷方式选项)→ 目录 → 安装 → 完成 ----
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
@@ -41,6 +59,7 @@ SetCompressor /SOLID lzma
; ---- 安装内容(构建与发布.md §8)----
Section "主程序" SEC01
SectionIn RO
SetOutPath "$INSTDIR"
File "..\bin\mc-client.exe"
File "..\bin\mc-server.exe"
@@ -80,15 +99,21 @@ Section "主程序" SEC01
WriteRegDWORD HKCU "${UNINSTALL_KEY}" "NoRepair" 1
WriteUninstaller "$INSTDIR\uninstall.exe"
SectionEnd
; 快捷方式(桌面 + 开始菜单,中文名)
; 快捷方式选项 1:桌面(默认勾选)
Section "创建桌面快捷方式" SEC02
CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_EXE}"
SectionEnd
; 快捷方式选项 2:开始菜单(默认勾选)
Section "创建开始菜单快捷方式" SEC03
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_EXE}"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\卸载${PRODUCT_NAME}.lnk" "$INSTDIR\uninstall.exe"
SectionEnd
; ---- 卸载 ----
; ---- 卸载(保留用户存档 worlds/ 与日志)----
Section "Uninstall"
Delete "$DESKTOP\${PRODUCT_NAME}.lnk"
RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}"
@@ -101,3 +126,10 @@ Section "Uninstall"
; 保留用户存档(worlds/)与日志,不删除
DeleteRegKey HKCU "${UNINSTALL_KEY}"
SectionEnd
; ---- 组件说明(组件页底部;必须放在所有 Section 声明之后)----
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "安装游戏主程序(客户端、服务器、素材包与配置文件)。必选。"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC02} "在桌面创建「${PRODUCT_NAME}」快捷方式。"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC03} "在开始菜单创建「${PRODUCT_NAME}」与「卸载${PRODUCT_NAME}」快捷方式。"
!insertmacro MUI_FUNCTION_DESCRIPTION_END

View File

@@ -1,7 +1,7 @@
# 年糕历险记 —— 程序图标生成(构建与发布.md §8:exe/窗口使用原版素材 logo)
# 年糕历险记 —— 程序图标生成(构建与发布.md §8:exe/窗口/快捷方式/安装器使用原版素材 logo)
# 用法:pwsh -File scripts/make_icon.ps1
# 流程:素材包 pack.png → cmd/client/icon.png → go-winres 生成 cmd/client/icon.syso
# (资源目录树格式,Go 链接器自动嵌入 exe;资源管理器/任务栏/快捷方式显示图标)。
# 流程:素材包 pack.png → cmd/client/icon.png → go-winres 生成 icon.syso(嵌入游戏 exe)
# → 同时生成多尺寸 cmd/client/icon.ico(供 NSIS 安装器 MUI_ICON / MUI_UNICON 使用)
$ErrorActionPreference = "Stop"
$root = Split-Path $PSScriptRoot -Parent
@@ -20,9 +20,47 @@ $env:GOCACHE = Join-Path $root ".gocache"
Push-Location (Join-Path $root "cmd\client")
try {
go run github.com/tc-hib/go-winres@latest make --in winres.json --out icon --arch amd64 --no-suffix
if ($LASTEXITCODE -ne 0) { throw "go-winres 生成失败" }
if ($LASTEXITCODE -ne 0) { throw "go-winres 生成失败" }
Move-Item -Force (Join-Path (Get-Location) "icon") (Join-Path (Get-Location) "icon.syso")
} finally {
Pop-Location
}
Write-Host "== 图标资源已嵌入:cmd/client/icon.syso =="
Write-Host "== 图标资源已嵌入:cmd/client/icon.syso =="
# 3) 生成多尺寸 icon.ico(16/24/32/48/64/128/256,PNG 压缩,供 NSIS 安装器/卸载器使用)
Add-Type -AssemblyName System.Drawing
$src = [System.Drawing.Image]::FromFile((Join-Path $root "cmd\client\icon.png"))
$sizes = @(16, 24, 32, 48, 64, 128, 256)
$ms = New-Object System.IO.MemoryStream
$bw = New-Object System.IO.BinaryWriter($ms)
# ICONDIR:reserved(2)=0, type(2)=1, count(2)
$bw.Write([uint16]0); $bw.Write([uint16]1); $bw.Write([uint16]$sizes.Count)
$offset = 6 + 16 * $sizes.Count
$images = @()
foreach ($s in $sizes) {
$bmp = New-Object System.Drawing.Bitmap($s, $s)
$g = [System.Drawing.Graphics]::FromImage($bmp)
$g.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
$g.DrawImage($src, 0, 0, $s, $s)
$g.Dispose()
$pngMs = New-Object System.IO.MemoryStream
$bmp.Save($pngMs, [System.Drawing.Imaging.ImageFormat]::Png)
$images += ,$pngMs.ToArray()
$bmp.Dispose(); $pngMs.Dispose()
}
for ($i = 0; $i -lt $sizes.Count; $i++) {
$s = $sizes[$i]
$dim = if ($s -ge 256) { 0 } else { $s } # 256 用 0 表示
$bw.Write([byte]$dim); $bw.Write([byte]$dim)
$bw.Write([byte]0); $bw.Write([byte]0) # colors / reserved
$bw.Write([uint16]1); $bw.Write([uint16]32) # planes / bpp
$bw.Write([uint32]$images[$i].Length)
$bw.Write([uint32]$offset)
$offset += $images[$i].Length
}
foreach ($d in $images) { $bw.Write($d) }
$bw.Flush()
[System.IO.File]::WriteAllBytes((Join-Path $root "cmd\client\icon.ico"), $ms.ToArray())
$src.Dispose()
$bw.Close(); $ms.Dispose()
Write-Host "== 安装器图标已生成:cmd/client/icon.ico($($sizes -join '/') px)=="

48
scripts/make_nsis.ps1 Normal file
View File

@@ -0,0 +1,48 @@
# 年糕历险记 —— NSIS 正式安装器构建脚本(构建与发布.md §8 交付方案)
# 用法:pwsh -File scripts/make_nsis.ps1 [-Version 0.1.0]
# 前置:C 工具链(tools/ 下 zig 或 MinGW,构建 GL 客户端需要);
# NSIS 3(自动查找 tools/nsis/nsis-*/makensis.exe,其次 PATH 中的 makensis)
# 产物:dist/年糕历险记-Setup-v<版本>.exe(简体中文向导、快捷方式选项、完成页运行选项)
param([string]$Version = "0.1.0")
$ErrorActionPreference = "Stop"
$root = Split-Path $PSScriptRoot -Parent
# 1) 构建 bin/(复用 build.ps1:定位 zig/gcc,产出 mc-client.exe / mc-server.exe 及资源)
& (Join-Path $PSScriptRoot "build.ps1")
if ($LASTEXITCODE -ne 0) { throw "构建失败(build.ps1)" }
# 2) 定位 makensis:优先 tools/nsis/(本项目自带 NSIS 3.10),其次系统 PATH
$makensisPath = (Get-ChildItem (Join-Path $root "tools\nsis") -Recurse -Filter makensis.exe -ErrorAction SilentlyContinue | Select-Object -First 1).FullName
if (-not $makensisPath) {
$cmd = Get-Command makensis -ErrorAction SilentlyContinue
if ($cmd) { $makensisPath = $cmd.Source }
}
if (-not $makensisPath) {
throw "未找到 NSIS:请把 NSIS 3 放到 tools/nsis/(如 nsis-3.10)或加入 PATH。下载:https://nsis.sourceforge.io/Download"
}
# 3) 确保安装器图标存在(游戏 logo:make_icon.ps1 生成 icon.syso 与 icon.ico;
# 缺失时调用;规范见 构建与发布.md §8「安装器图标」)
if (-not (Test-Path (Join-Path $root "cmd\client\icon.ico"))) {
& (Join-Path $PSScriptRoot "make_icon.ps1")
if ($LASTEXITCODE -ne 0) { throw "图标生成失败(make_icon.ps1)" }
}
# 3) 编译安装器(中文界面、快捷方式选项、安装完成后运行选项)
# installer.nsi 需为 UTF-8 带 BOM(NSIS 3 按 BOM 识别编码;文本编辑器保存可能去掉 BOM,这里自动补回)
$nsi = Join-Path $PSScriptRoot "installer.nsi"
$nsiBytes = [System.IO.File]::ReadAllBytes($nsi)
if (-not ($nsiBytes.Length -ge 3 -and $nsiBytes[0] -eq 0xEF -and $nsiBytes[1] -eq 0xBB -and $nsiBytes[2] -eq 0xBF)) {
[System.IO.File]::WriteAllText($nsi, [System.IO.File]::ReadAllText($nsi), (New-Object System.Text.UTF8Encoding($true)))
Write-Host "== installer.nsi 已补 UTF-8 BOM =="
}
New-Item -ItemType Directory -Force -Path (Join-Path $root "dist") | Out-Null
& $makensisPath "/DVERSION=$Version" $nsi
if ($LASTEXITCODE -ne 0) { throw "makensis 编译失败" }
$exe = Join-Path $root "dist\年糕历险记-Setup-v$Version.exe"
if (-not (Test-Path $exe)) { throw "未找到安装器产物:$exe" }
$sizeMB = [math]::Round((Get-Item $exe).Length / 1MB, 1)
Write-Host "== NSIS 安装器就绪:$exe($sizeMB MB)=="