107 lines
2.3 KiB
Go
107 lines
2.3 KiB
Go
package core
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"github.com/goWxHook/goWxHook/resource"
|
||
"github.com/goWxHook/goWxHook/utils"
|
||
"github.com/goWxHook/goWxHook/utils/tcp"
|
||
"log/slog"
|
||
"os"
|
||
"os/exec"
|
||
"strconv"
|
||
"time"
|
||
)
|
||
|
||
var (
|
||
GlobalCallUrl string
|
||
lastErrorStr string
|
||
GlobalDebug bool
|
||
)
|
||
|
||
func init() {
|
||
files := map[string]*[]byte{
|
||
"Helper_3.9.10.19.dll": &resource.HelperDll,
|
||
"Loader_3.9.10.19.dll": &resource.LoaderDll,
|
||
"callexe.exe": &resource.CallExe,
|
||
"HPSocket4C.dll": &resource.HPSocket4C,
|
||
}
|
||
for name, val := range files {
|
||
if !utils.FileExists(name) {
|
||
if err := utils.WriteFile(name, *val); err != nil {
|
||
panic(err)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取宿主机上下一个可用的Api端口,检测端口和+1的端口是否可用
|
||
func getNextAvailableApiPort(fromPort int) (int, error) {
|
||
const lowerLimit = 1000
|
||
const upperLimit = 65535
|
||
searchDown := (fromPort - lowerLimit) > (upperLimit - fromPort)
|
||
var step int
|
||
if searchDown {
|
||
step = -1
|
||
} else {
|
||
step = 1
|
||
}
|
||
|
||
var m = make(map[int]bool)
|
||
for {
|
||
fromPort += step
|
||
if fromPort < lowerLimit || fromPort > upperLimit {
|
||
return 0, errors.New("no available port")
|
||
}
|
||
portUsed := tcp.CheckPortConnection("127.0.0.1", fromPort)
|
||
m[fromPort] = portUsed
|
||
if !portUsed {
|
||
beforePort := fromPort - step
|
||
if v, ok := m[beforePort]; ok && !v {
|
||
if searchDown {
|
||
return fromPort, nil
|
||
} else {
|
||
return beforePort, nil
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// WxModuleInit 初始化微信模块
|
||
// 除此之外,系统主动检测启动端口用于dll和服务内部统信
|
||
func WxModuleInit(listenerPort int, debug bool) error {
|
||
GlobalDebug = debug
|
||
if GlobalDebug {
|
||
slog.SetLogLoggerLevel(slog.LevelDebug)
|
||
}
|
||
// 获取内部服务使用端口
|
||
port, err := getNextAvailableApiPort(listenerPort)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
var lserr error
|
||
go func() {
|
||
lserr = registerWxCallBackListen(port + 1)
|
||
}()
|
||
time.Sleep(2 * time.Second)
|
||
if lserr != nil {
|
||
return lserr
|
||
}
|
||
args := []string{strconv.Itoa(os.Getpid()), strconv.Itoa(port)}
|
||
cmd := exec.Command(".\\callexe.exe", args...)
|
||
err = cmd.Start()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
// 等待3秒进程启动
|
||
time.Sleep(3 * time.Second)
|
||
GlobalCallUrl = fmt.Sprintf("http://127.0.0.1:%d", port)
|
||
slog.Info(fmt.Sprintf("启动微信监听 %d\n", port))
|
||
api := WxApi{}
|
||
if err := api.Ping(); err != nil {
|
||
return err
|
||
}
|
||
return nil
|
||
}
|