use crate::models::{ExtraSettings, Proxy, ProxyType, SS_CIPHERS};
use crate::utils::string::trim_whitespace;
use log::error;
use serde_json::{json, Value as JsonValue};
pub fn proxy_to_ss_sub(
base_conf: &str,
nodes: &mut Vec<Proxy>,
_ext: &mut ExtraSettings,
) -> String {
let base_conf = trim_whitespace(base_conf, true, true);
let base_conf = if base_conf.is_empty() {
"{}"
} else {
&base_conf
};
let base_json: JsonValue = match serde_json::from_str(base_conf) {
Ok(json) => json,
Err(e) => {
error!("SIP008 base loader failed with error: {}", e);
json!({})
}
};
let mut proxies = Vec::new();
for node in nodes {
let remark = &node.remark;
let hostname = &node.hostname;
let port = node.port;
let password = node.password.as_deref().unwrap_or("");
let method = node.encrypt_method.as_deref().unwrap_or("");
let mut plugin = node.plugin.as_deref().unwrap_or("").to_string();
let plugin_opts = node.plugin_option.as_deref().unwrap_or("");
let protocol = node.protocol.as_deref().unwrap_or("");
let obfs = node.obfs.as_deref().unwrap_or("");
match node.proxy_type {
ProxyType::Shadowsocks => {
if plugin == "simple-obfs" {
plugin = "obfs-local".to_string();
}
}
ProxyType::ShadowsocksR => {
if !SS_CIPHERS.contains(&method) || protocol != "origin" || obfs != "plain" {
continue;
}
}
_ => continue, }
let mut proxy = match base_json.as_object() {
Some(obj) => obj.clone(),
None => serde_json::Map::new(),
};
proxy.insert("remarks".to_string(), json!(remark));
proxy.insert("server".to_string(), json!(hostname));
proxy.insert("server_port".to_string(), json!(port));
proxy.insert("method".to_string(), json!(method));
proxy.insert("password".to_string(), json!(password));
proxy.insert("plugin".to_string(), json!(plugin));
proxy.insert("plugin_opts".to_string(), json!(plugin_opts));
proxies.push(JsonValue::Object(proxy));
}
match serde_json::to_string_pretty(&proxies) {
Ok(json_str) => json_str,
Err(e) => {
error!("Failed to serialize SIP008 JSON: {}", e);
String::new()
}
}
}