96 lines
2.5 KiB
Go
96 lines
2.5 KiB
Go
|
|
// Copyright (c) 2026 S.A. (SNOWARE). Written for SCU Team.
|
||
|
|
// Licensed under MulanPubL-2.0.
|
||
|
|
// You may obtain a copy at: http://license.coscl.org.cn/MulanPubL-2.0
|
||
|
|
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND.
|
||
|
|
|
||
|
|
// DoConnect 模块:负责 EasyTier 子进程的完整生命周期管理(启动、监控、输出捕获、清理)。
|
||
|
|
package main
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"fmt"
|
||
|
|
"os"
|
||
|
|
"os/exec"
|
||
|
|
"path/filepath"
|
||
|
|
"strings"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
// connectToVirtualHotspot 构建 EasyTier 命令行,清理旧进程,启动新进程,并在 500ms 内检测进程是否存活。
|
||
|
|
// 返回子进程的 *os.Process 引用,失败返回 nil。
|
||
|
|
func connectToVirtualHotspot() *os.Process {
|
||
|
|
log.Info().Msg("连接虚拟热点开始")
|
||
|
|
|
||
|
|
host := "magpie.snoware.sa-tale.eu.cc"
|
||
|
|
port := "11010"
|
||
|
|
netname := "scu_team"
|
||
|
|
token := "@5cut0t"
|
||
|
|
|
||
|
|
miner := Miner{}
|
||
|
|
cmd := miner.BuildTaskCommand(
|
||
|
|
fmt.Sprintf("tcp://%s:%s", host, port),
|
||
|
|
netname,
|
||
|
|
token,
|
||
|
|
)
|
||
|
|
|
||
|
|
log.Info().
|
||
|
|
Str("host", host).
|
||
|
|
Str("port", port).
|
||
|
|
Str("network", netname).
|
||
|
|
Msg("启动 EasyTier 进程")
|
||
|
|
|
||
|
|
exePath, err := os.Executable()
|
||
|
|
if err != nil {
|
||
|
|
log.Error().Err(err).Msg("获取自身可执行文件路径失败")
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
workdir := filepath.Dir(exePath)
|
||
|
|
log.Debug().Str("work_dir", workdir).Msg("工作目录")
|
||
|
|
|
||
|
|
cleanupOldEasyTier()
|
||
|
|
|
||
|
|
parts := strings.Fields(cmd)
|
||
|
|
easyTierPath := filepath.Join(workdir, parts[0][2:])
|
||
|
|
if _, err := os.Stat(easyTierPath); os.IsNotExist(err) {
|
||
|
|
log.Error().Str("path", easyTierPath).Msg("easytier-core.exe 不存在,请确保该文件与 srcc.exe 在同一目录")
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
c := exec.Command(easyTierPath, parts[1:]...)
|
||
|
|
c.Dir = workdir
|
||
|
|
|
||
|
|
var stderr, stdout bytes.Buffer
|
||
|
|
c.Stderr = &stderr
|
||
|
|
c.Stdout = &stdout
|
||
|
|
|
||
|
|
if err := c.Start(); err != nil {
|
||
|
|
log.Error().Err(err).Msg("EasyTier 启动失败")
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
done := make(chan error, 1)
|
||
|
|
go func() {
|
||
|
|
done <- c.Wait()
|
||
|
|
}()
|
||
|
|
select {
|
||
|
|
case err := <-done:
|
||
|
|
log.Error().Err(err).Str("stdout", stdout.String()).Str("stderr", stderr.String()).Msg("EasyTier 进程启动后立即退出")
|
||
|
|
return nil
|
||
|
|
case <-time.After(500 * time.Millisecond):
|
||
|
|
}
|
||
|
|
|
||
|
|
log.Info().Int("pid", c.Process.Pid).Msg("EasyTier 进程已启动")
|
||
|
|
return c.Process
|
||
|
|
}
|
||
|
|
|
||
|
|
// cleanupOldEasyTier 通过 taskkill 强制终止所有旧 easytier-core.exe 进程,避免端口冲突。
|
||
|
|
func cleanupOldEasyTier() {
|
||
|
|
cmd := exec.Command("taskkill", "/f", "/im", "easytier-core.exe")
|
||
|
|
cmd.Stdout = nil
|
||
|
|
cmd.Stderr = nil
|
||
|
|
if err := cmd.Run(); err != nil {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
log.Warn().Msg("检测到旧的 EasyTier 进程,已终止")
|
||
|
|
}
|