From 20f1fe8318d4c1bf86fd190cd0ab896303f150fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=98=89=E4=BC=9F?= <8473136@qq.com> Date: Wed, 26 Feb 2025 14:56:51 +0800 Subject: [PATCH] :building_construction: refactor proxy handling to replace stcpModel with visitorsModel and enhance configuration structure in ServerService --- electron/api/config.ts | 337 ------------------- electron/api/file.ts | 21 -- electron/api/frpc.ts | 722 ----------------------------------------- electron/api/github.ts | 590 --------------------------------- electron/api/update.ts | 81 ----- 5 files changed, 1751 deletions(-) delete mode 100644 electron/api/config.ts delete mode 100644 electron/api/file.ts delete mode 100644 electron/api/frpc.ts delete mode 100644 electron/api/github.ts delete mode 100644 electron/api/update.ts diff --git a/electron/api/config.ts b/electron/api/config.ts deleted file mode 100644 index 444904d..0000000 --- a/electron/api/config.ts +++ /dev/null @@ -1,337 +0,0 @@ -// import { app, dialog, ipcMain, shell } from "electron"; -// import { clearConfig, getConfig, saveConfig } from "../storage/config"; -// import { clearVersion, listVersion } from "../storage/version"; -// import { genIniConfig, genTomlConfig, stopFrpcProcess } from "./frpc"; -// import { clearProxy, insertProxy, listProxy } from "../storage/proxy"; -// import path from "path"; -// import fs from "fs"; -// import { logDebug, logError, logInfo, LogModule, logWarn } from "../utils/log"; -// -// const toml = require("@iarna/toml"); -// const { v4: uuidv4 } = require("uuid"); -// -// export const initConfigApi = win => { -// ipcMain.on("config.saveConfig", async (event, args) => { -// logInfo(LogModule.APP, "Attempting to save configuration."); -// saveConfig(args, (err, numberOfUpdated, upsert) => { -// if (!err) { -// const start = args.systemSelfStart || false; -// logDebug(LogModule.APP, "Startup status set to: " + start); -// app.setLoginItemSettings({ -// openAtLogin: start, //win -// openAsHidden: start //macOs -// }); -// logInfo(LogModule.APP, "Configuration saved successfully."); -// } else { -// logError(LogModule.APP, `Error saving configuration: ${err}`); -// } -// event.reply("Config.saveConfig.hook", { -// err: err, -// numberOfUpdated: numberOfUpdated, -// upsert: upsert -// }); -// }); -// }); -// -// ipcMain.on("config.getConfig", async (event, args) => { -// logInfo(LogModule.APP, "Requesting configuration."); -// getConfig((err, doc) => { -// if (err) { -// logError(LogModule.APP, `Error retrieving configuration: ${err}`); -// } -// event.reply("Config.getConfig.hook", { -// err: err, -// data: doc -// }); -// }); -// }); -// -// ipcMain.on("config.versions", event => { -// logInfo(LogModule.APP, "Requesting version information."); -// listVersion((err, doc) => { -// if (err) { -// logError(LogModule.APP, `Error retrieving version information: ${err}`); -// } -// event.reply("Config.versions.hook", { -// err: err, -// data: doc -// }); -// }); -// }); -// -// ipcMain.on("config.hasConfig", event => { -// logInfo(LogModule.APP, "Checking if configuration exists."); -// getConfig((err, doc) => { -// if (err) { -// logError(LogModule.APP, `Error checking configuration: ${err}`); -// } -// event.reply("Config.getConfig.hook", { -// err: err, -// data: doc -// }); -// }); -// }); -// -// ipcMain.on("config.exportConfig", async (event, args) => { -// logInfo(LogModule.APP, "Attempting to export configuration."); -// const result = await dialog.showOpenDialog({ -// properties: ["openDirectory"] -// }); -// const outputDirectory = result.filePaths[0]; -// if (!outputDirectory) { -// logWarn(LogModule.APP, "Export canceled by user."); -// return; -// } -// -// logInfo( -// LogModule.APP, -// `Exporting configuration to directory ${outputDirectory} with type: ${args}` -// ); -// getConfig((err1, config) => { -// if (!err1 && config) { -// listProxy((err2, proxys) => { -// if (!err2) { -// let configContent = ""; -// if (args === "ini") { -// configContent = genIniConfig(config, proxys); -// } else if (args === "toml") { -// configContent = genTomlConfig(config, proxys); -// } -// const configPath = path.join( -// outputDirectory, -// `frpc-desktop.${args}` -// ); -// fs.writeFile( -// configPath, // 配置文件目录 -// configContent, // 配置文件内容 -// { flag: "w" }, -// err => { -// if (err) { -// logError( -// LogModule.APP, -// `Error writing configuration file: ${err}` -// ); -// event.reply("config.exportConfig.hook", { -// data: "导出错误", -// err: err -// }); -// } else { -// logInfo( -// LogModule.APP, -// "Configuration exported successfully." -// ); -// event.reply("Config.exportConfig.hook", { -// data: { -// configPath: configPath -// } -// }); -// } -// } -// ); -// } else { -// logError(LogModule.APP, `Error listing proxies: ${err2}`); -// } -// }); -// } else { -// logError(LogModule.APP, `Error retrieving configuration: ${err1}`); -// } -// }); -// }); -// -// const parseTomlConfig = (tomlPath: string) => { -// logInfo(LogModule.APP, `Parsing TOML configuration from ${tomlPath}`); -// const importConfigPath = tomlPath; -// const tomlData = fs.readFileSync(importConfigPath, "utf-8"); -// logInfo(LogModule.APP, "Configuration content read successfully."); -// const sourceConfig = toml.parse(tomlData); -// // 解析config -// const targetConfig: FrpConfig = { -// currentVersion: null, -// serverAddr: sourceConfig.serverAddr || "", -// serverPort: sourceConfig.serverPort || "", -// authMethod: sourceConfig?.user -// ? "multiuser" -// : sourceConfig?.auth?.method || "", -// authToken: sourceConfig?.auth?.token || "", -// transportHeartbeatInterval: -// sourceConfig?.transport?.heartbeatInterval || 30, -// transportHeartbeatTimeout: -// sourceConfig?.transport?.heartbeatTimeout || 90, -// tlsConfigEnable: sourceConfig?.transport?.tls?.enable || false, -// tlsConfigCertFile: sourceConfig?.transport?.tls?.certFile || "", -// tlsConfigKeyFile: sourceConfig?.transport?.tls?.keyFile || "", -// tlsConfigServerName: sourceConfig?.transport?.tls?.serverName || "", -// tlsConfigTrustedCaFile: sourceConfig?.transport?.tls?.trustedCaFile || "", -// logLevel: sourceConfig?.log?.level || "info", -// logMaxDays: sourceConfig?.log?.maxDays || 3, -// proxyConfigProxyUrl: sourceConfig?.transport?.proxyURL || "", -// proxyConfigEnable: Boolean(sourceConfig?.transport?.proxyURL) || false, -// user: sourceConfig?.user || "", -// metaToken: sourceConfig?.metadatas?.token || "", -// systemSelfStart: false, -// systemStartupConnect: false, -// systemSilentStartup: false, -// webEnable: true, -// webPort: sourceConfig?.webServer?.port || 57400, -// transportProtocol: sourceConfig?.transport?.protocol || "tcp", -// transportDialServerTimeout: -// sourceConfig?.transport?.dialServerTimeout || 10, -// transportDialServerKeepalive: -// sourceConfig?.transport?.dialServerKeepalive || 70, -// transportPoolCount: sourceConfig?.transport?.poolCount || 0, -// transportTcpMux: sourceConfig?.transport?.tcpMux || true, -// transportTcpMuxKeepaliveInterval: -// sourceConfig?.transport?.tcpMuxKeepaliveInterval || 7200 -// }; -// let frpcProxys = []; -// // 解析proxy -// if (sourceConfig?.proxies && sourceConfig.proxies.length > 0) { -// const frpcProxys1 = sourceConfig.proxies.map(m => { -// const rm: Proxy = { -// _id: uuidv4(), -// name: m?.name, -// type: m?.type, -// localIp: m?.localIP || "", -// localPort: m?.localPort || null, -// remotePort: m?.remotePort || null, -// customDomains: m?.customDomains || [], -// subdomain: m.subdomain || "", -// basicAuth: m.basicAuth || false, -// httpUser: m.httpUser || "", -// httpPassword: m.httpPassword || "", -// // 以下为stcp参数 -// visitorsModel: "visitorsProvider", -// serverName: "", -// secretKey: m?.secretKey || "", -// bindAddr: "", -// bindPort: null, -// status: m?.status || true, -// fallbackTo: m?.fallbackTo, -// fallbackTimeoutMs: m?.fallbackTimeoutMs || 500, -// keepTunnelOpen: m?.keepTunnelOpen || false, -// https2http: m?.https2http || false, -// https2httpCaFile: m?.https2httpCaFile || "", -// https2httpKeyFile: m?.https2httpKeyFile || "" -// }; -// return rm; -// }); -// frpcProxys = [...frpcProxys, ...frpcProxys1]; -// logInfo(LogModule.APP, "Parsed proxies from configuration."); -// } -// // 解析stcp的访问者 -// if (sourceConfig?.visitors && sourceConfig.visitors.length > 0) { -// const frpcProxys2 = sourceConfig.visitors.map(m => { -// const rm: Proxy = { -// _id: uuidv4(), -// name: m?.name, -// type: m?.type, -// localIp: "", -// localPort: null, -// remotePort: null, -// customDomains: [], -// subdomain: m.subdomain || "", -// basicAuth: m.basicAuth || false, -// httpUser: m.httpUser || "", -// httpPassword: m.httpPassword || "", -// // 以下为stcp参数 -// visitorsModel: "visitors", -// serverName: m?.serverName, -// secretKey: m?.secretKey || "", -// bindAddr: m?.bindAddr, -// bindPort: m?.bindPort, -// status: m?.status || true, -// fallbackTo: m?.fallbackTo, -// fallbackTimeoutMs: m?.fallbackTimeoutMs || 500, -// keepTunnelOpen: m?.keepTunnelOpen || false, -// https2http: m?.https2http || false, -// https2httpCaFile: m?.https2httpCaFile || "", -// https2httpKeyFile: m?.https2httpKeyFile || "" -// }; -// return rm; -// }); -// frpcProxys = [...frpcProxys, ...frpcProxys2]; -// logInfo(LogModule.APP, "Parsed visitors from configuration."); -// } -// if (targetConfig) { -// clearConfig(() => { -// logInfo(LogModule.APP, "Clearing existing configuration."); -// saveConfig(targetConfig); -// logInfo(LogModule.APP, "New configuration saved."); -// }); -// } -// if (frpcProxys && frpcProxys.length > 0) { -// clearProxy(() => { -// frpcProxys.forEach(f => { -// insertProxy(f, err => { -// if (err) { -// logError(LogModule.APP, `Error inserting proxy: ${err}`); -// } else { -// logInfo(LogModule.APP, `Inserted proxy: ${JSON.stringify(f)}`); -// } -// }); -// }); -// }); -// } -// }; -// -// ipcMain.on("config.importConfig", async (event, args) => { -// logInfo(LogModule.APP, "Attempting to import configuration."); -// const result = await dialog.showOpenDialog(win, { -// properties: ["openFile"], -// filters: [ -// { name: "FrpcConfig Files", extensions: ["toml", "ini"] } // 允许选择的文件类型 -// ] -// }); -// if (result.canceled) { -// logWarn(LogModule.APP, "Import canceled by user."); -// return; -// } else { -// const filePath = result.filePaths[0]; -// const fileExtension = path.extname(filePath); // 获取文件后缀名 -// logWarn( -// LogModule.APP, -// `Importing file ${filePath} with extension ${fileExtension}` -// ); -// if (fileExtension === ".toml") { -// parseTomlConfig(filePath); -// event.reply("Config.importConfig.hook", { -// success: true -// }); -// } else { -// logError( -// LogModule.APP, -// `Import failed, unsupported file format: ${fileExtension}` -// ); -// event.reply("Config.importConfig.hook", { -// success: false, -// data: `导入失败,暂不支持 ${fileExtension} 格式文件` -// }); -// } -// } -// }); -// -// ipcMain.on("config.clearAll", async (event, args) => { -// logInfo(LogModule.APP, "Clearing all configurations."); -// stopFrpcProcess(() => { -// clearConfig(); -// clearProxy(); -// clearVersion(); -// event.reply("Config.clearAll.hook", {}); -// logInfo(LogModule.APP, "All configurations cleared."); -// }); -// }); -// -// ipcMain.on("config.openDataFolder", async (event, args) => { -// const userDataPath = app.getPath("userData"); -// logInfo(LogModule.APP, "Attempting to open data folder."); -// shell.openPath(userDataPath).then(errorMessage => { -// if (errorMessage) { -// logError(LogModule.APP, `Failed to open data folder: ${errorMessage}`); -// event.reply("Config.openDataFolder.hook", false); -// } else { -// logInfo(LogModule.APP, "Data folder opened successfully."); -// event.reply("Config.openDataFolder.hook", true); -// } -// }); -// }); -// }; diff --git a/electron/api/file.ts b/electron/api/file.ts deleted file mode 100644 index 643cd44..0000000 --- a/electron/api/file.ts +++ /dev/null @@ -1,21 +0,0 @@ -// import {dialog, ipcMain} from "electron"; -// import { logInfo, logError, LogModule } from "../utils/log"; -// -// export const initFileApi = () => { -// ipcMain.handle("file.selectFile", async (event, args) => { -// logInfo(LogModule.APP, `Attempting to open file dialog with filters: ${JSON.stringify(args)}`); -// try { -// const result = dialog.showOpenDialogSync({ -// properties: ['openFile'], -// filters: [ -// { name: 'Text Files', extensions: args }, -// ] -// }); -// logInfo(LogModule.APP, `File dialog result: ${JSON.stringify(result)}`); -// return result; -// } catch (error) { -// logError(LogModule.APP, `Error opening file dialog: ${error.message}`); -// return null; -// } -// }); -// } diff --git a/electron/api/frpc.ts b/electron/api/frpc.ts deleted file mode 100644 index 00e8365..0000000 --- a/electron/api/frpc.ts +++ /dev/null @@ -1,722 +0,0 @@ -// import { app, ipcMain, Notification } from "electron"; -// import { getConfig } from "../storage/config"; -// import { listProxy } from "../storage/proxy"; -// import { getVersionById } from "../storage/version"; -// import treeKill from "tree-kill"; -// import { logInfo, logError, LogModule, logDebug, logWarn } from "../utils/log"; -// -// const fs = require("fs"); -// const path = require("path"); -// const { exec, spawn } = require("child_process"); -// -// export let frpcProcess = null; -// const runningCmd = { -// commandPath: null, -// configPath: null -// }; -// let frpcStatusListener = null; -// -// const getFrpcVersionWorkerPath = ( -// versionId: number, -// callback: (workerPath: string) => void -// ) => { -// getVersionById(versionId, (err2, version) => { -// if (!err2) { -// if (version) { -// callback(version["frpcVersionPath"]); -// } -// } -// }); -// }; -// -// const isRangePort = (m: Proxy) => { -// return ( -// (m.type === "tcp" || m.type === "udp") && -// (String(m.localPort).indexOf("-") !== -1 || -// String(m.localPort).indexOf(",") !== -1) -// ); -// }; -// -// /** -// * 生成toml配置文件 -// * @param config -// * @param proxys -// */ -// export const genTomlConfig = (config: FrpConfig, proxys: Proxy[]) => { -// const proxyToml = proxys.map(m => { -// const rangePort = isRangePort(m); -// config.tlsConfigKeyFile = config.tlsConfigKeyFile.replace(/\\/g, "\\\\"); -// config.tlsConfigCertFile = config.tlsConfigCertFile.replace(/\\/g, "\\\\"); -// config.tlsConfigTrustedCaFile = config.tlsConfigTrustedCaFile.replace( -// /\\/g, -// "\\\\" -// ); -// let toml = `${ -// rangePort -// ? `{{- range $_, $v := parseNumberRangePair "${m.localPort}" "${m.remotePort}" }}` -// : "" -// } -// [[${ -// (m.type === "stcp" || m.type === "xtcp" || m.type === "sudp") && -// m.visitorsModel === "visitors" -// ? "visitors" -// : "proxies" -// }]] -// ${rangePort ? "" : `name = "${m.name}"`} -// type = "${m.type}"\n`; -// -// switch (m.type) { -// case "tcp": -// case "udp": -// if (rangePort) { -// toml += `name = "${m.name}-{{ $v.First }}" -// localPort = {{ $v.First }} -// remotePort = {{ $v.Second }}\n`; -// } else { -// toml += `localIP = "${m.localIp}" -// localPort = ${m.localPort} -// remotePort = ${m.remotePort}\n`; -// } -// break; -// case "http": -// case "https": -// const customDomains = m.customDomains.filter(f1 => f1 !== ""); -// if (customDomains && customDomains.length > 0) { -// toml += `customDomains=[${m.customDomains.map(m => `"${m}"`)}]\n`; -// } -// if (m.subdomain) { -// toml += `subdomain="${m.subdomain}"\n`; -// } -// if (m.basicAuth) { -// toml += `httpUser = "${m.httpUser}" -// httpPassword = "${m.httpPassword}"\n`; -// } -// if (m.https2http) { -// toml += `[proxies.plugin] -// type = "https2http" -// localAddr = "${m.localIp}:${m.localPort}" -// -// crtPath = "${m.https2httpCaFile}" -// keyPath = "${m.https2httpKeyFile}"\n`; -// } else { -// toml += `localIP = "${m.localIp}" -// localPort = ${m.localPort}\n`; -// } -// -// break; -// case "xtcp": -// if (m.visitorsModel === "visitors") { -// toml += `keepTunnelOpen = ${m.keepTunnelOpen}\n`; -// } -// case "stcp": -// case "sudp": -// if (m.visitorsModel === "visitors") { -// // 访问者 -// toml += `serverName = "${m.serverName}" -// bindAddr = "${m.bindAddr}" -// bindPort = ${m.bindPort}\n`; -// if (m.fallbackTo) { -// toml += `fallbackTo = "${m.fallbackTo}" -// fallbackTimeoutMs = ${m.fallbackTimeoutMs || 500}\n`; -// } -// } else if (m.visitorsModel === "visitorsProvider") { -// // 被访问者 -// toml += `localIP = "${m.localIp}" -// localPort = ${m.localPort}\n`; -// } -// -// toml += `secretKey="${m.secretKey}"\n`; -// break; -// default: -// break; -// } -// -// if (rangePort) { -// toml += `{{- end }}\n`; -// } -// return toml; -// }); -// const toml = `serverAddr = "${config.serverAddr}" -// serverPort = ${config.serverPort} -// ${ -// config.authMethod === "token" -// ? `auth.method = "token" -// auth.token = "${config.authToken}"` -// : "" -// } -// ${ -// config.authMethod === "multiuser" -// ? `user = "${config.user}" -// metadatas.token = "${config.metaToken}"` -// : "" -// } -// log.to = "frpc.log" -// log.level = "${config.logLevel}" -// log.maxDays = ${config.logMaxDays} -// webServer.addr = "127.0.0.1" -// webServer.port = ${config.webPort} -// ${ -// config.transportProtocol -// ? `transport.protocol = "${config.transportProtocol}"` -// : "" -// } -// ${ -// config.transportPoolCount -// ? `transport.poolCount = ${config.transportPoolCount}` -// : "" -// } -// ${ -// config.transportDialServerTimeout -// ? `transport.dialServerTimeout = ${config.transportDialServerTimeout}` -// : "" -// } -// ${ -// config.transportDialServerKeepalive -// ? `transport.dialServerKeepalive = ${config.transportDialServerKeepalive}` -// : "" -// } -// ${ -// config.transportHeartbeatInterval -// ? `transport.heartbeatInterval = ${config.transportHeartbeatInterval}` -// : "" -// } -// ${ -// config.transportHeartbeatTimeout -// ? `transport.heartbeatTimeout = ${config.transportHeartbeatTimeout}` -// : "" -// } -// ${config.transportTcpMux ? `transport.tcpMux = ${config.transportTcpMux}` : ""} -// ${ -// config.transportTcpMux && config.transportTcpMuxKeepaliveInterval -// ? `transport.tcpMuxKeepaliveInterval = ${config.transportTcpMuxKeepaliveInterval}` -// : "" -// } -// transport.tls.enable = ${config.tlsConfigEnable} -// ${ -// config.tlsConfigEnable && config.tlsConfigCertFile -// ? `transport.tls.certFile = "${config.tlsConfigCertFile}"` -// : "" -// } -// ${ -// config.tlsConfigEnable && config.tlsConfigKeyFile -// ? `transport.tls.keyFile = "${config.tlsConfigKeyFile}"` -// : "" -// } -// ${ -// config.tlsConfigEnable && config.tlsConfigTrustedCaFile -// ? `transport.tls.trustedCaFile = "${config.tlsConfigTrustedCaFile}"` -// : "" -// } -// ${ -// config.tlsConfigEnable && config.tlsConfigServerName -// ? `transport.tls.serverName = "${config.tlsConfigServerName}"` -// : "" -// } -// ${ -// config.proxyConfigEnable -// ? `transport.proxyURL = "${config.proxyConfigProxyUrl}"` -// : "" -// } -// ${proxyToml.join("")}`; -// return toml; -// }; -// -// /** -// * 生成ini配置 -// * @param config -// * @param proxys -// */ -// export const genIniConfig = (config: FrpConfig, proxys: Proxy[]) => { -// const proxyIni = proxys.map(m => { -// const rangePort = isRangePort(m); -// let ini = `[${rangePort ? "range:" : ""}${m.name}] -// type = "${m.type}" -// `; -// switch (m.type) { -// case "tcp": -// case "udp": -// ini += ` -// local_ip = "${m.localIp}" -// local_port = ${m.localPort} -// remote_port = ${m.remotePort}\n`; -// break; -// case "http": -// ini += ` -// local_ip = "${m.localIp}" -// local_port = ${m.localPort} -// custom_domains=[${m.customDomains.map(m => `${m}`)}] -// subdomain="${m.subdomain}"\n`; -// if (m.basicAuth) { -// ini += ` -// httpUser = "${m.httpUser}" -// httpPassword = "${m.httpPassword}"\n`; -// } -// break; -// case "https": -// ini += ` -// custom_domains=[${m.customDomains.map(m => `${m}`)}] -// subdomain="${m.subdomain}"\n`; -// if (m.basicAuth) { -// ini += ` -// httpUser = "${m.httpUser}" -// httpPassword = "${m.httpPassword}"\n`; -// } -// if (m.https2http) { -// ini += ` -// plugin = https2http -// plugin_local_addr = ${m.localIp}:${m.localPort} -// plugin_crt_path = ${m.https2httpCaFile} -// plugin_key_path = ${m.https2httpKeyFile}\n`; -// } else { -// ini += ` -// local_ip = "${m.localIp}" -// local_port = ${m.localPort}\n`; -// } -// break; -// case "xtcp": -// if (m.visitorsModel === "visitors") { -// ini += `keep_tunnel_open = ${m.keepTunnelOpen}\n`; -// } -// case "stcp": -// case "sudp": -// if (m.visitorsModel === "visitors") { -// // 访问者 -// ini += ` -// role = visitor -// server_name = "${m.serverName}" -// bind_addr = "${m.bindAddr}" -// bind_port = ${m.bindPort}\n`; -// if (m.fallbackTo) { -// ini += ` -// fallback_to = ${m.fallbackTo} -// fallback_timeout_ms = ${m.fallbackTimeoutMs || 500}\n`; -// } -// } else if (m.visitorsModel === "visitorsProvider") { -// // 被访问者 -// ini += ` -// local_ip = "${m.localIp}" -// local_port = ${m.localPort}\n`; -// } -// ini += ` -// sk="${m.secretKey}"\n`; -// break; -// default: -// break; -// } -// -// return ini; -// }); -// const ini = ` -// [common] -// server_addr = ${config.serverAddr} -// server_port = ${config.serverPort} -// ${ -// config.authMethod === "token" -// ? ` -// authentication_method = ${config.authMethod} -// token = ${config.authToken}\n` -// : "" -// } -// ${ -// config.authMethod === "multiuser" -// ? ` -// user = ${config.user} -// meta_token = ${config.metaToken}\n` -// : "" -// } -// -// ${config.transportProtocol ? `protocol = ${config.transportProtocol}` : ""} -// ${config.transportPoolCount ? `pool_count = ${config.transportPoolCount}` : ""} -// ${ -// config.transportDialServerTimeout -// ? `dial_server_timeout = ${config.transportDialServerTimeout}` -// : "" -// } -// ${ -// config.transportDialServerKeepalive -// ? `dial_server_keepalive = ${config.transportDialServerKeepalive}` -// : "" -// } -// ${ -// config.transportHeartbeatInterval -// ? ` -// heartbeat_interval = ${config.transportHeartbeatInterval} -// ` -// : "" -// } -// ${ -// config.transportHeartbeatTimeout -// ? ` -// heartbeat_timeout = ${config.transportHeartbeatTimeout} -// ` -// : "" -// } -// ${config.transportTcpMux ? `transport.tcp_mux = ${config.transportTcpMux}` : ""} -// ${ -// config.transportTcpMux && config.transportTcpMuxKeepaliveInterval -// ? `tcp_mux_keepalive_interval = ${config.transportTcpMuxKeepaliveInterval}` -// : "" -// } -// ${ -// config.tlsConfigEnable && config.tlsConfigCertFile -// ? ` -// tls_cert_file = ${config.tlsConfigCertFile}\n` -// : "" -// } -// ${ -// config.tlsConfigEnable && config.tlsConfigKeyFile -// ? ` -// tls_key_file = ${config.tlsConfigKeyFile}\n` -// : "" -// } -// ${ -// config.tlsConfigEnable && config.tlsConfigTrustedCaFile -// ? ` -// tls_trusted_ca_file = ${config.tlsConfigTrustedCaFile}\n` -// : "" -// } -// ${ -// config.tlsConfigEnable && config.tlsConfigServerName -// ? ` -// tls_server_name = ${config.tlsConfigServerName}\n` -// : "" -// } -// -// ${ -// config.proxyConfigEnable -// ? ` -// http_proxy = "${config.proxyConfigProxyUrl}"\n` -// : "" -// } -// -// log_file = "frpc.log" -// log_level = ${config.logLevel} -// log_max_days = ${config.logMaxDays} -// admin_addr = 127.0.0.1 -// admin_port = ${config.webPort} -// tls_enable = ${config.tlsConfigEnable} -// -// -// ${proxyIni.join("")} -// `; -// return ini; -// }; -// -// /** -// * 生成配置文件 -// */ -// export const generateConfig = ( -// config: FrpConfig, -// callback: (configPath: string) => void -// ) => { -// listProxy((err3, proxys) => { -// if (err3) { -// logError(LogModule.FRP_CLIENT, `Failed to list proxies: ${err3.message}`); -// return; -// } -// -// const { currentVersion } = config; -// let filename = null; -// let configContent = ""; -// const filtered = proxys -// .map(m => { -// if (m.status == null || m.status == undefined) { -// m.status = true; -// } -// return m; -// }) -// .filter(f => f.status); -// -// if (currentVersion < 124395282) { -// // 版本小于v0.52.0 -// filename = "frp.ini"; -// configContent = genIniConfig(config, filtered); -// logInfo( -// LogModule.FRP_CLIENT, -// `Using INI format for configuration: ${filename}` -// ); -// } else { -// filename = "frp.toml"; -// configContent = genTomlConfig(config, filtered); -// logInfo( -// LogModule.FRP_CLIENT, -// `Using TOML format for configuration: ${filename}` -// ); -// } -// -// const configPath = path.join(app.getPath("userData"), filename); -// logInfo( -// LogModule.FRP_CLIENT, -// `Writing configuration to file: ${configPath}` -// ); -// -// fs.writeFile( -// configPath, // 配置文件目录 -// configContent, // 配置文件内容 -// { flag: "w" }, -// err => { -// if (err) { -// logError( -// LogModule.FRP_CLIENT, -// `Failed to write configuration file: ${err.message}` -// ); -// } else { -// logInfo( -// LogModule.FRP_CLIENT, -// `Configuration file written successfully: ${filename}` -// ); -// callback(filename); -// } -// } -// ); -// }); -// }; -// -// /** -// * 启动frpc子进程 -// * @param cwd -// * @param commandPath -// * @param configPath -// */ -// const startFrpcProcess = (commandPath: string, configPath: string) => { -// logInfo( -// LogModule.FRP_CLIENT, -// `Starting frpc process. Directory: ${app.getPath( -// "userData" -// )}, Command: ${commandPath}` -// ); -// -// const command = `${commandPath} -c ${configPath}`; -// frpcProcess = spawn(command, { -// cwd: app.getPath("userData"), -// shell: true -// }); -// runningCmd.commandPath = commandPath; -// runningCmd.configPath = configPath; -// -// frpcProcess.stdout.on("data", data => { -// logDebug(LogModule.FRP_CLIENT, `Frpc process output: ${data}`); -// }); -// -// frpcProcess.stdout.on("error", data => { -// logError(LogModule.FRP_CLIENT, `Frpc process error: ${data}`); -// stopFrpcProcess(() => {}); -// }); -// -// frpcStatusListener = setInterval(() => { -// const status = frpcProcessStatus(); -// logDebug( -// LogModule.FRP_CLIENT, -// `Monitoring frpc process status: ${status}, Listener ID: ${frpcStatusListener}` -// ); -// if (!status) { -// new Notification({ -// title: "Frpc Desktop", -// body: "Connection lost, please check the logs for details." -// }).show(); -// logError( -// LogModule.FRP_CLIENT, -// "Frpc process status check failed. Connection lost." -// ); -// clearInterval(frpcStatusListener); -// } -// }, 3000); -// }; -// -// /** -// * 重载frpc配置 -// */ -// export const reloadFrpcProcess = () => { -// if (frpcProcess && !frpcProcess.killed) { -// logDebug( -// LogModule.FRP_CLIENT, -// "Attempting to reload frpc process configuration." -// ); -// getConfig((err1, config) => { -// if (!err1) { -// if (config) { -// generateConfig(config, configPath => { -// const command = `${runningCmd.commandPath} reload -c ${configPath}`; -// logInfo( -// LogModule.FRP_CLIENT, -// `Reloading configuration: ${command}` -// ); -// exec( -// command, -// { -// cwd: app.getPath("userData"), -// shell: true -// }, -// (error, stdout, stderr) => { -// if (error) { -// logError( -// LogModule.FRP_CLIENT, -// `Error reloading configuration: ${error.message}` -// ); -// return; -// } -// logDebug( -// LogModule.FRP_CLIENT, -// `Configuration reload output: ${stdout}` -// ); -// if (stderr) { -// logWarn( -// LogModule.FRP_CLIENT, -// `Configuration reload warnings: ${stderr}` -// ); -// } -// } -// ); -// }); -// } else { -// logWarn(LogModule.FRP_CLIENT, "No configuration found to reload."); -// } -// } else { -// logError(LogModule.FRP_CLIENT, `Error getting configuration: ${err1}`); -// } -// }); -// } else { -// logDebug( -// LogModule.FRP_CLIENT, -// "frpc process is not running or has been killed." -// ); -// } -// }; -// -// /** -// * 停止frpc子进程 -// */ -// export const stopFrpcProcess = (callback?: () => void) => { -// if (frpcProcess) { -// treeKill(frpcProcess.pid, (error: Error) => { -// if (error) { -// logError( -// LogModule.FRP_CLIENT, -// `Failed to stop frpc process with pid: ${frpcProcess.pid}. Error: ${error.message}` -// ); -// callback(); -// } else { -// logInfo( -// LogModule.FRP_CLIENT, -// `Successfully stopped frpc process with pid: ${frpcProcess.pid}.` -// ); -// frpcProcess = null; -// clearInterval(frpcStatusListener); -// callback(); -// } -// }); -// } else { -// logWarn( -// LogModule.FRP_CLIENT, -// "Attempted to stop frpc process, but no process is running." -// ); -// logWarn(LogModule.FRP_CLIENT, "No frpc process to stop."); -// callback(); -// } -// }; -// -// /** -// * 获取frpc子进程状态 -// */ -// export const frpcProcessStatus = () => { -// if (!frpcProcess) { -// logDebug(LogModule.FRP_CLIENT, "frpc process is not running."); -// return false; -// } -// try { -// // 发送信号给进程,如果进程存在,会正常返回 -// process.kill(frpcProcess.pid, 0); -// logDebug( -// LogModule.FRP_CLIENT, -// `frpc process is running with pid: ${frpcProcess.pid}` -// ); -// return true; -// } catch (error) { -// // 进程不存在,抛出异常 -// logError( -// LogModule.FRP_CLIENT, -// `frpc process not found. Error: ${error.message}` -// ); -// return false; -// } -// }; -// -// /** -// * 启动frpc流程 -// * @param config -// */ -// export const startFrpWorkerProcess = async (config: FrpConfig) => { -// logInfo(LogModule.FRP_CLIENT, "Starting frpc worker process..."); -// getFrpcVersionWorkerPath(config.currentVersion, (frpcVersionPath: string) => { -// if (frpcVersionPath) { -// logInfo( -// LogModule.FRP_CLIENT, -// `Found frpc version path: ${frpcVersionPath}` -// ); -// generateConfig(config, configPath => { -// const platform = process.platform; -// if (platform === "win32") { -// logInfo(LogModule.FRP_CLIENT, "Starting frpc on Windows."); -// startFrpcProcess(path.join(frpcVersionPath, "frpc.exe"), configPath); -// } else { -// logInfo( -// LogModule.FRP_CLIENT, -// "Starting frpc on non-Windows platform." -// ); -// startFrpcProcess(path.join(frpcVersionPath, "frpc"), configPath); -// } -// }); -// } else { -// logError(LogModule.FRP_CLIENT, "frpc version path not found."); -// } -// }); -// }; -// -// export const initFrpcApi = () => { -// ipcMain.handle("frpc.running", async (event, args) => { -// logDebug(LogModule.FRP_CLIENT, "Checking if frpc process is running..."); -// return frpcProcessStatus(); -// }); -// -// ipcMain.on("frpc.start", async (event, args) => { -// logInfo(LogModule.FRP_CLIENT, "Received request to start frpc process."); -// getConfig((err1, config) => { -// if (!err1) { -// if (!config) { -// logWarn( -// LogModule.FRP_CLIENT, -// "Configuration not found. Prompting user to set configuration." -// ); -// event.reply( -// "Home.frpc.start.error.hook", -// "请先前往设置页面,修改配置后再启动" -// ); -// return; -// } -// if (!config.currentVersion) { -// logWarn( -// LogModule.FRP_CLIENT, -// "Current version not set in configuration. Prompting user." -// ); -// event.reply( -// "Home.frpc.start.error.hook", -// "请先前往设置页面,修改配置后再启动" -// ); -// return; -// } -// startFrpWorkerProcess(config); -// } else { -// logError(LogModule.FRP_CLIENT, `Error getting configuration: ${err1}`); -// } -// }); -// }); -// -// ipcMain.on("frpc.stop", () => { -// logInfo(LogModule.FRP_CLIENT, "Received request to stop frpc process."); -// if (frpcProcess && !frpcProcess.killed) { -// stopFrpcProcess(() => {}); -// } else { -// logWarn(LogModule.FRP_CLIENT, "No frpc process to stop."); -// } -// }); -// }; diff --git a/electron/api/github.ts b/electron/api/github.ts deleted file mode 100644 index 85115cd..0000000 --- a/electron/api/github.ts +++ /dev/null @@ -1,590 +0,0 @@ -// import { app, BrowserWindow, dialog, ipcMain, net } from "electron"; -// import { -// deleteVersionById, -// getVersionById, -// insertVersion, -// listVersion -// } from "../storage/version"; -// import frpReleasesJson from "../json/frp-releases.json"; -// import frpChecksums from "../json/frp_all_sha256_checksums.json"; -// import { logDebug, logError, logInfo, LogModule, logWarn } from "../utils/log"; -// // import { calculateFileChecksum, formatBytes } from "../utils/FileUtils"; -// -// const fs = require("fs"); -// const path = require("path"); -// const zlib = require("zlib"); -// const { download } = require("electron-dl"); -// const AdmZip = require("adm-zip"); -// -// const versionRelation = { -// win32_x64: ["window", "amd64"], -// win32_arm64: ["window", "arm64"], -// win32_ia32: ["window", "386"], -// darwin_arm64: ["darwin", "arm64"], -// darwin_x64: ["darwin", "amd64"], -// darwin_amd64: ["darwin", "amd64"], -// linux_x64: ["linux", "amd64"], -// linux_arm64: ["linux", "arm64"] -// }; -// const platform = process.platform; -// const arch = process.arch; -// let currArch = `${platform}_${arch}`; -// const frpArch = versionRelation[currArch]; -// -// const unTarGZ = (tarGzPath: string, targetPath: string) => { -// const tar = require("tar"); -// const unzip = zlib.createGunzip(); -// logInfo( -// LogModule.APP, -// `Starting to extract tar.gz: ${tarGzPath} to ${targetPath}` -// ); -// -// const readStream = fs.createReadStream(tarGzPath); -// if (!fs.existsSync(unzip)) { -// fs.mkdirSync(targetPath, { recursive: true, mode: 0o777 }); -// logInfo(LogModule.APP, `Created target directory: ${targetPath}`); -// } -// -// readStream.on("error", err => { -// logError(LogModule.APP, `Error reading tar.gz file: ${err.message}`); -// }); -// -// readStream -// .pipe(unzip) -// .on("error", err => { -// logError(LogModule.APP, `Error during gunzip: ${err.message}`); -// }) -// .pipe( -// tar -// .extract({ -// cwd: targetPath, -// filter: filePath => path.basename(filePath) === "frpc" -// }) -// .on("error", err => { -// logError(LogModule.APP, `Error extracting tar file: ${err.message}`); -// }) -// ) -// .on("finish", () => { -// const frpcPath = path.join("frp", path.basename(tarGzPath, ".tar.gz")); -// logInfo( -// LogModule.APP, -// `Extraction completed. Extracted directory: ${frpcPath}` -// ); -// }); -// return path.join("frp", path.basename(tarGzPath, ".tar.gz")); -// }; -// -// const unZip = (zipPath: string, targetPath: string) => { -// if (!fs.existsSync(path.join(targetPath, path.basename(zipPath, ".zip")))) { -// fs.mkdirSync(path.join(targetPath, path.basename(zipPath, ".zip")), { -// recursive: true -// }); -// logInfo(LogModule.APP, `Created target directory: ${targetPath}`); -// logInfo( -// LogModule.APP, -// `Created directory for zip extraction: ${path.basename(zipPath, ".zip")}` -// ); -// } -// -// logDebug( -// LogModule.APP, -// `Starting to unzip: ${zipPath} to target directory: ${targetPath}` -// ); -// logInfo(LogModule.APP, `Starting to extract zip file: ${zipPath}`); -// -// const zip = new AdmZip(zipPath); -// try { -// zip.extractAllTo(targetPath, true); // 第二个参数为 true,表示覆盖已存在的文件 -// const frpcPath = path.join("frp", path.basename(zipPath, ".zip")); -// logInfo( -// LogModule.APP, -// `Extraction completed. Extracted directory: ${frpcPath}` -// ); -// logDebug( -// LogModule.APP, -// `Unzip completed. Extracted directory: ${frpcPath}` -// ); -// return frpcPath; -// } catch (error) { -// logError(LogModule.APP, `Error extracting zip file: ${error.message}`); -// } -// -// return null; -// }; -// -// export const initGitHubApi = win => { -// // 版本 -// let versions: FrpVersion[] = []; -// -// const getVersionByGithubVersionId = versionId => { -// logDebug(LogModule.APP, `Attempting to get version with ID: ${versionId}`); -// const version = versions.find(f => f.id === versionId); -// if (version) { -// logInfo( -// LogModule.APP, -// `Version details ID:${version.id}, Name:${version.name}, Published At:${version.published_at}` -// ); -// } else { -// logWarn(LogModule.APP, `No version found for ID: ${versionId}`); -// } -// return version; -// }; -// -// const getVersionByAssetName = (assetName: string) => { -// logDebug( -// LogModule.APP, -// `Attempting to get version with asset name: ${assetName}` -// ); -// const version = versions.find(f => -// f.assets.some(asset => asset.name === assetName) -// ); -// if (version) { -// logInfo( -// LogModule.APP, -// `Version details ID:${version.id}, Name:${version.name}, Published At:${version.published_at}` -// ); -// } else { -// logWarn(LogModule.APP, `No version found for asset name: ${assetName}`); -// } -// return version; -// }; -// -// const getAdaptiveAsset = versionId => { -// const { assets } = getVersionByGithubVersionId(versionId); -// if (!assets || assets.length === 0) { -// logWarn(LogModule.GITHUB, `No assets found for version ID: ${versionId}`); -// return null; -// } -// -// const asset = assets.find(f => { -// const a = frpArch; -// if (a) { -// const flag = a.every(item => f.name.includes(item)); -// if (flag) { -// logInfo( -// LogModule.GITHUB, -// `Found matching asset: ${f.name} for version ID: ${versionId}` -// ); -// } -// return flag; -// } -// logWarn( -// LogModule.GITHUB, -// `No architecture match found for asset: ${f.name}` -// ); -// return false; -// }); -// -// if (!asset) { -// logError( -// LogModule.GITHUB, -// `No adaptive asset found for version ID: ${versionId}` -// ); -// } -// return asset; -// }; -// -// /** -// * handle github api release json -// * @param githubReleaseJsonStr jsonStr -// * @returns versions -// */ -// const handleApiResponse = (githubReleaseJsonStr: string) => { -// const downloadPath = path.join(app.getPath("userData"), "download"); -// const frpPath = path.join(app.getPath("userData"), "frp"); -// logInfo(LogModule.GITHUB, "Parsing GitHub release JSON response."); -// -// versions = JSON.parse(githubReleaseJsonStr); -// if (versions) { -// logInfo( -// LogModule.GITHUB, -// "Successfully parsed versions from GitHub response." -// ); -// -// const returnVersionsData = versions -// .filter(f => getAdaptiveAsset(f.id)) -// .map(m => { -// const asset = getAdaptiveAsset(m.id); -// const download_count = m.assets.reduce( -// (sum, item) => sum + item.download_count, -// 0 -// ); -// if (asset) { -// const absPath = path.join( -// frpPath, -// asset.name.replace(/(\.tar\.gz|\.zip)$/, "") -// ); -// m.absPath = absPath; -// m.download_completed = fs.existsSync(absPath); -// m.download_count = download_count; -// m.size = formatBytes(asset.size); -// logInfo( -// LogModule.GITHUB, -// `Asset found: ${asset.name}, download count: ${download_count}` -// ); -// } else { -// logWarn(LogModule.GITHUB, `No asset found for version ID: ${m.id}`); -// } -// return m; -// }); -// logDebug( -// LogModule.GITHUB, -// `Retrieved FRP versions: ${JSON.stringify(returnVersionsData)}` -// ); -// return returnVersionsData; -// } else { -// logError( -// LogModule.GITHUB, -// "Failed to parse versions: No versions found in response." -// ); -// return []; -// } -// }; -// -// /** -// * conventMirrorUrl -// * @param mirror mirror -// * @returns mirrorUrl -// */ -// const conventMirrorUrl = (mirror: string) => { -// switch (mirror) { -// case "github": -// return { -// api: "https://api.github.com", -// asset: "https://github.com" -// }; -// default: -// return { -// api: "https://api.github.com", -// asset: "https://github.com" -// }; -// } -// }; -// -// /** -// * 获取github上的frp所有版本 -// */ -// ipcMain.on("github.getFrpVersions", async (event, mirror: string) => { -// const { api } = conventMirrorUrl(mirror); -// const mirrorUrl = api; -// logInfo(LogModule.GITHUB, `Requesting mirror URL: ${mirrorUrl}`); -// const request = net.request({ -// method: "get", -// url: `${mirrorUrl}/repos/fatedier/frp/releases?page=1&per_page=1000` -// }); -// -// let githubReleaseJsonStr = null; -// request.on("response", response => { -// logInfo( -// LogModule.GITHUB, -// `Received response with status code: ${response.statusCode}` -// ); -// let responseData: Buffer = Buffer.alloc(0); -// response.on("data", (data: Buffer) => { -// responseData = Buffer.concat([responseData, data]); -// }); -// response.on("end", () => { -// if (response.statusCode === 200) { -// githubReleaseJsonStr = responseData.toString(); -// logInfo( -// LogModule.GITHUB, -// "Successfully retrieved GitHub release data." -// ); -// } else { -// logWarn( -// LogModule.GITHUB, -// "Failed to retrieve data, using local JSON instead. Status code: " + -// response.statusCode -// ); -// githubReleaseJsonStr = JSON.stringify(frpReleasesJson); -// } -// const versions = handleApiResponse(githubReleaseJsonStr); -// event.reply("Download.frpVersionHook", versions); -// }); -// }); -// -// request.on("error", jerror => { -// logError( -// LogModule.GITHUB, -// "Error occurred while requesting GitHub releases: " + error -// ); -// githubReleaseJsonStr = JSON.stringify(frpReleasesJson); -// const versions = handleApiResponse(githubReleaseJsonStr); -// event.reply("Download.frpVersionHook", versions); -// }); -// -// request.end(); -// }); -// -// const decompressFrp = (frpFilename: string, compressedFilePath: string) => { -// const targetPath = path.resolve(path.join(app.getPath("userData"), "frp")); -// const ext = path.extname(frpFilename); -// let frpcVersionPath = ""; -// try { -// if (ext === ".zip") { -// unZip( -// // path.join( -// // path.join(app.getPath("userData"), "download"), -// // `${frpFilename}` -// // ), -// compressedFilePath, -// targetPath -// ); -// logInfo(LogModule.APP, `Unzipped file to path: ${frpcVersionPath}`); -// frpcVersionPath = path.join("frp", path.basename(frpFilename, ".zip")); -// } else if (ext === ".gz" && frpFilename.includes(".tar.gz")) { -// unTarGZ( -// // path.join( -// // path.join(app.getPath("userData"), "download"), -// // `${frpFilename}` -// // ), -// compressedFilePath, -// targetPath -// ); -// frpcVersionPath = path.join( -// "frp", -// path.basename(frpFilename, ".tar.gz") -// ); -// logInfo(LogModule.APP, `Untarred file to path: ${frpcVersionPath}`); -// } -// } catch (error) { -// logError(LogModule.APP, `Error during extraction: ${error.message}`); -// } -// -// return frpcVersionPath; -// }; -// -// /** -// * 下载请求 -// */ -// ipcMain.on("github.download", async (event, args) => { -// const { versionId, mirror } = args; -// const version = getVersionByGithubVersionId(versionId); -// const asset = getAdaptiveAsset(versionId); -// const { browser_download_url } = asset; -// -// let url = browser_download_url.replace( -// "https://github.com", -// conventMirrorUrl(mirror).asset -// ); -// -// logDebug( -// LogModule.GITHUB, -// `Starting download for versionId: ${versionId}, mirror: ${mirror}, download URL: ${url}` -// ); -// -// await download(BrowserWindow.getFocusedWindow(), url, { -// filename: `${asset.name}`, -// directory: path.join(app.getPath("userData"), "download"), -// onProgress: progress => { -// event.reply("Download.frpVersionDownloadOnProgress", { -// id: versionId, -// progress: progress -// }); -// logDebug( -// LogModule.GITHUB, -// `Download progress for versionId: ${versionId} is ${ -// progress.percent * 100 -// }%` -// ); -// }, -// onCompleted: () => { -// logInfo( -// LogModule.GITHUB, -// `Download completed for versionId: ${versionId}, asset: ${asset.name}` -// ); -// -// const frpcVersionPath = decompressFrp( -// asset.name, -// path.join( -// path.join(app.getPath("userData"), "download"), -// `${asset.name}` -// ) -// ); -// version["frpcVersionPath"] = frpcVersionPath; -// insertVersion(version, (err, document) => { -// if (!err) { -// listVersion((err, doc) => { -// event.reply("Config.versions.hook", { err, data: doc }); -// event.reply("Download.frpVersionDownloadOnCompleted", versionId); -// version.download_completed = true; -// logInfo( -// LogModule.GITHUB, -// `Version ${versionId} has been inserted successfully.` -// ); -// }); -// } else { -// logError(LogModule.GITHUB, `Error inserting version: ${err}`); -// } -// }); -// } -// }); -// }); -// -// /** -// * 删除下载 -// */ -// ipcMain.on("github.deleteVersion", async (event, args) => { -// const { absPath, id } = args; -// logDebug( -// LogModule.GITHUB, -// `Attempting to delete version with ID: ${id} and path: ${absPath}` -// ); -// if (fs.existsSync(absPath)) { -// // if (process.platform === 'darwin') { -// // fs.unlinkSync(absPath.replace(/ /g, '\\ ')); -// // }else{ -// // fs.unlinkSync(absPath); -// // } -// fs.rmSync(absPath, { recursive: true, force: true }); -// deleteVersionById(id, () => { -// logInfo( -// LogModule.GITHUB, -// `Successfully deleted version with ID: ${id}` -// ); -// }); -// } else { -// logWarn( -// LogModule.GITHUB, -// `Version with ID: ${id} not found at path: ${absPath}` -// ); -// } -// listVersion((err, doc) => { -// if (err) { -// logError(LogModule.GITHUB, `Error listing versions: ${err}`); -// } else { -// event.reply("Config.versions.hook", { err, data: doc }); -// event.reply("Download.deleteVersion.hook", { -// err: null, -// data: "删除成功" -// }); -// } -// }); -// }); -// -// /** -// * 获取最后版本 -// */ -// ipcMain.on("github.getFrpcDesktopLastVersions", async event => { -// logInfo(LogModule.GITHUB, "Requesting the latest version from GitHub."); -// const request = net.request({ -// method: "get", -// url: "https://api.github.com/repos/luckjiawei/frpc-desktop/releases/latest" -// }); -// request.on("response", response => { -// let responseData: Buffer = Buffer.alloc(0); -// response.on("data", (data: Buffer) => { -// responseData = Buffer.concat([responseData, data]); -// }); -// response.on("end", () => { -// try { -// versions = JSON.parse(responseData.toString()); -// logInfo( -// LogModule.GITHUB, -// "Successfully retrieved the latest version." -// ); -// event.reply("github.getFrpcDesktopLastVersionsHook", versions); -// } catch (error) { -// logError( -// LogModule.GITHUB, -// `Error parsing response data: ${error.message}` -// ); -// } -// }); -// }); -// request.on("error", error => { -// logError(LogModule.GITHUB, `Request error: ${error.message}`); -// }); -// request.end(); -// }); -// -// ipcMain.on( -// "download.importFrpFile", -// async (event, filePath: string, targetPath: string) => { -// const result = await dialog.showOpenDialog(win, { -// properties: ["openFile"], -// filters: [ -// { name: "Frp 文件", extensions: ["tar.gz", "zip"] } // 允许选择的文件类型,分开后缀以确保可以选择 -// ] -// }); -// if (result.canceled) { -// logWarn(LogModule.APP, "Import canceled by user."); -// logWarn(LogModule.GITHUB, "User canceled the file import operation."); -// return; -// } else { -// const filePath = result.filePaths[0]; -// // const fileExtension = path.extname(filePath); -// logInfo(LogModule.APP, `User selected file: ${filePath}`); -// const checksum = calculateFileChecksum(filePath); -// logInfo(LogModule.APP, `Calculated checksum for the file: ${checksum}`); -// const frpName = frpChecksums[checksum]; -// if (frpName) { -// logInfo(LogModule.APP, `FRP file name found: ${frpName}`); -// if (frpArch.every(item => frpName.includes(item))) { -// logInfo( -// LogModule.APP, -// `Architecture matches for FRP file: ${frpName}` -// ); -// const version = getVersionByAssetName(frpName); -// getVersionById(version.id, (err, existingVersion) => { -// if (!err && existingVersion) { -// logInfo( -// LogModule.APP, -// `Version already exists: ${JSON.stringify(existingVersion)}` -// ); -// event.reply("Download.importFrpFile.hook", { -// success: false, -// data: `导入失败,版本已存在` -// }); -// return; // 终止后续执行 -// } -// -// const frpcVersionPath = decompressFrp(frpName, filePath); -// logInfo( -// LogModule.APP, -// `Successfully decompressed FRP file: ${frpName} to path: ${frpcVersionPath}` -// ); -// version["frpcVersionPath"] = frpcVersionPath; -// insertVersion(version, (err, document) => { -// if (!err) { -// listVersion((err, doc) => { -// event.reply("Config.versions.hook", { err, data: doc }); -// version.download_completed = true; -// event.reply("Download.importFrpFile.hook", { -// success: true, -// data: `导入成功` -// }); -// }); -// } else { -// logError(LogModule.APP, `Error inserting version: ${err}`); -// event.reply("Download.importFrpFile.hook", { -// success: true, -// data: `导入失败,未知错误` -// }); -// } -// }); -// }); -// } else { -// logWarn( -// LogModule.APP, -// `Architecture does not match for FRP file: ${frpName}` -// ); -// event.reply("Download.importFrpFile.hook", { -// success: false, -// data: `导入失败,所选 frp 架构与操作系统不符` -// }); -// } -// } else { -// logWarn( -// LogModule.APP, -// `No matching FRP file name found for checksum: ${checksum}` -// ); -// event.reply("Download.importFrpFile.hook", { -// success: false, -// data: `导入失败,无法识别文件` -// }); -// } -// } -// } -// ); -// }; diff --git a/electron/api/update.ts b/electron/api/update.ts deleted file mode 100644 index 485f9b8..0000000 --- a/electron/api/update.ts +++ /dev/null @@ -1,81 +0,0 @@ -// import {app, dialog, autoUpdater, BrowserWindow} from "electron"; -// -// const log = require('electron-log'); -// -// -// export const initUpdaterApi = (win: BrowserWindow) => { -// //更新测试打开 -// Object.defineProperty(app, 'isPackaged', { -// get() { -// return true; -// } -// }); -// const server = 'https://hazel-git-master-uiluck.vercel.app' -// let packageName = null -// const platform = process.platform; -// const arch = process.arch; -// switch (platform) { -// case "darwin": -// if (arch == "arm64") { -// packageName = "darwin_arm64"; -// } else { -// packageName = "darwin"; -// } -// break; -// case "win32": -// packageName = "exe"; -// break; -// case "linux": -// packageName = "AppImage"; -// if (arch == "arm64") { -// packageName = "AppImage_arm64"; -// } else { -// packageName = "AppImage"; -// } -// break; -// } -// const url = `${server}/update/${packageName}/${app.getVersion()}` -// log.info(`开启自动更新 ${url}`); -// autoUpdater.setFeedURL({url: url}) -// -// autoUpdater.on('checking-for-update', () => { -// log.info("正在检查更新") -// }) -// -// autoUpdater.on('update-available', (event, info) => { -// log.info(`发现新版本`) -// }) -// -// autoUpdater.on('update-not-available', () => { -// log.info('没有可用的更新') -// -// }) -// -// autoUpdater.on('error', (err) => { -// log.error(`更新错误:${err.message}`) -// -// }) -// -// autoUpdater.on('update-downloaded', () => { -// dialog.showMessageBox({ -// type: 'info', -// title: '应用更新', -// message: '发现新版本,是否更新?', -// buttons: ['是', '否'] -// }).then((buttonIndex) => { -// if (buttonIndex.response == 0) { //选择是,则退出程序,安装新版本 -// autoUpdater.quitAndInstall() -// app.quit() -// } -// }) -// }) -// -// // setInterval(() => { -// // log.initialize("定时检查更新") -// // // autoUpdater.checkForUpdates(); -// // }, 60000) -// autoUpdater.checkForUpdates(); -// log.info("手动检查更新一次") -// -// -// }