Skip to content

Commit

Permalink
Merge branch 'refs/heads/1.2.x' into 1.2.x-2024-07-20-1
Browse files Browse the repository at this point in the history
# Conflicts:
#	common/src/cli.rs
  • Loading branch information
vnt-dev committed Jul 20, 2024
2 parents 7ebdffc + 1abe33c commit 81c6c8c
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 44 deletions.
1 change: 1 addition & 0 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ serde_yaml = "0.9.32"
getopts = "0.2.21"
gethostname = "0.4.3"
uuid = { version = "1.8.0", features = ["v4"] }
sys-locale = "0.3.1"

[features]
default = []
Expand Down
218 changes: 174 additions & 44 deletions common/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ use crate::{config, generated_serial_number};
use anyhow::anyhow;
use console::style;
use getopts::Options;
use std::collections::HashMap;
use std::io;
use std::net::Ipv4Addr;
use std::path::PathBuf;
use std::str::FromStr;
use sys_locale::get_locale;
use vnt::channel::punch::PunchModel;
use vnt::channel::UseChannelType;
use vnt::cipher::CipherModel;
Expand Down Expand Up @@ -343,38 +345,122 @@ pub fn parse_args_config() -> anyhow::Result<Option<(Config, Vec<String>, bool)>
Ok(Some((config, vnt_link_config, cmd)))
}

