From d8b0e9929cd96069e053b7abe2f1692728367bbc Mon Sep 17 00:00:00 2001 From: Tunglies <77394545+Tunglies@users.noreply.github.com> Date: Wed, 29 Oct 2025 21:09:21 +0800 Subject: [PATCH] fix: include Mihomo-go122 by default for macOS 10.15+ to resolve Intel architecture compatibility issues --- UPDATELOG.md | 1 + scripts/prebuild.mjs | 443 +++++++++++++++++++++---------------------- 2 files changed, 216 insertions(+), 228 deletions(-) diff --git a/UPDATELOG.md b/UPDATELOG.md index 2d297526..b38c286f 100644 --- a/UPDATELOG.md +++ b/UPDATELOG.md @@ -42,6 +42,7 @@ - 优化首页当前节点对MATCH规则的支持 - 允许在 `界面设置` 修改 `悬浮跳转导航延迟` - 添加热键绑定错误的提示信息 +- 在 macOS 10.15 及更高版本默认包含 Mihomo-go122,以解决 Intel 架构 Mac 无法运行内核的问题 ### 🐞 修复问题 diff --git a/scripts/prebuild.mjs b/scripts/prebuild.mjs index 1cf801c5..d127a0ca 100644 --- a/scripts/prebuild.mjs +++ b/scripts/prebuild.mjs @@ -18,7 +18,6 @@ import { log_debug, log_error, log_info, log_success } from "./utils.mjs"; * 3. Use file hash to detect changes and skip unnecessary chmod/copy operations * 4. Use --force or -f flag to force re-download and update all resources * - * This optimization significantly reduces build time for local development */ const cwd = process.cwd(); @@ -56,8 +55,7 @@ const ARCH_MAP = { const arg1 = process.argv.slice(2)[0]; const arg2 = process.argv.slice(2)[1]; -let target; -target = arg1 === "--force" || arg1 === "-f" ? arg2 : arg1; +let target = arg1 === "--force" || arg1 === "-f" ? arg2 : arg1; const { platform, arch } = target ? { platform: PLATFORM_MAP[target], arch: ARCH_MAP[target] } : process; @@ -68,7 +66,9 @@ const SIDECAR_HOST = target .toString() .match(/(?<=host: ).+(?=\s*)/g)[0]; -/* ======= Version Cache Functions ======= */ +// ======================= +// Version Cache +// ======================= async function loadVersionCache() { try { if (fs.existsSync(VERSION_CACHE_FILE)) { @@ -80,7 +80,6 @@ async function loadVersionCache() { } return {}; } - async function saveVersionCache(cache) { try { await fsp.mkdir(TEMP_DIR, { recursive: true }); @@ -90,28 +89,24 @@ async function saveVersionCache(cache) { log_debug("Failed to save version cache:", err.message); } } - async function getCachedVersion(key) { const cache = await loadVersionCache(); const cached = cache[key]; if (cached && Date.now() - cached.timestamp < 3600000) { - // 1小时内有效 log_info(`Using cached version for ${key}: ${cached.version}`); return cached.version; } return null; } - async function setCachedVersion(key, version) { const cache = await loadVersionCache(); - cache[key] = { - version, - timestamp: Date.now(), - }; + cache[key] = { version, timestamp: Date.now() }; await saveVersionCache(cache); } -/* ======= File Hash Functions ======= */ +// ======================= +// Hash Cache & File Hash +// ======================= async function calculateFileHash(filePath) { try { const fileBuffer = await fsp.readFile(filePath); @@ -122,7 +117,6 @@ async function calculateFileHash(filePath) { return null; } } - async function loadHashCache() { try { if (fs.existsSync(HASH_CACHE_FILE)) { @@ -134,7 +128,6 @@ async function loadHashCache() { } return {}; } - async function saveHashCache(cache) { try { await fsp.mkdir(TEMP_DIR, { recursive: true }); @@ -144,28 +137,20 @@ async function saveHashCache(cache) { log_debug("Failed to save hash cache:", err.message); } } - async function hasFileChanged(filePath, targetPath) { if (FORCE) return true; if (!fs.existsSync(targetPath)) return true; - const hashCache = await loadHashCache(); const sourceHash = await calculateFileHash(filePath); const targetHash = await calculateFileHash(targetPath); - if (!sourceHash || !targetHash) return true; - const cacheKey = targetPath; const cachedHash = hashCache[cacheKey]; - if (cachedHash === sourceHash && sourceHash === targetHash) { - // 文件未变化,不输出日志 return false; } - return true; } - async function updateHashCache(targetPath) { const hashCache = await loadHashCache(); const hash = await calculateFileHash(targetPath); @@ -175,18 +160,25 @@ async function updateHashCache(targetPath) { } } -/* ======= clash meta alpha======= */ +// ======================= +// Meta maps (stable & alpha) +// ======================= const META_ALPHA_VERSION_URL = "https://github.com/MetaCubeX/mihomo/releases/download/Prerelease-Alpha/version.txt"; const META_ALPHA_URL_PREFIX = `https://github.com/MetaCubeX/mihomo/releases/download/Prerelease-Alpha`; let META_ALPHA_VERSION; +const META_VERSION_URL = + "https://github.com/MetaCubeX/mihomo/releases/latest/download/version.txt"; +const META_URL_PREFIX = `https://github.com/MetaCubeX/mihomo/releases/download`; +let META_VERSION; + const META_ALPHA_MAP = { "win32-x64": "mihomo-windows-amd64-v2", "win32-ia32": "mihomo-windows-386", "win32-arm64": "mihomo-windows-arm64", - "darwin-x64": "mihomo-darwin-amd64-v1", - "darwin-arm64": "mihomo-darwin-arm64", + "darwin-x64": "mihomo-darwin-amd64-v1-go122", + "darwin-arm64": "mihomo-darwin-arm64-go122", "linux-x64": "mihomo-linux-amd64-v2", "linux-ia32": "mihomo-linux-386", "linux-arm64": "mihomo-linux-arm64", @@ -195,9 +187,24 @@ const META_ALPHA_MAP = { "linux-loong64": "mihomo-linux-loong64", }; -// Fetch the latest alpha release version from the version.txt file +const META_MAP = { + "win32-x64": "mihomo-windows-amd64-v2", + "win32-ia32": "mihomo-windows-386", + "win32-arm64": "mihomo-windows-arm64", + "darwin-x64": "mihomo-darwin-amd64-v2-go122", + "darwin-arm64": "mihomo-darwin-arm64-go122", + "linux-x64": "mihomo-linux-amd64-v2", + "linux-ia32": "mihomo-linux-386", + "linux-arm64": "mihomo-linux-arm64", + "linux-arm": "mihomo-linux-armv7", + "linux-riscv64": "mihomo-linux-riscv64", + "linux-loong64": "mihomo-linux-loong64", +}; + +// ======================= +// Fetch latest versions +// ======================= async function getLatestAlphaVersion() { - // 如果不强制更新,先尝试从缓存获取 if (!FORCE) { const cached = await getCachedVersion("META_ALPHA_VERSION"); if (cached) { @@ -205,58 +212,33 @@ async function getLatestAlphaVersion() { return; } } - const options = {}; - const httpProxy = process.env.HTTP_PROXY || process.env.http_proxy || process.env.HTTPS_PROXY || process.env.https_proxy; + if (httpProxy) options.agent = new HttpsProxyAgent(httpProxy); - if (httpProxy) { - options.agent = new HttpsProxyAgent(httpProxy); - } try { const response = await fetch(META_ALPHA_VERSION_URL, { ...options, method: "GET", }); - let v = await response.text(); - META_ALPHA_VERSION = v.trim(); // Trim to remove extra whitespaces + if (!response.ok) + throw new Error( + `Failed to fetch ${META_ALPHA_VERSION_URL}: ${response.status}`, + ); + META_ALPHA_VERSION = (await response.text()).trim(); log_info(`Latest alpha version: ${META_ALPHA_VERSION}`); - - // 保存到缓存 await setCachedVersion("META_ALPHA_VERSION", META_ALPHA_VERSION); - } catch (error) { - log_error("Error fetching latest alpha version:", error.message); + } catch (err) { + log_error("Error fetching latest alpha version:", err.message); process.exit(1); } } -/* ======= clash meta stable ======= */ -const META_VERSION_URL = - "https://github.com/MetaCubeX/mihomo/releases/latest/download/version.txt"; -const META_URL_PREFIX = `https://github.com/MetaCubeX/mihomo/releases/download`; -let META_VERSION; - -const META_MAP = { - "win32-x64": "mihomo-windows-amd64-v2", - "win32-ia32": "mihomo-windows-386", - "win32-arm64": "mihomo-windows-arm64", - "darwin-x64": "mihomo-darwin-amd64-v2", - "darwin-arm64": "mihomo-darwin-arm64", - "linux-x64": "mihomo-linux-amd64-v2", - "linux-ia32": "mihomo-linux-386", - "linux-arm64": "mihomo-linux-arm64", - "linux-arm": "mihomo-linux-armv7", - "linux-riscv64": "mihomo-linux-riscv64", - "linux-loong64": "mihomo-linux-loong64", -}; - -// Fetch the latest release version from the version.txt file async function getLatestReleaseVersion() { - // 如果不强制更新,先尝试从缓存获取 if (!FORCE) { const cached = await getCachedVersion("META_VERSION"); if (cached) { @@ -264,67 +246,57 @@ async function getLatestReleaseVersion() { return; } } - const options = {}; - const httpProxy = process.env.HTTP_PROXY || process.env.http_proxy || process.env.HTTPS_PROXY || process.env.https_proxy; + if (httpProxy) options.agent = new HttpsProxyAgent(httpProxy); - if (httpProxy) { - options.agent = new HttpsProxyAgent(httpProxy); - } try { const response = await fetch(META_VERSION_URL, { ...options, method: "GET", }); - let v = await response.text(); - META_VERSION = v.trim(); // Trim to remove extra whitespaces + if (!response.ok) + throw new Error( + `Failed to fetch ${META_VERSION_URL}: ${response.status}`, + ); + META_VERSION = (await response.text()).trim(); log_info(`Latest release version: ${META_VERSION}`); - - // 保存到缓存 await setCachedVersion("META_VERSION", META_VERSION); - } catch (error) { - log_error("Error fetching latest release version:", error.message); + } catch (err) { + log_error("Error fetching latest release version:", err.message); process.exit(1); } } -/* - * check available - */ +// ======================= +// Validate availability +// ======================= if (!META_MAP[`${platform}-${arch}`]) { - throw new Error( - `clash meta alpha unsupported platform "${platform}-${arch}"`, - ); + throw new Error(`clash meta unsupported platform "${platform}-${arch}"`); } - if (!META_ALPHA_MAP[`${platform}-${arch}`]) { throw new Error( `clash meta alpha unsupported platform "${platform}-${arch}"`, ); } -/** - * core info - */ +// ======================= +// Build meta objects +// ======================= function clashMetaAlpha() { const name = META_ALPHA_MAP[`${platform}-${arch}`]; const isWin = platform === "win32"; const urlExt = isWin ? "zip" : "gz"; - const downloadURL = `${META_ALPHA_URL_PREFIX}/${name}-${META_ALPHA_VERSION}.${urlExt}`; - const exeFile = `${name}${isWin ? ".exe" : ""}`; - const zipFile = `${name}-${META_ALPHA_VERSION}.${urlExt}`; - return { name: "verge-mihomo-alpha", targetFile: `verge-mihomo-alpha-${SIDECAR_HOST}${isWin ? ".exe" : ""}`, - exeFile, - zipFile, - downloadURL, + exeFile: `${name}${isWin ? ".exe" : ""}`, + zipFile: `${name}-${META_ALPHA_VERSION}.${urlExt}`, + downloadURL: `${META_ALPHA_URL_PREFIX}/${name}-${META_ALPHA_VERSION}.${urlExt}`, }; } @@ -332,40 +304,83 @@ function clashMeta() { const name = META_MAP[`${platform}-${arch}`]; const isWin = platform === "win32"; const urlExt = isWin ? "zip" : "gz"; - const downloadURL = `${META_URL_PREFIX}/${META_VERSION}/${name}-${META_VERSION}.${urlExt}`; - const exeFile = `${name}${isWin ? ".exe" : ""}`; - const zipFile = `${name}-${META_VERSION}.${urlExt}`; - return { name: "verge-mihomo", targetFile: `verge-mihomo-${SIDECAR_HOST}${isWin ? ".exe" : ""}`, - exeFile, - zipFile, - downloadURL, + exeFile: `${name}${isWin ? ".exe" : ""}`, + zipFile: `${name}-${META_VERSION}.${urlExt}`, + downloadURL: `${META_URL_PREFIX}/${META_VERSION}/${name}-${META_VERSION}.${urlExt}`, }; } -/** - * download sidecar and rename - */ + +// ======================= +// download helper (增强:status + magic bytes) +// ======================= +async function downloadFile(url, outPath) { + const options = {}; + const httpProxy = + process.env.HTTP_PROXY || + process.env.http_proxy || + process.env.HTTPS_PROXY || + process.env.https_proxy; + if (httpProxy) options.agent = new HttpsProxyAgent(httpProxy); + + const response = await fetch(url, { + ...options, + method: "GET", + headers: { "Content-Type": "application/octet-stream" }, + }); + if (!response.ok) { + const body = await response.text().catch(() => ""); + // 将 body 写到文件以便排查(可通过临时目录查看) + await fsp.mkdir(path.dirname(outPath), { recursive: true }); + await fsp.writeFile(outPath, body); + throw new Error(`Failed to download ${url}: status ${response.status}`); + } + + const buf = Buffer.from(await response.arrayBuffer()); + await fsp.mkdir(path.dirname(outPath), { recursive: true }); + + // 简单 magic 字节检查 + if (url.endsWith(".gz") || url.endsWith(".tgz")) { + if (!(buf[0] === 0x1f && buf[1] === 0x8b)) { + await fsp.writeFile(outPath, buf); + throw new Error( + `Downloaded file for ${url} is not a valid gzip (magic mismatch).`, + ); + } + } else if (url.endsWith(".zip")) { + if (!(buf[0] === 0x50 && buf[1] === 0x4b)) { + await fsp.writeFile(outPath, buf); + throw new Error( + `Downloaded file for ${url} is not a valid zip (magic mismatch).`, + ); + } + } + + await fsp.writeFile(outPath, buf); + log_success(`download finished: ${url}`); +} + +// ======================= +// resolveSidecar (支持 zip / tgz / gz) +// ======================= async function resolveSidecar(binInfo) { const { name, targetFile, zipFile, exeFile, downloadURL } = binInfo; - const sidecarDir = path.join(cwd, "src-tauri", "sidecar"); const sidecarPath = path.join(sidecarDir, targetFile); - await fsp.mkdir(sidecarDir, { recursive: true }); - // 检查文件是否已存在,如果存在则跳过重复下载 if (!FORCE && fs.existsSync(sidecarPath)) { - log_success(`"${name}" already exists, skipping download to save time`); + log_success(`"${name}" already exists, skipping download`); return; } const tempDir = path.join(TEMP_DIR, name); const tempZip = path.join(tempDir, zipFile); const tempExe = path.join(tempDir, exeFile); - await fsp.mkdir(tempDir, { recursive: true }); + try { if (!fs.existsSync(tempZip)) { await downloadFile(downloadURL, tempZip); @@ -374,78 +389,76 @@ async function resolveSidecar(binInfo) { if (zipFile.endsWith(".zip")) { const zip = new AdmZip(tempZip); zip.getEntries().forEach((entry) => { - log_debug(`"${name}" entry name`, entry.entryName); + log_debug(`"${name}" entry: ${entry.entryName}`); }); zip.extractAllTo(tempDir, true); - await fsp.rename(tempExe, sidecarPath); + // 尝试按 exeFile 重命名,否则找第一个可执行文件 + if (fs.existsSync(tempExe)) { + await fsp.rename(tempExe, sidecarPath); + } else { + // 搜索候选 + const files = await fsp.readdir(tempDir); + const candidate = files.find( + (f) => + f === path.basename(exeFile) || + f.endsWith(".exe") || + !f.includes("."), + ); + if (!candidate) + throw new Error(`Expected binary not found in ${tempDir}`); + await fsp.rename(path.join(tempDir, candidate), sidecarPath); + } + if (platform !== "win32") execSync(`chmod 755 ${sidecarPath}`); log_success(`unzip finished: "${name}"`); } else if (zipFile.endsWith(".tgz")) { - // tgz - await fsp.mkdir(tempDir, { recursive: true }); - await extract({ - cwd: tempDir, - file: tempZip, - //strip: 1, // 可能需要根据实际的 .tgz 文件结构调整 - }); + await extract({ cwd: tempDir, file: tempZip }); const files = await fsp.readdir(tempDir); - log_debug(`"${name}" files in tempDir:`, files); - const extractedFile = files.find((file) => file.startsWith("虚空终端-")); - if (extractedFile) { - const extractedFilePath = path.join(tempDir, extractedFile); - await fsp.rename(extractedFilePath, sidecarPath); - log_success(`"${name}" file renamed to "${sidecarPath}"`); - execSync(`chmod 755 ${sidecarPath}`); - log_success(`chmod binary finished: "${name}"`); - } else { - throw new Error(`Expected file not found in ${tempDir}`); - } + log_debug(`"${name}" extracted files:`, files); + // 优先寻找给定 exeFile 或已知前缀 + let extracted = files.find( + (f) => + f === path.basename(exeFile) || + f.startsWith("虚空终端-") || + !f.includes("."), + ); + if (!extracted) extracted = files[0]; + if (!extracted) throw new Error(`Expected file not found in ${tempDir}`); + await fsp.rename(path.join(tempDir, extracted), sidecarPath); + execSync(`chmod 755 ${sidecarPath}`); + log_success(`tgz processed: "${name}"`); } else { - // gz + // .gz const readStream = fs.createReadStream(tempZip); const writeStream = fs.createWriteStream(sidecarPath); await new Promise((resolve, reject) => { - const onError = (error) => { - log_error(`"${name}" gz failed:`, error.message); - reject(error); - }; readStream - .pipe(zlib.createGunzip().on("error", onError)) + .pipe(zlib.createGunzip()) + .on("error", (e) => { + log_error(`gunzip error for ${name}:`, e.message); + reject(e); + }) .pipe(writeStream) .on("finish", () => { - execSync(`chmod 755 ${sidecarPath}`); - log_success(`chmod binary finished: "${name}"`); + if (platform !== "win32") execSync(`chmod 755 ${sidecarPath}`); resolve(); }) - .on("error", onError); + .on("error", (e) => { + log_error(`write stream error for ${name}:`, e.message); + reject(e); + }); }); + log_success(`gz binary processed: "${name}"`); } } catch (err) { - // 需要删除文件 await fsp.rm(sidecarPath, { recursive: true, force: true }); throw err; } finally { - // delete temp dir await fsp.rm(tempDir, { recursive: true, force: true }); } } -const resolveSetDnsScript = () => - resolveResource({ - file: "set_dns.sh", - localPath: path.join(cwd, "scripts/set_dns.sh"), - }); -const resolveUnSetDnsScript = () => - resolveResource({ - file: "unset_dns.sh", - localPath: path.join(cwd, "scripts/unset_dns.sh"), - }); - -/** - * download the file to the resources dir - */ async function resolveResource(binInfo) { const { file, downloadURL, localPath } = binInfo; - const resDir = path.join(cwd, "src-tauri/resources"); const targetPath = path.join(resDir, file); @@ -465,12 +478,9 @@ async function resolveResource(binInfo) { } if (localPath) { - // 检查文件哈希是否变化 if (!(await hasFileChanged(localPath, targetPath))) { - // 文件未变化,静默跳过 return; } - await fsp.mkdir(resDir, { recursive: true }); await fsp.copyFile(localPath, targetPath); await updateHashCache(targetPath); @@ -480,44 +490,17 @@ async function resolveResource(binInfo) { log_success(`${file} finished`); } -/** - * download file and save to `path` - */ async function downloadFile(url, path) { - const options = {}; - - const httpProxy = - process.env.HTTP_PROXY || - process.env.http_proxy || - process.env.HTTPS_PROXY || - process.env.https_proxy; - - if (httpProxy) { - options.agent = new HttpsProxyAgent(httpProxy); - } - - const response = await fetch(url, { - ...options, - method: "GET", - headers: { "Content-Type": "application/octet-stream" }, - }); - const buffer = await response.arrayBuffer(); - await fsp.writeFile(path, new Uint8Array(buffer)); - - log_success(`download finished: ${url}`); -} - -// SimpleSC.dll +// SimpleSC.dll (win plugin) const resolvePlugin = async () => { const url = "https://nsis.sourceforge.io/mediawiki/images/e/ef/NSIS_Simple_Service_Plugin_Unicode_1.30.zip"; - const tempDir = path.join(TEMP_DIR, "SimpleSC"); const tempZip = path.join( tempDir, "NSIS_Simple_Service_Plugin_Unicode_1.30.zip", ); const tempDll = path.join(tempDir, "SimpleSC.dll"); - const pluginDir = path.join(process.env.APPDATA, "Local/NSIS"); + const pluginDir = path.join(process.env.APPDATA || "", "Local/NSIS"); const pluginPath = path.join(pluginDir, "SimpleSC.dll"); await fsp.mkdir(pluginDir, { recursive: true }); await fsp.mkdir(tempDir, { recursive: true }); @@ -527,18 +510,33 @@ const resolvePlugin = async () => { await downloadFile(url, tempZip); } const zip = new AdmZip(tempZip); - zip.getEntries().forEach((entry) => { - log_debug(`"SimpleSC" entry name`, entry.entryName); - }); + zip + .getEntries() + .forEach((entry) => log_debug(`"SimpleSC" entry`, entry.entryName)); zip.extractAllTo(tempDir, true); - await fsp.cp(tempDll, pluginPath, { recursive: true, force: true }); - log_success(`unzip finished: "SimpleSC"`); + if (fs.existsSync(tempDll)) { + await fsp.cp(tempDll, pluginPath, { recursive: true, force: true }); + log_success(`unzip finished: "SimpleSC"`); + } else { + // 如果 dll 名称不同,尝试找到 dll + const files = await fsp.readdir(tempDir); + const dll = files.find((f) => f.toLowerCase().endsWith(".dll")); + if (dll) { + await fsp.cp(path.join(tempDir, dll), pluginPath, { + recursive: true, + force: true, + }); + log_success(`unzip finished: "SimpleSC" (found ${dll})`); + } else { + throw new Error("SimpleSC.dll not found in zip"); + } + } } finally { await fsp.rm(tempDir, { recursive: true, force: true }); } }; -// service chmod +// service chmod (保留并使用 glob) const resolveServicePermission = async () => { const serviceExecutables = [ "clash-verge-service*", @@ -550,23 +548,20 @@ const resolveServicePermission = async () => { let hasChanges = false; for (let f of serviceExecutables) { - // 使用glob模块来处理通配符 const files = glob.sync(path.join(resDir, f)); for (let filePath of files) { if (fs.existsSync(filePath)) { const currentHash = await calculateFileHash(filePath); const cacheKey = `${filePath}_chmod`; - - // 检查文件哈希是否变化 if (!FORCE && hashCache[cacheKey] === currentHash) { - // 权限未变化,静默跳过 continue; } - - execSync(`chmod 755 ${filePath}`); - log_success(`chmod finished: "${filePath}"`); - - // 更新哈希缓存 + try { + execSync(`chmod 755 ${filePath}`); + log_success(`chmod finished: "${filePath}"`); + } catch (e) { + log_error(`chmod failed for ${filePath}:`, e.message); + } hashCache[cacheKey] = currentHash; hasChanges = true; } @@ -578,34 +573,22 @@ const resolveServicePermission = async () => { } }; -// 在 resolveResource 函数后添加新函数 +// resolve locales (从 src/locales 复制到 resources/locales,并使用 hash 检查) async function resolveLocales() { const srcLocalesDir = path.join(cwd, "src/locales"); const targetLocalesDir = path.join(cwd, "src-tauri/resources/locales"); try { - // 确保目标目录存在 await fsp.mkdir(targetLocalesDir, { recursive: true }); - - // 读取所有语言文件 const files = await fsp.readdir(srcLocalesDir); - - // 复制每个文件,只有当哈希变化时才复制 for (const file of files) { const srcPath = path.join(srcLocalesDir, file); const targetPath = path.join(targetLocalesDir, file); - - // 检查文件是否需要更新 - if (!(await hasFileChanged(srcPath, targetPath))) { - // 文件未变化,静默跳过 - continue; - } - + if (!(await hasFileChanged(srcPath, targetPath))) continue; await fsp.copyFile(srcPath, targetPath); await updateHashCache(targetPath); log_success(`Copied locale file: ${file}`); } - log_success("All locale files processed successfully"); } catch (err) { log_error("Error copying locale files:", err.message); @@ -613,34 +596,30 @@ async function resolveLocales() { } } -/** - * main - */ +// ======================= +// Other resource resolvers (service, mmdb, geosite, geoip, enableLoopback, sysproxy) +// ======================= const SERVICE_URL = `https://github.com/clash-verge-rev/clash-verge-service-ipc/releases/download/${SIDECAR_HOST}`; - const resolveService = () => { let ext = platform === "win32" ? ".exe" : ""; let suffix = platform === "linux" ? "-" + SIDECAR_HOST : ""; - resolveResource({ + return resolveResource({ file: "clash-verge-service" + suffix + ext, downloadURL: `${SERVICE_URL}/clash-verge-service${ext}`, }); }; - const resolveInstall = () => { let ext = platform === "win32" ? ".exe" : ""; let suffix = platform === "linux" ? "-" + SIDECAR_HOST : ""; - resolveResource({ + return resolveResource({ file: "clash-verge-service-install" + suffix + ext, downloadURL: `${SERVICE_URL}/clash-verge-service-install${ext}`, }); }; - const resolveUninstall = () => { let ext = platform === "win32" ? ".exe" : ""; let suffix = platform === "linux" ? "-" + SIDECAR_HOST : ""; - - resolveResource({ + return resolveResource({ file: "clash-verge-service-uninstall" + suffix + ext, downloadURL: `${SERVICE_URL}/clash-verge-service-uninstall${ext}`, }); @@ -666,15 +645,27 @@ const resolveEnableLoopback = () => file: "enableLoopback.exe", downloadURL: `https://github.com/Kuingsmile/uwp-tool/releases/download/latest/enableLoopback.exe`, }); - const resolveWinSysproxy = () => resolveResource({ file: "sysproxy.exe", downloadURL: `https://github.com/clash-verge-rev/sysproxy/releases/download/${arch}/sysproxy.exe`, }); +const resolveSetDnsScript = () => + resolveResource({ + file: "set_dns.sh", + localPath: path.join(cwd, "scripts/set_dns.sh"), + }); +const resolveUnSetDnsScript = () => + resolveResource({ + file: "unset_dns.sh", + localPath: path.join(cwd, "scripts/unset_dns.sh"), + }); + +// ======================= +// Tasks +// ======================= const tasks = [ - // { name: "clash", func: resolveClash, retry: 5 }, { name: "verge-mihomo-alpha", func: () => @@ -724,11 +715,7 @@ const tasks = [ retry: 5, macosOnly: true, }, - { - name: "locales", - func: resolveLocales, - retry: 2, - }, + { name: "locales", func: resolveLocales, retry: 2 }, ]; async function runTask() {