package global import ( "context" "os" "runtime" runtimeDebug "runtime/debug" B "github.com/sagernet/sing-box" "github.com/sagernet/sing-box/common/urltest" "github.com/sagernet/sing-box/experimental/libbox" "github.com/sagernet/sing-box/option" E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/service" "github.com/sagernet/sing/service/filemanager" "github.com/sagernet/sing/service/pause" ) var ( sWorkingPath string sTempPath string sUserID int sGroupID int ) func Setup(basePath string, workingPath string, tempPath string) { tcpConn := runtime.GOOS == "windows" //TODO add TVOS libbox.Setup(basePath, workingPath, tempPath, tcpConn) sWorkingPath = workingPath os.Chdir(sWorkingPath) sTempPath = tempPath sUserID = os.Getuid() sGroupID = os.Getgid() } func NewService(options option.Options) (*libbox.BoxService, error) { runtimeDebug.FreeOSMemory() ctx, cancel := context.WithCancel(context.Background()) ctx = filemanager.WithDefault(ctx, sWorkingPath, sTempPath, sUserID, sGroupID) urlTestHistoryStorage := urltest.NewHistoryStorage() ctx = service.ContextWithPtr(ctx, urlTestHistoryStorage) instance, err := B.New(B.Options{ Context: ctx, Options: options, }) if err != nil { cancel() return nil, E.Cause(err, "create service") } runtimeDebug.FreeOSMemory() service := libbox.NewBoxService( ctx, cancel, instance, service.FromContext[pause.Manager](ctx), urlTestHistoryStorage, ) return &service, nil } func parseConfig(configContent string) (option.Options, error) { var options option.Options err := options.UnmarshalJSON([]byte(configContent)) if err != nil { return option.Options{}, E.Cause(err, "decode config") } return options, nil }