update v-advance

This commit is contained in:
lzx
2025-12-01 15:45:05 +08:00
parent 16173b7ccd
commit de010e39ee
22 changed files with 1963 additions and 175 deletions

353
internal/sustain/proxy.go Normal file
View File

@@ -0,0 +1,353 @@
/*
持续挖矿
1在主配置文件中选择是否开启
2开启后将读取挖矿配置(mining.conf)
3根据配置启动相应的挖矿软件开始挖矿
4接收到tcp协议传送过来的新挖矿任务后停止当前挖矿并开启新的挖矿
5新挖矿任务到期或结束后重新开启挖矿
配置文件:算法、挖矿软件、挖矿配置(算法、钱包、矿工号、挖矿地址)
*/
package sustain
import (
message "client/internal/msg"
"client/internal/src"
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"sync"
"time"
"gopkg.in/ini.v1"
)
// SustainMiningConfig 持续挖矿配置
type SustainMiningConfig struct {
Enabled bool // 是否启用持续挖矿
Algo string // 算法
Coin string // 币种
Miner string // 挖矿软件 (lolminer/bzminer/rigel)
PoolUrl string // 矿池地址
Wallet string // 钱包地址
WorkerID string // 矿工号
PoolUser string // 矿池账号(可选)
WalletMining bool // 是否使用钱包挖矿
}
// SustainMiner 持续挖矿管理器
type SustainMiner struct {
mu sync.Mutex
config SustainMiningConfig
miningConfig message.MiningConfig
os *src.SystemServer
osName string
currentProcess *exec.Cmd // 当前挖矿进程
isRunning bool // 是否正在运行持续挖矿
isPaused bool // 是否被暂停(因为有新任务)
stopChan chan struct{} // 停止信号
}
// NewSustainMiner 创建持续挖矿管理器
func NewSustainMiner(os *src.SystemServer, osName string, miningConfig message.MiningConfig) *SustainMiner {
return &SustainMiner{
os: os,
osName: osName,
miningConfig: miningConfig,
stopChan: make(chan struct{}),
}
}
// LoadConfig 从配置文件加载持续挖矿配置
func (s *SustainMiner) LoadConfig() error {
var confFile string
if runtime.GOOS == "windows" {
confFile = "mining.windows.conf"
} else {
confFile = "mining.linux.conf"
}
cfg, err := ini.Load(confFile)
if err != nil {
return fmt.Errorf("读取配置文件失败: %v", err)
}
// 读取 [sustain] 部分
section := cfg.Section("sustain")
s.config.Enabled, _ = section.Key("enabled").Bool()
if !s.config.Enabled {
log.Println("持续挖矿未启用")
return nil
}
// 读取配置值,并去掉可能的引号
s.config.Algo = strings.Trim(section.Key("algo").String(), `"`)
s.config.Coin = strings.Trim(section.Key("coin").String(), `"`)
s.config.Miner = strings.Trim(section.Key("miner").String(), `"`)
s.config.PoolUrl = strings.Trim(section.Key("pool_url").String(), `"`)
s.config.Wallet = strings.Trim(section.Key("wallet").String(), `"`)
s.config.WorkerID = strings.Trim(section.Key("worker_id").String(), `"`)
s.config.PoolUser = strings.Trim(section.Key("pool_user").String(), `"`)
s.config.WalletMining, _ = section.Key("wallet_mining").Bool()
// 验证配置
if s.config.Algo == "" || s.config.Coin == "" || s.config.Miner == "" ||
s.config.PoolUrl == "" || s.config.Wallet == "" || s.config.WorkerID == "" {
return fmt.Errorf("持续挖矿配置不完整")
}
// 验证挖矿软件路径
switch strings.ToLower(s.config.Miner) {
case "lolminer":
if s.miningConfig.LolMinerPath == "" {
return fmt.Errorf("lolminer 路径未配置")
}
case "bzminer":
if s.miningConfig.BzMinerPath == "" {
return fmt.Errorf("bzminer 路径未配置")
}
case "rigel":
if s.miningConfig.RigelPath == "" {
return fmt.Errorf("rigel 路径未配置")
}
default:
return fmt.Errorf("不支持的挖矿软件: %s", s.config.Miner)
}
log.Printf("持续挖矿配置加载成功: 算法=%s, 币种=%s, 挖矿软件=%s", s.config.Algo, s.config.Coin, s.config.Miner)
return nil
}
// Start 启动持续挖矿
func (s *SustainMiner) Start() error {
s.mu.Lock()
defer s.mu.Unlock()
if !s.config.Enabled {
return nil
}
if s.isRunning {
log.Println("持续挖矿已在运行中")
return nil
}
s.isRunning = true
s.isPaused = false
s.stopChan = make(chan struct{})
log.Println("启动持续挖矿...")
go s.run()
return nil
}
// Stop 停止持续挖矿
func (s *SustainMiner) Stop() {
s.mu.Lock()
defer s.mu.Unlock()
if !s.isRunning {
return
}
log.Println("停止持续挖矿...")
close(s.stopChan)
s.isRunning = false
// 停止当前挖矿进程
if s.currentProcess != nil && s.currentProcess.Process != nil {
log.Println("停止当前挖矿进程...")
if runtime.GOOS == "linux" && s.config.Miner == "rigel" {
// Linux rigel 使用 Interrupt 信号
s.currentProcess.Process.Signal(os.Interrupt)
} else {
s.currentProcess.Process.Kill()
}
s.currentProcess = nil
}
}
// Pause 暂停持续挖矿(当有新任务时调用)
func (s *SustainMiner) Pause() {
s.mu.Lock()
defer s.mu.Unlock()
if !s.isRunning || s.isPaused {
return
}
log.Println("暂停持续挖矿(有新任务)...")
s.isPaused = true
// 停止当前挖矿进程
if s.currentProcess != nil && s.currentProcess.Process != nil {
if runtime.GOOS == "linux" && s.config.Miner == "rigel" {
s.currentProcess.Process.Signal(os.Interrupt)
} else {
s.currentProcess.Process.Kill()
}
s.currentProcess = nil
}
}
// Resume 恢复持续挖矿(当任务结束后调用)
func (s *SustainMiner) Resume() {
s.mu.Lock()
defer s.mu.Unlock()
if !s.isRunning || !s.isPaused {
return
}
log.Println("恢复持续挖矿...")
s.isPaused = false
// 重新启动挖矿
go s.startMining()
}
// run 持续挖矿主循环
func (s *SustainMiner) run() {
for {
select {
case <-s.stopChan:
log.Println("持续挖矿已停止")
return
default:
s.mu.Lock()
paused := s.isPaused
s.mu.Unlock()
if !paused {
s.startMining()
// 等待挖矿进程结束(正常情况下不会结束,除非被停止)
if s.currentProcess != nil {
s.currentProcess.Wait()
}
} else {
// 如果被暂停,等待恢复
time.Sleep(1 * time.Second)
}
}
}
}
// startMining 启动挖矿进程
func (s *SustainMiner) startMining() {
s.mu.Lock()
defer s.mu.Unlock()
if s.isPaused {
return
}
var cmd *exec.Cmd
var err error
address := s.config.Wallet
if !s.config.WalletMining && s.config.PoolUser != "" {
address = s.config.PoolUser
}
switch strings.ToLower(s.config.Miner) {
case "lolminer":
cmd, err = s.startLolMiner(address)
case "bzminer":
cmd, err = s.startBzMiner(address)
case "rigel":
cmd, err = s.startRigel(address)
default:
log.Printf("不支持的挖矿软件: %s", s.config.Miner)
return
}
if err != nil {
log.Printf("启动持续挖矿失败: %v", err)
return
}
s.currentProcess = cmd
log.Printf("持续挖矿已启动: %s (PID: %d)", s.config.Miner, cmd.Process.Pid)
}
// startLolMiner 启动 lolminer
func (s *SustainMiner) startLolMiner(address string) (*exec.Cmd, error) {
dir := s.miningConfig.LolMinerPath
var name string
if runtime.GOOS == "windows" {
name = filepath.Join(dir, "lolMiner.exe")
} else {
name = filepath.Join(dir, "lolMiner")
}
args := []string{"--algo", s.config.Coin, "--pool", s.config.PoolUrl, "--user", address + "." + s.config.WorkerID}
cmd := exec.Command(name, args...)
cmd.Dir = dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
log.Printf("启动持续挖矿 lolminer: %s %s", name, strings.Join(args, " "))
err := cmd.Start()
return cmd, err
}
// startBzMiner 启动 bzminer
func (s *SustainMiner) startBzMiner(address string) (*exec.Cmd, error) {
dir := s.miningConfig.BzMinerPath
var name string
if runtime.GOOS == "windows" {
name = filepath.Join(dir, "bzminer.exe")
} else {
name = filepath.Join(dir, "bzminer")
}
args := []string{"-a", s.config.Coin, "-w", address + "." + s.config.WorkerID, "-p", s.config.PoolUrl}
cmd := exec.Command(name, args...)
cmd.Dir = dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
log.Printf("启动持续挖矿 bzminer: %s %s", name, strings.Join(args, " "))
err := cmd.Start()
return cmd, err
}
// startRigel 启动 rigel
func (s *SustainMiner) startRigel(address string) (*exec.Cmd, error) {
dir := s.miningConfig.RigelPath
var name string
if runtime.GOOS == "windows" {
name = filepath.Join(dir, "rigel.exe")
} else {
name = filepath.Join(dir, "rigel")
}
args := []string{"--no-watchdog", "-a", strings.ToLower(s.config.Algo), "-o", s.config.PoolUrl, "-u", address, "-w", s.config.WorkerID, "--log-file", "logs/miner.log"}
cmd := exec.Command(name, args...)
cmd.Dir = dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
log.Printf("启动持续挖矿 rigel: %s %s", name, strings.Join(args, " "))
err := cmd.Start()
return cmd, err
}
// IsRunning 检查是否正在运行
func (s *SustainMiner) IsRunning() bool {
s.mu.Lock()
defer s.mu.Unlock()
return s.isRunning && !s.isPaused
}
// IsPaused 检查是否被暂停
func (s *SustainMiner) IsPaused() bool {
s.mu.Lock()
defer s.mu.Unlock()
return s.isPaused
}