120 lines
2.5 KiB
Go
120 lines
2.5 KiB
Go
package blocker
|
|
|
|
import (
|
|
"log"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type Blocker struct {
|
|
mu sync.Mutex
|
|
allowedKeywords []string
|
|
running bool
|
|
stopChan chan struct{}
|
|
OnBlocked func(procName string, title string)
|
|
OnKill func(procName string, title string)
|
|
}
|
|
|
|
var Instance = &Blocker{
|
|
allowedKeywords: []string{"chrome", "idea64", "vscode", "wails", "simple_care", "client"},
|
|
stopChan: make(chan struct{}),
|
|
}
|
|
|
|
func parseKeywordList(keywords string) []string {
|
|
keywords = strings.ReplaceAll(keywords, "\r\n", "\n")
|
|
parts := strings.FieldsFunc(keywords, func(r rune) bool {
|
|
return r == ',' || r == '\n' || r == ';' || r == '|'
|
|
})
|
|
seen := map[string]bool{}
|
|
var list []string
|
|
for _, p := range parts {
|
|
trimmed := strings.TrimSpace(strings.ToLower(p))
|
|
trimmed = strings.TrimSuffix(trimmed, ".exe")
|
|
if trimmed == "" || seen[trimmed] {
|
|
continue
|
|
}
|
|
seen[trimmed] = true
|
|
list = append(list, trimmed)
|
|
}
|
|
return list
|
|
}
|
|
|
|
var keywordAliases = map[string][]string{
|
|
"lark": {"lark", "feishu", "larkshell", "larkhelper"},
|
|
"feishu": {"lark", "feishu", "larkshell", "larkhelper"},
|
|
"teams": {"teams", "ms-teams", "msteams"},
|
|
"zalo": {"zalo", "zalopcb"},
|
|
}
|
|
|
|
func expandKeyword(kw string) []string {
|
|
base := []string{kw}
|
|
if aliases, ok := keywordAliases[kw]; ok {
|
|
base = append(base, aliases...)
|
|
}
|
|
seen := map[string]bool{}
|
|
var out []string
|
|
for _, a := range base {
|
|
a = strings.TrimSpace(strings.ToLower(a))
|
|
if a != "" && !seen[a] {
|
|
seen[a] = true
|
|
out = append(out, a)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func matchesAllowedKeyword(kw, pNameLower, wTitleLower string) bool {
|
|
for _, variant := range expandKeyword(kw) {
|
|
if strings.Contains(pNameLower, variant) || strings.Contains(wTitleLower, variant) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (b *Blocker) SetKeywords(keywords string) {
|
|
b.mu.Lock()
|
|
b.allowedKeywords = parseKeywordList(keywords)
|
|
b.mu.Unlock()
|
|
log.Printf("[BLOCKER] Keywords updated: %v", b.allowedKeywords)
|
|
}
|
|
|
|
func (b *Blocker) Start() {
|
|
b.mu.Lock()
|
|
if b.running {
|
|
b.mu.Unlock()
|
|
return
|
|
}
|
|
b.running = true
|
|
b.stopChan = make(chan struct{})
|
|
b.mu.Unlock()
|
|
|
|
go func() {
|
|
ticker := time.NewTicker(3 * time.Second)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-ticker.C:
|
|
b.checkAndKill()
|
|
case <-b.stopChan:
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
log.Println("[BLOCKER] Application Blocker Daemon Started.")
|
|
}
|
|
|
|
func (b *Blocker) Stop() {
|
|
b.mu.Lock()
|
|
defer b.mu.Unlock()
|
|
|
|
if !b.running {
|
|
return
|
|
}
|
|
b.running = false
|
|
close(b.stopChan)
|
|
log.Println("[BLOCKER] Application Blocker Daemon Stopped.")
|
|
}
|