feat(cafegame): 自 go-hua 迁入网咖游戏识别与运行记录框架

- 游戏来源常量/按目录特征识别(云更新/网维大师/易乐游)/RunAppRecord 上报框架
- 网吧业务专用包, 附测试、examples/cafegame 例程与包 README
This commit is contained in:
2026-09-20 12:37:10 +08:00
parent a6ba78c92c
commit 63d0a0caf8
10 changed files with 1843 additions and 0 deletions
+117
View File
@@ -0,0 +1,117 @@
//go:build windows
package cafegame
import (
"os"
"path/filepath"
"sync"
"time"
)
// ProcessMonitor 单个游戏进程的监视器:等待进程退出后向 waitChan 发送结果
type ProcessMonitor struct {
pid int
exeName string
exePath string
AppData
status int
waitChan chan AppWaitData
}
// NewProcessMonitor 创建进程监视器
func NewProcessMonitor(pid int, exePath string, app AppData, waitChan chan AppWaitData) *ProcessMonitor {
process := new(ProcessMonitor)
process.pid = pid
process.exeName = filepath.Base(exePath)
process.exePath = exePath
process.waitChan = waitChan
process.AppData = app
return process
}
// monitor 阻塞等待进程退出
func (receiver *ProcessMonitor) monitor() error {
defer func() {
receiver.waitChan <- AppWaitData{Pid: receiver.pid, AppData: receiver.AppData}
}()
process, err := os.FindProcess(receiver.pid)
if err != nil {
// 查找进程失败
return err
}
_, err = process.Wait()
if err != nil {
//"进程运行错误
return err
}
// 进程已经结束
return nil
}
// Start 在后台协程中开始监视进程
func (receiver *ProcessMonitor) Start() {
go receiver.monitor()
}
// AppMonitor 单个游戏的监控器:聚合该游戏的所有进程
type AppMonitor struct {
AppData
processList []*ProcessMonitor
mux sync.Mutex
waitChan chan AppWaitData
recordId int
startTime int64
}
// NewAppMonitor 创建游戏监控器
func NewAppMonitor(app AppData, path string, waitChan chan AppWaitData) *AppMonitor {
monitor := new(AppMonitor)
monitor.AppData = app
monitor.waitChan = waitChan
monitor.startTime = time.Now().Unix()
return monitor
}
// AddProcess 添加该游戏的一个进程(之前无进程时重置开始时间)
func (receiver *AppMonitor) AddProcess(pid int, exePath string) {
receiver.mux.Lock()
defer receiver.mux.Unlock()
// 没有进程,重新设置开始时间为当前时间
if len(receiver.processList) == 0 {
receiver.startTime = time.Now().Unix()
}
process := NewProcessMonitor(pid, exePath, receiver.AppData, receiver.waitChan)
process.Start()
receiver.processList = append(receiver.processList, process)
}
// RemoveProcess 移除指定 PID 的进程
func (receiver *AppMonitor) RemoveProcess(pid int) {
receiver.mux.Lock()
defer receiver.mux.Unlock()
for i := 0; i < len(receiver.processList); i++ {
if pid == receiver.processList[i].pid {
receiver.processList = append(receiver.processList[0:i], receiver.processList[i+1:]...)
i--
}
}
}
// AppIsRun 该游戏是否仍有进程在运行
func (receiver *AppMonitor) AppIsRun() bool {
receiver.mux.Lock()
defer receiver.mux.Unlock()
return len(receiver.processList) > 0
}
// GetStartInterval 返回游戏开始运行至今的秒数
func (receiver *AppMonitor) GetStartInterval() int64 {
receiver.mux.Lock()
defer receiver.mux.Unlock()
now := time.Now().Unix()
interval := now - receiver.startTime
return interval
}