184 lines
4.5 KiB
Go
184 lines
4.5 KiB
Go
//go:generate goversioninfo -icon=assets/iconwin.ico
|
||
package main
|
||
|
||
import (
|
||
"bytes"
|
||
"fmt"
|
||
"log"
|
||
"net"
|
||
"os"
|
||
"os/exec"
|
||
"path/filepath"
|
||
"strings"
|
||
"syscall"
|
||
"unsafe"
|
||
|
||
_ "embed"
|
||
|
||
"github.com/getlantern/systray"
|
||
"github.com/google/gopacket"
|
||
"github.com/google/gopacket/pcap"
|
||
"github.com/tiagomdiogo/ScaGo/sniffer"
|
||
)
|
||
|
||
var (
|
||
devName string
|
||
localIp string
|
||
sendIpList []string
|
||
)
|
||
|
||
//go:embed assets/iconwin.ico
|
||
var iconBytes []byte
|
||
|
||
func sendPacket(packet gopacket.Packet, dstIp string) {
|
||
socket, err := net.DialUDP("udp",
|
||
&net.UDPAddr{IP: net.ParseIP(localIp), Port: 6112},
|
||
&net.UDPAddr{IP: net.ParseIP(dstIp), Port: 6112},
|
||
)
|
||
if err != nil {
|
||
log.Println(err)
|
||
}
|
||
defer socket.Close()
|
||
socket.Write(packet.ApplicationLayer().Payload())
|
||
}
|
||
|
||
func handlePacket(packet gopacket.Packet) {
|
||
log.Println("Sniffed packet:", packet.ApplicationLayer().Payload())
|
||
logBuf := bytes.Buffer{}
|
||
for _, ip := range sendIpList {
|
||
sendPacket(packet, ip)
|
||
logBuf.WriteString(fmt.Sprintf("发送数据包到 %s\n", ip))
|
||
}
|
||
log.Println(logBuf.String())
|
||
}
|
||
|
||
func buildSendIpList() {
|
||
for i := 1; i <= 50; i++ {
|
||
sendIpList = append(sendIpList, fmt.Sprintf("192.168.73.%d", i))
|
||
}
|
||
for i := 10; i <= 30; i++ {
|
||
sendIpList = append(sendIpList, fmt.Sprintf("192.168.72.%d", i))
|
||
}
|
||
}
|
||
|
||
func IsInCIDR(ip net.IP, cidr string) bool {
|
||
_, ipnet, err := net.ParseCIDR(cidr)
|
||
if err != nil {
|
||
return false
|
||
}
|
||
return ipnet.Contains(ip)
|
||
}
|
||
|
||
func init() {
|
||
// 设置日志输出到文件
|
||
// 获取当前路径
|
||
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||
if err != nil {
|
||
log.Fatal("无法获取当前路径:", err)
|
||
}
|
||
logFile, err := os.OpenFile(filepath.Join(dir, "war3-broadcaster.log"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||
if err != nil {
|
||
log.Fatal("无法创建日志文件:", err)
|
||
}
|
||
log.SetOutput(logFile)
|
||
}
|
||
|
||
func onReady() {
|
||
systray.SetIcon(iconBytes)
|
||
systray.SetTitle("WAR3开房助手")
|
||
systray.SetTooltip("WAR3开房助手 - 运行中")
|
||
|
||
mOpenLog := systray.AddMenuItem("打开日志", "打开日志文件")
|
||
mQuit := systray.AddMenuItem("退出", "关闭程序")
|
||
|
||
go func() {
|
||
for {
|
||
select {
|
||
case <-mOpenLog.ClickedCh:
|
||
exec.Command("notepad.exe", "war3-broadcaster.log").Start()
|
||
case <-mQuit.ClickedCh:
|
||
systray.Quit()
|
||
return
|
||
}
|
||
}
|
||
}()
|
||
}
|
||
|
||
func onExit() {
|
||
// 清理工作
|
||
}
|
||
|
||
func checkProcessRunning(processName string) bool {
|
||
cmd := exec.Command("tasklist")
|
||
output, err := cmd.Output()
|
||
if err != nil {
|
||
return false
|
||
}
|
||
// 判断存在两个war3-broadcaster.exe
|
||
return strings.Count(string(output), processName) >= 2
|
||
}
|
||
|
||
func checkPcapInstalled() bool {
|
||
cmd := exec.Command("sc", "query", "npcap")
|
||
output, err := cmd.Output()
|
||
if err != nil {
|
||
return false
|
||
}
|
||
return strings.Contains(string(output), "RUNNING")
|
||
}
|
||
|
||
// 添加新的辅助函数
|
||
func showMessageBox(message string, title string, flags uint32) {
|
||
syscall.MustLoadDLL("user32.dll").MustFindProc("MessageBoxW").Call(
|
||
0,
|
||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(message))),
|
||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))),
|
||
uintptr(flags))
|
||
}
|
||
|
||
func main() {
|
||
// 检查pcap是否安装
|
||
if !checkPcapInstalled() {
|
||
showMessageBox("请先安装Npcap", "错误", 0x10)
|
||
os.Exit(1)
|
||
}
|
||
// 检查是否已经有进程在运行
|
||
if checkProcessRunning("war3-broadcaster.exe") {
|
||
showMessageBox("WAR3开房助手已经在运行中", "提示", 0x40)
|
||
os.Exit(1)
|
||
}
|
||
go func() {
|
||
buildSendIpList()
|
||
devices, err := pcap.FindAllDevs()
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
log.Println("搜索网络设备中...")
|
||
devName = ""
|
||
for _, device := range devices {
|
||
for _, address := range device.Addresses {
|
||
if IsInCIDR(address.IP, "192.168.72.3/22") {
|
||
devName = device.Name
|
||
localIp = address.IP.String()
|
||
break
|
||
}
|
||
}
|
||
}
|
||
if devName == "" {
|
||
showMessageBox("找不到网络设备,请确认是否已连接樱花祭世界", "错误", 0x10)
|
||
os.Exit(1)
|
||
log.Fatalln("找不到网络设备,请确认是否已连接樱花祭世界")
|
||
}
|
||
showMessageBox("成功找到设备,开始捕获War3广播数据", "提示", 0x40)
|
||
log.Printf("找到设备: %s, 本地IP: %s\n", devName, localIp)
|
||
log.Println("开始捕获War3广播数据")
|
||
sniffer, err := sniffer.NewSniffer(devName, "dst net 255.255.255.255 and udp", handlePacket)
|
||
if err != nil {
|
||
log.Fatalln(err)
|
||
}
|
||
sniffer.Start()
|
||
}()
|
||
|
||
systray.Run(onReady, onExit)
|
||
}
|