fn get_description(key: &str, language: &str) -> String {
// 设置一个全局的映射来存储中英文对照
let descriptions: HashMap<&str, (&str, &str)> = [
("-k <token>", ("使用相同的token,就能组建一个局域网络", "Use the same token to form a local network")),
("-n <name>", ("给设备一个名字,便于区分不同设备,默认使用系统版本", "Give the device a name to distinguish it, defaults to system version")),
("-d <id>", ("设备唯一标识符,不使用--ip参数时,服务端凭此参数分配虚拟ip,注意不能重复", "Device unique identifier, used by the server to allocate virtual IP when --ip parameter is not used, must be unique")),
("-s <server>", ("注册和中继服务器地址,协议支持使用tcp://和ws://和wss://,默认为udp://", "Registration and relay server address, protocols support using tcp://, ws://, and wss://, default is udp://")),
("-e <stun-server>", ("stun服务器,用于探测NAT类型,可使用多个地址,如-e stun.miwifi.com -e turn.cloudflare.com", "STUN server for detecting NAT type, can specify multiple addresses, e.g., -e stun.miwifi.com -e turn.cloudflare.com")),
("-a", ("使用tap模式,默认使用tun模式,使用tap时需要配合'--nic'参数指定tap网卡", "Use tap mode, default is tun mode, specify '--nic' parameter with tap network card")),
("-i <in-ip>", ("配置点对网(IP代理)时使用,-i 192.168.0.0/24,10.26.0.3表示允许接收网段192.168.0.0/24的数据并转发到10.26.0.3,可指定多个网段", "Used when configuring point-to-point network (IP proxy), -i 192.168.0.0/24,10.26.0.3 allows receiving data from subnet 192.168.0.0/24 and forwarding to 10.26.0.3, specify multiple subnets")),
("-o <out-ip>", ("配置点对网时使用,-o 192.168.0.0/24表示允许将数据转发到192.168.0.0/24,可指定多个网段", "Used when configuring point-to-point network, -o 192.168.0.0/24 allows forwarding data to 192.168.0.0/24, specify multiple subnets")),
("-w <password>", ("使用该密码生成的密钥对客户端数据进行加密,并且服务端无法解密,使用相同密码的客户端才能通信", "Encrypt client data with keys generated by this password, server cannot decrypt, clients must use the same password to communicate")),
("-W", ("加密当前客户端和服务端通信的数据,请留意服务端指纹是否正确", "Encrypt the data currently being communicated between the client and server, please pay attention to whether the server fingerprint is correct")),
("-u <mtu>", ("自定义mtu(不加密默认为1450,加密默认为1410", "Customize MTU (1450 by default without encryption, 1410 with encryption)")),
("-f <conf_file>", ("读取配置文件中的配置", "Read configuration from file")),
("--ip <ip>", ("指定虚拟ip,指定的ip不能和其他设备重复,必须有效并且在服务端所属网段下,默认情况由服务端分配", "Specify virtual IP, must be unique and valid within server subnet, by default allocated by server")),
("--model <model>", ("加密模式(默认aes_gcm),可选值{}", "Encryption mode (default aes_gcm), options {}")),
("--finger", ("增加数据指纹校验,可增加安全性,如果服务端开启指纹校验,则客户端也必须开启", "Add data fingerprint verification for increased security, client must enable if server does")),
("--punch <punch>", ("取值ipv4/ipv6/all,ipv4表示仅使用ipv4打洞", "Values ipv4/ipv6/all, ipv4 for IPv4 hole punching only")),
("--ports <port,port>", ("取值0~65535,指定本地监听的一组端口,默认监听两个随机端口,使用过多端口会增加网络负担", "Values 0~65535, specify a group of local listening ports, defaults to two random ports, using many ports increases network load")),
("--cmd", ("开启交互式命令,使用此参数开启控制台输入", "Enable interactive command mode, use this parameter to enable console input")),
("--no-proxy", ("关闭内置代理,如需点对网则需要配置网卡NAT转发", "Disable built-in proxy, configure network card NAT forwarding for point-to-point networking")),
("--first-latency", ("优先低延迟的通道,默认情况优先使用p2p通道", "Prioritize low-latency channels, defaults to prioritizing p2p channel")),
("--use-channel <p2p>", ("使用通道 relay/p2p/all,默认两者都使用", "Use channel relay/p2p/all, defaults to using both")),
("--nic <tun0>", ("指定虚拟网卡名称", "Specify virtual network card name")),
("--packet-loss <0>", ("模拟丢包,取值0~1之间的小数,程序会按设定的概率主动丢包,可用于模拟弱网", "Simulate packet loss, value between 0 and 1, program actively drops packets based on set probability, useful for simulating weak networks")),
("--packet-delay <0>", ("模拟丢包,取值0~1之间的小数,程序会按设定的概率主动丢包,可用于模拟弱网", "Simulate latency, integer, in milliseconds (ms). The program will delay sending packets according to the set value and can be used to simulate weak networks")),
("--dns <host:port>", ("DNS服务器地址,可使用多个dns,不指定时使用系统解析", "DNS server address, can specify multiple DNS servers, defaults to system resolution if not specified")),
("--mapping <mapping>", ("端口映射,例如 --mapping udp:0.0.0.0:80-domain:80 映射目标是本地路由能访问的设备", "Port mapping, e.g., --mapping udp:0.0.0.0:80-domain:80 maps to a device accessible by local routing")),
("--compressor-all <lz4>", ("启用压缩,可选值lz4/zstd<,level>,level为压缩级别,例如 --compressor lz4 或--compressor zstd,10", "Enable compression, options lz4/zstd<,level>, level is compression level, e.g., --compressor lz4 or --compressor zstd,10")),
("--compressor-lz4 <lz4>", ("启用压缩,可选值lz4,例如 --compressor lz4", "Enable compression, option lz4, e.g., --compressor lz4")),
("--compressor-zstd <zstd>", ("启用压缩,可选值zstd<,level>,level为压缩级别,例如 --compressor zstd,10", "Enable compression, options zstd<,level>, level is compression level, e.g., --compressor zstd,10")),
("--vnt-mapping <x>", ("vnt地址映射,例如 --vnt-mapping tcp:80-10.26.0.10:80 映射目标是vnt网络或其子网中的设备", "VNT address mapping, e.g., --vnt-mapping tcp:80-10.26.0.10:80 maps to a device in VNT network or its subnet")),
("--disable-stats", ("关闭流量统计", "Disable traffic statistics")),
("--list", ("后台运行时,查看其他设备列表", "View list of other devices when running in background")),
("--all", ("后台运行时,查看其他设备完整信息", "View complete information of other devices when running in background")),
("--info", ("后台运行时,查看当前设备信息", "View information of current device when running in background")),
("--route", ("后台运行时,查看数据转发路径", "View data forwarding path when running in background")),
("--chart_a", ("后台运行时,查看所有IP的流量统计", "View traffic statistics of all IPs when running in background")),
("--chart_b <IP>", ("后台运行时,查看单个IP的历史流量", "View historical traffic of a single IP when running in background")),
("--stop", ("停止后台运行", "Stop running in background"))
// ... 其他选项
]
.iter()
.cloned()
.collect();

if let Some(&(zh, en)) = descriptions.get(key) {
if language.starts_with("zh") {
return zh.to_string(); // 返回 String 类型
}
// 默认返回英文
return en.to_string(); // 返回 String 类型
}
// 如果没有找到对应的键,则返回空字符串
String::new()
}

