diff --git a/README.md b/README.md index 2a16c77..5b5003f 100644 --- a/README.md +++ b/README.md @@ -7,14 +7,34 @@ | OS | Артефакты | UI | |----|----------|----| | Windows amd64 | `Navis.exe` | GUI (WebView2) | -| macOS arm64 | `Navis` · **`Navis.dmg`** · `Navis.app.zip` | CLI / .app | -| macOS amd64 | `Navis` · **`Navis.dmg`** · `Navis.app.zip` | CLI / .app | +| macOS universal | `Navis.dmg` · `Navis.app.zip` | CLI / .app — **рекомендуется** | +| macOS arm64 | `Navis` · `Navis.dmg` · `Navis.app.zip` | CLI / .app | +| macOS amd64 | `Navis` · `Navis.dmg` · `Navis.app.zip` | CLI / .app | ## Скачать macOS прямо с git Репозиторий: https://git.evilfox.cc/test2/navi -### 1. Узнайте архитектуру Mac +### Быстрая установка (автовыбор архитектуры) + +```bash +curl -fsSL "https://git.evilfox.cc/test2/navi/raw/branch/main/scripts/install-macos.sh" | bash +``` + +Скрипт скачает **универсальный DMG** (работает на Intel и Apple Silicon) и откроет его. + +### Универсальный DMG (рекомендуется) + +Подходит для **всех** Mac — M1/M2/M3/M4 и Intel: + +```bash +cd ~/Downloads +curl -fL -o Navis.dmg \ + "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.dmg" +open Navis.dmg +``` + +### 1. Узнайте архитектуру Mac (если нужна отдельная сборка) В Терминале: @@ -25,7 +45,9 @@ uname -m - `arm64` → Apple Silicon (M1/M2/M3/M4) → папка **darwin-arm64** - `x86_64` → Intel → папка **darwin-amd64** -### 2a. Скачать DMG (удобнее) +> **Важно:** на Mac M4 нельзя ставить сборку из `darwin-amd64` — иконка будет с перечёркиванием. Используйте **darwin-universal** или **darwin-arm64**. + +### 2a. Скачать DMG для конкретной архитектуры **Apple Silicon:** @@ -153,6 +175,7 @@ cd ~/Navis | Архитектура | CLI | DMG | ZIP (.app) | |-------------|-----|-----|------------| +| **universal** | [Navis](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis) | [Navis.dmg](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.dmg) | [Navis.app.zip](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.app.zip) | | arm64 | [Navis](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis) | [Navis.dmg](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.dmg) | [Navis.app.zip](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.app.zip) | | amd64 | [Navis](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis) | [Navis.dmg](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.dmg) | [Navis.app.zip](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.app.zip) | | манифест | [update.json](https://git.evilfox.cc/test2/navi/raw/branch/main/dist/update.json) | | | @@ -210,6 +233,9 @@ https://evilfox.win/ Некоторые AV (Bkav, Microsoft Wacapew/Wacatac, Ikarus Trojan.WinGo.Agent, Google, Trapmine) часто помечают **любые** неподписанные Go-бинарники с сетью и сменой системного прокси. +В 2.2.1: +- универсальный macOS DMG (Intel + Apple Silicon), скрипт автоустановки, предупреждения при неверной архитектуре. + В 2.2.0: - компактный список нод с пингом (как в Happ); - параллельный пинг, кнопка «Лучший», автоподключение к серверу с минимальной задержкой после подписки. diff --git a/build-macos.bat b/build-macos.bat index 37ba0d6..c1b6069 100644 --- a/build-macos.bat +++ b/build-macos.bat @@ -4,6 +4,7 @@ cd /d "%~dp0" mkdir "dist\navis-release\darwin-arm64" 2>nul mkdir "dist\navis-release\darwin-amd64" 2>nul +mkdir "dist\navis-release\darwin-universal" 2>nul set CGO_ENABLED=0 set GOOS=darwin @@ -19,15 +20,23 @@ set GOOS= set GOARCH= set CGO_ENABLED= +go build -o "tools\mklipo\mklipo.exe" .\tools\mklipo +if errorlevel 1 exit /b 1 +tools\mklipo\mklipo.exe "dist\navis-release\darwin-amd64\Navis" "dist\navis-release\darwin-arm64\Navis" "dist\navis-release\darwin-universal\Navis" +if errorlevel 1 exit /b 1 + go build -o "tools\packmac\packmac.exe" .\tools\packmac if errorlevel 1 exit /b 1 -tools\packmac\packmac.exe -bin "dist\navis-release\darwin-arm64\Navis" -out "dist\navis-release\darwin-arm64" -version 2.2.0 -arch arm64 +tools\packmac\packmac.exe -bin "dist\navis-release\darwin-arm64\Navis" -out "dist\navis-release\darwin-arm64" -version 2.2.1 -arch arm64 if errorlevel 1 exit /b 1 -tools\packmac\packmac.exe -bin "dist\navis-release\darwin-amd64\Navis" -out "dist\navis-release\darwin-amd64" -version 2.2.0 -arch amd64 +tools\packmac\packmac.exe -bin "dist\navis-release\darwin-amd64\Navis" -out "dist\navis-release\darwin-amd64" -version 2.2.1 -arch amd64 +if errorlevel 1 exit /b 1 +tools\packmac\packmac.exe -bin "dist\navis-release\darwin-universal\Navis" -out "dist\navis-release\darwin-universal" -version 2.2.1 -arch universal if errorlevel 1 exit /b 1 echo Built: +dir "dist\navis-release\darwin-universal" dir "dist\navis-release\darwin-arm64" dir "dist\navis-release\darwin-amd64" endlocal diff --git a/dist/navis-release/Navis.exe b/dist/navis-release/Navis.exe index 7c13344..e7a994b 100644 Binary files a/dist/navis-release/Navis.exe and b/dist/navis-release/Navis.exe differ diff --git a/dist/navis-release/darwin-amd64/Navis b/dist/navis-release/darwin-amd64/Navis index 905635d..3806f77 100644 Binary files a/dist/navis-release/darwin-amd64/Navis and b/dist/navis-release/darwin-amd64/Navis differ diff --git a/dist/navis-release/darwin-amd64/Navis.app.zip b/dist/navis-release/darwin-amd64/Navis.app.zip index f9371e0..1c03fc7 100644 Binary files a/dist/navis-release/darwin-amd64/Navis.app.zip and b/dist/navis-release/darwin-amd64/Navis.app.zip differ diff --git a/dist/navis-release/darwin-amd64/Navis.dmg b/dist/navis-release/darwin-amd64/Navis.dmg index 5315be5..90fb6ac 100644 Binary files a/dist/navis-release/darwin-amd64/Navis.dmg and b/dist/navis-release/darwin-amd64/Navis.dmg differ diff --git a/dist/navis-release/darwin-arm64/Navis b/dist/navis-release/darwin-arm64/Navis index b88bbc3..8a36804 100644 Binary files a/dist/navis-release/darwin-arm64/Navis and b/dist/navis-release/darwin-arm64/Navis differ diff --git a/dist/navis-release/darwin-arm64/Navis.app.zip b/dist/navis-release/darwin-arm64/Navis.app.zip index 9d0cdb5..4708563 100644 Binary files a/dist/navis-release/darwin-arm64/Navis.app.zip and b/dist/navis-release/darwin-arm64/Navis.app.zip differ diff --git a/dist/navis-release/darwin-arm64/Navis.dmg b/dist/navis-release/darwin-arm64/Navis.dmg index 90779f5..c71b32e 100644 Binary files a/dist/navis-release/darwin-arm64/Navis.dmg and b/dist/navis-release/darwin-arm64/Navis.dmg differ diff --git a/dist/navis-release/darwin-universal/Navis b/dist/navis-release/darwin-universal/Navis new file mode 100644 index 0000000..b4ad106 Binary files /dev/null and b/dist/navis-release/darwin-universal/Navis differ diff --git a/dist/navis-release/darwin-universal/Navis.app.zip b/dist/navis-release/darwin-universal/Navis.app.zip new file mode 100644 index 0000000..2dc7608 Binary files /dev/null and b/dist/navis-release/darwin-universal/Navis.app.zip differ diff --git a/dist/navis-release/darwin-universal/Navis.dmg b/dist/navis-release/darwin-universal/Navis.dmg new file mode 100644 index 0000000..d18157d Binary files /dev/null and b/dist/navis-release/darwin-universal/Navis.dmg differ diff --git a/dist/navis-release/update.json b/dist/navis-release/update.json index 05df1b6..e258e40 100644 --- a/dist/navis-release/update.json +++ b/dist/navis-release/update.json @@ -1,30 +1,42 @@ { - "version": "2.2.0", - "notes": "Компактный список нод с пингом (как Happ), автовыбор и подключение к серверу с лучшим пингом", + "version": "2.2.1", + "notes": "Универсальный macOS DMG (Intel + Apple Silicon), скрипт автоустановки, предупреждения при неверной архитектуре", "platform": "windows-amd64", "os": "windows", "arch": "amd64", "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe", - "sha256": "acd3a57cb52d745ecd0dc24074cfbd0299820d863ce00c2d4ce7753fb7dc73f3", + "sha256": "993e17d6390c8a4378e51016012006f18db1f6bd7c25957a4bf82fe31ab63473", "mandatory": false, "platforms": { "windows-amd64": { "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe", - "sha256": "acd3a57cb52d745ecd0dc24074cfbd0299820d863ce00c2d4ce7753fb7dc73f3", + "sha256": "993e17d6390c8a4378e51016012006f18db1f6bd7c25957a4bf82fe31ab63473", "os": "windows", "arch": "amd64" }, "darwin-arm64": { "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis", - "sha256": "777564f1605209deb67b440a8f94667443498df38cef0a34a0ab8ab9922dab44", + "sha256": "b1589bffebb7cbeee17ca5a40cedb6ca614a3580be22488505a1403e1021c2b6", "os": "darwin", - "arch": "arm64" + "arch": "arm64", + "dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.dmg", + "zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.app.zip" }, "darwin-amd64": { "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis", - "sha256": "5d0b0e3a2edebdb26f78eb39a7a67c6d7d7fb46beaa737869a0fec1150da3935", + "sha256": "149258fbad816aa2e73384da492bc91e3bf6700d4d01d55c9f35a3f68998232c", "os": "darwin", - "arch": "amd64" + "arch": "amd64", + "dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.dmg", + "zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.app.zip" + }, + "darwin-universal": { + "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis", + "sha256": "37ceb0e47cd542dadcd406cedecc760d9aa71a40f0b109f81d560de3a4eba79", + "os": "darwin", + "arch": "universal", + "dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.dmg", + "zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.app.zip" } } } diff --git a/dist/update.json b/dist/update.json index 05df1b6..e258e40 100644 --- a/dist/update.json +++ b/dist/update.json @@ -1,30 +1,42 @@ { - "version": "2.2.0", - "notes": "Компактный список нод с пингом (как Happ), автовыбор и подключение к серверу с лучшим пингом", + "version": "2.2.1", + "notes": "Универсальный macOS DMG (Intel + Apple Silicon), скрипт автоустановки, предупреждения при неверной архитектуре", "platform": "windows-amd64", "os": "windows", "arch": "amd64", "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe", - "sha256": "acd3a57cb52d745ecd0dc24074cfbd0299820d863ce00c2d4ce7753fb7dc73f3", + "sha256": "993e17d6390c8a4378e51016012006f18db1f6bd7c25957a4bf82fe31ab63473", "mandatory": false, "platforms": { "windows-amd64": { "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe", - "sha256": "acd3a57cb52d745ecd0dc24074cfbd0299820d863ce00c2d4ce7753fb7dc73f3", + "sha256": "993e17d6390c8a4378e51016012006f18db1f6bd7c25957a4bf82fe31ab63473", "os": "windows", "arch": "amd64" }, "darwin-arm64": { "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis", - "sha256": "777564f1605209deb67b440a8f94667443498df38cef0a34a0ab8ab9922dab44", + "sha256": "b1589bffebb7cbeee17ca5a40cedb6ca614a3580be22488505a1403e1021c2b6", "os": "darwin", - "arch": "arm64" + "arch": "arm64", + "dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.dmg", + "zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.app.zip" }, "darwin-amd64": { "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis", - "sha256": "5d0b0e3a2edebdb26f78eb39a7a67c6d7d7fb46beaa737869a0fec1150da3935", + "sha256": "149258fbad816aa2e73384da492bc91e3bf6700d4d01d55c9f35a3f68998232c", "os": "darwin", - "arch": "amd64" + "arch": "amd64", + "dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.dmg", + "zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.app.zip" + }, + "darwin-universal": { + "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis", + "sha256": "37ceb0e47cd542dadcd406cedecc760d9aa71a40f0b109f81d560de3a4eba79", + "os": "darwin", + "arch": "universal", + "dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.dmg", + "zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.app.zip" } } } diff --git a/internal/appui/index.html b/internal/appui/index.html index 9d47ad5..3f55ffc 100644 --- a/internal/appui/index.html +++ b/internal/appui/index.html @@ -725,7 +725,7 @@

