- 修复内网穿透
This commit is contained in:
+65
-38
@@ -546,57 +546,84 @@ async fn sse_handler() -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ===================== NPC 内网穿透客户端 =====================
|
// ===================== NPC 内网穿透客户端 =====================
|
||||||
|
/// 多平台兼容:
|
||||||
|
/// - Windows: 二进制名为 npc.exe
|
||||||
|
/// - macOS/Linux: 二进制名为 npc
|
||||||
|
/// 每次启动检查持久化目录(与 data.json 同一目录下的 npc/)中是否存在,
|
||||||
|
/// 不存在则从嵌入式 npc.zip 解压。
|
||||||
pub fn setup_npc() {
|
pub fn setup_npc() {
|
||||||
let zip_data = match Asset::get("npc.zip") {
|
let data_dir = dirs::data_dir()
|
||||||
Some(data) => data,
|
|
||||||
None => {
|
|
||||||
eprintln!("[dpm] 警告: npc.zip 未嵌入到程序中,跳过");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let data_dir = dirs::home_dir()
|
|
||||||
.unwrap_or_else(|| PathBuf::from("."))
|
.unwrap_or_else(|| PathBuf::from("."))
|
||||||
.join(".dpm")
|
.join("dpm")
|
||||||
.join("npc");
|
.join("npc");
|
||||||
if let Err(e) = fs::create_dir_all(&data_dir) {
|
if let Err(e) = fs::create_dir_all(&data_dir) {
|
||||||
eprintln!("[dpm] 无法创建 npc 目录 ({}): {}", data_dir.display(), e);
|
eprintln!("[dpm] 无法创建 npc 目录 ({}): {}", data_dir.display(), e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let exe_path = data_dir.join("npc.exe");
|
// 根据平台确定二进制文件名
|
||||||
|
let exe_name = if cfg!(target_os = "windows") {
|
||||||
// 解压 npc.exe
|
"npc.exe"
|
||||||
let cursor = Cursor::new(zip_data.data);
|
} else {
|
||||||
let mut archive = match zip::ZipArchive::new(cursor) {
|
"npc"
|
||||||
Ok(a) => a,
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("[dpm] npc.zip 解压失败: {}", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
let exe_path = data_dir.join(exe_name);
|
||||||
|
|
||||||
let mut extracted = false;
|
// 检查文件是否已存在,不存在则从嵌入式 zip 解压
|
||||||
for i in 0..archive.len() {
|
if !exe_path.exists() {
|
||||||
let mut file = match archive.by_index(i) {
|
let zip_data = match Asset::get("npc.zip") {
|
||||||
Ok(f) => f,
|
Some(data) => data,
|
||||||
Err(_) => continue,
|
None => {
|
||||||
};
|
eprintln!("[dpm] 警告: npc.zip 未嵌入到程序中,跳过");
|
||||||
if file.name() == "npc.exe" {
|
|
||||||
if let Err(e) = fs::File::create(&exe_path)
|
|
||||||
.and_then(|mut out| std::io::copy(&mut file, &mut out).map(|_| ()))
|
|
||||||
{
|
|
||||||
eprintln!("[dpm] npc.exe 写入失败: {}", e);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
extracted = true;
|
};
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !extracted {
|
let cursor = Cursor::new(zip_data.data);
|
||||||
eprintln!("[dpm] npc.zip 中未找到 npc.exe");
|
let mut archive = match zip::ZipArchive::new(cursor) {
|
||||||
return;
|
Ok(a) => a,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("[dpm] npc.zip 解压失败: {}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut extracted = false;
|
||||||
|
for i in 0..archive.len() {
|
||||||
|
let mut file = match archive.by_index(i) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(_) => continue,
|
||||||
|
};
|
||||||
|
// 兼容 zip 中二进制名为 npc.exe 或 npc 的情况
|
||||||
|
let name = file.name().trim_end_matches('/');
|
||||||
|
let is_match = name == "npc.exe" || name == "npc" || name == exe_name;
|
||||||
|
if is_match {
|
||||||
|
if let Err(e) = fs::File::create(&exe_path)
|
||||||
|
.and_then(|mut out| std::io::copy(&mut file, &mut out).map(|_| ()))
|
||||||
|
{
|
||||||
|
eprintln!("[dpm] {} 写入失败: {}", exe_name, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
extracted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !extracted {
|
||||||
|
eprintln!("[dpm] npc.zip 中未找到 npc/npc.exe");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unix 平台设置可执行权限
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
{
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
if let Err(e) = fs::set_permissions(&exe_path, fs::Permissions::from_mode(0o755)) {
|
||||||
|
eprintln!("[dpm] 设置执行权限失败: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("[dpm] npc 客户端已解压到 {}", exe_path.display());
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("[dpm] 启动 npc 客户端...");
|
println!("[dpm] 启动 npc 客户端...");
|
||||||
|
|||||||
Reference in New Issue
Block a user