fn print_usage(program: &str, _opts: Options) {
// 获取系统语言 Locale::user_default().unwrap_or_else(|_| Locale::default());
let language = get_locale().unwrap_or_else(|| String::from("en-US"));
println!("Usage: {} [options]", program);
println!("version:{}", vnt::VNT_VERSION);
println!("Serial:{}", generated_serial_number::SERIAL_NUMBER);
println!("Options:");
println!(
" -k <token> {}",
green("使用相同的token,就能组建一个局域网络".to_string())
green(get_description("-k <token>", &language).to_string())
);
println!(
" -n <name> {}",
get_description("-n <name>", &language)
);
println!(" -n <name> 给设备一个名字,便于区分不同设备,默认使用系统版本");
println!(" -d <id> 设备唯一标识符,不使用--ip参数时,服务端凭此参数分配虚拟ip,注意不能重复");
println!(
" -s <server> 注册和中继服务器地址,协议支持使用tcp://和ws://和wss://,默认为udp://"
" -d <id> {}",
get_description("-d <id>", &language)
);
println!(
" -s <server> {}",
get_description("-s <server>", &language)
);
println!(
" -e <stun-server> {}",
get_description("-e <stun-server>", &language)
);
println!(" -e <stun-server> stun服务器,用于探测NAT类型,可使用多个地址,如-e stun.miwifi.com -e turn.cloudflare.com");
#[cfg(target_os = "windows")]
#[cfg(feature = "integrated_tun")]
println!(" -a {}", get_description("-a", &language));
println!(
" -a 使用tap模式,默认使用tun模式,使用tap时需要配合'--nic'参数指定tap网卡"
" -i <in-ip> {}",
get_description("-i <in-ip>", &language)
);
println!(
" -o <out-ip> {}",
get_description("-o <out-ip>", &language)
);
println!(
" -w <password> {}",
get_description("-w <password>", &language)
);
println!(" -i <in-ip> 配置点对网(IP代理)时使用,-i 192.168.0.0/24,10.26.0.3表示允许接收网段192.168.0.0/24的数据");
println!(" 并转发到10.26.0.3,可指定多个网段");
println!(" -o <out-ip> 配置点对网时使用,-o 192.168.0.0/24表示允许将数据转发到192.168.0.0/24,可指定多个网段");

println!(" -w <password> 使用该密码生成的密钥对客户端数据进行加密,并且服务端无法解密,使用相同密码的客户端才能通信");
#[cfg(feature = "server_encrypt")]
println!(" -W 加密当前客户端和服务端通信的数据,请留意服务端指纹是否正确");
println!(" -u <mtu> 自定义mtu(不加密默认为1450,加密默认为1410)");
println!(" -W {}", get_description("-W", &language));
println!(
" -u <mtu> {}",
get_description("-u <mtu>", &language)
);
#[cfg(feature = "file_config")]
println!(" -f <conf_file> 读取配置文件中的配置");
println!(
" -f <conf_file> {}",
get_description("-f <conf_file>", &language)
);

println!(" --ip <ip> 指定虚拟ip,指定的ip不能和其他设备重复,必须有效并且在服务端所属网段下,默认情况由服务端分配");
println!(
" --ip <ip> {}",
get_description("--ip <ip>", &language)
);
let mut enums = String::new();
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
enums.push_str("/aes_gcm");
Expand All @@ -388,7 +474,8 @@ fn print_usage(program: &str, _opts: Options) {
enums.push_str("/sm4_cbc");
enums.push_str("/xor");
println!(
" --model <model> 加密模式(默认aes_gcm),可选值{}",
" --model <model> {}{}",
get_description("--model <model>", &language),
&enums[1..]
);
#[cfg(any(
Expand All @@ -399,45 +486,88 @@ fn print_usage(program: &str, _opts: Options) {
feature = "aes_ecb",
feature = "sm4_cbc"
))]
println!(" --finger 增加数据指纹校验,可增加安全性,如果服务端开启指纹校验,则客户端也必须开启");
println!(" --punch <punch> 取值ipv4/ipv6/all,ipv4表示仅使用ipv4打洞");
println!(" --ports <port,port> 取值0~65535,指定本地监听的一组端口,默认监听两个随机端口,使用过多端口会增加网络负担");
println!(
" --finger {}",
get_description("--finger", &language)
);
println!(
" --punch <punch> {}",
get_description("--punch <punch>", &language)
);
println!(
" --ports <port,port> {}",
get_description("--ports <port,port>", &language)
);
#[cfg(feature = "command")]
println!(" --cmd 开启交互式命令,使用此参数开启控制台输入");
println!(
" --cmd {}",
get_description("--cmd", &language)
);
#[cfg(feature = "ip_proxy")]
#[cfg(feature = "integrated_tun")]
println!(" --no-proxy 关闭内置代理,如需点对网则需要配置网卡NAT转发");
println!(" --first-latency 优先低延迟的通道,默认情况优先使用p2p通道");
println!(" --use-channel <p2p> 使用通道 relay/p2p/all,默认两者都使用");
println!(
" --no-proxy {}",
get_description("--no-proxy", &language)
);
println!(
" --first-latency {}",
get_description("--first-latency", &language)
);
println!(
" --use-channel <p2p> {}",
get_description("--use-channel <p2p>", &language)
);
#[cfg(not(feature = "vn-link-model"))]
println!(" --nic <tun0> 指定虚拟网卡名称");
println!(" --packet-loss <0> 模拟丢包,取值0~1之间的小数,程序会按设定的概率主动丢包,可用于模拟弱网");
println!(
" --packet-delay <0> 模拟延迟,整数,单位毫秒(ms),程序会按设定的值延迟发包,可用于模拟弱网"
" --nic <tun0> {}",
get_description("--nic <tun0>", &language)
);
println!(
" --packet-loss <0> {}",
get_description("--packet-loss <0>", &language)
);
println!(
" --packet-delay <0> {}",
get_description("--packet-delay <0>", &language)
);
println!(
" --dns <host:port> {}",
get_description("--dns <host:port>", &language)
);
println!(" --dns <host:port> DNS服务器地址,可使用多个dns,不指定时使用系统解析");