Navis

- 2.2 + 2.2.1

Быстрый клиент · Naive · Hy2 · AWG · Xray

diff --git a/internal/update/update.go b/internal/update/update.go index a86f42a..d6a7bdf 100644 --- a/internal/update/update.go +++ b/internal/update/update.go @@ -17,7 +17,7 @@ import ( ) // CurrentVersion is the shipped client version. -const CurrentVersion = "2.2.0" +const CurrentVersion = "2.2.1" // DefaultManifestURL is the update feed (hosted in the project git repo). const DefaultManifestURL = "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/update.json" diff --git a/scripts/install-macos.sh b/scripts/install-macos.sh new file mode 100644 index 0000000..dd1d7a4 --- /dev/null +++ b/scripts/install-macos.sh @@ -0,0 +1,34 @@ +#!/bin/bash +set -euo pipefail + +BASE="https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release" +ARCH="$(uname -m)" + +case "$ARCH" in + arm64) + SUBDIR="darwin-arm64" + ;; + x86_64) + SUBDIR="darwin-amd64" + ;; + *) + echo "Неподдерживаемая архитектура: $ARCH" >&2 + exit 1 + ;; +esac + +DEST="${1:-$HOME/Downloads/Navis.dmg}" +UNIVERSAL="$BASE/darwin-universal/Navis.dmg" +SPECIFIC="$BASE/$SUBDIR/Navis.dmg" + +echo "Mac: $ARCH" +echo "Рекомендуется универсальный DMG (Intel + Apple Silicon)…" +if curl -fL -o "$DEST" "$UNIVERSAL"; then + echo "Скачан: $DEST" +else + echo "Универсальный DMG недоступен, скачиваю $SUBDIR…" + curl -fL -o "$DEST" "$SPECIFIC" +fi + +open "$DEST" +echo "Откройте диск и перетащите Navis.app в Программы." diff --git a/server/README.md b/server/README.md index 6066eac..21a66f3 100644 --- a/server/README.md +++ b/server/README.md @@ -6,6 +6,7 @@ - Windows: `…/dist/navis-release/Navis.exe` - macOS arm64: `…/dist/navis-release/darwin-arm64/Navis` - macOS amd64: `…/dist/navis-release/darwin-amd64/Navis` +- macOS universal (рекомендуется): `…/dist/navis-release/darwin-universal/Navis.dmg` Пример `dist/update.json` (multi-platform + legacy url для старых клиентов): diff --git a/server/update.json b/server/update.json index 05df1b6..e258e40 100644 --- a/server/update.json +++ b/server/update.json @@ -1,30 +1,42 @@ { - "version": "2.2.0", - "notes": "Компактный список нод с пингом (как Happ), автовыбор и подключение к серверу с лучшим пингом", + "version": "2.2.1", + "notes": "Универсальный macOS DMG (Intel + Apple Silicon), скрипт автоустановки, предупреждения при неверной архитектуре", "platform": "windows-amd64", "os": "windows", "arch": "amd64", "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe", - "sha256": "acd3a57cb52d745ecd0dc24074cfbd0299820d863ce00c2d4ce7753fb7dc73f3", + "sha256": "993e17d6390c8a4378e51016012006f18db1f6bd7c25957a4bf82fe31ab63473", "mandatory": false, "platforms": { "windows-amd64": { "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/Navis.exe", - "sha256": "acd3a57cb52d745ecd0dc24074cfbd0299820d863ce00c2d4ce7753fb7dc73f3", + "sha256": "993e17d6390c8a4378e51016012006f18db1f6bd7c25957a4bf82fe31ab63473", "os": "windows", "arch": "amd64" }, "darwin-arm64": { "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis", - "sha256": "777564f1605209deb67b440a8f94667443498df38cef0a34a0ab8ab9922dab44", + "sha256": "b1589bffebb7cbeee17ca5a40cedb6ca614a3580be22488505a1403e1021c2b6", "os": "darwin", - "arch": "arm64" + "arch": "arm64", + "dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.dmg", + "zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.app.zip" }, "darwin-amd64": { "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis", - "sha256": "5d0b0e3a2edebdb26f78eb39a7a67c6d7d7fb46beaa737869a0fec1150da3935", + "sha256": "149258fbad816aa2e73384da492bc91e3bf6700d4d01d55c9f35a3f68998232c", "os": "darwin", - "arch": "amd64" + "arch": "amd64", + "dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.dmg", + "zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-amd64/Navis.app.zip" + }, + "darwin-universal": { + "url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis", + "sha256": "37ceb0e47cd542dadcd406cedecc760d9aa71a40f0b109f81d560de3a4eba79", + "os": "darwin", + "arch": "universal", + "dmg_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.dmg", + "zip_url": "https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.app.zip" } } } diff --git a/tools/mklipo/main.go b/tools/mklipo/main.go new file mode 100644 index 0000000..bdd09d3 --- /dev/null +++ b/tools/mklipo/main.go @@ -0,0 +1,105 @@ +// mklipo merges two Mach-O binaries into one macOS universal (fat) binary. +package main + +import ( + "encoding/binary" + "fmt" + "os" +) + +const ( + fatMagic = 0xCAFEBABE + cpuTypeX86_64 = 0x01000007 + cpuTypeARM64 = 0x0100000c + fatArchSize = 20 +) + +type slice struct { + cpu, sub uint32 + data []byte +} + +func main() { + if len(os.Args) != 4 { + fmt.Fprintln(os.Stderr, "usage: mklipo ") + os.Exit(2) + } + amd, err := os.ReadFile(os.Args[1]) + if err != nil { + fatal(err) + } + arm, err := os.ReadFile(os.Args[2]) + if err != nil { + fatal(err) + } + if err := writeFat(os.Args[3], []slice{ + {cpuTypeX86_64, 3, amd}, + {cpuTypeARM64, 0, arm}, + }); err != nil { + fatal(err) + } +} + +func writeFat(path string, parts []slice) error { + const align uint32 = 0x4000 + hdr := 8 + fatArchSize*len(parts) + offsets := make([]uint32, len(parts)) + cur := uint32(hdr) + for i, p := range parts { + pad := (align - (cur % align)) % align + cur += pad + offsets[i] = cur + cur += uint32(len(p.data)) + } + + out, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o755) + if err != nil { + return err + } + defer out.Close() + + if err := binary.Write(out, binary.BigEndian, uint32(fatMagic)); err != nil { + return err + } + if err := binary.Write(out, binary.BigEndian, uint32(len(parts))); err != nil { + return err + } + for i, p := range parts { + if err := binary.Write(out, binary.BigEndian, p.cpu); err != nil { + return err + } + if err := binary.Write(out, binary.BigEndian, p.sub); err != nil { + return err + } + if err := binary.Write(out, binary.BigEndian, offsets[i]); err != nil { + return err + } + if err := binary.Write(out, binary.BigEndian, uint32(len(p.data))); err != nil { + return err + } + if err := binary.Write(out, binary.BigEndian, align); err != nil { + return err + } + } + + cur = uint32(hdr) + for _, p := range parts { + pad := (align - (cur % align)) % align + if pad > 0 { + if _, err := out.Write(make([]byte, pad)); err != nil { + return err + } + cur += pad + } + if _, err := out.Write(p.data); err != nil { + return err + } + cur += uint32(len(p.data)) + } + return nil +} + +func fatal(err error) { + fmt.Fprintln(os.Stderr, "mklipo:", err) + os.Exit(1) +} diff --git a/tools/packmac/main.go b/tools/packmac/main.go index df5bd20..87d0fdd 100644 --- a/tools/packmac/main.go +++ b/tools/packmac/main.go @@ -42,33 +42,49 @@ func run(binPath, outDir, version, arch string) error { defer os.RemoveAll(stage) appRoot := filepath.Join(stage, "Navis.app") - if err := writeAppBundle(appRoot, binPath, version); err != nil { + if err := writeAppBundle(appRoot, binPath, version, arch); err != nil { return err } readme := filepath.Join(stage, "README.txt") if err := os.WriteFile(readme, []byte(readmeText(version, arch)), 0o644); err != nil { return err } + warnName := archWarningFilename(arch) + if warnName != "" { + if err := os.WriteFile(filepath.Join(stage, warnName), []byte(archWarningText(arch)), 0o644); err != nil { + return err + } + } + zipEntries := []string{"Navis.app", "README.txt"} + if warnName != "" { + zipEntries = append(zipEntries, warnName) + } zipPath := filepath.Join(outDir, "Navis.app.zip") - if err := zipDir(zipPath, stage, []string{"Navis.app", "README.txt"}); err != nil { + if err := zipDir(zipPath, stage, zipEntries); err != nil { return fmt.Errorf("zip: %w", err) } fmt.Println("wrote", zipPath) dmgPath := filepath.Join(outDir, "Navis.dmg") - if err := writeDMG(dmgPath, appRoot, readme, "Navis-"+arch); err != nil { + dmgFiles := []dmgEntry{{appRoot, "/Navis.app"}} + if warnName != "" { + dmgFiles = append(dmgFiles, dmgEntry{filepath.Join(stage, warnName), "/" + warnName}) + } + dmgFiles = append(dmgFiles, dmgEntry{readme, "/README.txt"}) + if err := writeDMG(dmgPath, dmgFiles, "Navis-"+arch); err != nil { return fmt.Errorf("dmg: %w", err) } fmt.Println("wrote", dmgPath) return nil } -func writeAppBundle(appRoot, binPath, version string) error { +func writeAppBundle(appRoot, binPath, version, arch string) error { macOSDir := filepath.Join(appRoot, "Contents", "MacOS") if err := os.MkdirAll(macOSDir, 0o755); err != nil { return err } + archPriority := architecturePriorityXML(arch) plist := fmt.Sprintf(` @@ -80,10 +96,10 @@ func writeAppBundle(appRoot, binPath, version string) error { CFBundleShortVersionString%s CFBundleVersion%s LSMinimumSystemVersion11.0 - CFBundleInfoDictionaryVersion6.0 + CFBundleInfoDictionaryVersion6.0%s -`, version, version) +`, version, version, archPriority) if err := os.WriteFile(filepath.Join(appRoot, "Contents", "Info.plist"), []byte(plist), 0o644); err != nil { return err } @@ -94,21 +110,25 @@ func writeAppBundle(appRoot, binPath, version string) error { return nil } -func writeDMG(dmgPath, appRoot, readmePath, volume string) error { +type dmgEntry struct { + srcPath string + dstPath string +} + +func writeDMG(dmgPath string, files []dmgEntry, volume string) error { _ = os.Remove(dmgPath) - appSize, err := dirSize(appRoot) - if err != nil { - return err + var need int64 + for _, f := range files { + if fi, err := os.Stat(f.srcPath); err == nil && !fi.IsDir() { + need += fi.Size() + } else if sz, err := dirSize(f.srcPath); err == nil { + need += sz + } } - readmeSize, err := fileSize(readmePath) - if err != nil { - return err - } - need := appSize + readmeSize + 4*1024*1024 + need += 4 * 1024 * 1024 if need < 12*1024*1024 { need = 12 * 1024 * 1024 } - // round up to 2048 need = ((need + 2047) / 2048) * 2048 mydisk, err := diskfs.Create(dmgPath, need, diskfs.SectorSizeDefault) @@ -125,13 +145,23 @@ func writeDMG(dmgPath, appRoot, readmePath, volume string) error { return err } - if err := copyTreeToISO(fs, appRoot, "/Navis.app"); err != nil { - _ = fs.Close() - return err - } - if err := writeISOFile(fs, "/README.txt", readmePath, 0o644); err != nil { - _ = fs.Close() - return err + for _, f := range files { + info, err := os.Stat(f.srcPath) + if err != nil { + _ = fs.Close() + return err + } + if info.IsDir() { + if err := copyTreeToISO(fs, f.srcPath, f.dstPath); err != nil { + _ = fs.Close() + return err + } + continue + } + if err := writeISOFile(fs, f.dstPath, f.srcPath, 0o644); err != nil { + _ = fs.Close() + return err + } } iso, ok := fs.(*iso9660.FileSystem) @@ -336,19 +366,114 @@ func sanitizeVol(s string) string { } func readmeText(version, arch string) string { - return fmt.Sprintf(`Navis %s for macOS (%s) + switch arch { + case "universal": + return fmt.Sprintf(`Navis %s for macOS (универсальная сборка) -1) Open this disk image -2) Drag Navis.app to Applications (or any folder) -3) First launch may need: +Подходит для Apple Silicon (M1/M2/M3/M4) и Intel Mac. + +1) Перетащите Navis.app в Программы (Applications) +2) При первом запуске, если macOS блокирует: xattr -dr com.apple.quarantine /Applications/Navis.app -4) Run from Terminal: +3) В Терминале: /Applications/Navis.app/Contents/MacOS/Navis init /Applications/Navis.app/Contents/MacOS/Navis install-core /Applications/Navis.app/Contents/MacOS/Navis connect -Or use the CLI binary next to this DMG on git (file named Navis). +Магазин: https://evilfox.win/ +`, version) + case "arm64": + return fmt.Sprintf(`Navis %s for macOS (Apple Silicon: M1/M2/M3/M4) -Shop: https://evilfox.win/ +⚠️ Только для Mac с чипом Apple Silicon (arm64). +На Intel Mac скачайте darwin-amd64 или darwin-universal. + +1) Перетащите Navis.app в Программы +2) xattr -dr com.apple.quarantine /Applications/Navis.app +3) /Applications/Navis.app/Contents/MacOS/Navis connect + +Магазин: https://evilfox.win/ +`, version) + case "amd64": + return fmt.Sprintf(`Navis %s for macOS (Intel x86_64) + +⚠️ Только для Intel Mac. +На Mac M1/M2/M3/M4 эта сборка НЕ запустится — скачайте darwin-arm64 или darwin-universal. + +1) Перетащите Navis.app в Программы +2) xattr -dr com.apple.quarantine /Applications/Navis.app +3) /Applications/Navis.app/Contents/MacOS/Navis connect + +Магазин: https://evilfox.win/ +`, version) + default: + return fmt.Sprintf(`Navis %s for macOS (%s) + +1) Drag Navis.app to Applications +2) xattr -dr com.apple.quarantine /Applications/Navis.app +3) /Applications/Navis.app/Contents/MacOS/Navis connect `, version, arch) + } +} + +func archWarningFilename(arch string) string { + switch arch { + case "amd64": + return "ТОЛЬКО-INTEL-MAC.txt" + case "arm64": + return "ТОЛЬКО-APPLE-SILICON.txt" + default: + return "" + } +} + +func archWarningText(arch string) string { + switch arch { + case "amd64": + return `ВНИМАНИЕ + +Эта сборка Navis только для Intel Mac (x86_64). + +Если у вас Mac mini / MacBook с чипом M1, M2, M3 или M4 — +закройте этот диск и скачайте универсальный DMG: + +https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.dmg + +Или arm64: +https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-arm64/Navis.dmg +` + case "arm64": + return `ВНИМАНИЕ + +Эта сборка Navis только для Apple Silicon (M1/M2/M3/M4). + +Если у вас Intel Mac — скачайте darwin-amd64 или универсальный DMG: + +https://git.evilfox.cc/test2/navi/raw/branch/main/dist/navis-release/darwin-universal/Navis.dmg +` + default: + return "" + } +} + +func architecturePriorityXML(arch string) string { + switch arch { + case "universal": + return ` + LSArchitecturePriority + + arm64 + x86_64 + ` + case "arm64": + return ` + LSArchitecturePriority + arm64` + case "amd64": + return ` + LSArchitecturePriority + x86_64` + default: + return "" + } } diff --git a/versioninfo.json b/versioninfo.json index 9ea57a9..b07185d 100644 --- a/versioninfo.json +++ b/versioninfo.json @@ -1,7 +1,7 @@ { "FixedFileInfo": { - "FileVersion": { "Major": 2, "Minor": 2, "Patch": 0, "Build": 0 }, - "ProductVersion": { "Major": 2, "Minor": 2, "Patch": 0, "Build": 0 }, + "FileVersion": { "Major": 2, "Minor": 2, "Patch": 1, "Build": 0 }, + "ProductVersion": { "Major": 2, "Minor": 2, "Patch": 1, "Build": 0 }, "FileFlagsMask": "3f", "FileFlags": "00", "FileOS": "40004", @@ -11,12 +11,12 @@ "StringFileInfo": { "CompanyName": "EvilFox", "FileDescription": "Navis 2 — VPN client (Naive / Hy2 / AWG / VLESS / VMess / Trojan)", - "FileVersion": "2.2.0.0", + "FileVersion": "2.2.1.0", "InternalName": "Navis", "LegalCopyright": "Copyright (c) EvilFox", "OriginalFilename": "Navis.exe", "ProductName": "Navis", - "ProductVersion": "2.2.0.0", + "ProductVersion": "2.2.1.0", "Comments": "Open-source VPN/proxy client. https://evilfox.win/" }, "VarFileInfo": {