|
1 | | -// use once_cell::sync::Lazy; |
2 | | -// use std::collections::HashMap; |
3 | | -// use std::io::BufRead; |
4 | | -// use std::net::{TcpListener, TcpStream}; |
5 | | -// use std::sync::{Arc, Mutex}; |
6 | | -// use std::thread; |
7 | | -// use tauri::{AppHandle, Manager, WindowBuilder, WindowUrl}; |
| 1 | +use once_cell::sync::Lazy; |
| 2 | +use std::collections::HashMap; |
| 3 | +use std::io::BufRead; |
| 4 | +use std::net::{TcpListener, TcpStream}; |
| 5 | +use std::sync::{Arc, Mutex}; |
| 6 | +use std::thread; |
| 7 | +use tauri::{AppHandle, Manager, WindowBuilder, WindowUrl}; |
8 | 8 |
|
9 | | -// use crate::{constants::*, errors::*}; |
| 9 | +use crate::constants::*; |
10 | 10 |
|
11 | | -// type SharedStreams = Arc<Mutex<HashMap<i32, TcpStream>>>; |
| 11 | +type SharedStreams = Arc<Mutex<HashMap<i32, TcpStream>>>; |
12 | 12 |
|
13 | | -// pub static GAME_STREAMS: Lazy<SharedStreams> = Lazy::new(|| Arc::new(Mutex::new(HashMap::new()))); |
| 13 | +pub static GAME_STREAMS: Lazy<SharedStreams> = Lazy::new(|| Arc::new(Mutex::new(HashMap::new()))); |
14 | 14 |
|
15 | | -// fn create_overlay_window( |
16 | | -// app: &tauri::AppHandle, |
17 | | -// label: &str, |
18 | | -// attached_id: i32, |
19 | | -// ) -> tauri::Result<()> { |
20 | | -// match WindowBuilder::new( |
21 | | -// app, |
22 | | -// label, |
23 | | -// WindowUrl::App(format!("index.html?attached_id={}", attached_id).into()), |
24 | | -// ) |
25 | | -// .transparent(true) |
26 | | -// .decorations(false) |
27 | | -// .always_on_top(false) |
28 | | -// .resizable(false) |
29 | | -// .visible(true) |
30 | | -// .position(-1000.0, -1000.0) |
31 | | -// .skip_taskbar(true) |
32 | | -// .build() |
33 | | -// { |
34 | | -// Ok(window) => { |
35 | | -// let _ = window.set_title(label); |
36 | | -// } |
37 | | -// Err(err) => { |
38 | | -// println!("{}", err.to_string()); |
39 | | -// } |
40 | | -// } |
| 15 | +fn create_overlay_window( |
| 16 | + app: &tauri::AppHandle, |
| 17 | + label: &str, |
| 18 | + attached_id: i32, |
| 19 | +) -> tauri::Result<()> { |
| 20 | + match WindowBuilder::new( |
| 21 | + app, |
| 22 | + label, |
| 23 | + WindowUrl::App(format!("index.html?attached_id={}", attached_id).into()), |
| 24 | + ) |
| 25 | + .transparent(true) |
| 26 | + .decorations(false) |
| 27 | + .always_on_top(false) |
| 28 | + .resizable(false) |
| 29 | + .visible(false) |
| 30 | + .position(-10000.0, -10000.0) |
| 31 | + .skip_taskbar(true) |
| 32 | + .build() |
| 33 | + { |
| 34 | + Ok(window) => { |
| 35 | + let _ = window.set_title(label); |
| 36 | + } |
| 37 | + Err(err) => { |
| 38 | + println!("{}", err.to_string()); |
| 39 | + } |
| 40 | + } |
41 | 41 |
|
42 | | -// Ok(()) |
43 | | -// } |
| 42 | + Ok(()) |
| 43 | +} |
44 | 44 |
|
45 | | -// pub fn listen_for_ipc(_app_handle: AppHandle) { |
46 | | -// thread::spawn(move || { |
47 | | -// let listener = TcpListener::bind(format!("127.0.0.1:{}", IPC_PORT)) |
48 | | -// .expect("Failed to bind to IPC port"); |
| 45 | +pub fn listen_for_ipc(app_handle: AppHandle) { |
| 46 | + thread::spawn(move || { |
| 47 | + let listener = match TcpListener::bind(format!("127.0.0.1:{}", IPC_PORT)) { |
| 48 | + Ok(l) => l, |
| 49 | + Err(e) => { |
| 50 | + log::error!("Failed to bind to IPC port: {}", e); |
| 51 | + return; |
| 52 | + } |
| 53 | + }; |
49 | 54 |
|
50 | | -// for stream in listener.incoming() { |
51 | | -// if let Ok(stream) = stream { |
52 | | -// let handle = app_handle.clone(); |
| 55 | + for stream in listener.incoming() { |
| 56 | + if let Ok(stream) = stream { |
| 57 | + let handle = app_handle.clone(); |
53 | 58 |
|
54 | | -// thread::spawn(move || { |
55 | | -// let Ok(stream_clone) = stream.try_clone() else { |
56 | | -// log::error!("Failed to clone IPC stream"); |
57 | | -// return; |
58 | | -// }; |
59 | | -// let mut reader = std::io::BufReader::new(stream_clone); |
60 | | -// let mut line = String::new(); |
61 | | -// while let Ok(bytes) = reader.read_line(&mut line) { |
62 | | -// if bytes == 0 { |
63 | | -// break; |
64 | | -// } |
| 59 | + thread::spawn(move || { |
| 60 | + let Ok(stream_clone) = stream.try_clone() else { |
| 61 | + log::error!("Failed to clone IPC stream"); |
| 62 | + return; |
| 63 | + }; |
| 64 | + let mut reader = std::io::BufReader::new(stream_clone); |
| 65 | + let mut line = String::new(); |
| 66 | + while let Ok(bytes) = reader.read_line(&mut line) { |
| 67 | + if bytes == 0 { |
| 68 | + break; |
| 69 | + } |
65 | 70 |
|
66 | | -// if line.starts_with("init:") { |
67 | | -// if let Some(pid_str) = line.strip_prefix("init:") { |
68 | | -// if let Ok(pid) = pid_str.trim().parse::<i32>() { |
69 | | -// if let Ok(stream_clone) = stream.try_clone() { |
70 | | -// if let Ok(mut streams) = GAME_STREAMS.lock() { |
71 | | -// streams.insert(pid, stream_clone); |
72 | | -// } |
73 | | -// } |
74 | | -// } |
75 | | -// } |
76 | | -// } else if line.starts_with("pos:") { |
77 | | -// if let Some(coords) = line.strip_prefix("pos:") { |
78 | | -// let parts: Vec<_> = coords.trim().split(',').collect(); |
79 | | -// if parts.len() == 5 { |
80 | | -// if let (Ok(_x), Ok(_y), Ok(w), Ok(h), Ok(pid)) = ( |
81 | | -// parts[0].parse::<i32>(), |
82 | | -// parts[1].parse::<i32>(), |
83 | | -// parts[2].parse::<i32>(), |
84 | | -// parts[3].parse::<i32>(), |
85 | | -// parts[4].parse::<i32>(), |
86 | | -// ) { |
87 | | -// let window_label = format!("omp_overlay_window:{}", pid); |
88 | | -// if let Some(win) = handle.get_window(&window_label) { |
89 | | -// let _ = win.set_position(tauri::PhysicalPosition { |
90 | | -// x: -1 * w - 1000, |
91 | | -// y: -1 * h - 1000, |
92 | | -// }); |
| 71 | + if line.starts_with("init:") { |
| 72 | + if let Some(pid_str) = line.strip_prefix("init:") { |
| 73 | + if let Ok(pid) = pid_str.trim().parse::<i32>() { |
| 74 | + if let Ok(stream_clone) = stream.try_clone() { |
| 75 | + if let Ok(mut streams) = GAME_STREAMS.lock() { |
| 76 | + streams.insert(pid, stream_clone); |
| 77 | + } |
| 78 | + } |
| 79 | + } |
| 80 | + } |
| 81 | + } else if line.starts_with("pos:") { |
| 82 | + if let Some(coords) = line.strip_prefix("pos:") { |
| 83 | + let parts: Vec<_> = coords.trim().split(',').collect(); |
| 84 | + if parts.len() == 5 { |
| 85 | + if let (Ok(_x), Ok(_y), Ok(w), Ok(h), Ok(pid)) = ( |
| 86 | + parts[0].parse::<i32>(), |
| 87 | + parts[1].parse::<i32>(), |
| 88 | + parts[2].parse::<i32>(), |
| 89 | + parts[3].parse::<i32>(), |
| 90 | + parts[4].parse::<i32>(), |
| 91 | + ) { |
| 92 | + let window_label = format!("omp_overlay_window:{}", pid); |
| 93 | + if let Some(win) = handle.get_window(&window_label) { |
| 94 | + // let _ = win.set_position(tauri::PhysicalPosition { |
| 95 | + // x: -1 * w - 1000, |
| 96 | + // y: -1 * h - 1000, |
| 97 | + // }); |
93 | 98 |
|
94 | | -// let _ = win.set_size(tauri::PhysicalSize { |
95 | | -// width: w as u32, |
96 | | -// height: h as u32, |
97 | | -// }); |
98 | | -// } |
99 | | -// } |
100 | | -// } |
101 | | -// } |
102 | | -// } else if line.starts_with("show_overlay:") { |
103 | | -// let parts: Vec<_> = line.trim().split(':').collect(); |
104 | | -// if parts.len() >= 2 { |
105 | | -// if let Ok(pid) = parts[1].parse::<i32>() { |
106 | | -// let window_label = format!("omp_overlay_window:{}", pid); |
107 | | -// let _ = create_overlay_window(&handle, &window_label, pid); |
108 | | -// } |
109 | | -// } |
110 | | -// } else if line.starts_with("hide_overlay:") { |
111 | | -// let parts: Vec<_> = line.trim().split(':').collect(); |
112 | | -// if parts.len() >= 2 { |
113 | | -// let window_label = format!("omp_overlay_window:{}", parts[1]); |
114 | | -// if let Some(window) = handle.get_window(&window_label) { |
115 | | -// let _ = window.close(); |
116 | | -// } else { |
117 | | -// log::warn!("IPC overlay window not found: {}", window_label); |
118 | | -// } |
119 | | -// } |
120 | | -// } else { |
121 | | -// log::warn!("Unknown IPC command received: {}", line.trim()); |
122 | | -// } |
123 | | -// line.clear(); |
124 | | -// } |
125 | | -// }); |
126 | | -// } |
127 | | -// } |
128 | | -// }); |
129 | | -// } |
| 99 | + let _ = win.set_size(tauri::PhysicalSize { |
| 100 | + width: w as u32, |
| 101 | + height: h as u32, |
| 102 | + }); |
| 103 | + } |
| 104 | + } |
| 105 | + } |
| 106 | + } |
| 107 | + } else if line.starts_with("show_overlay:") { |
| 108 | + let parts: Vec<_> = line.trim().split(':').collect(); |
| 109 | + if parts.len() >= 2 { |
| 110 | + if let Ok(pid) = parts[1].parse::<i32>() { |
| 111 | + let window_label = format!("omp_overlay_window:{}", pid); |
| 112 | + let _ = create_overlay_window(&handle, &window_label, pid); |
| 113 | + } |
| 114 | + } |
| 115 | + } else if line.starts_with("hide_overlay:") { |
| 116 | + let parts: Vec<_> = line.trim().split(':').collect(); |
| 117 | + if parts.len() >= 2 { |
| 118 | + let window_label = format!("omp_overlay_window:{}", parts[1]); |
| 119 | + if let Some(window) = handle.get_window(&window_label) { |
| 120 | + let _ = window.close(); |
| 121 | + } else { |
| 122 | + log::warn!("IPC overlay window not found: {}", window_label); |
| 123 | + } |
| 124 | + } |
| 125 | + } else { |
| 126 | + log::warn!("Unknown IPC command received: {}", line.trim()); |
| 127 | + } |
| 128 | + line.clear(); |
| 129 | + } |
| 130 | + }); |
| 131 | + } |
| 132 | + } |
| 133 | + }); |
| 134 | +} |
130 | 135 |
|
131 | 136 | #[tauri::command] |
132 | | -pub fn send_message_to_game(_id: i32, _message: &str) -> std::result::Result<(), ()> { |
133 | | - // use std::io::Write; |
| 137 | +pub fn send_message_to_game(id: i32, message: &str) -> std::result::Result<(), String> { |
| 138 | + use std::io::Write; |
134 | 139 |
|
135 | | - // let mut streams = GAME_STREAMS.lock().map_err(|_| { |
136 | | - // crate::errors::LauncherError::InternalError("Failed to acquire stream lock".to_string()) |
137 | | - // })?; |
| 140 | + let mut streams = GAME_STREAMS.lock().map_err(|_| { |
| 141 | + crate::errors::LauncherError::InternalError("Failed to acquire stream lock".to_string()) |
| 142 | + .to_string() |
| 143 | + })?; |
138 | 144 |
|
139 | | - // if let Some(stream) = streams.get_mut(&id) { |
140 | | - // let full_message = format!("{}\n", message); |
141 | | - // stream.write_all(full_message.as_bytes()).map_err(|e| { |
142 | | - // crate::errors::LauncherError::Network(format!("Failed to write to stream: {}", e)) |
143 | | - // })?; |
144 | | - // Ok(()) |
145 | | - // } else { |
146 | | - // log::warn!("No IPC stream found for process ID: {}", id); |
147 | | - // Err(crate::errors::LauncherError::NotFound( |
148 | | - // "no_stream_found".to_string(), |
149 | | - // )) |
150 | | - // } |
151 | | - Ok(()) |
| 145 | + if let Some(stream) = streams.get_mut(&id) { |
| 146 | + let full_message = format!("{}\n", message); |
| 147 | + stream.write_all(full_message.as_bytes()).map_err(|e| { |
| 148 | + crate::errors::LauncherError::Network(format!("Failed to write to stream: {}", e)) |
| 149 | + .to_string() |
| 150 | + })?; |
| 151 | + return Ok(()); |
| 152 | + } else { |
| 153 | + log::warn!("No IPC stream found for process ID: {}", id); |
| 154 | + return Err( |
| 155 | + crate::errors::LauncherError::NotFound("no_stream_found".to_string()).to_string(), |
| 156 | + ); |
| 157 | + } |
152 | 158 | } |
0 commit comments