#[cfg(feature = "port_mapping")]
println!(" --mapping <mapping> 端口映射,例如 --mapping udp:0.0.0.0:80-domain:80 映射目标是本地路由能访问的设备");
println!(
" --mapping <mapping> {}",
get_description("--mapping <mapping>", &language)
);

#[cfg(all(feature = "lz4", feature = "zstd"))]
println!(" --compressor <lz4> 启用压缩,可选值lz4/zstd<,level>,level为压缩级别,例如 --compressor lz4 或--compressor zstd,10");
println!(
" --compressor <lz4> {}",
get_description("--compressor-all <lz4>", &language)
);
#[cfg(feature = "lz4")]
#[cfg(not(feature = "zstd"))]
println!(" --compressor <lz4> 启用压缩,可选值lz4,例如 --compressor lz4");
println!(
" --compressor <lz4> {}",
get_description("--compressor-lz4 <lz4>", &language)
);
#[cfg(feature = "zstd")]
#[cfg(not(feature = "lz4"))]
println!(" --compressor <zstd> 启用压缩,可选值zstd<,level>,level为压缩级别,例如 --compressor zstd,10");
println!(
" --compressor <zstd> {}",
get_description("--compressor-zstd <zstd>", &language)
);

#[cfg(not(feature = "integrated_tun"))]
println!(
" --vnt-mapping <x> {}",
green(
"vnt地址映射,例如 --vnt-mapping tcp:80-10.26.0.10:80 映射目标是vnt网络或其子网中的设备"
.to_string()
)
green(get_description("--vnt-mapping <x>", &language).to_string())
);
println!(
" --disable-stats {}",
get_description("--disable-stats", &language)
);
println!(" --disable-stats 关闭流量统计");
println!(" --allow-wg 允许接入WireGuard客户端");
println!();
#[cfg(feature = "command")]
Expand All @@ -449,34 +579,34 @@ fn print_usage(program: &str, _opts: Options) {
// );
println!(
" --list {}",
yellow("后台运行时,查看其他设备列表".to_string())
yellow(get_description("--list", &language).to_string())
);
println!(
" --all {}",
yellow("后台运行时,查看其他设备完整信息".to_string())
yellow(get_description("--all", &language).to_string())
);
println!(
" --info {}",
yellow("后台运行时,查看当前设备信息".to_string())
yellow(get_description("--info", &language).to_string())
);
println!(
" --route {}",
yellow("后台运行时,查看数据转发路径".to_string())
yellow(get_description("--route", &language).to_string())
);
println!(
" --chart_a {}",
yellow("后台运行时,查看所有IP的流量统计".to_string())
yellow(get_description("--chart_a", &language).to_string())
);
println!(
" --chart_b <IP> {}",
yellow("后台运行时,查看单个IP的历史流量".to_string())
yellow(get_description("--chart_b <IP>", &language).to_string())
);
println!(
" --stop {}",
yellow("停止后台运行".to_string())
yellow(get_description("--stop", &language).to_string())
);
}
println!(" -h, --help 帮助");
println!(" -h, --help display help information(显示帮助信息)");
}

fn green(str: String) -> impl std::fmt::Display {
Expand Down

0 comments on commit 81c6c8c

Please sign in to comment.