- 游戏来源常量/按目录特征识别(云更新/网维大师/易乐游)/RunAppRecord 上报框架 - 网吧业务专用包, 附测试、examples/cafegame 例程与包 README
118 lines
2.9 KiB
Go
118 lines
2.9 KiB
Go
//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
|
|
}
|