diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 09aca54..636f89a 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -23,7 +23,6 @@ use commands::runners; use commands::skin; use commands::steam; use commands::workshop; -use networking::direct; use networking::relay; use networking::stun; use state::{DownloadState, GameState, ProxyGuard}; @@ -108,7 +107,6 @@ pub fn run() { game::restore_instance, commands::console2lce::import_world, stun::stun_discover, - direct::start_direct_proxy, relay::start_relay_proxy, relay::start_host_relay, relay::stop_proxy, diff --git a/src-tauri/src/networking/direct.rs b/src-tauri/src/networking/direct.rs deleted file mode 100644 index 29eaf1b..0000000 --- a/src-tauri/src/networking/direct.rs +++ /dev/null @@ -1,93 +0,0 @@ -use tauri::State; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use tokio_util::sync::CancellationToken; -use crate::state::ProxyGuard; -async fn run_direct_proxy( - proxy_state: &ProxyGuard, - target_ip: &str, - target_port: u16, - cancel: CancellationToken, -) -> Result { - let remote = tokio::net::TcpStream::connect(format!("{}:{}", target_ip, target_port)) - .await - .map_err(|e| format!("Direct TCP connect failed: {}", e))?; - - let listener = tokio::net::TcpListener::bind("0.0.0.0:0") - .await - .map_err(|e| format!("Bind failed: {}", e))?; - let local_port = listener.local_addr().map_err(|e| e.to_string())?.port(); - { - let mut port = proxy_state.local_port.lock().await; - *port = Some(local_port); - } - - let (local_stream, _) = tokio::select! { - result = listener.accept() => result.map_err(|e| format!("Accept failed: {}", e))?, - _ = cancel.cancelled() => return Err("Proxy cancelled".into()), - }; - - let (mut a_read, mut a_write) = remote.into_split(); - let (mut b_read, mut b_write) = local_stream.into_split(); - let cancel_a = cancel.clone(); - let task_a = tokio::spawn(async move { - let mut buf = [0u8; 65536]; - loop { - tokio::select! { - result = a_read.read(&mut buf) => { - match result { - Ok(0) | Err(_) => break, - Ok(n) => { if b_write.write_all(&buf[..n]).await.is_err() { break; } } - } - } - _ = cancel_a.cancelled() => break, - } - } - }); - - let cancel_b = cancel.clone(); - let task_b = tokio::spawn(async move { - let mut buf = [0u8; 65536]; - loop { - tokio::select! { - result = b_read.read(&mut buf) => { - match result { - Ok(0) | Err(_) => break, - Ok(n) => { if a_write.write_all(&buf[..n]).await.is_err() { break; } } - } - } - _ = cancel_b.cancelled() => break, - } - } - }); - - tokio::select! { - _ = task_a => {}, - _ = task_b => {}, - _ = cancel.cancelled() => {}, - } - - Ok(local_port) -} - -#[tauri::command] -pub async fn start_direct_proxy( - proxy_state: State<'_, ProxyGuard>, - target_ip: String, - target_port: u16, -) -> Result { - let cancel = CancellationToken::new(); - let session_id = "__direct__".to_string(); - { - let mut tokens = proxy_state.cancel_tokens.lock().await; - tokens.insert(session_id.clone(), cancel.clone()); - } - - let local_port = run_direct_proxy(&proxy_state, &target_ip, target_port, cancel).await?; - - { - let mut tokens = proxy_state.cancel_tokens.lock().await; - tokens.remove(&session_id); - } - - Ok(local_port) -} diff --git a/src-tauri/src/networking/mod.rs b/src-tauri/src/networking/mod.rs index 2e65f2d..6261c84 100644 --- a/src-tauri/src/networking/mod.rs +++ b/src-tauri/src/networking/mod.rs @@ -1,3 +1,2 @@ pub mod stun; pub mod relay; -pub mod direct; diff --git a/src-tauri/src/networking/relay.rs b/src-tauri/src/networking/relay.rs index ef1ed60..adbc7e6 100644 --- a/src-tauri/src/networking/relay.rs +++ b/src-tauri/src/networking/relay.rs @@ -1,268 +1,176 @@ -use futures_util::{SinkExt, StreamExt}; use tauri::State; use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::{TcpListener, TcpStream}; use tokio_util::sync::CancellationToken; use crate::state::ProxyGuard; -use crate::util; -async fn run_relay_proxy( - proxy_state: &ProxyGuard, - ws_url: &str, - auth_token: &str, - cancel: CancellationToken, -) -> Result { - use tokio_tungstenite::tungstenite::client::IntoClientRequest; - eprintln!("[Emerald] Joiner relay: connecting WS..."); - let mut request = ws_url - .into_client_request() - .map_err(|e| format!("Failed to build WS request: {}", e))?; - request.headers_mut().insert( - http::header::AUTHORIZATION, - format!("Bearer {}", auth_token) - .parse() - .map_err(|_| "Invalid auth header value".to_string())?, - ); - request.headers_mut().insert( - http::header::USER_AGENT, - "MCLCE-LceLive/1.0" - .parse() - .map_err(|_| "Invalid UA header value".to_string())?, - ); - - let (ws_stream, _) = tokio_tungstenite::connect_async(request) - .await - .map_err(|e| format!("Relay WS connect failed: {}", e))?; - eprintln!("[Emerald] Joiner relay: WS connected"); - - let listener = tokio::net::TcpListener::bind("0.0.0.0:61000") - .await - .map_err(|e| format!("Bind failed: {}", e))?; - let local_port = listener.local_addr().map_err(|e| e.to_string())?.port(); - eprintln!("[Emerald] Joiner relay: bound on 0.0.0.0:{}", local_port); - - { - let mut port = proxy_state.local_port.lock().await; - *port = Some(local_port); +const PROXY_ADDR: &str = "proxy.mclegacyedition.xyz:2052"; //neo: yeah bro im hardcoding it +async fn read_line(stream: &mut TcpStream) -> Result { + let mut buf = Vec::new(); + let mut byte = [0u8; 1]; + loop { + stream.read_exact(&mut byte).await.map_err(|e| e.to_string())?; + if byte[0] == b'\n' { break; } + buf.push(byte[0]); } + String::from_utf8(buf).map_err(|e| e.to_string()) +} - tokio::spawn(async move { - eprintln!("[Emerald] Joiner relay: waiting for TCP accept on port {}...", local_port); - let (tcp_stream, _) = tokio::select! { - result = listener.accept() => { - eprintln!("[Emerald] Joiner relay: TCP accepted"); - result.map_err(|e| format!("Accept failed: {}", e)).unwrap() - }, - _ = cancel.cancelled() => { - eprintln!("[Emerald] Joiner relay: cancelled before accept"); - return; - }, - }; - - eprintln!("[Emerald] Joiner relay: starting forwarders"); - let (tcp_read, tcp_write) = tcp_stream.into_split(); - let (ws_write, ws_read) = ws_stream.split(); - let cancel_ws = cancel.clone(); - let forward_tcp = tokio::spawn(async move { - let mut ws_write = ws_write; - let mut tcp_read = tcp_read; - let mut buf = [0u8; 65536]; - loop { - tokio::select! { - result = tcp_read.read(&mut buf) => { - match result { - Ok(0) => { eprintln!("[Emerald] Joiner relay: TCP→WS EOF"); break; }, - Err(e) => { eprintln!("[Emerald] Joiner relay: TCP→WS read error: {e}"); break; }, - Ok(n) => { - eprintln!("[Emerald] Joiner relay: TCP→WS forwarding {} bytes", n); - if ws_write.send(tokio_tungstenite::tungstenite::Message::Binary(buf[..n].to_vec())).await.is_err() { - eprintln!("[Emerald] Joiner relay: TCP→WS send error"); break; - } - } - } - } - _ = cancel_ws.cancelled() => { eprintln!("[Emerald] Joiner relay: TCP→WS cancelled"); break; }, - } - } - }); - - let cancel_tcp = cancel.clone(); - let forward_ws = tokio::spawn(async move { - let ws_read = ws_read; - let mut tcp_write = tcp_write; - tokio::pin!(ws_read); - loop { - tokio::select! { - result = ws_read.next() => { - match result { - Some(Ok(tokio_tungstenite::tungstenite::Message::Binary(data))) => { - eprintln!("[Emerald] Joiner relay: WS→TCP forwarding {} bytes", data.len()); - if tcp_write.write_all(&data).await.is_err() { break; } - } - Some(Ok(tokio_tungstenite::tungstenite::Message::Close(_))) => { break; } - None => { break; } - Some(Err(e)) => { eprintln!("[Emerald] Joiner relay: WS→TCP error: {e}"); break; } - _ => {} - } - } - _ = cancel_tcp.cancelled() => { break; }, - } - } - }); - - tokio::select! { - _ = forward_tcp => eprintln!("[Emerald] Joiner relay: forward_tcp done"), - _ = forward_ws => eprintln!("[Emerald] Joiner relay: forward_ws done"), - _ = cancel.cancelled() => eprintln!("[Emerald] Joiner relay: cancelled"), - } - eprintln!("[Emerald] Joiner relay: relay task ended"); - }); - - Ok(local_port) +async fn write_line(stream: &mut TcpStream, line: &str) -> Result<(), String> { + let data = format!("{}\n", line); + stream.write_all(data.as_bytes()).await.map_err(|e| e.to_string()) } async fn run_host_relay( _proxy_state: &ProxyGuard, - ws_url: &str, + proxy_addr: &str, auth_token: &str, game_port: u16, cancel: CancellationToken, ) -> Result<(), String> { - use tokio_tungstenite::tungstenite::client::IntoClientRequest; - eprintln!("[Emerald] Host relay: connecting WS..."); - let mut request = ws_url - .into_client_request() - .map_err(|e| format!("Failed to build WS request: {}", e))?; - request.headers_mut().insert( - http::header::AUTHORIZATION, - format!("Bearer {}", auth_token) - .parse() - .map_err(|_| "Invalid auth header value".to_string())?, - ); - request.headers_mut().insert( - http::header::USER_AGENT, - "MCLCE-LceLive/1.0" - .parse() - .map_err(|_| "Invalid UA header value".to_string())?, - ); - - let (ws_stream, _) = tokio_tungstenite::connect_async(request) + let mut host_conn = TcpStream::connect(proxy_addr) .await - .map_err(|e| format!("Host relay WS connect failed: {}", e))?; - eprintln!("[Emerald] Host relay: WS connected"); - eprintln!("[Emerald] Host relay: connecting to game 127.0.0.1:{}...", game_port); + .map_err(|e| format!("Proxy connect failed: {}", e))?; + + write_line(&mut host_conn, &format!("HOST {} 0", auth_token)).await?; let game_stream = loop { - match tokio::net::TcpStream::connect(format!("127.0.0.1:{}", game_port)).await { - Ok(stream) => { eprintln!("[Emerald] Host relay: connected to game"); break stream; }, - Err(e) => { - eprintln!("[Emerald] Host relay: game connect failed (retrying): {e}"); + match TcpStream::connect(format!("127.0.0.1:{}", game_port)).await { + Ok(s) => break s, + Err(_) => { tokio::select! { - _ = cancel.cancelled() => return Err("Host relay cancelled".into()), - _ = tokio::time::sleep(std::time::Duration::from_secs(2)) => {} + _ = cancel.cancelled() => return Err("Cancelled".into()), + _ = tokio::time::sleep(std::time::Duration::from_secs(1)) => {} } } } }; - eprintln!("[Emerald] Host relay: starting forwarders"); - let (game_read, game_write) = game_stream.into_split(); - let (ws_write, ws_read) = ws_stream.split(); - let cancel_ws = cancel.clone(); - let forward_game = tokio::spawn(async move { - let mut ws_write = ws_write; - let mut game_read = game_read; + let client_line = read_line(&mut host_conn).await?; + let client_parts: Vec<&str> = client_line.split_whitespace().collect(); + if client_parts.len() < 2 || client_parts[0] != "CLIENT" { + return Err(format!("Expected CLIENT, got: {}", client_line)); + } + let joiner_id = client_parts[1]; + let mut accept_conn = TcpStream::connect(proxy_addr) + .await + .map_err(|e| format!("Proxy connect failed: {}", e))?; + write_line(&mut accept_conn, &format!("ACCEPT {} 0 {}", auth_token, joiner_id)).await?; + let (mut g_read, mut g_write) = game_stream.into_split(); + let (mut a_read, mut a_write) = accept_conn.into_split(); + let c1 = cancel.clone(); + let c2 = cancel.clone(); + let t1 = tokio::spawn(async move { let mut buf = [0u8; 65536]; loop { tokio::select! { - result = game_read.read(&mut buf) => { - match result { - Ok(0) => { eprintln!("[Emerald] Host relay: game→WS EOF"); break; }, - Err(e) => { eprintln!("[Emerald] Host relay: game→WS read error: {e}"); break; }, - Ok(n) => { - eprintln!("[Emerald] Host relay: game→WS forwarding {} bytes", n); - if ws_write.send(tokio_tungstenite::tungstenite::Message::Binary(buf[..n].to_vec())).await.is_err() { break; } - } + r = g_read.read(&mut buf) => { + match r { + Ok(0) | Err(_) => break, + Ok(n) => { if a_write.write_all(&buf[..n]).await.is_err() { break; } } } } - _ = cancel_ws.cancelled() => { break; }, + _ = c1.cancelled() => break, } } }); - let cancel_ws2 = cancel.clone(); - let forward_ws = tokio::spawn(async move { - let ws_read = ws_read; - let mut game_write = game_write; - tokio::pin!(ws_read); + let t2 = tokio::spawn(async move { + let mut buf = [0u8; 65536]; loop { tokio::select! { - result = ws_read.next() => { - match result { - Some(Ok(tokio_tungstenite::tungstenite::Message::Binary(data))) => { - eprintln!("[Emerald] Host relay: WS→game forwarding {} bytes", data.len()); - if game_write.write_all(&data).await.is_err() { break; } - } - Some(Ok(tokio_tungstenite::tungstenite::Message::Close(_))) => { break; } - None => { break; } - Some(Err(e)) => { eprintln!("[Emerald] Host relay: WS→game error: {e}"); break; } - _ => {} + r = a_read.read(&mut buf) => { + match r { + Ok(0) | Err(_) => break, + Ok(n) => { if g_write.write_all(&buf[..n]).await.is_err() { break; } } } } - _ = cancel_ws2.cancelled() => { break; }, + _ = c2.cancelled() => break, } } }); - tokio::select! { - _ = forward_game => eprintln!("[Emerald] Host relay: forward_game done"), - _ = forward_ws => eprintln!("[Emerald] Host relay: forward_ws done"), - _ = cancel.cancelled() => eprintln!("[Emerald] Host relay: cancelled"), - } - + let _ = tokio::join!(t1, t2); Ok(()) } -#[tauri::command] -pub async fn start_relay_proxy( - proxy_state: State<'_, ProxyGuard>, - api_base_url: String, - access_token: String, - session_id: String, +async fn run_relay_proxy( + proxy_state: &ProxyGuard, + proxy_addr: &str, + auth_token: &str, + target_session: &str, + cancel: CancellationToken, ) -> Result { - let ws_base = util::ws_base_url(&api_base_url); - let ws_url = format!("{}/api/relay/ws?sessionId={}&role=joiner", ws_base, session_id); - let cancel = CancellationToken::new(); + let mut stream = TcpStream::connect(proxy_addr) + .await + .map_err(|e| format!("Proxy connect failed: {}", e))?; + + write_line(&mut stream, &format!("JOIN {} 0 {}", auth_token, target_session)).await?; + let listener = TcpListener::bind("0.0.0.0:61000") + .await + .map_err(|e| format!("Bind failed: {}", e))?; + let local_port = listener.local_addr().map_err(|e| e.to_string())?.port(); { - let mut tokens = proxy_state.cancel_tokens.lock().await; - tokens.insert(session_id.clone(), cancel.clone()); + let mut port = proxy_state.local_port.lock().await; + *port = Some(local_port); } - let local_port = run_relay_proxy(&proxy_state, &ws_url, &access_token, cancel).await?; + let (local_stream, _) = tokio::select! { + r = listener.accept() => r.map_err(|e| format!("Accept failed: {}", e))?, + _ = cancel.cancelled() => return Err("Cancelled".into()), + }; - { - let mut tokens = proxy_state.cancel_tokens.lock().await; - tokens.remove(&session_id); - } + let (mut l_read, mut l_write) = local_stream.into_split(); + let (mut s_read, mut s_write) = stream.into_split(); + let c1 = cancel.clone(); + let c2 = cancel.clone(); + let t1 = tokio::spawn(async move { + let mut buf = [0u8; 65536]; + loop { + tokio::select! { + r = l_read.read(&mut buf) => { + match r { + Ok(0) | Err(_) => break, + Ok(n) => { if s_write.write_all(&buf[..n]).await.is_err() { break; } } + } + } + _ = c1.cancelled() => break, + } + } + }); + let t2 = tokio::spawn(async move { + let mut buf = [0u8; 65536]; + loop { + tokio::select! { + r = s_read.read(&mut buf) => { + match r { + Ok(0) | Err(_) => break, + Ok(n) => { if l_write.write_all(&buf[..n]).await.is_err() { break; } } + } + } + _ = c2.cancelled() => break, + } + } + }); + + let _ = tokio::join!(t1, t2); Ok(local_port) } #[tauri::command] pub async fn start_host_relay( proxy_state: State<'_, ProxyGuard>, - api_base_url: String, - access_token: String, - session_id: String, + auth_token: String, game_port: u16, ) -> Result<(), String> { - let ws_base = util::ws_base_url(&api_base_url); - let ws_url = format!("{}/api/relay/ws?sessionId={}&role=host", ws_base, session_id); + let addr = PROXY_ADDR; let cancel = CancellationToken::new(); + let session_id = "__host__".to_string(); { let mut tokens = proxy_state.cancel_tokens.lock().await; tokens.insert(session_id.clone(), cancel.clone()); } - let result = run_host_relay(&proxy_state, &ws_url, &access_token, game_port, cancel).await; - + let result = run_host_relay(&proxy_state, &addr, &auth_token, game_port, cancel).await; { let mut tokens = proxy_state.cancel_tokens.lock().await; tokens.remove(&session_id); @@ -271,6 +179,29 @@ pub async fn start_host_relay( result } +#[tauri::command] +pub async fn start_relay_proxy( + proxy_state: State<'_, ProxyGuard>, + auth_token: String, + target_session: String, +) -> Result { + let addr = PROXY_ADDR; + let cancel = CancellationToken::new(); + let session_id = target_session.clone(); + { + let mut tokens = proxy_state.cancel_tokens.lock().await; + tokens.insert(session_id.clone(), cancel.clone()); + } + + let local_port = run_relay_proxy(&proxy_state, &addr, &auth_token, &target_session, cancel).await?; + { + let mut tokens = proxy_state.cancel_tokens.lock().await; + tokens.remove(&session_id); + } + + Ok(local_port) +} + #[tauri::command] pub async fn stop_proxy(proxy_state: State<'_, ProxyGuard>, session_id: String) -> Result<(), String> { let mut tokens = proxy_state.cancel_tokens.lock().await; @@ -299,10 +230,10 @@ pub async fn join_game( game_state: State<'_, crate::state::GameState>, _proxy_state: State<'_, ProxyGuard>, _api_base_url: String, - _access_token: String, + _auth_token: String, host_ip: String, host_port: u16, - _session_id: String, + _target_session: String, instance_id: String, ) -> Result<(), String> { let server = crate::types::McServer { diff --git a/src-tauri/src/util.rs b/src-tauri/src/util.rs index 576a70e..774bc9a 100644 --- a/src-tauri/src/util.rs +++ b/src-tauri/src/util.rs @@ -44,14 +44,6 @@ pub fn copy_dir_all(src: impl AsRef, dst: impl AsRef String { - if api_base_url.starts_with("https") { - api_base_url.replace("https", "wss") - } else { - api_base_url.replace("http", "ws") - } -} - #[cfg(unix)] pub fn unix_path_to_wine_z_path(unix_path: &PathBuf) -> String { let p = unix_path.to_string_lossy(); diff --git a/src/components/modals/ChooseInstanceModal.tsx b/src/components/modals/ChooseInstanceModal.tsx index 637069d..1592e4d 100644 --- a/src/components/modals/ChooseInstanceModal.tsx +++ b/src/components/modals/ChooseInstanceModal.tsx @@ -62,9 +62,8 @@ export default function ChooseInstanceModal({ if (sessionId) { setStatus("Connecting via relay..."); - const baseUrl = lceLiveService.apiBaseUrl; const accessToken = lceLiveService.accessToken ?? ""; - await TauriService.startRelayProxy(baseUrl, accessToken, sessionId); + await TauriService.startRelayProxy(accessToken, sessionId); setStatus("Launching game..."); await TauriService.launchGame( selectedInstance, diff --git a/src/components/views/CreditsView.tsx b/src/components/views/CreditsView.tsx index a0730ac..8599c22 100644 --- a/src/components/views/CreditsView.tsx +++ b/src/components/views/CreditsView.tsx @@ -209,6 +209,7 @@ const CreditsView = memo(function CreditsView() { { name: "dr.av", url: "#" }, { name: "alreadywarned", url: "#" }, { name: "andrewjcf", url: "#" }, + { name: "dille", url: "#" }, ], }, ], @@ -427,4 +428,4 @@ const CreditsView = memo(function CreditsView() { ); }); -export default CreditsView; +export default CreditsView; \ No newline at end of file diff --git a/src/components/views/LceLiveView.tsx b/src/components/views/LceLiveView.tsx index 36bff36..5372e0b 100644 --- a/src/components/views/LceLiveView.tsx +++ b/src/components/views/LceLiveView.tsx @@ -234,21 +234,19 @@ const LceLiveView = memo(function LceLiveView({ const handleInviteFriend = async (friend: LceLiveAccount) => { playPressSound(); const name = lceLiveService.displayUsername; - const sessionId = crypto.randomUUID(); + const hostUsername = lceLiveService.account?.username ?? name; try { await lceLiveService.sendGameInvite( friend.accountId, hostIp, hostPort, name, - sessionId, + hostUsername, ); setInvitedFriends((prev) => new Set(prev).add(friend.accountId)); setHostStatus("Connecting relay..."); TauriService.startHostRelay( - lceLiveService.apiBaseUrl, lceLiveService.accessToken ?? "", - sessionId, 25565, ) .then(() => setHostStatus("Relay active")) diff --git a/src/hooks/useGameManager.ts b/src/hooks/useGameManager.ts index 9b3d80e..72315bb 100644 --- a/src/hooks/useGameManager.ts +++ b/src/hooks/useGameManager.ts @@ -71,7 +71,7 @@ export const BASE_EDITIONS = [ id: "moon_edition", name: "Minecraft: Moon Edition", desc: "Galacticraft LCE port (Modded build!)", - url: "https://INTENTIONALLY_INVALID_LINK_BECAUSE_FUCK_YOU_THATS_WHY", //neo: placeholder for now + url: "https://github.com/blazin-blaze/moon-edition/releases/download/v1.0.1/moonEditionWindows64.zip", titleImage: "/images/minecraft_title_moon.png", supportsSlimSkins: false, logo: "/images/moonEdition.png", @@ -635,4 +635,4 @@ export function useGameManager({ updateCustomization, saveCustomPath, }; -} +} \ No newline at end of file diff --git a/src/services/TauriService.ts b/src/services/TauriService.ts index c96c759..cbfbc37 100644 --- a/src/services/TauriService.ts +++ b/src/services/TauriService.ts @@ -300,31 +300,19 @@ export class TauriService { return invoke("stun_discover"); } - static async startDirectProxy( - targetIp: string, - targetPort: number, - ): Promise { - return invoke("start_direct_proxy", { targetIp, targetPort }); - } - static async startRelayProxy( - apiBaseUrl: string, - accessToken: string, - sessionId: string, + authToken: string, + targetSession: string, ): Promise { - return invoke("start_relay_proxy", { apiBaseUrl, accessToken, sessionId }); + return invoke("start_relay_proxy", { authToken, targetSession }); } static async startHostRelay( - apiBaseUrl: string, - accessToken: string, - sessionId: string, + authToken: string, gamePort: number, ): Promise { return invoke("start_host_relay", { - apiBaseUrl, - accessToken, - sessionId, + authToken, gamePort, }); } @@ -339,18 +327,18 @@ export class TauriService { static async joinGame( apiBaseUrl: string, - accessToken: string, + authToken: string, hostIp: string, hostPort: number, - sessionId: string, + targetSession: string, instanceId: string, ): Promise { return invoke("join_game", { apiBaseUrl, - accessToken, + authToken, hostIp, hostPort, - sessionId, + targetSession, instanceId, }); }