From 1c181a70fd0aa8393078693e58a9cf59b5663804 Mon Sep 17 00:00:00 2001 From: newt Date: Sun, 17 Nov 2024 12:43:15 +0000 Subject: [PATCH] feat: two-way sync --- .gitmodules | 3 ++ src/main.rs | 85 ++++++++++------------------------------------------- src/ws.rs | 14 ++++++--- vencord | 1 + 4 files changed, 29 insertions(+), 74 deletions(-) create mode 100644 .gitmodules create mode 160000 vencord diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..eca1aa1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "vencord"] + path = vencord + url = ssh://git@git.newty.dev:2222/newt/muter-vencord.git diff --git a/src/main.rs b/src/main.rs index 6423d31..92a426f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,5 @@ use muter::ORDERING; -use std::{ - ptr, - sync::atomic::{AtomicBool, AtomicPtr}, - thread, - time::Duration, -}; +use std::{ptr, sync::atomic::AtomicBool}; use warp::Filter; use windows::Win32::{ Foundation::{BOOL, HWND, LPARAM, WPARAM}, @@ -21,50 +16,9 @@ use windows::Win32::{ mod ws; -static mut DISCORD_WHND: AtomicPtr = AtomicPtr::new(ptr::null_mut()); +const PORT: u16 = 3034; static mut IS_MUTED: AtomicBool = AtomicBool::new(false); - -unsafe extern "system" fn search_windows(hwnd: HWND, _: LPARAM) -> BOOL { - let mut name = [0u16; 1024]; - let len = unsafe { GetWindowTextW(hwnd, &mut name) }; - let name = String::from_utf16_lossy(&name[..len as usize]); - - if name.to_lowercase().contains(&"- discord".to_string()) { - println!("Discord window found: {:?}", name); - DISCORD_WHND.store(Box::into_raw(Box::new(hwnd)), ORDERING); - } - - BOOL(1) -} - -unsafe fn press_keys(window: HWND, keys: &[VIRTUAL_KEY]) -> windows::core::Result<()> { - let keys = keys.iter().map(|key| { - ( - key.0 as usize, - MapVirtualKeyW(key.0.into(), MAPVK_VK_TO_VSC) as isize, - ) - }); - let down = keys - .clone() - .map(|(key, scan)| (WPARAM(key), LPARAM(scan << 16))) - .collect::>(); - let up = keys - .map(|(key, scan)| (WPARAM(key), LPARAM(0x7FFF | (scan << 16) | (0b11 << 30)))) - .collect::>(); - - for (wparam, lparam) in down { - println!("Pressing key: {:?}", wparam); - PostMessageW(window, WM_KEYDOWN, wparam, lparam)?; - } - - thread::sleep(Duration::from_secs(10)); - - for (wparam, lparam) in up { - PostMessageW(window, WM_KEYUP, wparam, lparam)?; - } - - Ok(()) -} +static mut PREFER: AtomicBool = AtomicBool::new(false); #[tokio::main] async fn main() -> Result<(), muter::Error> { @@ -82,20 +36,6 @@ async fn main() -> Result<(), muter::Error> { // Activate the IAudioEndpointVolume interface for the capture device let endpoint_volume: IAudioEndpointVolume = default_device.Activate(CLSCTX_ALL, None)?; - // Attach process to Discord - EnumWindows(Some(search_windows), LPARAM(0))?; - - let discord = { - let hwnd = DISCORD_WHND.load(ORDERING); - - if hwnd.is_null() { - println!("Discord window not found"); - return Ok(()); - }; - - *hwnd - }; - // Setup WSS serve let server = warp::serve( warp::path::end() @@ -104,7 +44,7 @@ async fn main() -> Result<(), muter::Error> { ws.on_upgrade(move |socket| ws::user_connected(socket)) }), ) - .run(([127, 0, 0, 1], 3034)); + .run(([127, 0, 0, 1], PORT)); tokio::task::spawn(server); // Check if the microphone is muted @@ -112,14 +52,19 @@ async fn main() -> Result<(), muter::Error> { loop { // check if the mute status has changed + let prefer = PREFER.load(ORDERING); let muted = IS_MUTED.load(ORDERING); - let is_new_muted = endpoint_volume.GetMute()?.as_bool(); - if is_new_muted != muted { - IS_MUTED.store(is_new_muted, ORDERING); - println!("Microphone is {}", if muted { "muted" } else { "unmuted" }); - // send keybind to discord (ctrl+shift+m) - // press_keys(discord, &[VK_CONTROL, VK_SHIFT, VK_M])?; + if prefer { + endpoint_volume.SetMute(BOOL(muted as i32), ptr::null())?; + PREFER.store(false, ORDERING); + println!("Microphone is {}", if muted { "muted" } else { "unmuted" }); + } else { + let new = endpoint_volume.GetMute()?.as_bool(); + if muted != new { + IS_MUTED.store(new, ORDERING); + println!("Microphone is {}", if new { "muted" } else { "unmuted" }); + } } } } diff --git a/src/ws.rs b/src/ws.rs index db62397..0648737 100644 --- a/src/ws.rs +++ b/src/ws.rs @@ -4,19 +4,25 @@ use std::time::Duration; use tokio::time::timeout; use warp::{filters::ws::Message, ws::WebSocket}; -use crate::IS_MUTED; +use crate::{IS_MUTED, PREFER}; pub async fn user_connected(socket: WebSocket) { println!("User connected"); let (mut tx, mut rx) = socket.split(); - let mut prev_mute = unsafe { !IS_MUTED.load(ORDERING) }; loop { match timeout(Duration::from_millis(100), rx.next()).await { Ok(Some(Ok(msg))) => { - if msg.is_close() { + // check for mute message + if msg.is_binary() { + let mute = msg.as_bytes() != [1]; + unsafe { + IS_MUTED.store(mute, ORDERING); + PREFER.store(true, ORDERING); + } + } else if msg.is_close() { break; } } @@ -31,7 +37,7 @@ pub async fn user_connected(socket: WebSocket) { let mute = unsafe { IS_MUTED.load(ORDERING) }; if mute != prev_mute { - tx.send(Message::binary(vec![if mute { 1 } else { 0 }])) + tx.send(Message::binary(if mute { vec![1] } else { vec![] })) .await .unwrap(); prev_mute = mute; diff --git a/vencord b/vencord new file mode 160000 index 0000000..6c6e209 --- /dev/null +++ b/vencord @@ -0,0 +1 @@ +Subproject commit 6c6e2098364bc70659c57856375ba10ccb3888e7