diff --git a/neveko-core/src/args.rs b/neveko-core/src/args.rs index bc3a007..162dcfc 100644 --- a/neveko-core/src/args.rs +++ b/neveko-core/src/args.rs @@ -148,6 +148,13 @@ pub struct Args { default_value = "false" )] pub i2p_advanced: bool, + /// Manually configured tunnels.json directory + #[arg( + long, + help = "ADVANCED. Location of the manually created destination tunnels.", + default_value = "/home/user/neveko/i2p-manual" + )] + pub i2p_tunnels_json: String, /// Dummy flag for normal neveko i2p-zero config. Future use. #[arg( long, diff --git a/neveko-core/src/i2p.rs b/neveko-core/src/i2p.rs index bee6cde..5c7f947 100644 --- a/neveko-core/src/i2p.rs +++ b/neveko-core/src/i2p.rs @@ -184,10 +184,23 @@ fn create_http_proxy() { /// /// `port` - the port of the tunnel (e.g. `utils::get_app_port()`) pub fn get_destination(port: Option) -> String { - let file_path = format!( + let mut file_path = format!( "/home/{}/.i2p-zero/config/tunnels.json", env::var("USER").unwrap_or(String::from("user")) ); + let args = args::Args::parse(); + let is_advanced_mode = + std::env::var(crate::NEVEKO_I2P_ADVANCED_MODE).unwrap_or(utils::empty_string()); + if args.i2p_advanced || is_advanced_mode == String::from("1") { + let advanced_tunnel = + std::env::var(crate::NEVEKO_I2P_TUNNELS_JSON).unwrap_or(utils::empty_string()); + let manual_tunnel = if advanced_tunnel == utils::empty_string() { + args.i2p_tunnels_json + } else { + advanced_tunnel + }; + file_path = format!("{}/tunnels.json", manual_tunnel); + } // Don't panic if i2p-zero isn't installed let contents = match fs::read_to_string(file_path) { Ok(file) => file, diff --git a/neveko-core/src/lib.rs b/neveko-core/src/lib.rs index a05b0f8..b87163a 100644 --- a/neveko-core/src/lib.rs +++ b/neveko-core/src/lib.rs @@ -23,6 +23,10 @@ pub const NEVEKO_JWT_SECRET_KEY: &str = "NEVEKO_JWT_SECRET_KEY"; pub const MONERO_WALLET_PASSWORD: &str = "MONERO_WALLET_PASSWORD"; /// Environment variable for I2P proxy host pub const NEVEKO_I2P_PROXY_HOST: &str = "NEVEKO_I2P_PROXY_HOST"; +/// Environment variable for I2P manual tunnels.json +pub const NEVEKO_I2P_TUNNELS_JSON: &str = "NEVEKO_I2P_TUNNELS_JSON"; +/// Environment variable for I2P advanced mode +pub const NEVEKO_I2P_ADVANCED_MODE: &str = "NEVEKO_I2P_ADVANCED_MODE"; /// The latest monero release download pub const MONERO_RELEASE_VERSION: &str = "monero-linux-x64-v0.18.2.2.tar.bz2"; diff --git a/neveko-core/src/utils.rs b/neveko-core/src/utils.rs index a318a28..b04fd85 100644 --- a/neveko-core/src/utils.rs +++ b/neveko-core/src/utils.rs @@ -85,6 +85,8 @@ pub struct Connections { pub blockchain_dir: String, pub daemon_host: String, pub i2p_proxy_host: String, + /// path to manually created tunnels json + pub i2p_tunnels_json: String, pub i2p_zero_dir: String, pub is_remote_node: bool, pub is_i2p_advanced: bool, @@ -101,6 +103,7 @@ impl Default for Connections { blockchain_dir: String::from("/home/user/.bitmonero"), daemon_host: String::from("http://localhost:38081"), i2p_proxy_host: String::from("http://localhost:4444"), + i2p_tunnels_json: String::from("/home/user/neveko/i2p-manual"), i2p_zero_dir: String::from("/home/user/i2p-zero-linux.v1.21"), is_remote_node: false, is_i2p_advanced: false, @@ -146,8 +149,16 @@ impl ReleaseEnvironment { /// start core module from gui pub fn start_core(conn: &Connections) { let env = if !conn.mainnet { "dev" } else { "prod" }; - let remote_node = if !conn.is_remote_node { "--full-node" } else { "--remote-node" }; - let i2p_advanced = if !conn.is_i2p_advanced { "--i2p-normal" } else { "--i2p-advanced" }; + let remote_node = if !conn.is_remote_node { + "--full-node" + } else { + "--remote-node" + }; + let i2p_advanced = if !conn.is_i2p_advanced { + "--i2p-normal" + } else { + "--i2p-advanced" + }; let args = [ "--monero-location", &conn.monero_location, @@ -214,9 +225,12 @@ pub fn get_app_port() -> u16 { /// i2p http proxy pub fn get_i2p_http_proxy() -> String { let args = args::Args::parse(); - let advanced_proxy = - std::env::var(crate::NEVEKO_I2P_PROXY_HOST).unwrap_or(empty_string()); - if advanced_proxy == empty_string() { args.i2p_proxy_host } else { advanced_proxy } + let advanced_proxy = std::env::var(crate::NEVEKO_I2P_PROXY_HOST).unwrap_or(empty_string()); + if advanced_proxy == empty_string() { + args.i2p_proxy_host + } else { + advanced_proxy + } } /// app auth port diff --git a/neveko-gui/src/apps/home.rs b/neveko-gui/src/apps/home.rs index 4e6086a..1fe5c96 100644 --- a/neveko-gui/src/apps/home.rs +++ b/neveko-gui/src/apps/home.rs @@ -262,17 +262,25 @@ impl eframe::App for HomeApp { .labelled_by(cm_i2p_dir_label.id); }); ui.horizontal(|ui| { - let cm_i2p_proxy_label = ui.label("i2p proxy host: \t"); + let cm_i2p_proxy_label = ui.label("i2p proxy host: \t"); ui.text_edit_singleline(&mut self.connections.i2p_proxy_host) .labelled_by(cm_i2p_proxy_label.id); }); + ui.horizontal(|ui| { + let cm_i2p_tunnels_label = ui.label("tunnels.json dir: "); + ui.text_edit_singleline(&mut self.connections.i2p_tunnels_json) + .labelled_by(cm_i2p_tunnels_label.id); + }); let mut is_remote_node = self.connections.is_remote_node; if ui.checkbox(&mut is_remote_node, "remote node").changed() { self.connections.is_remote_node = !self.connections.is_remote_node; log::debug!("is remote node: {}", self.connections.is_remote_node); } let mut is_i2p_advanced = self.connections.is_i2p_advanced; - if ui.checkbox(&mut is_i2p_advanced, "i2p advanced mode").changed() { + if ui + .checkbox(&mut is_i2p_advanced, "i2p advanced mode") + .changed() + { self.connections.is_i2p_advanced = !self.connections.is_i2p_advanced; log::debug!("is i2p advanced mode: {}", self.connections.is_i2p_advanced); } @@ -286,7 +294,15 @@ impl eframe::App for HomeApp { utils::kill_child_processes(true); utils::start_core(&self.connections); // set the i2p proxy host for advanced user re-use - std::env::set_var(neveko_core::NEVEKO_I2P_PROXY_HOST, self.connections.i2p_proxy_host.clone()); + std::env::set_var( + neveko_core::NEVEKO_I2P_PROXY_HOST, + self.connections.i2p_proxy_host.clone(), + ); + std::env::set_var( + neveko_core::NEVEKO_I2P_TUNNELS_JSON, + self.connections.i2p_tunnels_json.clone(), + ); + std::env::set_var(neveko_core::NEVEKO_I2P_ADVANCED_MODE, String::from("1")); self.is_loading = true; start_core_timeout(self.core_timeout_tx.clone(), ctx.clone()); } @@ -355,6 +371,9 @@ impl eframe::App for HomeApp { if self.s_i2p_status == i2p::ProxyStatus::Open { str_i2p_status = String::from("online"); } + if self.connections.is_i2p_advanced { + str_i2p_status = String::from("remote proxy"); + } ui.horizontal(|ui| { self.logo_i2p.show(ui); ui.horizontal(|ui| { @@ -397,7 +416,7 @@ impl eframe::App for HomeApp { } } } - if !self.is_core_running && !self.is_installing + if !self.is_core_running && !self.is_installing && !self.connections.is_remote_node && !self.connections.is_i2p_advanced && (self.s_xmr_rpc_ver.result.version == 0 || self.s_i2p_status == i2p::ProxyStatus::Opening) { if !self.is_loading { if ui.button("Install Software").clicked() {