commit b8ca5d7643ddd91238d2db255c5c0f37206e0ceb Author: Micoya Date: Sun Nov 24 17:16:13 2024 +0800 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4d43033 --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# Windows系统文件 +Thumbs.db +ehthumbs.db +Desktop.ini +$RECYCLE.BIN/ + +# Windows可执行文件和编译输出 +*.exe +*.dll +*.sys +*.msi +*.msm +*.msp +*.obj +*.pdb +*.syso + +# Visual Studio文件 +.vs/ +*.user +*.suo +*.sln.docstates +*.userprefs +Debug/ +Release/ +x64/ +x86/ + +# Go语言特定 +*.test +*.out +*.prof +vendor/ + +# 日志文件 +*.log + +# IDE配置文件 +.idea/ +.vscode/ + +# 临时文件 +*.tmp +*.bak +*.swp +*~ diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..645763e --- /dev/null +++ b/README.MD @@ -0,0 +1,15 @@ +# WAR3开房助手托盘版本 + +## 使用说明 + +1. 安装Npcap +2. 运行war3-broadcaster.exe + +## 编译说明 + +1. 安装goversioninfo +``` +go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@latest +``` + +2. 运行build.ps1 diff --git a/assets/iconwin.ico b/assets/iconwin.ico new file mode 100644 index 0000000..24539c7 Binary files /dev/null and b/assets/iconwin.ico differ diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..04fdd37 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,5 @@ +go generate +if (-not (Test-Path -Path build)) { + New-Item -ItemType Directory -Path build +} +go build -ldflags -H=windowsgui -o build/war3-broadcaster.exe diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e1f4919 --- /dev/null +++ b/go.mod @@ -0,0 +1,23 @@ +module war3-broadcaster + +go 1.23.3 + +require ( + github.com/gen2brain/shm v0.1.0 // indirect + github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 // indirect + github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 // indirect + github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 // indirect + github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 // indirect + github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 // indirect + github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f // indirect + github.com/getlantern/systray v1.2.2 // indirect + github.com/go-stack/stack v1.8.0 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/google/gopacket v1.1.20-0.20220810144506-32ee38206866 // indirect + github.com/jezek/xgb v1.1.1 // indirect + github.com/kbinani/screenshot v0.0.0-20240820160931-a8a2c5d0e191 // indirect + github.com/lxn/win v0.0.0-20210218163916-a377121e959e // indirect + github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect + github.com/tiagomdiogo/ScaGo v0.0.0-20240903173942-8aaf5f4fa242 // indirect + golang.org/x/sys v0.24.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..8aff8f8 --- /dev/null +++ b/go.sum @@ -0,0 +1,62 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gen2brain/shm v0.1.0 h1:MwPeg+zJQXN0RM9o+HqaSFypNoNEcNpeoGp0BTSx2YY= +github.com/gen2brain/shm v0.1.0/go.mod h1:UgIcVtvmOu+aCJpqJX7GOtiN7X2ct+TKLg4RTxwPIUA= +github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4= +github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY= +github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 h1:6uJ+sZ/e03gkbqZ0kUG6mfKoqDb4XMAzMIwlajq19So= +github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A= +github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 h1:guBYzEaLz0Vfc/jv0czrr2z7qyzTOGC9hiQ0VC+hKjk= +github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7/go.mod h1:zx/1xUUeYPy3Pcmet8OSXLbF47l+3y6hIPpyLWoR9oc= +github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0= +github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o= +github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc= +github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA= +github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA= +github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA= +github.com/getlantern/systray v1.2.2 h1:dCEHtfmvkJG7HZ8lS/sLklTH4RKUcIsKrAD9sThoEBE= +github.com/getlantern/systray v1.2.2/go.mod h1:pXFOI1wwqwYXEhLPm9ZGjS2u/vVELeIgNMY5HvhHhcE= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/google/gopacket v1.1.20-0.20220810144506-32ee38206866 h1:NaJi58bCZZh0jjPw78EqDZekPEfhlzYE01C5R+zh1tE= +github.com/google/gopacket v1.1.20-0.20220810144506-32ee38206866/go.mod h1:riddUzxTSBpJXk3qBHtYr4qOhFhT6k/1c0E3qkQjQpA= +github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4= +github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk= +github.com/kbinani/screenshot v0.0.0-20240820160931-a8a2c5d0e191 h1:5UHVWNX1qrIbNw7OpKbxe5bHkhHRk3xRKztMjERuCsU= +github.com/kbinani/screenshot v0.0.0-20240820160931-a8a2c5d0e191/go.mod h1:Pmpz2BLf55auQZ67u3rvyI2vAQvNetkK/4zYUmpauZQ= +github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= +github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc= +github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= +github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= +github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/tiagomdiogo/ScaGo v0.0.0-20240903173942-8aaf5f4fa242 h1:ji8Y9OhJWqUY8JRBdWeSYaE6+uqF8GMgJWKfjxhTVhY= +github.com/tiagomdiogo/ScaGo v0.0.0-20240903173942-8aaf5f4fa242/go.mod h1:lyE8zo8P2kS87KWnDpKhzp9ARtCQKhrSZiwla+uLaTc= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E= diff --git a/main.go b/main.go new file mode 100644 index 0000000..08f4b1b --- /dev/null +++ b/main.go @@ -0,0 +1,183 @@ +//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) +} diff --git a/versioninfo.json b/versioninfo.json new file mode 100644 index 0000000..d2d9a8f --- /dev/null +++ b/versioninfo.json @@ -0,0 +1,18 @@ +{ + "FixedFileInfo": { + "FileVersion": { + "Major": 1, + "Minor": 0, + "Patch": 0, + "Build": 0 + }, + "ProductVersion": { + "Major": 1, + "Minor": 0, + "Patch": 0, + "Build": 0 + } + }, + "IconPath": "assets/iconwin.ico", + "ManifestPath": "" +} \ No newline at end of file