fc3a66dc83
Go 控制面(SQLite + REST API)嵌入 Mihomo 数据面,Vue 3 多语言 Web 管理台。 含订阅/节点/规则/出站/监控/日志、OpenAPI、API Key、Gitea Actions CI(runs-on: ubuntu-latest) 与开源文档;镜像发布至 git.rc707blog.top Container Registry。 Co-authored-by: Cursor <cursoragent@cursor.com>
75 lines
1.3 KiB
Go
75 lines
1.3 KiB
Go
package core
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/metacubex/mihomo/hub"
|
|
"github.com/metacubex/mihomo/hub/executor"
|
|
)
|
|
|
|
type Engine struct {
|
|
mu sync.Mutex
|
|
apiAddr string
|
|
secret string
|
|
lastGood []byte
|
|
running bool
|
|
}
|
|
|
|
func NewEngine() *Engine {
|
|
return &Engine{}
|
|
}
|
|
|
|
func (e *Engine) Configure(apiAddr, secret string) {
|
|
e.mu.Lock()
|
|
defer e.mu.Unlock()
|
|
e.apiAddr = apiAddr
|
|
e.secret = secret
|
|
}
|
|
|
|
func (e *Engine) Reload(yaml []byte) error {
|
|
e.mu.Lock()
|
|
defer e.mu.Unlock()
|
|
|
|
if _, err := executor.ParseWithBytes(yaml); err != nil {
|
|
return fmt.Errorf("config validation failed: %w", err)
|
|
}
|
|
|
|
opts := []hub.Option{
|
|
hub.WithExternalController(e.apiAddr),
|
|
}
|
|
if e.secret != "" {
|
|
opts = append(opts, hub.WithSecret(e.secret))
|
|
}
|
|
|
|
if err := hub.Parse(yaml, opts...); err != nil {
|
|
return fmt.Errorf("mihomo reload failed: %w", err)
|
|
}
|
|
|
|
e.lastGood = append([]byte(nil), yaml...)
|
|
e.running = true
|
|
return nil
|
|
}
|
|
|
|
func (e *Engine) Shutdown() {
|
|
e.mu.Lock()
|
|
defer e.mu.Unlock()
|
|
executor.Shutdown()
|
|
e.running = false
|
|
}
|
|
|
|
func (e *Engine) LastGoodConfig() []byte {
|
|
e.mu.Lock()
|
|
defer e.mu.Unlock()
|
|
if e.lastGood == nil {
|
|
return nil
|
|
}
|
|
return append([]byte(nil), e.lastGood...)
|
|
}
|
|
|
|
func (e *Engine) Running() bool {
|
|
e.mu.Lock()
|
|
defer e.mu.Unlock()
|
|
return e.running
|
|
}
|