123 lines
3.3 KiB
Go
123 lines
3.3 KiB
Go
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os/exec"
|
|
)
|
|
|
|
func pressDiscordMuteHotkey() error {
|
|
script := `
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
Add-Type @"
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
public static class Win32 {
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct RECT {
|
|
public int Left;
|
|
public int Top;
|
|
public int Right;
|
|
public int Bottom;
|
|
}
|
|
[DllImport("user32.dll")]
|
|
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
|
|
[DllImport("user32.dll")]
|
|
public static extern bool SetCursorPos(int X, int Y);
|
|
[DllImport("user32.dll")]
|
|
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, UIntPtr dwExtraInfo);
|
|
}
|
|
"@
|
|
|
|
function Click-WindowCenter($p) {
|
|
if ($null -eq $p) { return }
|
|
$hWnd = [IntPtr]$p.MainWindowHandle
|
|
if ($hWnd -eq [IntPtr]::Zero) { return }
|
|
|
|
$rect = New-Object 'Win32+RECT'
|
|
if (-not [Win32]::GetWindowRect($hWnd, [ref]$rect)) { return }
|
|
|
|
$x = [int](($rect.Left + $rect.Right) / 2)
|
|
$y = [int](($rect.Top + $rect.Bottom) / 2)
|
|
[Win32]::SetCursorPos($x, $y) | Out-Null
|
|
Start-Sleep -Milliseconds 50
|
|
[Win32]::mouse_event(0x0002, 0, 0, 0, [UIntPtr]::Zero)
|
|
[Win32]::mouse_event(0x0004, 0, 0, 0, [UIntPtr]::Zero)
|
|
Start-Sleep -Milliseconds 100
|
|
}
|
|
|
|
function Get-DiscordWindows {
|
|
$windows = foreach ($p in Get-Process) {
|
|
$title = ($p.MainWindowTitle | Out-String).Trim()
|
|
if (-not $title) { continue }
|
|
if (-not $title.ToLower().Contains('discord')) { continue }
|
|
$p
|
|
}
|
|
if (-not $windows) { return @() }
|
|
return $windows
|
|
}
|
|
|
|
function Get-BestDiscordWindow {
|
|
$windows = Get-DiscordWindows
|
|
if (-not $windows -or $windows.Count -eq 0) { return $null }
|
|
|
|
$browserKeywords = @('google chrome', 'microsoft edge', 'mozilla firefox', 'brave', 'opera')
|
|
$ranked = $windows | Sort-Object {
|
|
$title = ($_.MainWindowTitle | Out-String).Trim().ToLower()
|
|
$score = 0
|
|
foreach ($keyword in $browserKeywords) {
|
|
if ($title.Contains($keyword)) { $score += 10 }
|
|
}
|
|
if ($title -match '^\(\d+\)\s*discord') { $score += 20 }
|
|
if ($title.Contains('discord')) { $score += 5 }
|
|
$score
|
|
} -Descending
|
|
|
|
return $ranked | Select-Object -First 1
|
|
}
|
|
|
|
function Get-VRChatWindow {
|
|
$windows = Get-Process | Where-Object {
|
|
$_.MainWindowTitle -and (
|
|
$_.MainWindowTitle -eq 'VRChat' -or $_.MainWindowTitle.ToLower().StartsWith('vrchat ')
|
|
)
|
|
}
|
|
if (-not $windows) { return $null }
|
|
return $windows | Sort-Object { $_.MainWindowHandle } -Descending | Select-Object -First 1
|
|
}
|
|
|
|
function Activate-Window($p) {
|
|
if ($null -eq $p) { return }
|
|
$wshell = New-Object -ComObject WScript.Shell
|
|
try { $null = $wshell.AppActivate($p.Id) } catch {}
|
|
Start-Sleep -Milliseconds 200
|
|
Click-WindowCenter $p
|
|
}
|
|
|
|
$discord = Get-BestDiscordWindow
|
|
if ($null -eq $discord) { exit 2 }
|
|
|
|
Activate-Window $discord
|
|
$wshell = New-Object -ComObject WScript.Shell
|
|
Start-Sleep -Milliseconds 200
|
|
$wshell.SendKeys('^+m')
|
|
Start-Sleep -Milliseconds 200
|
|
|
|
$vrchat = Get-VRChatWindow
|
|
if ($null -ne $vrchat) {
|
|
Activate-Window $vrchat
|
|
}
|
|
`
|
|
|
|
cmd := exec.Command("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", script)
|
|
out, err := cmd.CombinedOutput()
|
|
if len(out) > 0 {
|
|
log.Printf("discord mute output: %s", string(out))
|
|
}
|
|
if err != nil {
|
|
return fmt.Errorf("discord mute failed: %w", err)
|
|
}
|
|
return nil
|
|
}
|