initial commit

master
Micoya 2024-11-24 17:16:13 +08:00
commit b8ca5d7643
8 changed files with 352 additions and 0 deletions

46
.gitignore vendored Normal file
View File

@ -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
*~

15
README.MD Normal file
View File

@ -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

BIN
assets/iconwin.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

5
build.ps1 Normal file
View File

@ -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

23
go.mod Normal file
View File

@ -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
)

62
go.sum Normal file
View File

@ -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=

183
main.go Normal file
View File

@ -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)
}

18
versioninfo.json Normal file
View File

@ -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": ""
}