Simplify GUI settings and build flags
This commit is contained in:
@@ -3,120 +3,87 @@ package app
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
vkControl = 0x11
|
||||
vkShift = 0x10
|
||||
vkM = 0x4D
|
||||
keyUp = 0x0002
|
||||
swRestore = 9
|
||||
)
|
||||
|
||||
func pressDiscordMuteHotkey() error {
|
||||
script := `
|
||||
$ErrorActionPreference = "Stop"
|
||||
user32 := syscall.NewLazyDLL("user32.dll")
|
||||
enumWindows := user32.NewProc("EnumWindows")
|
||||
getWindowTextW := user32.NewProc("GetWindowTextW")
|
||||
isWindowVisible := user32.NewProc("IsWindowVisible")
|
||||
setForegroundWindow := user32.NewProc("SetForegroundWindow")
|
||||
showWindow := user32.NewProc("ShowWindow")
|
||||
getWindowRect := user32.NewProc("GetWindowRect")
|
||||
keybdEvent := user32.NewProc("keybd_event")
|
||||
setCursorPos := user32.NewProc("SetCursorPos")
|
||||
sleep := syscall.NewLazyDLL("kernel32.dll").NewProc("Sleep")
|
||||
|
||||
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))
|
||||
var target uintptr
|
||||
cb := syscall.NewCallback(func(hwnd uintptr, lparam uintptr) uintptr {
|
||||
vis, _, _ := isWindowVisible.Call(hwnd)
|
||||
if vis == 0 {
|
||||
return 1
|
||||
}
|
||||
buf := make([]uint16, 512)
|
||||
n, _, _ := getWindowTextW.Call(hwnd, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)))
|
||||
if n == 0 {
|
||||
return 1
|
||||
}
|
||||
title := strings.ToLower(strings.TrimSpace(syscall.UTF16ToString(buf[:n])))
|
||||
if !strings.Contains(title, "discord") {
|
||||
return 1
|
||||
}
|
||||
target = hwnd
|
||||
return 0
|
||||
})
|
||||
r1, _, err1 := enumWindows.Call(cb, 0)
|
||||
if r1 == 0 && target == 0 {
|
||||
return fmt.Errorf("discord window not found: %v", err1)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("discord mute failed: %w", err)
|
||||
if target == 0 {
|
||||
return fmt.Errorf("discord window not found")
|
||||
}
|
||||
|
||||
showWindow.Call(target, swRestore)
|
||||
setForegroundWindow.Call(target)
|
||||
sleep.Call(150)
|
||||
|
||||
type rect struct {
|
||||
Left int32
|
||||
Top int32
|
||||
Right int32
|
||||
Bottom int32
|
||||
}
|
||||
var r rect
|
||||
if v, _, _ := getWindowRect.Call(target, uintptr(unsafe.Pointer(&r))); v != 0 {
|
||||
x := int((r.Left + r.Right) / 2)
|
||||
y := int((r.Top + r.Bottom) / 2)
|
||||
setCursorPos.Call(uintptr(x), uintptr(y))
|
||||
sleep.Call(50)
|
||||
}
|
||||
|
||||
send := func(vk byte, flags uintptr) {
|
||||
keybdEvent.Call(uintptr(vk), 0, flags, 0)
|
||||
}
|
||||
send(vkControl, 0)
|
||||
send(vkShift, 0)
|
||||
send(vkM, 0)
|
||||
send(vkM, keyUp)
|
||||
send(vkShift, keyUp)
|
||||
send(vkControl, keyUp)
|
||||
sleep.Call(100)
|
||||
|
||||
SetDiscordWindow("Discord")
|
||||
log.Printf("discord hotkey sent via keybd_event")
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user