package core import ( "context" "os" "s-ui/config" "s-ui/logger" sb "github.com/sagernet/sing-box" "github.com/sagernet/sing-box/adapter" _ "github.com/sagernet/sing-box/experimental/clashapi" _ "github.com/sagernet/sing-box/experimental/v2rayapi" "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" _ "github.com/sagernet/sing-box/transport/v2rayquic" _ "github.com/sagernet/sing-dns/quic" "github.com/sagernet/sing/service" ) var ( globalCtx context.Context inbound_manager adapter.InboundManager outbound_manager adapter.OutboundManager endpoint_manager adapter.EndpointManager router adapter.Router connTracker *ConnTracker factory log.Factory ) type Core struct { isRunning bool instance *Box } func NewCore() *Core { globalCtx = context.Background() globalCtx = sb.Context(globalCtx, inboundRegistry(), outboundRegistry(), EndpointRegistry()) return &Core{ isRunning: false, instance: nil, } } func (c *Core) GetCtx() context.Context { return globalCtx } func (c *Core) GetInstance() *Box { return c.instance } func (c *Core) Start() error { filepath := config.GetBinFolderPath() + "/config.json" configFile, err := os.ReadFile(filepath) if err != nil { return err } var opt option.Options err = opt.UnmarshalJSONContext(globalCtx, configFile) if err != nil { logger.Error("Unmarshal config err:", err.Error()) } c.instance, err = NewBox(Options{ Context: globalCtx, Options: opt, }) if err != nil { return err } err = c.instance.Start() if err != nil { return err } globalCtx = service.ContextWith(globalCtx, c) inbound_manager = service.FromContext[adapter.InboundManager](globalCtx) outbound_manager = service.FromContext[adapter.OutboundManager](globalCtx) endpoint_manager = service.FromContext[adapter.EndpointManager](globalCtx) router = service.FromContext[adapter.Router](globalCtx) c.isRunning = true return nil } func (c *Core) Stop() error { if c.isRunning { c.isRunning = false return c.instance.Close() } return nil } func (c *Core) Restart() error { err := c.Stop() if err != nil { logger.Error("stop sing-box err:", err.Error()) return err } logger.Info("sing-box stopped") return c.Start() } func (c *Core) IsRunning() bool { return c.isRunning }