Clean project layout and fix release workflow
Some checks failed
build-windows-exe / build (push) Failing after 1m13s
Some checks failed
build-windows-exe / build (push) Failing after 1m13s
This commit is contained in:
@@ -3,87 +3,82 @@ package app
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
vkControl = 0x11
|
||||
vkShift = 0x10
|
||||
vkM = 0x4D
|
||||
keyUp = 0x0002
|
||||
swRestore = 9
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func pressDiscordMuteHotkey() error {
|
||||
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")
|
||||
script := `
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
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 target == 0 {
|
||||
return fmt.Errorf("discord window not found")
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
showWindow.Call(target, swRestore)
|
||||
setForegroundWindow.Call(target)
|
||||
sleep.Call(150)
|
||||
function Get-BestDiscordWindow {
|
||||
$windows = Get-DiscordWindows
|
||||
if (-not $windows -or $windows.Count -eq 0) { return $null }
|
||||
|
||||
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)
|
||||
}
|
||||
$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
|
||||
|
||||
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)
|
||||
return $ranked | Select-Object -First 1
|
||||
}
|
||||
|
||||
SetDiscordWindow("Discord")
|
||||
log.Printf("discord hotkey sent via keybd_event")
|
||||
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
|
||||
}
|
||||
|
||||
$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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user