big refactor. make compatible v2 and v1 interface

This commit is contained in:
Hiddify
2024-03-16 01:39:33 +01:00
parent c51f73faed
commit 361419b95e
27 changed files with 1455 additions and 1085 deletions

View File

@@ -111,7 +111,7 @@ release: # Create a new tag for release.
sed -i -e "s|<key>CFBundleVersion</key>\s*<string>[^<]*</string>|<key>CFBundleVersion</key><string>$${VERSION_STR}</string>|" Info.plist &&\ sed -i -e "s|<key>CFBundleVersion</key>\s*<string>[^<]*</string>|<key>CFBundleVersion</key><string>$${VERSION_STR}</string>|" Info.plist &&\
sed -i -e "s|<key>CFBundleShortVersionString</key>\s*<string>[^<]*</string>|<key>CFBundleShortVersionString</key><string>$${VERSION_STR}</string>|" Info.plist &&\ sed -i -e "s|<key>CFBundleShortVersionString</key>\s*<string>[^<]*</string>|<key>CFBundleShortVersionString</key><string>$${VERSION_STR}</string>|" Info.plist &&\
sed -i "s|ENV VERSION=.*|ENV VERSION=v$${TAG}|g" docker/Dockerfile && \ sed -i "s|ENV VERSION=.*|ENV VERSION=v$${TAG}|g" docker/Dockerfile && \
git add Info.plist && \ git add Info.plist docker/Dockerfile && \
git commit -m "release: version $${TAG}" && \ git commit -m "release: version $${TAG}" && \
echo "creating git tag : v$${TAG}" && \ echo "creating git tag : v$${TAG}" && \
git push && \ git push && \

View File

@@ -1,21 +0,0 @@
// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.
// simple does nothing except block while running the service.
package main
import "C"
import (
"fmt"
"github.com/hiddify/libcore/admin_service"
)
//export AdminServiceStart
func AdminServiceStart(arg *C.char) *C.char {
goArg := C.GoString(arg)
exitCode, outMessage := admin_service.StartService(goArg)
return C.CString(fmt.Sprintf("%d %s", exitCode, outMessage))
}

View File

@@ -1,72 +0,0 @@
package main
import (
"github.com/sagernet/sing-box/experimental/libbox"
"github.com/sagernet/sing-box/log"
)
var (
statusClient *libbox.CommandClient
groupClient *libbox.CommandClient
groupInfoOnlyClient *libbox.CommandClient
)
func StartCommand(command int32, port int64, logFactory log.Factory) error {
switch command {
case libbox.CommandStatus:
statusClient = libbox.NewCommandClient(
&CommandClientHandler{
port: port,
logger: logFactory.NewLogger("[Status Command Client]"),
},
&libbox.CommandClientOptions{
Command: libbox.CommandStatus,
StatusInterval: 1000000000, //1000ms debounce
},
)
return statusClient.Connect()
case libbox.CommandGroup:
groupClient = libbox.NewCommandClient(
&CommandClientHandler{
port: port,
logger: logFactory.NewLogger("[Group Command Client]"),
},
&libbox.CommandClientOptions{
Command: libbox.CommandGroup,
StatusInterval: 300000000, //300ms debounce
},
)
return groupClient.Connect()
case libbox.CommandGroupInfoOnly:
groupInfoOnlyClient = libbox.NewCommandClient(
&CommandClientHandler{
port: port,
logger: logFactory.NewLogger("[GroupInfoOnly Command Client]"),
},
&libbox.CommandClientOptions{
Command: libbox.CommandGroupInfoOnly,
StatusInterval: 300000000, //300ms debounce
},
)
return groupInfoOnlyClient.Connect()
}
return nil
}
func StopCommand(command int32) error {
switch command {
case libbox.CommandStatus:
err := statusClient.Disconnect()
statusClient = nil
return err
case libbox.CommandGroup:
err := groupClient.Disconnect()
groupClient = nil
return err
case libbox.CommandGroupInfoOnly:
err := groupInfoOnlyClient.Disconnect()
groupInfoOnlyClient = nil
return err
}
return nil
}

View File

@@ -1,15 +0,0 @@
package main
const (
Stopped = "Stopped"
Starting = "Starting"
Started = "Started"
Stopping = "Stopping"
)
const (
EmptyConfiguration = "EmptyConfiguration"
StartCommandServer = "StartCommandServer"
CreateService = "CreateService"
StartService = "StartService"
)

View File

@@ -7,10 +7,7 @@ import "C"
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"os" "os"
"path/filepath"
"time"
"unsafe" "unsafe"
"github.com/hiddify/libcore/bridge" "github.com/hiddify/libcore/bridge"
@@ -18,16 +15,9 @@ import (
pb "github.com/hiddify/libcore/hiddifyrpc" pb "github.com/hiddify/libcore/hiddifyrpc"
v2 "github.com/hiddify/libcore/v2" v2 "github.com/hiddify/libcore/v2"
"github.com/sagernet/sing-box/experimental/libbox"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
) )
// var v2.Box *libbox.BoxService
var configOptions *config.ConfigOptions
var activeConfigPath *string
var logFactory *log.Factory
//export setupOnce //export setupOnce
func setupOnce(api unsafe.Pointer) { func setupOnce(api unsafe.Pointer) {
bridge.InitializeDartApi(api) bridge.InitializeDartApi(api)
@@ -35,287 +25,146 @@ func setupOnce(api unsafe.Pointer) {
//export setup //export setup
func setup(baseDir *C.char, workingDir *C.char, tempDir *C.char, statusPort C.longlong, debug bool) (CErr *C.char) { func setup(baseDir *C.char, workingDir *C.char, tempDir *C.char, statusPort C.longlong, debug bool) (CErr *C.char) {
defer config.DeferPanicToError("setup", func(err error) { err := v2.Setup(C.GoString(baseDir), C.GoString(workingDir), C.GoString(tempDir), int64(statusPort), debug)
CErr = C.CString(err.Error())
fmt.Printf("Error: %+v\n", err)
})
Setup(C.GoString(baseDir), C.GoString(workingDir), C.GoString(tempDir)) return emptyOrErrorC(err)
statusPropagationPort = int64(statusPort)
var defaultWriter io.Writer
if !debug {
defaultWriter = io.Discard
}
factory, err := log.New(
log.Options{
DefaultWriter: defaultWriter,
BaseTime: time.Now(),
Observable: false,
})
if err != nil {
return C.CString(err.Error())
}
logFactory = &factory
return C.CString("")
} }
//export parse //export parse
func parse(path *C.char, tempPath *C.char, debug bool) (CErr *C.char) { func parse(path *C.char, tempPath *C.char, debug bool) (CErr *C.char) {
defer config.DeferPanicToError("parse", func(err error) { res, err := v2.Parse(&pb.ParseRequest{
CErr = C.CString(err.Error()) ConfigPath: C.GoString(path),
TempPath: C.GoString(tempPath),
}) })
if err != nil {
log.Error(err.Error())
return C.CString(err.Error())
}
config, err := config.ParseConfig(C.GoString(tempPath), debug) err = os.WriteFile(C.GoString(path), []byte(res.Content), 0644)
if err != nil { return emptyOrErrorC(err)
return C.CString(err.Error())
}
err = os.WriteFile(C.GoString(path), config, 0644)
if err != nil {
return C.CString(err.Error())
}
return C.CString("")
} }
//export changeConfigOptions //export changeConfigOptions
func changeConfigOptions(configOptionsJson *C.char) (CErr *C.char) { func changeConfigOptions(configOptionsJson *C.char) (CErr *C.char) {
defer config.DeferPanicToError("changeConfigOptions", func(err error) {
CErr = C.CString(err.Error()) _, err := v2.ChangeConfigOptions(&pb.ChangeConfigOptionsRequest{
ConfigOptionsJson: C.GoString(configOptionsJson),
}) })
return emptyOrErrorC(err)
configOptions = &config.ConfigOptions{}
err := json.Unmarshal([]byte(C.GoString(configOptionsJson)), configOptions)
if err != nil {
return C.CString(err.Error())
}
if configOptions.Warp.WireguardConfigStr != "" {
err := json.Unmarshal([]byte(configOptions.Warp.WireguardConfigStr), &configOptions.Warp.WireguardConfig)
if err != nil {
return C.CString(err.Error())
}
}
return C.CString("")
} }
//export generateConfig //export generateConfig
func generateConfig(path *C.char) (res *C.char) { func generateConfig(path *C.char) (res *C.char) {
defer config.DeferPanicToError("generateConfig", func(err error) { _, err := v2.GenerateConfig(&pb.GenerateConfigRequest{
res = C.CString("error" + err.Error()) Path: C.GoString(path),
}) })
return emptyOrErrorC(err)
config, err := generateConfigFromFile(C.GoString(path), *configOptions)
if err != nil {
return C.CString("error" + err.Error())
}
return C.CString(config)
}
func generateConfigFromFile(path string, configOpt config.ConfigOptions) (string, error) {
os.Chdir(filepath.Dir(path))
content, err := os.ReadFile(path)
if err != nil {
return "", err
}
options, err := parseConfig(string(content))
if err != nil {
return "", err
}
config, err := config.BuildConfigJson(configOpt, options)
if err != nil {
return "", err
}
return config, nil
} }
//export start //export start
func start(configPath *C.char, disableMemoryLimit bool) (CErr *C.char) { func start(configPath *C.char, disableMemoryLimit bool) (CErr *C.char) {
defer config.DeferPanicToError("start", func(err error) {
stopAndAlert("Unexpected Error!", err) _, err := v2.Start(&pb.StartRequest{
CErr = C.CString(err.Error()) ConfigPath: C.GoString(configPath),
EnableOldCommandServer: true,
DisableMemoryLimit: disableMemoryLimit,
}) })
return emptyOrErrorC(err)
if v2.CoreState != pb.CoreState_STOPPED {
return C.CString("")
}
propagateStatus(pb.CoreState_STARTING)
path := C.GoString(configPath)
activeConfigPath = &path
libbox.SetMemoryLimit(!disableMemoryLimit)
err := startService(false)
if err != nil {
return C.CString(err.Error())
}
return C.CString("")
}
func startService(delayStart bool) error {
content, err := os.ReadFile(*activeConfigPath)
if err != nil {
return stopAndAlert(EmptyConfiguration, err)
}
options, err := parseConfig(string(content))
if err != nil {
return stopAndAlert(EmptyConfiguration, err)
}
os.Chdir(filepath.Dir(*activeConfigPath))
var patchedOptions *option.Options
patchedOptions, err = config.BuildConfig(*configOptions, options)
if err != nil {
return stopAndAlert("Error Building Config", err)
}
config.SaveCurrentConfig(filepath.Join(sWorkingPath, "current-config.json"), *patchedOptions)
err = startCommandServer(*logFactory)
if err != nil {
return stopAndAlert(StartCommandServer, err)
}
instance, err := NewService(*patchedOptions)
if err != nil {
return stopAndAlert(CreateService, err)
}
if delayStart {
time.Sleep(250 * time.Millisecond)
}
err = instance.Start()
if err != nil {
return stopAndAlert(StartService, err)
}
v2.Box = instance
commandServer.SetService(v2.Box)
propagateStatus(pb.CoreState_STARTED)
return nil
} }
//export stop //export stop
func stop() (CErr *C.char) { func stop() (CErr *C.char) {
defer config.DeferPanicToError("stop", func(err error) {
stopAndAlert("Unexpected Error in Stop!", err)
CErr = C.CString(err.Error())
})
if v2.CoreState != pb.CoreState_STARTED { _, err := v2.Stop()
stopAndAlert("Already Stopped", nil) return emptyOrErrorC(err)
return C.CString("")
}
if v2.Box == nil {
return C.CString("instance not found")
}
propagateStatus(pb.CoreState_STOPPING)
config.DeactivateTunnelService()
commandServer.SetService(nil)
err := v2.Box.Close()
if err != nil {
stopAndAlert("Unexpected Error in Close!", err)
return C.CString(err.Error())
}
v2.Box = nil
err = commandServer.Close()
if err != nil {
stopAndAlert("Unexpected Error in Stop CommandServer/!", err)
return C.CString(err.Error())
}
commandServer = nil
propagateStatus(pb.CoreState_STOPPED)
return C.CString("")
} }
//export restart //export restart
func restart(configPath *C.char, disableMemoryLimit bool) (CErr *C.char) { func restart(configPath *C.char, disableMemoryLimit bool) (CErr *C.char) {
defer config.DeferPanicToError("restart", func(err error) {
stopAndAlert("Unexpected Error!", err) _, err := v2.Restart(&pb.StartRequest{
CErr = C.CString(err.Error()) ConfigPath: C.GoString(configPath),
EnableOldCommandServer: true,
DisableMemoryLimit: disableMemoryLimit,
}) })
log.Debug("[Service] Restarting") return emptyOrErrorC(err)
if v2.CoreState != pb.CoreState_STARTED {
return C.CString("")
}
if v2.Box == nil {
return C.CString("instance not found")
}
err := stop()
if C.GoString(err) != "" {
return err
}
propagateStatus(pb.CoreState_STARTING)
time.Sleep(250 * time.Millisecond)
path := C.GoString(configPath)
activeConfigPath = &path
libbox.SetMemoryLimit(!disableMemoryLimit)
gErr := startService(false)
if gErr != nil {
return C.CString(gErr.Error())
}
return C.CString("")
} }
//export startCommandClient //export startCommandClient
func startCommandClient(command C.int, port C.longlong) *C.char { func startCommandClient(command C.int, port C.longlong) *C.char {
err := StartCommand(int32(command), int64(port), *logFactory) err := v2.StartCommand(int32(command), int64(port))
if err != nil { return emptyOrErrorC(err)
return C.CString(err.Error())
}
return C.CString("")
} }
//export stopCommandClient //export stopCommandClient
func stopCommandClient(command C.int) *C.char { func stopCommandClient(command C.int) *C.char {
err := StopCommand(int32(command)) err := v2.StopCommand(int32(command))
if err != nil { return emptyOrErrorC(err)
return C.CString(err.Error())
}
return C.CString("")
} }
//export selectOutbound //export selectOutbound
func selectOutbound(groupTag *C.char, outboundTag *C.char) (CErr *C.char) { func selectOutbound(groupTag *C.char, outboundTag *C.char) (CErr *C.char) {
defer config.DeferPanicToError("selectOutbound", func(err error) {
CErr = C.CString(err.Error()) _, err := v2.SelectOutbound(&pb.SelectOutboundRequest{
GroupTag: C.GoString(groupTag),
OutboundTag: C.GoString(outboundTag),
}) })
err := libbox.NewStandaloneCommandClient().SelectOutbound(C.GoString(groupTag), C.GoString(outboundTag)) return emptyOrErrorC(err)
if err != nil {
return C.CString(err.Error())
}
return C.CString("")
} }
//export urlTest //export urlTest
func urlTest(groupTag *C.char) (CErr *C.char) { func urlTest(groupTag *C.char) (CErr *C.char) {
defer config.DeferPanicToError("urlTest", func(err error) { _, err := v2.UrlTest(&pb.UrlTestRequest{
CErr = C.CString(err.Error()) GroupTag: C.GoString(groupTag),
}) })
err := libbox.NewStandaloneCommandClient().URLTest(C.GoString(groupTag)) return emptyOrErrorC(err)
if err != nil { }
return C.CString(err.Error())
func emptyOrErrorC(err error) *C.char {
if err == nil {
return C.CString("")
} }
return C.CString("") log.Error(err.Error())
return C.CString(err.Error())
} }
//export generateWarpConfig //export generateWarpConfig
func generateWarpConfig(licenseKey *C.char, accountId *C.char, accessToken *C.char) (CResp *C.char) { func generateWarpConfig(licenseKey *C.char, accountId *C.char, accessToken *C.char) (CResp *C.char) {
defer config.DeferPanicToError("generateWarpConfig", func(err error) { res, err := v2.GenerateWarpConfig(&pb.GenerateWarpConfigRequest{
CResp = C.CString(fmt.Sprint("error: ", err.Error())) LicenseKey: C.GoString(licenseKey),
AccountId: C.GoString(accountId),
AccessToken: C.GoString(accessToken),
}) })
account, err := config.GenerateWarpAccount(C.GoString(licenseKey), C.GoString(accountId), C.GoString(accessToken))
if err != nil { if err != nil {
return C.CString(fmt.Sprint("error: ", err.Error())) return C.CString(fmt.Sprint("error: ", err.Error()))
} }
return C.CString(account) warpAccount := config.WarpAccount{
AccountID: res.Account.AccountId,
AccessToken: res.Account.AccessToken,
}
warpConfig := config.WarpWireguardConfig{
PrivateKey: res.Config.PrivateKey,
LocalAddressIPv4: res.Config.LocalAddressIpv4,
LocalAddressIPv6: res.Config.LocalAddressIpv6,
PeerPublicKey: res.Config.PeerPublicKey,
}
log := res.Log
response := &config.WarpGenerationResponse{
WarpAccount: warpAccount,
Log: log,
Config: warpConfig,
}
responseJson, err := json.Marshal(response)
if err != nil {
return C.CString("")
}
return C.CString(string(responseJson))
} }
func main() {} func main() {}

10
custom/grpc_interface.go Normal file
View File

@@ -0,0 +1,10 @@
package main
import "C"
import v2 "github.com/hiddify/libcore/v2"
//export StartCoreGrpcServer
func StartCoreGrpcServer(listenAddress *C.char) (CErr *C.char) {
err := v2.StartCoreGrpcServer(C.GoString(listenAddress))
return emptyOrErrorC(err)
}

View File

@@ -1,68 +0,0 @@
package main
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
}

View File

@@ -1,69 +0,0 @@
package main
import "C"
import (
"encoding/json"
"fmt"
"github.com/hiddify/libcore/bridge"
"github.com/hiddify/libcore/config"
pb "github.com/hiddify/libcore/hiddifyrpc"
v2 "github.com/hiddify/libcore/v2"
)
var statusPropagationPort int64
// var status = Stopped
type StatusMessage struct {
Status string `json:"status"`
Alert *string `json:"alert"`
Message *string `json:"message"`
}
func propagateStatus(newStatus pb.CoreState) {
v2.CoreState = newStatus
msg, _ := json.Marshal(StatusMessage{Status: convert2OldState(v2.CoreState)})
bridge.SendStringToPort(statusPropagationPort, string(msg))
}
func convert2OldState(newStatus pb.CoreState) string {
if newStatus == pb.CoreState_STOPPED {
return Stopped
}
if newStatus == pb.CoreState_STARTED {
return Started
}
if newStatus == pb.CoreState_STARTING {
return Starting
}
if newStatus == pb.CoreState_STOPPING {
return Stopping
}
return "Invalid"
}
func stopAndAlert(alert string, err error) (resultErr error) {
defer config.DeferPanicToError("stopAndAlert", func(err error) {
resultErr = err
})
v2.CoreState = pb.CoreState_STOPPED
message := err.Error()
fmt.Printf("Error: %s: %s\n", alert, message)
msg, _ := json.Marshal(StatusMessage{Status: convert2OldState(v2.CoreState), Alert: &alert, Message: &message})
bridge.SendStringToPort(statusPropagationPort, string(msg))
go config.DeactivateTunnelService()
if commandServer != nil {
commandServer.SetService(nil)
}
if v2.Box != nil {
v2.Box.Close()
v2.Box = nil
}
if commandServer != nil {
commandServer.Close()
}
return nil
}

View File

@@ -1,6 +1,6 @@
FROM alpine:latest FROM alpine:latest
ENV CONFIG='https://raw.githubusercontent.com/ircfspace/warpsub/main/export/warp#WARP%20(IRCF)' ENV CONFIG='https://raw.githubusercontent.com/ircfspace/warpsub/main/export/warp#WARP%20(IRCF)'
ENV VERSION=v0.17.8 ENV VERSION=v0.17.9.dev
WORKDIR /hiddify WORKDIR /hiddify
RUN apk add curl tar gzip libc6-compat # iptables ip6tables RUN apk add curl tar gzip libc6-compat # iptables ip6tables

View File

@@ -199,6 +199,34 @@ func (LogType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_b52c484803f63ee3, []int{4} return fileDescriptor_b52c484803f63ee3, []int{4}
} }
type StackType int32
const (
StackType_SYSTEM StackType = 0
StackType_GVISOR StackType = 1
StackType_MIXED StackType = 2
)
var StackType_name = map[int32]string{
0: "SYSTEM",
1: "GVISOR",
2: "MIXED",
}
var StackType_value = map[string]int32{
"SYSTEM": 0,
"GVISOR": 1,
"MIXED": 2,
}
func (x StackType) String() string {
return proto.EnumName(StackType_name, int32(x))
}
func (StackType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_b52c484803f63ee3, []int{5}
}
type CoreInfoResponse struct { type CoreInfoResponse struct {
CoreState CoreState `protobuf:"varint,1,opt,name=core_state,json=coreState,proto3,enum=hiddifyrpc.CoreState" json:"core_state,omitempty"` CoreState CoreState `protobuf:"varint,1,opt,name=core_state,json=coreState,proto3,enum=hiddifyrpc.CoreState" json:"core_state,omitempty"`
MessageType MessageType `protobuf:"varint,2,opt,name=message_type,json=messageType,proto3,enum=hiddifyrpc.MessageType" json:"message_type,omitempty"` MessageType MessageType `protobuf:"varint,2,opt,name=message_type,json=messageType,proto3,enum=hiddifyrpc.MessageType" json:"message_type,omitempty"`
@@ -255,13 +283,14 @@ func (m *CoreInfoResponse) GetMessage() string {
} }
type StartRequest struct { type StartRequest struct {
ConfigPath string `protobuf:"bytes,1,opt,name=config_path,json=configPath,proto3" json:"config_path,omitempty"` ConfigPath string `protobuf:"bytes,1,opt,name=config_path,json=configPath,proto3" json:"config_path,omitempty"`
ConfigContent string `protobuf:"bytes,2,opt,name=config_content,json=configContent,proto3" json:"config_content,omitempty"` ConfigContent string `protobuf:"bytes,2,opt,name=config_content,json=configContent,proto3" json:"config_content,omitempty"`
DisableMemoryLimit bool `protobuf:"varint,3,opt,name=disable_memory_limit,json=disableMemoryLimit,proto3" json:"disable_memory_limit,omitempty"` DisableMemoryLimit bool `protobuf:"varint,3,opt,name=disable_memory_limit,json=disableMemoryLimit,proto3" json:"disable_memory_limit,omitempty"`
DelayStart bool `protobuf:"varint,4,opt,name=delay_start,json=delayStart,proto3" json:"delay_start,omitempty"` DelayStart bool `protobuf:"varint,4,opt,name=delay_start,json=delayStart,proto3" json:"delay_start,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` EnableOldCommandServer bool `protobuf:"varint,5,opt,name=enable_old_command_server,json=enableOldCommandServer,proto3" json:"enable_old_command_server,omitempty"`
XXX_unrecognized []byte `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *StartRequest) Reset() { *m = StartRequest{} } func (m *StartRequest) Reset() { *m = StartRequest{} }
@@ -317,6 +346,13 @@ func (m *StartRequest) GetDelayStart() bool {
return false return false
} }
func (m *StartRequest) GetEnableOldCommandServer() bool {
if m != nil {
return m.EnableOldCommandServer
}
return false
}
type SetupRequest struct { type SetupRequest struct {
BasePath string `protobuf:"bytes,1,opt,name=base_path,json=basePath,proto3" json:"base_path,omitempty"` BasePath string `protobuf:"bytes,1,opt,name=base_path,json=basePath,proto3" json:"base_path,omitempty"`
WorkingPath string `protobuf:"bytes,2,opt,name=working_path,json=workingPath,proto3" json:"working_path,omitempty"` WorkingPath string `protobuf:"bytes,2,opt,name=working_path,json=workingPath,proto3" json:"working_path,omitempty"`
@@ -1010,7 +1046,9 @@ func (m *SystemProxyStatus) GetEnabled() bool {
type ParseRequest struct { type ParseRequest struct {
Content string `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` Content string `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"`
Debug bool `protobuf:"varint,2,opt,name=debug,proto3" json:"debug,omitempty"` ConfigPath string `protobuf:"bytes,2,opt,name=config_path,json=configPath,proto3" json:"config_path,omitempty"`
TempPath string `protobuf:"bytes,3,opt,name=temp_path,json=tempPath,proto3" json:"temp_path,omitempty"`
Debug bool `protobuf:"varint,4,opt,name=debug,proto3" json:"debug,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@@ -1048,6 +1086,20 @@ func (m *ParseRequest) GetContent() string {
return "" return ""
} }
func (m *ParseRequest) GetConfigPath() string {
if m != nil {
return m.ConfigPath
}
return ""
}
func (m *ParseRequest) GetTempPath() string {
if m != nil {
return m.TempPath
}
return ""
}
func (m *ParseRequest) GetDebug() bool { func (m *ParseRequest) GetDebug() bool {
if m != nil { if m != nil {
return m.Debug return m.Debug
@@ -1509,12 +1561,123 @@ func (m *StopRequest) XXX_DiscardUnknown() {
var xxx_messageInfo_StopRequest proto.InternalMessageInfo var xxx_messageInfo_StopRequest proto.InternalMessageInfo
type TunnelStartRequest struct {
Ipv6 bool `protobuf:"varint,1,opt,name=ipv6,proto3" json:"ipv6,omitempty"`
ServerPort int32 `protobuf:"varint,2,opt,name=server_port,json=serverPort,proto3" json:"server_port,omitempty"`
StrictRoute bool `protobuf:"varint,3,opt,name=strict_route,json=strictRoute,proto3" json:"strict_route,omitempty"`
EndpointIndependentNat bool `protobuf:"varint,4,opt,name=endpoint_independent_nat,json=endpointIndependentNat,proto3" json:"endpoint_independent_nat,omitempty"`
Stack StackType `protobuf:"varint,5,opt,name=stack,proto3,enum=hiddifyrpc.StackType" json:"stack,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *TunnelStartRequest) Reset() { *m = TunnelStartRequest{} }
func (m *TunnelStartRequest) String() string { return proto.CompactTextString(m) }
func (*TunnelStartRequest) ProtoMessage() {}
func (*TunnelStartRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_b52c484803f63ee3, []int{26}
}
func (m *TunnelStartRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_TunnelStartRequest.Unmarshal(m, b)
}
func (m *TunnelStartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_TunnelStartRequest.Marshal(b, m, deterministic)
}
func (m *TunnelStartRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_TunnelStartRequest.Merge(m, src)
}
func (m *TunnelStartRequest) XXX_Size() int {
return xxx_messageInfo_TunnelStartRequest.Size(m)
}
func (m *TunnelStartRequest) XXX_DiscardUnknown() {
xxx_messageInfo_TunnelStartRequest.DiscardUnknown(m)
}
var xxx_messageInfo_TunnelStartRequest proto.InternalMessageInfo
func (m *TunnelStartRequest) GetIpv6() bool {
if m != nil {
return m.Ipv6
}
return false
}
func (m *TunnelStartRequest) GetServerPort() int32 {
if m != nil {
return m.ServerPort
}
return 0
}
func (m *TunnelStartRequest) GetStrictRoute() bool {
if m != nil {
return m.StrictRoute
}
return false
}
func (m *TunnelStartRequest) GetEndpointIndependentNat() bool {
if m != nil {
return m.EndpointIndependentNat
}
return false
}
func (m *TunnelStartRequest) GetStack() StackType {
if m != nil {
return m.Stack
}
return StackType_SYSTEM
}
type TunnelResponse struct {
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *TunnelResponse) Reset() { *m = TunnelResponse{} }
func (m *TunnelResponse) String() string { return proto.CompactTextString(m) }
func (*TunnelResponse) ProtoMessage() {}
func (*TunnelResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_b52c484803f63ee3, []int{27}
}
func (m *TunnelResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_TunnelResponse.Unmarshal(m, b)
}
func (m *TunnelResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_TunnelResponse.Marshal(b, m, deterministic)
}
func (m *TunnelResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_TunnelResponse.Merge(m, src)
}
func (m *TunnelResponse) XXX_Size() int {
return xxx_messageInfo_TunnelResponse.Size(m)
}
func (m *TunnelResponse) XXX_DiscardUnknown() {
xxx_messageInfo_TunnelResponse.DiscardUnknown(m)
}
var xxx_messageInfo_TunnelResponse proto.InternalMessageInfo
func (m *TunnelResponse) GetMessage() string {
if m != nil {
return m.Message
}
return ""
}
func init() { func init() {
proto.RegisterEnum("hiddifyrpc.ResponseCode", ResponseCode_name, ResponseCode_value) proto.RegisterEnum("hiddifyrpc.ResponseCode", ResponseCode_name, ResponseCode_value)
proto.RegisterEnum("hiddifyrpc.CoreState", CoreState_name, CoreState_value) proto.RegisterEnum("hiddifyrpc.CoreState", CoreState_name, CoreState_value)
proto.RegisterEnum("hiddifyrpc.MessageType", MessageType_name, MessageType_value) proto.RegisterEnum("hiddifyrpc.MessageType", MessageType_name, MessageType_value)
proto.RegisterEnum("hiddifyrpc.LogLevel", LogLevel_name, LogLevel_value) proto.RegisterEnum("hiddifyrpc.LogLevel", LogLevel_name, LogLevel_value)
proto.RegisterEnum("hiddifyrpc.LogType", LogType_name, LogType_value) proto.RegisterEnum("hiddifyrpc.LogType", LogType_name, LogType_value)
proto.RegisterEnum("hiddifyrpc.StackType", StackType_name, StackType_value)
proto.RegisterType((*CoreInfoResponse)(nil), "hiddifyrpc.CoreInfoResponse") proto.RegisterType((*CoreInfoResponse)(nil), "hiddifyrpc.CoreInfoResponse")
proto.RegisterType((*StartRequest)(nil), "hiddifyrpc.StartRequest") proto.RegisterType((*StartRequest)(nil), "hiddifyrpc.StartRequest")
proto.RegisterType((*SetupRequest)(nil), "hiddifyrpc.SetupRequest") proto.RegisterType((*SetupRequest)(nil), "hiddifyrpc.SetupRequest")
@@ -1541,122 +1704,139 @@ func init() {
proto.RegisterType((*SetSystemProxyEnabledRequest)(nil), "hiddifyrpc.SetSystemProxyEnabledRequest") proto.RegisterType((*SetSystemProxyEnabledRequest)(nil), "hiddifyrpc.SetSystemProxyEnabledRequest")
proto.RegisterType((*LogMessage)(nil), "hiddifyrpc.LogMessage") proto.RegisterType((*LogMessage)(nil), "hiddifyrpc.LogMessage")
proto.RegisterType((*StopRequest)(nil), "hiddifyrpc.StopRequest") proto.RegisterType((*StopRequest)(nil), "hiddifyrpc.StopRequest")
proto.RegisterType((*TunnelStartRequest)(nil), "hiddifyrpc.TunnelStartRequest")
proto.RegisterType((*TunnelResponse)(nil), "hiddifyrpc.TunnelResponse")
} }
func init() { proto.RegisterFile("hiddifyrpc/hiddify.proto", fileDescriptor_b52c484803f63ee3) } func init() { proto.RegisterFile("hiddifyrpc/hiddify.proto", fileDescriptor_b52c484803f63ee3) }
var fileDescriptor_b52c484803f63ee3 = []byte{ var fileDescriptor_b52c484803f63ee3 = []byte{
// 1783 bytes of a gzipped FileDescriptorProto // 2025 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x18, 0x5d, 0x73, 0xe3, 0x56, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xdd, 0x72, 0xdb, 0xc6,
0x35, 0xb2, 0xe3, 0xd8, 0x3e, 0xb6, 0xb3, 0xca, 0x4d, 0x36, 0xeb, 0x4d, 0x77, 0xd9, 0xad, 0x86, 0x15, 0x36, 0x28, 0x52, 0x24, 0x0f, 0x49, 0x19, 0x5a, 0xc9, 0x32, 0xad, 0xd8, 0xb5, 0x83, 0x69,
0xd2, 0x10, 0x4a, 0xb6, 0xa4, 0x3b, 0xdd, 0x19, 0xa0, 0xec, 0x28, 0xb6, 0x92, 0x35, 0x71, 0x6c, 0x12, 0x55, 0x4d, 0xe5, 0x54, 0x71, 0xe3, 0xfe, 0x79, 0x3c, 0x14, 0x09, 0x29, 0xac, 0x28, 0x92,
0x8f, 0xac, 0xb0, 0x94, 0x07, 0x34, 0x8a, 0x7c, 0xe3, 0x15, 0x91, 0x75, 0x85, 0x74, 0x9d, 0xe2, 0x03, 0x40, 0x71, 0xdc, 0xce, 0x14, 0x03, 0x01, 0x2b, 0x1a, 0x15, 0x88, 0x45, 0x81, 0xa5, 0x12,
0x61, 0x86, 0x07, 0x98, 0xe1, 0x17, 0x30, 0x3c, 0xf2, 0xce, 0x5f, 0xe0, 0x85, 0x5f, 0xc0, 0x7f, 0x4e, 0x3b, 0xbd, 0x68, 0x67, 0xfa, 0x02, 0x9d, 0xe9, 0x65, 0x1f, 0xa4, 0x37, 0x7d, 0x82, 0x5e,
0x62, 0xee, 0x97, 0x2d, 0x39, 0x76, 0xb7, 0xd3, 0xf6, 0xed, 0xde, 0xf3, 0xa5, 0xf3, 0x7d, 0xce, 0xf5, 0x0d, 0x3a, 0x7d, 0x85, 0xde, 0x77, 0xf6, 0x07, 0x24, 0x40, 0x91, 0x56, 0x9a, 0xe4, 0x6e,
0x15, 0x34, 0xdf, 0x05, 0xa3, 0x51, 0x70, 0x33, 0x4b, 0x62, 0xff, 0x85, 0x3c, 0x1e, 0xc7, 0x09, 0xf7, 0x9c, 0xb3, 0x07, 0xe7, 0x7f, 0xbf, 0x05, 0x34, 0xdf, 0xf8, 0x9e, 0xe7, 0x5f, 0x4e, 0xe3,
0xa1, 0x04, 0xc1, 0x02, 0x63, 0xfc, 0x4b, 0x03, 0xbd, 0x45, 0x12, 0xdc, 0x89, 0x6e, 0x88, 0x8d, 0xc8, 0x7d, 0x2a, 0x97, 0x07, 0x51, 0x4c, 0x28, 0x41, 0x30, 0xe7, 0x68, 0x7f, 0x53, 0x40, 0x6d,
0xd3, 0x98, 0x44, 0x29, 0x46, 0x2f, 0x01, 0x7c, 0x92, 0x60, 0x37, 0xa5, 0x1e, 0xc5, 0x4d, 0xed, 0x93, 0x18, 0x77, 0xc3, 0x4b, 0x62, 0xe0, 0x24, 0x22, 0x61, 0x82, 0xd1, 0x33, 0x00, 0x97, 0xc4,
0xb9, 0x76, 0xb8, 0x7d, 0xf2, 0xf0, 0x78, 0xc1, 0x75, 0xcc, 0x38, 0x86, 0x0c, 0x69, 0x57, 0x7d, 0xd8, 0x4e, 0xa8, 0x43, 0x71, 0x53, 0x79, 0xa2, 0xec, 0x6d, 0x1c, 0xde, 0x3b, 0x98, 0x9f, 0x3a,
0x75, 0x44, 0x3f, 0x87, 0xfa, 0x04, 0xa7, 0xa9, 0x37, 0xc6, 0x2e, 0x9d, 0xc5, 0xb8, 0x59, 0xe0, 0x60, 0x27, 0x4c, 0xc6, 0x34, 0xaa, 0x6e, 0xba, 0x44, 0x3f, 0x85, 0xfa, 0x18, 0x27, 0x89, 0x33,
0x7c, 0x8f, 0xb2, 0x7c, 0x97, 0x02, 0xef, 0xcc, 0x62, 0x6c, 0xd7, 0x26, 0x8b, 0x0b, 0x6a, 0x42, 0xc2, 0x36, 0x9d, 0x46, 0xb8, 0x59, 0xe0, 0xe7, 0xee, 0x67, 0xcf, 0x9d, 0x09, 0xbe, 0x35, 0x8d,
0x59, 0x5e, 0x9b, 0xc5, 0xe7, 0xda, 0x61, 0xd5, 0x56, 0x57, 0xe3, 0xdf, 0x1a, 0xd4, 0x87, 0xd4, 0xb0, 0x51, 0x1b, 0xcf, 0x37, 0xa8, 0x09, 0x65, 0xb9, 0x6d, 0xae, 0x3d, 0x51, 0xf6, 0xaa, 0x46,
0x4b, 0xa8, 0x8d, 0xff, 0x38, 0xc5, 0x29, 0x45, 0xcf, 0xa0, 0xe6, 0x93, 0xe8, 0x26, 0x18, 0xbb, 0xba, 0xd5, 0xfe, 0xa3, 0x40, 0xdd, 0xa4, 0x4e, 0x4c, 0x0d, 0xfc, 0xdb, 0x09, 0x4e, 0x28, 0x7a,
0xb1, 0x47, 0xdf, 0x71, 0xed, 0xaa, 0x36, 0x08, 0xd0, 0xc0, 0xa3, 0xef, 0xd0, 0x47, 0xb0, 0x2d, 0x0c, 0x35, 0x97, 0x84, 0x97, 0xfe, 0xc8, 0x8e, 0x1c, 0xfa, 0x86, 0x5b, 0x57, 0x35, 0x40, 0x90,
0x09, 0x7c, 0x12, 0x51, 0x1c, 0x51, 0xae, 0x49, 0xd5, 0x6e, 0x08, 0x68, 0x4b, 0x00, 0xd1, 0xa7, 0x86, 0x0e, 0x7d, 0x83, 0xde, 0x83, 0x0d, 0x29, 0xe0, 0x92, 0x90, 0xe2, 0x90, 0x72, 0x4b, 0xaa,
0xb0, 0x37, 0x0a, 0x52, 0xef, 0x3a, 0xc4, 0xee, 0x04, 0x4f, 0x48, 0x32, 0x73, 0xc3, 0x60, 0x12, 0x46, 0x43, 0x50, 0xdb, 0x82, 0x88, 0x3e, 0x82, 0x6d, 0xcf, 0x4f, 0x9c, 0x8b, 0x00, 0xdb, 0x63,
0x50, 0xfe, 0xfd, 0x8a, 0x8d, 0x24, 0xee, 0x92, 0xa3, 0xba, 0x0c, 0xc3, 0xbe, 0x3c, 0xc2, 0xa1, 0x3c, 0x26, 0xf1, 0xd4, 0x0e, 0xfc, 0xb1, 0x4f, 0xf9, 0xf7, 0x2b, 0x06, 0x92, 0xbc, 0x33, 0xce,
0x37, 0x63, 0x7e, 0x49, 0x68, 0x73, 0x93, 0x13, 0x02, 0x07, 0x71, 0x0d, 0x8d, 0x5b, 0xa8, 0x0f, 0xea, 0x31, 0x0e, 0xfb, 0xb2, 0x87, 0x03, 0x67, 0xca, 0xe2, 0x12, 0xd3, 0x66, 0x91, 0x0b, 0x02,
0x31, 0x9d, 0xc6, 0x4a, 0xd5, 0x0f, 0xa0, 0x7a, 0xed, 0xa5, 0x38, 0xab, 0x68, 0x85, 0x01, 0xb8, 0x27, 0x71, 0x0b, 0xd1, 0x4f, 0xe0, 0x01, 0x0e, 0xb9, 0x46, 0x12, 0x78, 0xb6, 0x4b, 0xc6, 0x63,
0x9a, 0x1f, 0x42, 0xfd, 0x2b, 0x92, 0xdc, 0x06, 0x91, 0x34, 0x44, 0x28, 0x59, 0x93, 0x30, 0x4e, 0x27, 0xf4, 0xec, 0x04, 0xc7, 0xd7, 0x38, 0x6e, 0x96, 0xb8, 0xf8, 0x8e, 0x10, 0x18, 0x04, 0x5e,
0xf2, 0x01, 0x54, 0x29, 0x9e, 0xc4, 0x02, 0x2f, 0xfc, 0x52, 0x61, 0x00, 0x86, 0x34, 0x7c, 0xa8, 0x5b, 0xb0, 0x4d, 0xce, 0xd5, 0xae, 0xa0, 0x6e, 0x62, 0x3a, 0x89, 0x52, 0x2f, 0xdf, 0x81, 0xea,
0xcc, 0x03, 0xf6, 0x05, 0x34, 0x12, 0x79, 0x76, 0x7d, 0x32, 0x52, 0x31, 0x6b, 0x66, 0x7d, 0xaf, 0x85, 0x93, 0xe0, 0xac, 0x8f, 0x15, 0x46, 0xe0, 0x1e, 0xbe, 0x0b, 0xf5, 0x2f, 0x48, 0x7c, 0xe5,
0x88, 0x5b, 0x64, 0x84, 0xed, 0x7a, 0x92, 0xb9, 0x65, 0xbd, 0x5f, 0xc8, 0x7b, 0xdf, 0x80, 0xfa, 0x87, 0x32, 0x06, 0xc2, 0xbf, 0x9a, 0xa4, 0x71, 0x91, 0x77, 0xa0, 0x4a, 0xf1, 0x38, 0x12, 0x7c,
0x1b, 0x1c, 0x86, 0x44, 0x59, 0x84, 0x60, 0x33, 0xf2, 0x26, 0x58, 0x1a, 0xc3, 0xcf, 0xc6, 0x8f, 0x11, 0xd2, 0x0a, 0x23, 0x30, 0xa6, 0xe6, 0x42, 0x65, 0x96, 0xeb, 0x17, 0xd0, 0x88, 0xe5, 0xda,
0xa1, 0x21, 0x69, 0xa4, 0x36, 0x19, 0x71, 0x5a, 0x5e, 0x5c, 0x19, 0x4a, 0xd6, 0x24, 0xa6, 0x33, 0x76, 0x89, 0x97, 0xa6, 0xbb, 0x99, 0x4d, 0x5b, 0x2a, 0xdc, 0x26, 0x1e, 0x36, 0xea, 0x71, 0x66,
0xe3, 0xbf, 0x05, 0x80, 0xe1, 0x2c, 0xa5, 0x78, 0xc2, 0x12, 0x0f, 0xed, 0xc3, 0x96, 0x88, 0x01, 0x97, 0x4d, 0x5c, 0x21, 0x9f, 0x38, 0x0d, 0xea, 0x9f, 0xe2, 0x20, 0x20, 0xa9, 0x47, 0x08, 0x8a,
0x67, 0x28, 0xda, 0xf2, 0x86, 0x7e, 0x00, 0x30, 0x26, 0x09, 0x99, 0xd2, 0x20, 0xc2, 0x29, 0xd7, 0xa1, 0x33, 0xc6, 0xd2, 0x19, 0xbe, 0xd6, 0xbe, 0x07, 0x0d, 0x29, 0x23, 0xad, 0xc9, 0xa8, 0x53,
0xad, 0x64, 0x67, 0x20, 0x32, 0xd4, 0x11, 0xf6, 0x69, 0x40, 0xa2, 0xd4, 0x0d, 0x22, 0xee, 0xa5, 0xf2, 0xea, 0xca, 0x50, 0xd2, 0xc7, 0x11, 0x9d, 0x6a, 0xff, 0x28, 0x00, 0x98, 0xd3, 0x84, 0xe2,
0x12, 0x0f, 0xb5, 0x82, 0x76, 0x22, 0xf4, 0x31, 0x3c, 0xc8, 0x92, 0x91, 0xa9, 0x08, 0x5e, 0xc9, 0x31, 0xab, 0x59, 0xb4, 0x03, 0xeb, 0x22, 0x7d, 0xfc, 0xc0, 0x9a, 0x21, 0x77, 0xe8, 0x3b, 0x00,
0xce, 0x72, 0xf7, 0xa7, 0x14, 0xfd, 0x04, 0x76, 0x68, 0xe2, 0xdd, 0xdc, 0x04, 0xbe, 0xeb, 0xdd, 0x23, 0x12, 0x93, 0x09, 0xf5, 0x43, 0x9c, 0x70, 0xdb, 0x4a, 0x46, 0x86, 0x22, 0xab, 0x24, 0xc4,
0x79, 0x41, 0xc8, 0x32, 0xa0, 0x59, 0xe2, 0x71, 0xd6, 0x25, 0xc2, 0x54, 0x70, 0xa6, 0xf4, 0x34, 0x2e, 0xf5, 0x49, 0x98, 0xd8, 0x7e, 0xc8, 0xa3, 0x54, 0xe2, 0x55, 0x92, 0x52, 0xbb, 0x21, 0xfa,
0x0e, 0x83, 0xe8, 0xb6, 0xb9, 0x25, 0x94, 0x16, 0x37, 0x74, 0x00, 0x95, 0x11, 0xf9, 0x2a, 0xe2, 0x00, 0xee, 0x66, 0xc5, 0xc8, 0x44, 0xe4, 0xbd, 0x64, 0x64, 0x4f, 0x0f, 0x26, 0x14, 0x7d, 0x1f,
0x98, 0x32, 0xc7, 0xcc, 0xef, 0x2c, 0xe8, 0x82, 0xca, 0xa5, 0x84, 0x7a, 0x61, 0xb3, 0xc2, 0xf1, 0x36, 0x69, 0xec, 0x5c, 0x5e, 0xfa, 0xae, 0xed, 0x5c, 0x3b, 0x7e, 0xc0, 0xb2, 0x2c, 0x73, 0xae,
0x35, 0x01, 0x73, 0x18, 0x88, 0xd9, 0xa4, 0xc8, 0x25, 0x51, 0x95, 0x13, 0x35, 0x14, 0x94, 0x93, 0x4a, 0x46, 0x2b, 0xa5, 0x33, 0xa3, 0x27, 0x51, 0xe0, 0x87, 0x57, 0xcd, 0x75, 0x61, 0xb4, 0xd8,
0x19, 0x7f, 0xd3, 0x60, 0xa7, 0x3f, 0xa5, 0xd7, 0x64, 0x1a, 0x8d, 0xce, 0x13, 0x32, 0x8d, 0x3b, 0xa1, 0x5d, 0xa8, 0x78, 0xe4, 0x8b, 0x90, 0x73, 0xca, 0x9c, 0x33, 0xdb, 0xb3, 0xa4, 0x0b, 0x29,
0x14, 0x4f, 0x90, 0x0e, 0x45, 0xea, 0x8d, 0xa5, 0xdb, 0xd9, 0x91, 0x45, 0x6c, 0x5e, 0x8d, 0x55, 0x9b, 0x12, 0xea, 0x04, 0xcd, 0x0a, 0xe7, 0xd7, 0x04, 0xcd, 0x62, 0x24, 0xe6, 0x53, 0x2a, 0x2e,
0x9b, 0x9f, 0x91, 0x01, 0x8d, 0x69, 0x12, 0xba, 0x14, 0xa7, 0xd4, 0xa5, 0xc1, 0x44, 0xd4, 0x1c, 0x85, 0xaa, 0x5c, 0xa8, 0x91, 0x52, 0xb9, 0x98, 0xf6, 0x27, 0x05, 0x36, 0x07, 0x13, 0x7a, 0x41,
0x53, 0x23, 0x09, 0x1d, 0x9c, 0x52, 0x27, 0x98, 0x60, 0xf4, 0x43, 0xd8, 0x9e, 0xd3, 0xf0, 0x14, 0x26, 0xa1, 0x77, 0x12, 0x93, 0x49, 0xd4, 0xa5, 0x78, 0x8c, 0x54, 0x58, 0xa3, 0xce, 0x48, 0x86,
0x97, 0x2e, 0xab, 0x4b, 0xa2, 0x36, 0x83, 0x19, 0x7f, 0xd7, 0xa0, 0x91, 0xd3, 0xe2, 0x1b, 0x6a, 0x9d, 0x2d, 0x59, 0xc6, 0x66, 0x8d, 0x5c, 0x35, 0xf8, 0x1a, 0x69, 0xd0, 0x98, 0xc4, 0x81, 0x4d,
0x70, 0x00, 0x95, 0x14, 0x87, 0xd8, 0xa7, 0x78, 0xa4, 0x12, 0x5b, 0xdd, 0xd1, 0x67, 0x50, 0x0a, 0x71, 0x42, 0x6d, 0xea, 0x8f, 0x45, 0xbb, 0x32, 0x33, 0xe2, 0xc0, 0xc2, 0x09, 0xb5, 0xfc, 0x31,
0x28, 0x9e, 0xa4, 0xcd, 0xcd, 0xe7, 0xc5, 0xc3, 0xda, 0xc9, 0xd3, 0x6c, 0x12, 0xdf, 0xb3, 0xd8, 0x46, 0xdf, 0x85, 0x8d, 0x99, 0x0c, 0xef, 0x0e, 0x19, 0xb2, 0xba, 0x14, 0xea, 0x30, 0x9a, 0xf6,
0x16, 0xb4, 0x46, 0x7b, 0xc9, 0x1b, 0xdd, 0x20, 0xa5, 0xe8, 0x85, 0x92, 0xa4, 0x71, 0x49, 0x8f, 0x67, 0x05, 0x1a, 0x39, 0x2b, 0xbe, 0xa2, 0x05, 0xbb, 0x50, 0x49, 0x70, 0x80, 0x5d, 0x8a, 0xbd,
0xd7, 0x4a, 0x52, 0x52, 0xfa, 0x50, 0x7b, 0xeb, 0x25, 0xb1, 0xe9, 0xfb, 0x64, 0x1a, 0x51, 0xf4, 0xb4, 0xb0, 0xd3, 0x3d, 0xfa, 0x18, 0x4a, 0x3e, 0xc5, 0xe3, 0xa4, 0x59, 0x7c, 0xb2, 0xb6, 0x57,
0x14, 0xc0, 0x13, 0x47, 0x37, 0x18, 0x49, 0x93, 0xaa, 0x12, 0xd2, 0x19, 0xb1, 0x60, 0x7a, 0xbe, 0x3b, 0x7c, 0x94, 0x2d, 0xe2, 0x1b, 0x1e, 0x1b, 0x42, 0x56, 0xeb, 0x2c, 0x44, 0xa3, 0xe7, 0x27,
0x8f, 0xd3, 0xd4, 0xa5, 0xe4, 0x16, 0x47, 0xaa, 0x82, 0x05, 0xcc, 0x61, 0x20, 0xe3, 0x3f, 0x1a, 0x14, 0x3d, 0x4d, 0x35, 0x29, 0x5c, 0xd3, 0x83, 0x95, 0x9a, 0x52, 0x2d, 0x03, 0xa8, 0xbd, 0x72,
0xec, 0x32, 0x89, 0x6f, 0x83, 0x04, 0x8f, 0xa7, 0x5e, 0x32, 0x6a, 0xf1, 0x1e, 0xc4, 0x5a, 0x49, 0xe2, 0xa8, 0xe5, 0xba, 0x64, 0x12, 0x52, 0xf4, 0x08, 0xc0, 0x11, 0x4b, 0xdb, 0xf7, 0xa4, 0x4b,
0x9c, 0x04, 0x77, 0x1e, 0xc5, 0xee, 0x2d, 0x9e, 0xa9, 0x26, 0x26, 0x41, 0x17, 0x78, 0x86, 0x3e, 0x55, 0x49, 0xe9, 0x7a, 0x2c, 0x99, 0x8e, 0xeb, 0xe2, 0x24, 0xb1, 0x29, 0xb9, 0xc2, 0x61, 0xda,
0x01, 0x14, 0x12, 0xdf, 0x0b, 0x5d, 0x6f, 0x34, 0x4a, 0xd8, 0x27, 0x82, 0xf8, 0xee, 0xa5, 0xfc, 0xc1, 0x82, 0x66, 0x31, 0x92, 0xf6, 0x77, 0x05, 0xb6, 0x98, 0xc6, 0x57, 0x7e, 0x8c, 0x47, 0x13,
0x82, 0xce, 0x31, 0xa6, 0x40, 0x74, 0xe2, 0xbb, 0x97, 0x2b, 0xa9, 0x3f, 0x97, 0x8e, 0x5d, 0xa6, 0x27, 0xf6, 0xda, 0x7c, 0x7c, 0xb1, 0x29, 0x14, 0xc5, 0xfe, 0xb5, 0x43, 0xb1, 0x7d, 0x85, 0xa7,
0xfe, 0x1c, 0xfd, 0x08, 0x1e, 0xc4, 0x18, 0x27, 0x6e, 0x3c, 0xbd, 0x0e, 0x03, 0x9f, 0x2b, 0xb0, 0xe9, 0xfc, 0x93, 0xa4, 0x53, 0x3c, 0x45, 0x1f, 0x02, 0x0a, 0x88, 0xeb, 0x04, 0xb6, 0xe3, 0x79,
0x29, 0x3a, 0x24, 0x03, 0x0f, 0x38, 0xf4, 0x02, 0xcf, 0x8c, 0x7f, 0x6a, 0xb0, 0xcf, 0x94, 0x3f, 0x31, 0xfb, 0x84, 0x1f, 0x5d, 0x3f, 0x93, 0x5f, 0x50, 0x39, 0xa7, 0x25, 0x18, 0xdd, 0xe8, 0xfa,
0xc7, 0x11, 0x4e, 0x3c, 0x56, 0x24, 0xf3, 0x12, 0xff, 0x19, 0x94, 0xa5, 0x1f, 0xb8, 0xee, 0xb5, 0xd9, 0x52, 0xe9, 0x4f, 0x64, 0x60, 0x17, 0xa5, 0x3f, 0x41, 0xef, 0xc3, 0xdd, 0x08, 0xe3, 0xd8,
0x7c, 0x9b, 0xcf, 0xf8, 0xd0, 0x56, 0x74, 0x2c, 0x31, 0x42, 0x32, 0x96, 0x26, 0xb0, 0x23, 0x7a, 0x8e, 0x26, 0x17, 0x81, 0xef, 0x72, 0x03, 0x8a, 0x62, 0xb8, 0x32, 0xf2, 0x90, 0x53, 0x4f, 0xf1,
0x05, 0x5b, 0xa2, 0x25, 0x73, 0x4d, 0x6b, 0x27, 0xcf, 0x96, 0x65, 0x2c, 0x79, 0xcd, 0x96, 0xe4, 0x54, 0xfb, 0xab, 0x02, 0x3b, 0xcc, 0xf8, 0x13, 0x1c, 0xe2, 0xd8, 0x61, 0x4d, 0x32, 0x6b, 0xf1,
0xc6, 0x05, 0xec, 0x88, 0xe6, 0x31, 0x48, 0xc8, 0x9f, 0x58, 0xef, 0xa5, 0xd3, 0x14, 0x3d, 0x81, 0x1f, 0x42, 0x59, 0xc6, 0x81, 0xdb, 0x5e, 0xcb, 0xdf, 0x10, 0x99, 0x18, 0x1a, 0xa9, 0x1c, 0x2b,
0xea, 0xa2, 0x66, 0x35, 0x5e, 0xb3, 0x0b, 0x00, 0xeb, 0x49, 0x38, 0x62, 0xa7, 0x11, 0xd7, 0xa0, 0x8c, 0x80, 0x8c, 0xa4, 0x0b, 0x6c, 0x89, 0x9e, 0xc3, 0xba, 0x98, 0xe6, 0xdc, 0xd2, 0xda, 0xe1,
0x62, 0xab, 0xab, 0xf1, 0x2b, 0xa8, 0x0f, 0xbc, 0x24, 0xc5, 0xaa, 0xc5, 0x35, 0xa1, 0xac, 0xe6, 0xe3, 0x45, 0x1d, 0x0b, 0x51, 0x33, 0xa4, 0xb8, 0x76, 0x0a, 0x9b, 0x62, 0x78, 0x0c, 0x63, 0xf2,
0x86, 0xec, 0x5e, 0xf2, 0x8a, 0xf6, 0xa0, 0x34, 0xc2, 0xd7, 0xd3, 0xb1, 0x94, 0x20, 0x2e, 0xc6, 0x25, 0x1b, 0xdb, 0x74, 0x92, 0xa0, 0x87, 0x50, 0x9d, 0xf7, 0xac, 0xc2, 0x7b, 0x76, 0x4e, 0x60,
0x5f, 0x35, 0x68, 0x48, 0x01, 0xdf, 0x5b, 0x37, 0xce, 0x0f, 0xae, 0xb9, 0x02, 0xeb, 0xa7, 0x64, 0x33, 0x49, 0x0c, 0x6d, 0x8f, 0x5b, 0x50, 0x31, 0xd2, 0xad, 0xf6, 0x7b, 0xa8, 0x0f, 0x9d, 0x38,
0x17, 0x0e, 0x5a, 0xef, 0xbc, 0x68, 0x8c, 0x85, 0xa7, 0xfa, 0x31, 0x6f, 0x69, 0xca, 0xa4, 0x63, 0xc1, 0xe9, 0x88, 0x6b, 0x42, 0x39, 0xbd, 0x72, 0xe4, 0xf4, 0x92, 0xdb, 0xc5, 0x4b, 0xab, 0x70,
0xd8, 0x95, 0x13, 0x91, 0x08, 0x84, 0xfb, 0x87, 0x94, 0x44, 0xd2, 0xbc, 0x1d, 0x3f, 0xcb, 0xf2, 0xe3, 0xd2, 0x7a, 0xdb, 0xbc, 0x46, 0xdb, 0x50, 0xf2, 0xf0, 0xc5, 0x64, 0x24, 0xaf, 0x1c, 0xb1,
0xeb, 0x94, 0x44, 0xc6, 0xef, 0xe1, 0xa1, 0x8c, 0xb9, 0x94, 0x97, 0x69, 0xff, 0x99, 0x59, 0xc6, 0xd1, 0xfe, 0xa8, 0x40, 0x43, 0x7e, 0xfe, 0x5b, 0x9b, 0xe5, 0xf9, 0x1b, 0x73, 0x66, 0xfe, 0xea,
0xcf, 0xf9, 0x21, 0x55, 0xc8, 0x0f, 0xa9, 0x85, 0xcb, 0x8a, 0x59, 0x97, 0xbd, 0x86, 0xfd, 0x65, 0xeb, 0xb9, 0x07, 0xbb, 0xed, 0x37, 0x4e, 0x38, 0xc2, 0x22, 0xce, 0x83, 0x88, 0x0f, 0xc4, 0x34,
0xf9, 0xd2, 0x75, 0xf7, 0x67, 0xb7, 0xb6, 0x62, 0x76, 0x1b, 0x6f, 0xe1, 0xe1, 0x90, 0xb7, 0x0b, 0x20, 0x07, 0xb0, 0x25, 0xdd, 0x26, 0x82, 0x61, 0xff, 0x26, 0x21, 0xa1, 0x0c, 0xce, 0xa6, 0x9b,
0x55, 0xc5, 0x99, 0x89, 0x3b, 0x66, 0x05, 0xed, 0x2e, 0x7a, 0x50, 0x85, 0x03, 0x1c, 0x6f, 0xcc, 0x3d, 0xf2, 0x8b, 0x84, 0x84, 0xda, 0xaf, 0xe1, 0x9e, 0xac, 0x18, 0xa9, 0x2f, 0x73, 0x79, 0x64,
0xea, 0x95, 0x48, 0x7a, 0x8e, 0x97, 0xf5, 0xaa, 0x60, 0x8e, 0x37, 0x36, 0x7e, 0x0a, 0xdb, 0x57, 0x6e, 0x42, 0xbe, 0xce, 0x87, 0xac, 0xb0, 0x2a, 0x64, 0x6b, 0xd9, 0x90, 0xbd, 0x84, 0x9d, 0x45,
0xa2, 0xbf, 0x7d, 0x13, 0x89, 0xc6, 0x5f, 0xe0, 0xb1, 0x32, 0x84, 0xe5, 0x6b, 0xde, 0x59, 0xcf, 0xfd, 0x32, 0x74, 0x37, 0x41, 0x83, 0xb2, 0x04, 0x34, 0x68, 0xaf, 0xe0, 0x9e, 0xc9, 0x87, 0x4d,
0xa0, 0x16, 0x06, 0x3e, 0x66, 0x59, 0x90, 0xa9, 0x71, 0x09, 0x62, 0x35, 0x9e, 0x6f, 0x2f, 0x85, 0x3a, 0x03, 0x32, 0xf7, 0xf5, 0x88, 0x8d, 0x03, 0x7b, 0x3e, 0xc1, 0x2a, 0x9c, 0x60, 0x39, 0x23,
0xf7, 0xb5, 0x97, 0xe2, 0xfd, 0xf6, 0xf2, 0x05, 0x3c, 0x19, 0x62, 0x9a, 0xa9, 0x05, 0x4b, 0x24, 0xd6, 0xed, 0x44, 0xca, 0x73, 0xbe, 0xec, 0xf6, 0x94, 0x66, 0x39, 0x23, 0xed, 0x07, 0xb0, 0x71,
0xb5, 0x52, 0xe1, 0x29, 0x40, 0x90, 0xba, 0x2a, 0xf1, 0x65, 0x51, 0x04, 0xa9, 0xa4, 0x32, 0xfe, 0x2e, 0xa6, 0xe3, 0x57, 0xd1, 0xa8, 0xfd, 0x01, 0x1e, 0xa4, 0x8e, 0xb0, 0x6a, 0xcf, 0x07, 0xeb,
0x0c, 0xd0, 0x25, 0x63, 0xb9, 0x94, 0xa1, 0x23, 0x28, 0x85, 0xf8, 0x0e, 0x87, 0x32, 0x5d, 0xf7, 0x31, 0xd4, 0x02, 0xdf, 0xc5, 0xac, 0x0a, 0x32, 0x13, 0x42, 0x92, 0xd8, 0x84, 0xc8, 0x0f, 0xa7,
0xb2, 0xe9, 0xda, 0x25, 0xe3, 0x2e, 0xc3, 0xd9, 0x82, 0x04, 0x7d, 0x9c, 0xe9, 0xe9, 0xdb, 0x27, 0xc2, 0x6d, 0xc3, 0x69, 0xed, 0xe6, 0x70, 0x7a, 0x01, 0x0f, 0x4d, 0x4c, 0x33, 0x9d, 0xa4, 0x8b,
0xbb, 0x4b, 0xa4, 0x7c, 0xbf, 0x13, 0x8d, 0x7e, 0x7d, 0xca, 0x36, 0xa0, 0x36, 0xa4, 0x44, 0xed, 0x96, 0x48, 0x4d, 0x78, 0x04, 0xe0, 0x27, 0x76, 0xda, 0x36, 0xb2, 0xa5, 0xfc, 0x44, 0x4a, 0x69,
0x4a, 0x47, 0x06, 0xd4, 0xb3, 0x35, 0x81, 0xb6, 0xa0, 0xd0, 0xbf, 0xd0, 0x37, 0x10, 0xc0, 0xd6, 0xbf, 0x03, 0xe8, 0x91, 0x91, 0x44, 0x83, 0x68, 0x1f, 0x4a, 0x01, 0xbe, 0xc6, 0x81, 0x2c, 0xd7,
0x99, 0xd9, 0xe9, 0x5a, 0x6d, 0x5d, 0x3b, 0x32, 0xa1, 0x3a, 0xdf, 0x3c, 0x51, 0x0d, 0xca, 0x43, 0xed, 0x6c, 0xb9, 0xf6, 0xc8, 0xa8, 0xc7, 0x78, 0x86, 0x10, 0x41, 0x1f, 0x64, 0x6e, 0x84, 0x8d,
0xa7, 0x3f, 0x18, 0x58, 0x6d, 0x7d, 0x03, 0xd5, 0xa1, 0x32, 0x74, 0x4c, 0xdb, 0xe9, 0xf4, 0xce, 0xc3, 0xad, 0x05, 0x51, 0x0e, 0x2c, 0xc5, 0x35, 0xb1, 0xba, 0x64, 0x1b, 0x50, 0x33, 0x29, 0x49,
0x75, 0x4d, 0xa0, 0x4c, 0xdb, 0xb1, 0xda, 0x7a, 0x41, 0xa0, 0xfa, 0x83, 0x01, 0x43, 0x15, 0x8f, 0x91, 0x96, 0xf6, 0x2f, 0x05, 0x90, 0x35, 0x09, 0x43, 0x1c, 0xe4, 0x60, 0x26, 0x82, 0x22, 0x9f,
0xfe, 0x57, 0x80, 0x5a, 0x66, 0x0b, 0x45, 0x55, 0x28, 0x59, 0x97, 0x03, 0xe7, 0x4b, 0x7d, 0x03, 0x84, 0xc2, 0x76, 0xbe, 0x66, 0x81, 0x15, 0x60, 0xce, 0x8e, 0x48, 0x4c, 0x53, 0x50, 0x21, 0x48,
0x3d, 0x82, 0x5d, 0x7e, 0x74, 0x5b, 0xfd, 0xde, 0x59, 0xe7, 0xfc, 0xca, 0x36, 0x9d, 0x4e, 0xbf, 0x43, 0x12, 0x53, 0x16, 0xb9, 0x84, 0xc6, 0xbe, 0x4b, 0x6d, 0x86, 0x33, 0xb0, 0x2c, 0xbe, 0x9a,
0xa7, 0x6b, 0xa8, 0x09, 0x7b, 0x5c, 0x9c, 0xdb, 0xea, 0x5f, 0x5e, 0x9a, 0xbd, 0xb6, 0x3b, 0xb4, 0xa0, 0x19, 0x8c, 0x84, 0x7e, 0x0c, 0x4d, 0x1c, 0x7a, 0x11, 0xf1, 0x59, 0xf0, 0x43, 0x0f, 0x47,
0xec, 0xdf, 0x58, 0xb6, 0x5e, 0x40, 0x08, 0xb6, 0x5b, 0xb6, 0x65, 0x3a, 0x16, 0x07, 0x75, 0x5a, 0x38, 0xf4, 0x70, 0x48, 0xed, 0xd0, 0x49, 0x11, 0xe5, 0x4e, 0xca, 0xef, 0xce, 0xd9, 0x7d, 0x87,
0x96, 0x5e, 0x44, 0x3b, 0xd0, 0x10, 0xd4, 0x0a, 0xb4, 0x89, 0xf6, 0x40, 0xbf, 0xea, 0x59, 0xbf, 0x21, 0x8c, 0x52, 0x42, 0x1d, 0xf7, 0x8a, 0xa3, 0x8a, 0x05, 0x40, 0x6e, 0x32, 0x06, 0xf7, 0x5e,
0x1d, 0x58, 0x2d, 0xc7, 0x6a, 0xbb, 0x96, 0x6d, 0xf7, 0x6d, 0xbd, 0x84, 0x76, 0xe1, 0x81, 0xd9, 0xc8, 0x68, 0xfb, 0xb0, 0x21, 0x9c, 0xba, 0x1d, 0x5a, 0xed, 0x6b, 0x50, 0xcf, 0x4e, 0x05, 0xb4,
0xb5, 0x2d, 0xb3, 0xfd, 0xa5, 0xab, 0xb4, 0xdd, 0xca, 0x03, 0x85, 0x75, 0x65, 0xb4, 0x0f, 0xa8, 0x0e, 0x85, 0xc1, 0xa9, 0x7a, 0x07, 0x01, 0xac, 0x1f, 0xb7, 0xba, 0x3d, 0xbd, 0xa3, 0x2a, 0xfb,
0xd3, 0x1b, 0x3a, 0x66, 0xaf, 0x65, 0xb9, 0xbd, 0xbe, 0xe3, 0x9e, 0xf5, 0xaf, 0x7a, 0x6d, 0xbd, 0x2d, 0xa8, 0xce, 0x40, 0x3f, 0xaa, 0x41, 0xd9, 0xb4, 0x06, 0xc3, 0xa1, 0xde, 0x51, 0xef, 0xa0,
0xc2, 0x14, 0xcb, 0xc1, 0x15, 0x47, 0x75, 0x05, 0x46, 0x7c, 0x00, 0xd0, 0x63, 0x78, 0xc8, 0x15, 0x3a, 0x54, 0x4c, 0xab, 0x65, 0x58, 0xdd, 0xfe, 0x89, 0xaa, 0x08, 0x56, 0xcb, 0xb0, 0xf4, 0x8e,
0x70, 0x4f, 0xaf, 0x3a, 0xdd, 0x76, 0xa7, 0x77, 0x2e, 0xcd, 0xd5, 0x6b, 0x8c, 0x49, 0xa0, 0x06, 0x5a, 0x10, 0xac, 0xc1, 0x70, 0xc8, 0x58, 0x6b, 0xfb, 0xff, 0x2c, 0x40, 0x2d, 0xf3, 0x00, 0x40,
0xa6, 0x3d, 0xcc, 0x60, 0xea, 0x0b, 0x0c, 0xd3, 0x2c, 0x83, 0x69, 0x1c, 0x9d, 0x42, 0x45, 0xe5, 0x55, 0x28, 0xe9, 0x67, 0x43, 0xeb, 0xb5, 0x7a, 0x07, 0xdd, 0x87, 0x2d, 0xbe, 0xb4, 0xdb, 0x83,
0x06, 0xf3, 0x65, 0xdb, 0x3a, 0xbd, 0x3a, 0xd7, 0x37, 0x50, 0x05, 0x36, 0x3b, 0xbd, 0xb3, 0xbe, 0xfe, 0x71, 0xf7, 0xe4, 0xdc, 0x68, 0x59, 0xdd, 0x41, 0x5f, 0x55, 0x50, 0x13, 0xb6, 0xb9, 0x3a,
0x88, 0xc5, 0x5b, 0xd3, 0xee, 0x31, 0xef, 0x17, 0xb8, 0xb7, 0xb9, 0xf5, 0x45, 0x76, 0x3c, 0x33, 0xbb, 0x3d, 0x38, 0x3b, 0x6b, 0xf5, 0x3b, 0xb6, 0xa9, 0x1b, 0x9f, 0xe9, 0x86, 0x5a, 0x40, 0x08,
0x1d, 0xb3, 0xab, 0x6f, 0x1e, 0x7d, 0x02, 0x65, 0x99, 0x34, 0x8c, 0xaf, 0xd5, 0xb7, 0x2d, 0x7d, 0x36, 0xda, 0x86, 0xde, 0xb2, 0x74, 0x4e, 0xea, 0xb6, 0x75, 0x75, 0x0d, 0x6d, 0x42, 0x43, 0x48,
0x83, 0xc7, 0x50, 0x3a, 0x50, 0x63, 0x49, 0x20, 0xbf, 0x58, 0x38, 0xf9, 0x07, 0x40, 0xf9, 0x8d, 0xa7, 0xa4, 0x22, 0xda, 0x06, 0xf5, 0xbc, 0xaf, 0x7f, 0x3e, 0xd4, 0xdb, 0x96, 0xde, 0xb1, 0x75,
0x48, 0x37, 0xf4, 0x1a, 0x2a, 0x43, 0x6f, 0xc6, 0xb7, 0x4f, 0x94, 0x6b, 0xaf, 0xd9, 0xa5, 0xf5, 0xc3, 0x18, 0x18, 0x6a, 0x09, 0x6d, 0xc1, 0xdd, 0x56, 0xcf, 0xd0, 0x5b, 0x9d, 0xd7, 0x76, 0x6a,
0xe0, 0xf1, 0x0a, 0x8c, 0xec, 0x37, 0x1d, 0xd8, 0x56, 0x02, 0x86, 0x34, 0xc1, 0xde, 0xe4, 0x5b, 0xed, 0x7a, 0x9e, 0x28, 0xbc, 0x2b, 0xa3, 0x1d, 0x40, 0xdd, 0xbe, 0x69, 0xb5, 0xfa, 0x6d, 0xdd,
0x89, 0x39, 0xd4, 0x3e, 0xd5, 0xd0, 0x6b, 0x28, 0xf1, 0x57, 0x40, 0x5e, 0x42, 0xf6, 0xe9, 0x72, 0xee, 0x0f, 0x2c, 0xfb, 0x78, 0x70, 0xde, 0xef, 0xa8, 0x15, 0x66, 0x58, 0x8e, 0x9e, 0x9e, 0xa8,
0xf0, 0x64, 0xf9, 0x0d, 0x95, 0x7b, 0x75, 0x5d, 0x2e, 0x5e, 0x62, 0x6c, 0x7b, 0x61, 0x7d, 0x05, 0x2e, 0xe1, 0x88, 0x0f, 0x00, 0x7a, 0x00, 0xf7, 0xb8, 0x01, 0xf6, 0xd1, 0x79, 0xb7, 0xd7, 0xe9,
0x3d, 0xca, 0xcb, 0x9a, 0x97, 0xcb, 0xd7, 0x8b, 0xe2, 0xfa, 0x5c, 0x2c, 0x36, 0xb3, 0x94, 0x2f, 0xf6, 0x4f, 0xa4, 0xbb, 0x6a, 0x8d, 0x1d, 0x12, 0xac, 0x61, 0xcb, 0x30, 0x33, 0x9c, 0xfa, 0x9c,
0xd9, 0x6b, 0x65, 0xad, 0xdf, 0xb0, 0x98, 0x1e, 0x5c, 0x58, 0x1f, 0x76, 0x2e, 0xbd, 0x20, 0xfa, 0xc3, 0x2c, 0xcb, 0x70, 0x1a, 0xfb, 0x47, 0x50, 0x49, 0xbb, 0x83, 0xc5, 0xb2, 0xa3, 0x1f, 0x9d,
0xfe, 0x04, 0xb6, 0xa1, 0x71, 0xae, 0x3a, 0xd7, 0xd7, 0x0b, 0xdb, 0xcf, 0x21, 0xe6, 0x0c, 0x5c, 0x9f, 0xa8, 0x77, 0x50, 0x05, 0x8a, 0xdd, 0xfe, 0xf1, 0x40, 0xe4, 0xe2, 0x55, 0xcb, 0xe8, 0xb3,
0xca, 0x2b, 0x28, 0xf1, 0x07, 0xd7, 0x92, 0xcf, 0x33, 0x6f, 0xb0, 0x83, 0xbd, 0x55, 0x53, 0x17, 0xe8, 0x17, 0x78, 0xb4, 0xb9, 0xf7, 0x6b, 0x6c, 0x79, 0xdc, 0xb2, 0x5a, 0x3d, 0xb5, 0xb8, 0xff,
0xfd, 0x12, 0x4a, 0x7c, 0x66, 0xe7, 0x19, 0xb3, 0x7b, 0x40, 0x3e, 0xdc, 0xf9, 0x01, 0x7f, 0x26, 0x21, 0x94, 0x65, 0xdb, 0xb0, 0x73, 0xed, 0x81, 0xa1, 0xab, 0x77, 0x78, 0x0e, 0x65, 0x00, 0x15,
0x9f, 0xa4, 0x43, 0x9c, 0xdc, 0x05, 0x3e, 0xfe, 0xd6, 0x11, 0x7f, 0x05, 0x9b, 0xcc, 0x52, 0xb4, 0x56, 0x04, 0xf2, 0x8b, 0x85, 0xfd, 0x03, 0xa8, 0xce, 0x0a, 0x8d, 0x31, 0xcc, 0xd7, 0xa6, 0xa5,
0x93, 0xa5, 0xe2, 0x0f, 0xa4, 0xf7, 0x30, 0x9a, 0x50, 0xb6, 0x71, 0xfa, 0x9d, 0xb2, 0x8d, 0x65, 0x9f, 0x89, 0x4a, 0x39, 0xf9, 0xac, 0x6b, 0x0e, 0x0c, 0x55, 0x61, 0xda, 0xcf, 0xba, 0x9f, 0xb3,
0x7e, 0x6e, 0x84, 0xa2, 0x0f, 0xf3, 0x3e, 0x5c, 0x31, 0x5e, 0xd7, 0x38, 0xf3, 0x17, 0x50, 0x96, 0xfc, 0x1f, 0xfe, 0x45, 0x81, 0x12, 0xc7, 0xf7, 0xe8, 0x25, 0x54, 0x4c, 0x67, 0x2a, 0xd6, 0xb9,
0x43, 0x13, 0x1d, 0x64, 0x09, 0xf2, 0x93, 0x74, 0x0d, 0xb3, 0x0b, 0xe8, 0xfe, 0x08, 0x45, 0x1f, 0xeb, 0x28, 0xfb, 0x44, 0xd8, 0x7d, 0xb0, 0x84, 0x23, 0xab, 0xb7, 0x0b, 0x1b, 0xa9, 0x02, 0x93,
0x65, 0x69, 0xd7, 0x8e, 0xd8, 0x03, 0x63, 0x79, 0x63, 0x5c, 0xb1, 0xaa, 0xbe, 0x81, 0xbd, 0xf3, 0xc6, 0xd8, 0x19, 0x7f, 0x2d, 0x35, 0x7b, 0xca, 0x47, 0xca, 0xe1, 0xbf, 0xab, 0x50, 0x64, 0xb5,
0xdc, 0x8c, 0x94, 0xfb, 0xe2, 0x0a, 0xa7, 0x3f, 0xbd, 0x9f, 0x6a, 0x59, 0x0e, 0xbe, 0x75, 0xac, 0x8c, 0x5e, 0x42, 0x49, 0xbc, 0xdb, 0x9a, 0x0b, 0xad, 0x34, 0x9b, 0x02, 0xbb, 0x0f, 0x17, 0x5f,
0x98, 0xb6, 0xe8, 0x70, 0x29, 0xfb, 0xd6, 0x0e, 0xe4, 0x35, 0x3e, 0x38, 0x85, 0x1a, 0x6b, 0xa2, 0xbd, 0xb9, 0x77, 0xf2, 0xd9, 0xfc, 0xed, 0xcc, 0x40, 0x23, 0x1b, 0xc8, 0xe8, 0x7e, 0x5e, 0xd7,
0xef, 0x2d, 0xfa, 0xfd, 0xa5, 0x39, 0x2b, 0x07, 0x19, 0x2b, 0x85, 0xd3, 0xed, 0xdf, 0xd5, 0x8f, 0x6c, 0xce, 0xbc, 0x5d, 0x15, 0x33, 0x0c, 0x9d, 0xce, 0x01, 0x71, 0xc2, 0xdf, 0x36, 0x2b, 0x75,
0x5f, 0x2c, 0xd0, 0xd7, 0x5b, 0xfc, 0x5f, 0xcf, 0x67, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x78, 0xad, 0x06, 0xb6, 0xcc, 0x0e, 0xae, 0x6c, 0x00, 0x9b, 0x67, 0x8e, 0x1f, 0x7e, 0x7b, 0x0a, 0x3b,
0x0f, 0x0b, 0x3c, 0x07, 0x12, 0x00, 0x00, 0xd0, 0x38, 0x49, 0x47, 0xfe, 0xdb, 0x95, 0xed, 0xe4, 0x18, 0xb3, 0x03, 0x5c, 0xcb, 0x73, 0x28,
0xf1, 0x77, 0xee, 0x42, 0xcc, 0x33, 0x4f, 0xdf, 0xdd, 0xed, 0x65, 0x70, 0x05, 0xfd, 0x1c, 0x4a,
0x1c, 0xec, 0xe4, 0x0f, 0x66, 0xe1, 0x57, 0x3e, 0xef, 0x79, 0x64, 0xf4, 0x2b, 0xd8, 0x5a, 0x02,
0x53, 0xd0, 0xfb, 0xb9, 0x9c, 0xac, 0xc4, 0x31, 0xb7, 0x94, 0xc1, 0xb1, 0xfc, 0x43, 0xc1, 0x9e,
0xf2, 0xbe, 0x8b, 0xbf, 0x76, 0x39, 0x3d, 0x87, 0x22, 0x0b, 0x23, 0xda, 0xcc, 0x4a, 0xf1, 0x47,
0xef, 0x2d, 0x07, 0x5b, 0x50, 0x36, 0x70, 0xf2, 0x8d, 0x4a, 0x99, 0xf5, 0x57, 0x0e, 0xd8, 0xa0,
0x77, 0xf3, 0x09, 0x5a, 0x02, 0x7a, 0x56, 0x64, 0xea, 0x67, 0x50, 0x96, 0x50, 0x06, 0xed, 0x66,
0x05, 0xf2, 0xf8, 0x66, 0xc5, 0x61, 0x1b, 0xd0, 0x4d, 0x60, 0x83, 0xde, 0xcb, 0xca, 0xae, 0x04,
0x3e, 0xbb, 0xda, 0xe2, 0x2b, 0x60, 0xc9, 0xf3, 0xe3, 0x53, 0xd8, 0x3e, 0xc9, 0x21, 0x17, 0xf9,
0x06, 0x58, 0x12, 0xf4, 0x47, 0x37, 0xeb, 0x38, 0x7b, 0x82, 0x63, 0xc1, 0x25, 0x18, 0x08, 0xed,
0x2d, 0x94, 0xf6, 0x4a, 0x98, 0xb4, 0x22, 0x06, 0x47, 0x50, 0x63, 0x83, 0xfd, 0xd6, 0x89, 0xb2,
0xb3, 0x80, 0x7e, 0xe4, 0xe5, 0xca, 0x87, 0xdc, 0x7f, 0x15, 0x68, 0x48, 0x54, 0x23, 0xab, 0xf2,
0xc5, 0xed, 0xd3, 0x2e, 0x97, 0xae, 0x05, 0xf8, 0xf0, 0xa3, 0xd5, 0xc5, 0xf9, 0xb6, 0x63, 0xcf,
0x61, 0x7d, 0x75, 0x80, 0x6f, 0xf9, 0x9e, 0xfe, 0xa5, 0x4f, 0xff, 0xcf, 0x63, 0x47, 0x1b, 0xbf,
0xac, 0x1f, 0x3c, 0x9d, 0xb3, 0x2f, 0xd6, 0xf9, 0x2f, 0xcf, 0x8f, 0xff, 0x17, 0x00, 0x00, 0xff,
0xff, 0x17, 0x3d, 0x94, 0x57, 0x0e, 0x15, 0x00, 0x00,
} }

View File

@@ -44,6 +44,7 @@ message StartRequest {
string config_content = 2; // Optional if configPath is not provided. string config_content = 2; // Optional if configPath is not provided.
bool disable_memory_limit = 3; bool disable_memory_limit = 3;
bool delay_start = 4; bool delay_start = 4;
bool enable_old_command_server = 5;
} }
message SetupRequest { message SetupRequest {
@@ -123,8 +124,10 @@ message SystemProxyStatus {
} }
message ParseRequest { message ParseRequest {
string content = 1; string content = 1;
bool debug = 2; string config_path = 2;
string temp_path = 3;
bool debug = 4;
} }
message ParseResponse { message ParseResponse {
@@ -189,9 +192,31 @@ message LogMessage {
message StopRequest{ message StopRequest{
} }
service Hiddify {
enum StackType {
SYSTEM = 0;
GVISOR = 1;
MIXED = 2;
}
message TunnelStartRequest {
bool ipv6 = 1;
int32 server_port = 2;
bool strict_route = 3;
bool endpoint_independent_nat = 4;
StackType stack = 5;
}
message TunnelResponse {
string message = 1;
}
service Hello {
rpc SayHello (HelloRequest) returns (HelloResponse); rpc SayHello (HelloRequest) returns (HelloResponse);
rpc SayHelloStream (stream HelloRequest) returns (stream HelloResponse); rpc SayHelloStream (stream HelloRequest) returns (stream HelloResponse);
}
service Core {
rpc Start (StartRequest) returns (CoreInfoResponse); rpc Start (StartRequest) returns (CoreInfoResponse);
rpc CoreInfoListener (stream StopRequest) returns (stream CoreInfoResponse); rpc CoreInfoListener (stream StopRequest) returns (stream CoreInfoResponse);
rpc OutboundsInfo (stream StopRequest) returns (stream OutboundGroupList); rpc OutboundsInfo (stream StopRequest) returns (stream OutboundGroupList);
@@ -199,7 +224,7 @@ service Hiddify {
rpc GetSystemInfo (stream StopRequest) returns (stream SystemInfo); rpc GetSystemInfo (stream StopRequest) returns (stream SystemInfo);
rpc Setup (SetupRequest) returns (Response); rpc Setup (SetupRequest) returns (Response);
rpc Parse (ParseRequest) returns (ParseResponse); rpc Parse (ParseRequest) returns (ParseResponse);
//rpc ChangeConfigOptions (ChangeConfigOptionsRequest) returns (CoreInfoResponse); rpc ChangeConfigOptions (ChangeConfigOptionsRequest) returns (CoreInfoResponse);
//rpc GenerateConfig (GenerateConfigRequest) returns (GenerateConfigResponse); //rpc GenerateConfig (GenerateConfigRequest) returns (GenerateConfigResponse);
rpc StartService (StartRequest) returns (CoreInfoResponse); rpc StartService (StartRequest) returns (CoreInfoResponse);
rpc Stop (Empty) returns (CoreInfoResponse); rpc Stop (Empty) returns (CoreInfoResponse);
@@ -209,6 +234,14 @@ service Hiddify {
rpc GenerateWarpConfig (GenerateWarpConfigRequest) returns (WarpGenerationResponse); rpc GenerateWarpConfig (GenerateWarpConfigRequest) returns (WarpGenerationResponse);
rpc GetSystemProxyStatus (Empty) returns (SystemProxyStatus); rpc GetSystemProxyStatus (Empty) returns (SystemProxyStatus);
rpc SetSystemProxyEnabled (SetSystemProxyEnabledRequest) returns (Response); rpc SetSystemProxyEnabled (SetSystemProxyEnabledRequest) returns (Response);
rpc LogListener (stream StopRequest) returns (stream LogMessage); rpc LogListener (stream StopRequest) returns (stream LogMessage);
} }
service TunnelService {
rpc Start(StartRequest) returns (TunnelResponse);
rpc Stop(Empty) returns (TunnelResponse);
rpc Status(Empty) returns (TunnelResponse);
rpc Exit(Empty) returns (TunnelResponse);
}

File diff suppressed because it is too large Load Diff

View File

@@ -6,12 +6,11 @@ import (
pb "github.com/hiddify/libcore/hiddifyrpc" pb "github.com/hiddify/libcore/hiddifyrpc"
"github.com/sagernet/sing-box/experimental/libbox" "github.com/sagernet/sing-box/experimental/libbox"
"github.com/sagernet/sing/common/observable"
) )
var systemInfoObserver = observable.Observer[pb.SystemInfo]{} var systemInfoObserver = NewObserver[pb.SystemInfo](10)
var outboundsInfoObserver = observable.Observer[pb.OutboundGroupList]{} var outboundsInfoObserver = NewObserver[pb.OutboundGroupList](10)
var mainOutboundsInfoObserver = observable.Observer[pb.OutboundGroupList]{} var mainOutboundsInfoObserver = NewObserver[pb.OutboundGroupList](10)
var ( var (
statusClient *libbox.CommandClient statusClient *libbox.CommandClient
@@ -19,7 +18,7 @@ var (
groupInfoOnlyClient *libbox.CommandClient groupInfoOnlyClient *libbox.CommandClient
) )
func (s *server) GetSystemInfo(stream pb.Hiddify_GetSystemInfoServer) error { func (s *CoreService) GetSystemInfo(stream pb.Core_GetSystemInfoServer) error {
if statusClient == nil { if statusClient == nil {
statusClient = libbox.NewCommandClient( statusClient = libbox.NewCommandClient(
&CommandClientHandler{}, &CommandClientHandler{},
@@ -55,7 +54,7 @@ func (s *server) GetSystemInfo(stream pb.Hiddify_GetSystemInfoServer) error {
} }
} }
func (s *server) OutboundsInfo(stream pb.Hiddify_OutboundsInfoServer) error { func (s *CoreService) OutboundsInfo(stream pb.Core_OutboundsInfoServer) error {
if groupClient == nil { if groupClient == nil {
groupClient = libbox.NewCommandClient( groupClient = libbox.NewCommandClient(
&CommandClientHandler{}, &CommandClientHandler{},
@@ -91,7 +90,7 @@ func (s *server) OutboundsInfo(stream pb.Hiddify_OutboundsInfoServer) error {
} }
} }
func (s *server) MainOutboundsInfo(stream pb.Hiddify_MainOutboundsInfoServer) error { func (s *CoreService) MainOutboundsInfo(stream pb.Core_MainOutboundsInfoServer) error {
if groupInfoOnlyClient == nil { if groupInfoOnlyClient == nil {
groupInfoOnlyClient = libbox.NewCommandClient( groupInfoOnlyClient = libbox.NewCommandClient(
&CommandClientHandler{}, &CommandClientHandler{},
@@ -127,8 +126,10 @@ func (s *server) MainOutboundsInfo(stream pb.Hiddify_MainOutboundsInfoServer) er
} }
} }
// Implement the SelectOutbound method func (s *CoreService) SelectOutbound(ctx context.Context, in *pb.SelectOutboundRequest) (*pb.Response, error) {
func (s *server) SelectOutbound(ctx context.Context, in *pb.SelectOutboundRequest) (*pb.Response, error) { return SelectOutbound(in)
}
func SelectOutbound(in *pb.SelectOutboundRequest) (*pb.Response, error) {
err := libbox.NewStandaloneCommandClient().SelectOutbound(in.GroupTag, in.OutboundTag) err := libbox.NewStandaloneCommandClient().SelectOutbound(in.GroupTag, in.OutboundTag)
if err != nil { if err != nil {
@@ -144,8 +145,10 @@ func (s *server) SelectOutbound(ctx context.Context, in *pb.SelectOutboundReques
}, nil }, nil
} }
// Implement the UrlTest method func (s *CoreService) UrlTest(ctx context.Context, in *pb.UrlTestRequest) (*pb.Response, error) {
func (s *server) UrlTest(ctx context.Context, in *pb.UrlTestRequest) (*pb.Response, error) { return UrlTest(in)
}
func UrlTest(in *pb.UrlTestRequest) (*pb.Response, error) {
err := libbox.NewStandaloneCommandClient().URLTest(in.GroupTag) err := libbox.NewStandaloneCommandClient().URLTest(in.GroupTag)
if err != nil { if err != nil {

View File

@@ -1,16 +1,18 @@
package v2 package v2
import ( import (
"encoding/json"
"time" "time"
"github.com/hiddify/libcore/bridge"
pb "github.com/hiddify/libcore/hiddifyrpc" pb "github.com/hiddify/libcore/hiddifyrpc"
"github.com/sagernet/sing/common/observable"
) )
var coreInfoObserver = observable.Observer[pb.CoreInfoResponse]{} var coreInfoObserver = NewObserver[pb.CoreInfoResponse](10)
var CoreState = pb.CoreState_STOPPED var CoreState = pb.CoreState_STOPPED
func SetCoreStatus(state pb.CoreState, msgType pb.MessageType, message string) pb.CoreInfoResponse { func SetCoreStatus(state pb.CoreState, msgType pb.MessageType, message string) pb.CoreInfoResponse {
Log(pb.LogLevel_INFO, pb.LogType_CORE, message)
CoreState = state CoreState = state
info := pb.CoreInfoResponse{ info := pb.CoreInfoResponse{
CoreState: state, CoreState: state,
@@ -18,11 +20,13 @@ func SetCoreStatus(state pb.CoreState, msgType pb.MessageType, message string) p
Message: message, Message: message,
} }
coreInfoObserver.Emit(info) coreInfoObserver.Emit(info)
msg, _ := json.Marshal(StatusMessage{Status: convert2OldState(CoreState)})
bridge.SendStringToPort(statusPropagationPort, string(msg))
return info return info
} }
func (s *server) CoreInfoListener(stream pb.Hiddify_CoreInfoListenerServer) error { func (s *CoreService) CoreInfoListener(stream pb.Core_CoreInfoListenerServer) error {
coreSub, _, _ := coreInfoObserver.Subscribe() coreSub, _, _ := coreInfoObserver.Subscribe()
defer coreInfoObserver.UnSubscribe(coreSub) defer coreInfoObserver.UnSubscribe(coreSub)
stopch := make(chan int) stopch := make(chan int)

View File

@@ -2,11 +2,13 @@ package v2
import ( import (
"context" "context"
"encoding/json"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"time" "time"
"github.com/hiddify/libcore/bridge"
"github.com/hiddify/libcore/config" "github.com/hiddify/libcore/config"
pb "github.com/hiddify/libcore/hiddifyrpc" pb "github.com/hiddify/libcore/hiddifyrpc"
"github.com/sagernet/sing-box/experimental/libbox" "github.com/sagernet/sing-box/experimental/libbox"
@@ -22,19 +24,26 @@ var logFactory *log.Factory
func StopAndAlert(msgType pb.MessageType, message string) { func StopAndAlert(msgType pb.MessageType, message string) {
SetCoreStatus(pb.CoreState_STOPPED, msgType, message) SetCoreStatus(pb.CoreState_STOPPED, msgType, message)
config.DeactivateTunnelService() config.DeactivateTunnelService()
// if commandServer != nil { if commandServer != nil {
// commandServer.SetService(nil) commandServer.SetService(nil)
// } }
if Box != nil { if Box != nil {
Box.Close() Box.Close()
Box = nil Box = nil
} }
// if commandServer != nil { if commandServer != nil {
// commandServer.Close() commandServer.Close()
// } }
alert := msgType.String()
msg, _ := json.Marshal(StatusMessage{Status: convert2OldState(CoreState), Alert: &alert, Message: &message})
bridge.SendStringToPort(statusPropagationPort, string(msg))
} }
func (s *server) Start(ctx context.Context, in *pb.StartRequest) (*pb.CoreInfoResponse, error) { func (s *CoreService) Start(ctx context.Context, in *pb.StartRequest) (*pb.CoreInfoResponse, error) {
return Start(in)
}
func Start(in *pb.StartRequest) (*pb.CoreInfoResponse, error) {
defer config.DeferPanicToError("start", func(err error) { defer config.DeferPanicToError("start", func(err error) {
Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error()) Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error())
StopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error()) StopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error())
@@ -49,17 +58,23 @@ func (s *server) Start(ctx context.Context, in *pb.StartRequest) (*pb.CoreInfoRe
SetCoreStatus(pb.CoreState_STARTING, pb.MessageType_EMPTY, "") SetCoreStatus(pb.CoreState_STARTING, pb.MessageType_EMPTY, "")
libbox.SetMemoryLimit(!in.DisableMemoryLimit) libbox.SetMemoryLimit(!in.DisableMemoryLimit)
resp, err := s.StartService(ctx, in) resp, err := StartService(in)
return resp, err return resp, err
} }
func (s *CoreService) StartService(ctx context.Context, in *pb.StartRequest) (*pb.CoreInfoResponse, error) {
// Implement the StartService method return StartService(in)
func (s *server) StartService(ctx context.Context, in *pb.StartRequest) (*pb.CoreInfoResponse, error) { }
func StartService(in *pb.StartRequest) (*pb.CoreInfoResponse, error) {
content := in.ConfigContent content := in.ConfigContent
if content != "" { if content == "" {
if in.ConfigPath != "" {
activeConfigPath = &in.ConfigPath
}
fileContent, err := os.ReadFile(*activeConfigPath) fileContent, err := os.ReadFile(*activeConfigPath)
if err != nil { if err != nil {
Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error())
resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_ERROR_READING_CONFIG, err.Error()) resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_ERROR_READING_CONFIG, err.Error())
return &resp, err return &resp, err
} }
@@ -68,26 +83,31 @@ func (s *server) StartService(ctx context.Context, in *pb.StartRequest) (*pb.Cor
parsedContent, err := parseConfig(content) parsedContent, err := parseConfig(content)
if err != nil { if err != nil {
Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error())
resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_ERROR_PARSING_CONFIG, err.Error()) resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_ERROR_PARSING_CONFIG, err.Error())
return &resp, err return &resp, err
} }
var patchedOptions *option.Options var patchedOptions *option.Options
patchedOptions, err = config.BuildConfig(*configOptions, parsedContent) patchedOptions, err = config.BuildConfig(*configOptions, parsedContent)
if err != nil { if err != nil {
Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error())
resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_ERROR_BUILDING_CONFIG, err.Error()) resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_ERROR_BUILDING_CONFIG, err.Error())
return &resp, err return &resp, err
} }
config.SaveCurrentConfig(filepath.Join(sWorkingPath, "current-config.json"), *patchedOptions) config.SaveCurrentConfig(filepath.Join(sWorkingPath, "current-config.json"), *patchedOptions)
if in.EnableOldCommandServer {
// err = startCommandServer(*logFactory) err = startCommandServer(*logFactory)
// if err != nil { if err != nil {
// resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_START_COMMAND_SERVER, err.Error()) Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error())
// return &resp, err resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_START_COMMAND_SERVER, err.Error())
// } return &resp, err
}
}
instance, err := NewService(*patchedOptions) instance, err := NewService(*patchedOptions)
if err != nil { if err != nil {
Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error())
resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_CREATE_SERVICE, err.Error()) resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_CREATE_SERVICE, err.Error())
return &resp, err return &resp, err
} }
@@ -98,30 +118,55 @@ func (s *server) StartService(ctx context.Context, in *pb.StartRequest) (*pb.Cor
err = instance.Start() err = instance.Start()
if err != nil { if err != nil {
Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error())
resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_START_SERVICE, err.Error()) resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_START_SERVICE, err.Error())
return &resp, err return &resp, err
} }
Box = instance Box = instance
// commandServer.SetService(box) if in.EnableOldCommandServer {
commandServer.SetService(Box)
}
resp := SetCoreStatus(pb.CoreState_STARTED, pb.MessageType_EMPTY, "") resp := SetCoreStatus(pb.CoreState_STARTED, pb.MessageType_EMPTY, "")
return &resp, nil return &resp, nil
} }
func (s *server) Parse(ctx context.Context, in *pb.ParseRequest) (*pb.ParseResponse, error) { func (s *CoreService) Parse(ctx context.Context, in *pb.ParseRequest) (*pb.ParseResponse, error) {
return Parse(in)
}
func Parse(in *pb.ParseRequest) (*pb.ParseResponse, error) {
defer config.DeferPanicToError("parse", func(err error) { defer config.DeferPanicToError("parse", func(err error) {
Log(pb.LogLevel_FATAL, pb.LogType_CONFIG, err.Error()) Log(pb.LogLevel_FATAL, pb.LogType_CONFIG, err.Error())
StopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error()) StopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error())
}) })
content := in.Content
if in.TempPath != "" {
contentBytes, err := os.ReadFile(in.TempPath)
content = string(contentBytes)
os.Chdir(filepath.Dir(in.ConfigPath))
if err != nil {
return nil, err
}
config, err := config.ParseConfigContent(in.Content, true) }
config, err := config.ParseConfigContent(content, true)
if err != nil { if err != nil {
return &pb.ParseResponse{ return &pb.ParseResponse{
ResponseCode: pb.ResponseCode_FAILED, ResponseCode: pb.ResponseCode_FAILED,
Message: err.Error(), Message: err.Error(),
}, err }, err
} }
if in.ConfigPath != "" {
err = os.WriteFile(in.ConfigPath, config, 0644)
if err != nil {
return &pb.ParseResponse{
ResponseCode: pb.ResponseCode_FAILED,
Message: err.Error(),
}, err
}
}
return &pb.ParseResponse{ return &pb.ParseResponse{
ResponseCode: pb.ResponseCode_OK, ResponseCode: pb.ResponseCode_OK,
Content: string(config), Content: string(config),
@@ -129,31 +174,67 @@ func (s *server) Parse(ctx context.Context, in *pb.ParseRequest) (*pb.ParseRespo
}, err }, err
} }
// func (s *server) ChangeConfigOptions(ctx context.Context, in *pb.ChangeConfigOptionsRequest) (*pb.CoreInfoResponse, error) { func (s *CoreService) ChangeConfigOptions(ctx context.Context, in *pb.ChangeConfigOptionsRequest) (*pb.CoreInfoResponse, error) {
// // Implement your change config options logic return ChangeConfigOptions(in)
// // Return a CoreInfoResponse }
// }
// func (s *server) GenerateConfig(ctx context.Context, in *pb.GenerateConfigRequest) (*pb.GenerateConfigResponse, error) { func ChangeConfigOptions(in *pb.ChangeConfigOptionsRequest) (*pb.CoreInfoResponse, error) {
// defer config.DeferPanicToError("generateConfig", func(err error) { configOptions = &config.ConfigOptions{}
// Log(pb.LogLevel_FATAL, pb.LogType_CONFIG, err.Error()) err := json.Unmarshal([]byte(in.ConfigOptionsJson), configOptions)
// StopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error()) if err != nil {
// }) return nil, err
}
if configOptions.Warp.WireguardConfigStr != "" {
err := json.Unmarshal([]byte(configOptions.Warp.WireguardConfigStr), &configOptions.Warp.WireguardConfig)
if err != nil {
return nil, err
}
}
return &pb.CoreInfoResponse{}, nil
}
func (s *CoreService) GenerateConfig(ctx context.Context, in *pb.GenerateConfigRequest) (*pb.GenerateConfigResponse, error) {
return GenerateConfig(in)
}
func GenerateConfig(in *pb.GenerateConfigRequest) (*pb.GenerateConfigResponse, error) {
defer config.DeferPanicToError("generateConfig", func(err error) {
Log(pb.LogLevel_FATAL, pb.LogType_CONFIG, err.Error())
StopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error())
})
// config, err := generateConfigFromFile(C.GoString(path), *configOptions) config, err := generateConfigFromFile(in.Path, *configOptions)
// if err != nil { if err != nil {
// return C.CString("error" + err.Error()) return nil, err
// } }
// return C.CString(config) return &pb.GenerateConfigResponse{
// } ConfigContent: config,
}, nil
}
func generateConfigFromFile(path string, configOpt config.ConfigOptions) (string, error) {
os.Chdir(filepath.Dir(path))
content, err := os.ReadFile(path)
if err != nil {
return "", err
}
options, err := parseConfig(string(content))
if err != nil {
return "", err
}
config, err := config.BuildConfigJson(configOpt, options)
if err != nil {
return "", err
}
return config, nil
}
// Implement the Stop method func (s *CoreService) Stop(ctx context.Context, empty *pb.Empty) (*pb.CoreInfoResponse, error) {
func (s *server) Stop(ctx context.Context, empty *pb.Empty) (*pb.CoreInfoResponse, error) { return Stop()
}
func Stop() (*pb.CoreInfoResponse, error) {
defer config.DeferPanicToError("stop", func(err error) { defer config.DeferPanicToError("stop", func(err error) {
Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error()) Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error())
StopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error()) StopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error())
}) })
config.DeactivateTunnelService()
if CoreState != pb.CoreState_STARTED { if CoreState != pb.CoreState_STARTED {
Log(pb.LogLevel_FATAL, pb.LogType_CORE, "Core is not started") Log(pb.LogLevel_FATAL, pb.LogType_CORE, "Core is not started")
return &pb.CoreInfoResponse{ return &pb.CoreInfoResponse{
@@ -170,7 +251,10 @@ func (s *server) Stop(ctx context.Context, empty *pb.Empty) (*pb.CoreInfoRespons
}, fmt.Errorf("instance not found") }, fmt.Errorf("instance not found")
} }
SetCoreStatus(pb.CoreState_STOPPING, pb.MessageType_EMPTY, "") SetCoreStatus(pb.CoreState_STOPPING, pb.MessageType_EMPTY, "")
// commandServer.SetService(nil) config.DeactivateTunnelService()
if commandServer != nil {
commandServer.SetService(nil)
}
err := Box.Close() err := Box.Close()
if err != nil { if err != nil {
@@ -181,22 +265,25 @@ func (s *server) Stop(ctx context.Context, empty *pb.Empty) (*pb.CoreInfoRespons
}, fmt.Errorf("Error while stopping the service.") }, fmt.Errorf("Error while stopping the service.")
} }
Box = nil Box = nil
// err = commandServer.Close() if commandServer != nil {
// if err != nil { err = commandServer.Close()
// return &pb.CoreInfoResponse{ if err != nil {
// CoreState: CoreState, return &pb.CoreInfoResponse{
// MessageType: pb.MessageType_UNEXPECTED_ERROR, CoreState: CoreState,
// Message: "Error while Closing the comand server.", MessageType: pb.MessageType_UNEXPECTED_ERROR,
// }, fmt.Errorf("Error while Closing the comand server.") Message: "Error while Closing the comand server.",
}, fmt.Errorf("Error while Closing the comand server.")
// } }
// commandServer = nil commandServer = nil
}
resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_EMPTY, "") resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_EMPTY, "")
return &resp, nil return &resp, nil
} }
func (s *CoreService) Restart(ctx context.Context, in *pb.StartRequest) (*pb.CoreInfoResponse, error) {
func (s *server) Restart(ctx context.Context, in *pb.StartRequest) (*pb.CoreInfoResponse, error) { return Restart(in)
}
func Restart(in *pb.StartRequest) (*pb.CoreInfoResponse, error) {
defer config.DeferPanicToError("restart", func(err error) { defer config.DeferPanicToError("restart", func(err error) {
Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error()) Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error())
StopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error()) StopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error())
@@ -218,7 +305,7 @@ func (s *server) Restart(ctx context.Context, in *pb.StartRequest) (*pb.CoreInfo
}, fmt.Errorf("instance not found") }, fmt.Errorf("instance not found")
} }
resp, err := s.Stop(ctx, &pb.Empty{}) resp, err := Stop()
if err != nil { if err != nil {
return resp, err return resp, err
} }
@@ -227,6 +314,6 @@ func (s *server) Restart(ctx context.Context, in *pb.StartRequest) (*pb.CoreInfo
<-time.After(250 * time.Millisecond) <-time.After(250 * time.Millisecond)
libbox.SetMemoryLimit(!in.DisableMemoryLimit) libbox.SetMemoryLimit(!in.DisableMemoryLimit)
resp, gErr := s.StartService(ctx, in) resp, gErr := StartService(in)
return resp, gErr return resp, gErr
} }

View File

@@ -21,7 +21,7 @@ func main() {
log.Fatalf("did not connect: %v", err) log.Fatalf("did not connect: %v", err)
} }
defer conn.Close() defer conn.Close()
c := pb.NewHiddifyClient(conn) c := pb.NewHelloClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel() defer cancel()

View File

@@ -11,7 +11,7 @@ import (
func main() { func main() {
// defer C.free(unsafe.Pointer(port)) // defer C.free(unsafe.Pointer(port))
v2.StartGrpcServerGo("127.0.0.1:50051") v2.StartGrpcServer("127.0.0.1:50051")
sigChan := make(chan os.Signal, 1) sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
<-sigChan <-sigChan

View File

@@ -13,24 +13,18 @@ import (
"google.golang.org/grpc" "google.golang.org/grpc"
) )
type server struct { type HelloService struct {
pb.UnimplementedHiddifyServer pb.UnimplementedHelloServer
}
type CoreService struct {
pb.UnimplementedCoreServer
} }
//export StartGrpcServer type TunnelService struct {
func StartGrpcServer(listenAddress *C.char) (CErr *C.char) { pb.UnimplementedTunnelServiceServer
//Example Listen Address: "127.0.0.1:50051"
err := StartGrpcServerGo(C.GoString(listenAddress))
if err != nil {
return C.CString(err.Error())
}
return nil
} }
func StartGrpcServerGo(listenAddressG string) error { func StartGrpcServer(listenAddressG string, service string) error {
//Example Listen Address: "127.0.0.1:50051"
// defer C.free(unsafe.Pointer(CErr)) // free the C string when it's no longer needed
// defer C.free(unsafe.Pointer(listenAddress)) // free the C string when it's no longer needed
lis, err := net.Listen("tcp", listenAddressG) lis, err := net.Listen("tcp", listenAddressG)
if err != nil { if err != nil {
@@ -38,7 +32,13 @@ func StartGrpcServerGo(listenAddressG string) error {
return err return err
} }
s := grpc.NewServer() s := grpc.NewServer()
pb.RegisterHiddifyServer(s, &server{}) if service == "core" {
pb.RegisterCoreServer(s, &CoreService{})
} else if service == "hello" {
pb.RegisterHelloServer(s, &HelloService{})
} else if service == "tunnel" {
pb.RegisterTunnelServiceServer(s, &TunnelService{})
}
log.Printf("Server listening on %s", listenAddressG) log.Printf("Server listening on %s", listenAddressG)
go func() { go func() {
if err := s.Serve(lis); err != nil { if err := s.Serve(lis); err != nil {
@@ -47,3 +47,14 @@ func StartGrpcServerGo(listenAddressG string) error {
}() }()
return nil return nil
} }
func StartCoreGrpcServer(listenAddressG string) error {
return StartGrpcServer(listenAddressG, "core")
}
func StartHelloGrpcServer(listenAddressG string) error {
return StartGrpcServer(listenAddressG, "hello")
}
func StartTunnelGrpcServer(listenAddressG string) error {
return StartGrpcServer(listenAddressG, "tunnel")
}

View File

@@ -8,10 +8,10 @@ import (
pb "github.com/hiddify/libcore/hiddifyrpc" pb "github.com/hiddify/libcore/hiddifyrpc"
) )
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) { func (s *HelloService) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
return &pb.HelloResponse{Message: "Hello, " + in.Name}, nil return &pb.HelloResponse{Message: "Hello, " + in.Name}, nil
} }
func (s *server) SayHelloStream(stream pb.Hiddify_SayHelloStreamServer) error { func (s *HelloService) SayHelloStream(stream pb.Hello_SayHelloStreamServer) error {
for { for {
req, err := stream.Recv() req, err := stream.Recv()

View File

@@ -1,15 +1,21 @@
package v2 package v2
import ( import (
"fmt"
"time" "time"
pb "github.com/hiddify/libcore/hiddifyrpc" pb "github.com/hiddify/libcore/hiddifyrpc"
"github.com/sagernet/sing/common/observable" "github.com/sagernet/sing/common/observable"
) )
var logObserver = observable.Observer[pb.LogMessage]{} func NewObserver[T any](listenerBufferSize int) *observable.Observer[T] {
return observable.NewObserver[T](&observable.Subscriber[T]{}, listenerBufferSize)
}
var logObserver = NewObserver[pb.LogMessage](10)
func Log(level pb.LogLevel, typ pb.LogType, message string) { func Log(level pb.LogLevel, typ pb.LogType, message string) {
fmt.Printf("%s %s %s\n", level, typ, message)
logObserver.Emit(pb.LogMessage{ logObserver.Emit(pb.LogMessage{
Level: level, Level: level,
Type: typ, Type: typ,
@@ -18,7 +24,7 @@ func Log(level pb.LogLevel, typ pb.LogType, message string) {
} }
func (s *server) LogListener(stream pb.Hiddify_LogListenerServer) error { func (s *CoreService) LogListener(stream pb.Core_LogListenerServer) error {
logSub, _, _ := logObserver.Subscribe() logSub, _, _ := logObserver.Subscribe()
defer logObserver.UnSubscribe(logSub) defer logObserver.UnSubscribe(logSub)
@@ -30,9 +36,7 @@ func (s *server) LogListener(stream pb.Hiddify_LogListenerServer) error {
for { for {
select { select {
case <-stream.Context().Done(): case <-stream.Context().Done():
break return nil
case <-stopch:
break
case info := <-logSub: case info := <-logSub:
stream.Send(&info) stream.Send(&info)
case <-time.After(500 * time.Millisecond): case <-time.After(500 * time.Millisecond):

View File

@@ -1,4 +1,4 @@
package main package v2
import ( import (
"encoding/json" "encoding/json"
@@ -6,31 +6,34 @@ import (
"github.com/hiddify/libcore/bridge" "github.com/hiddify/libcore/bridge"
"github.com/sagernet/sing-box/experimental/libbox" "github.com/sagernet/sing-box/experimental/libbox"
"github.com/sagernet/sing-box/log"
) )
type CommandClientHandler struct { var (
port int64 _ libbox.CommandClientHandler = (*OldCommandClientHandler)(nil)
logger log.Logger )
type OldCommandClientHandler struct {
port int64
// logger log.Logger
} }
func (cch *CommandClientHandler) Connected() { func (cch *OldCommandClientHandler) Connected() {
cch.logger.Debug("CONNECTED") // cch.logger.Debug("CONNECTED")
} }
func (cch *CommandClientHandler) Disconnected(message string) { func (cch *OldCommandClientHandler) Disconnected(message string) {
cch.logger.Debug("DISCONNECTED: ", message) // cch.logger.Debug("DISCONNECTED: ", message)
} }
func (cch *CommandClientHandler) ClearLog() { func (cch *OldCommandClientHandler) ClearLog() {
cch.logger.Debug("clear log") // cch.logger.Debug("clear log")
} }
func (cch *CommandClientHandler) WriteLog(message string) { func (cch *OldCommandClientHandler) WriteLog(message string) {
cch.logger.Debug("log: ", message) // cch.logger.Debug("log: ", message)
} }
func (cch *CommandClientHandler) WriteStatus(message *libbox.StatusMessage) { func (cch *OldCommandClientHandler) WriteStatus(message *libbox.StatusMessage) {
msg, err := json.Marshal( msg, err := json.Marshal(
map[string]int64{ map[string]int64{
"connections-in": int64(message.ConnectionsIn), "connections-in": int64(message.ConnectionsIn),
@@ -41,7 +44,7 @@ func (cch *CommandClientHandler) WriteStatus(message *libbox.StatusMessage) {
"downlink-total": message.DownlinkTotal, "downlink-total": message.DownlinkTotal,
}, },
) )
cch.logger.Debug("Memory: ", libbox.FormatBytes(message.Memory), ", Goroutines: ", message.Goroutines) // cch.logger.Debug("Memory: ", libbox.FormatBytes(message.Memory), ", Goroutines: ", message.Goroutines)
if err != nil { if err != nil {
bridge.SendStringToPort(cch.port, fmt.Sprintf("error: %e", err)) bridge.SendStringToPort(cch.port, fmt.Sprintf("error: %e", err))
} else { } else {
@@ -49,7 +52,7 @@ func (cch *CommandClientHandler) WriteStatus(message *libbox.StatusMessage) {
} }
} }
func (cch *CommandClientHandler) WriteGroups(message libbox.OutboundGroupIterator) { func (cch *OldCommandClientHandler) WriteGroups(message libbox.OutboundGroupIterator) {
if message == nil { if message == nil {
return return
} }
@@ -79,12 +82,12 @@ func (cch *CommandClientHandler) WriteGroups(message libbox.OutboundGroupIterato
} }
} }
func (cch *CommandClientHandler) InitializeClashMode(modeList libbox.StringIterator, currentMode string) { func (cch *OldCommandClientHandler) InitializeClashMode(modeList libbox.StringIterator, currentMode string) {
cch.logger.Debug("initial clash mode: ", currentMode) // cch.logger.Debug("initial clash mode: ", currentMode)
} }
func (cch *CommandClientHandler) UpdateClashMode(newMode string) { func (cch *OldCommandClientHandler) UpdateClashMode(newMode string) {
cch.logger.Debug("update clash mode: ", newMode) // cch.logger.Debug("update clash mode: ", newMode)
} }
type OutboundGroup struct { type OutboundGroup struct {

View File

@@ -1,11 +1,10 @@
package main package v2
import ( import (
pb "github.com/hiddify/libcore/hiddifyrpc" pb "github.com/hiddify/libcore/hiddifyrpc"
v2 "github.com/hiddify/libcore/v2"
"github.com/sagernet/sing-box/experimental/libbox" "github.com/sagernet/sing-box/experimental/libbox"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
) )
var commandServer *libbox.CommandServer var commandServer *libbox.CommandServer
@@ -16,16 +15,21 @@ type CommandServerHandler struct {
func (csh *CommandServerHandler) ServiceReload() error { func (csh *CommandServerHandler) ServiceReload() error {
csh.logger.Trace("Reloading service") csh.logger.Trace("Reloading service")
propagateStatus(pb.CoreState_STARTING) SetCoreStatus(pb.CoreState_STARTING, pb.MessageType_EMPTY, "")
if commandServer != nil { if commandServer != nil {
commandServer.SetService(nil) commandServer.SetService(nil)
commandServer = nil commandServer = nil
} }
if v2.Box != nil { if Box != nil {
v2.Box.Close() Box.Close()
v2.Box = nil Box = nil
} }
return startService(true) _, err := StartService(&pb.StartRequest{
EnableOldCommandServer: true,
DelayStart: true,
})
return err
} }
func (csh *CommandServerHandler) GetSystemProxyStatus() *libbox.SystemProxyStatus { func (csh *CommandServerHandler) GetSystemProxyStatus() *libbox.SystemProxyStatus {

71
v2/old_commands.go Normal file
View File

@@ -0,0 +1,71 @@
package v2
import (
"github.com/sagernet/sing-box/experimental/libbox"
)
var (
oldStatusClient *libbox.CommandClient
oldGroupClient *libbox.CommandClient
oldGroupInfoOnlyClient *libbox.CommandClient
)
func StartCommand(command int32, port int64) error {
switch command {
case libbox.CommandStatus:
oldStatusClient = libbox.NewCommandClient(
&OldCommandClientHandler{
port: port,
// logger: logFactory.NewLogger("[Status Command Client]"),
},
&libbox.CommandClientOptions{
Command: libbox.CommandStatus,
StatusInterval: 1000000000, //1000ms debounce
},
)
return oldStatusClient.Connect()
case libbox.CommandGroup:
oldGroupClient = libbox.NewCommandClient(
&OldCommandClientHandler{
port: port,
// logger: logFactory.NewLogger("[Group Command Client]"),
},
&libbox.CommandClientOptions{
Command: libbox.CommandGroup,
StatusInterval: 300000000, //300ms debounce
},
)
return oldGroupClient.Connect()
case libbox.CommandGroupInfoOnly:
oldGroupInfoOnlyClient = libbox.NewCommandClient(
&OldCommandClientHandler{
port: port,
// logger: logFactory.NewLogger("[GroupInfoOnly Command Client]"),
},
&libbox.CommandClientOptions{
Command: libbox.CommandGroupInfoOnly,
StatusInterval: 300000000, //300ms debounce
},
)
return oldGroupInfoOnlyClient.Connect()
}
return nil
}
func StopCommand(command int32) error {
switch command {
case libbox.CommandStatus:
err := oldStatusClient.Disconnect()
oldStatusClient = nil
return err
case libbox.CommandGroup:
err := oldGroupClient.Disconnect()
oldGroupClient = nil
return err
case libbox.CommandGroupInfoOnly:
err := oldGroupInfoOnlyClient.Disconnect()
oldGroupInfoOnlyClient = nil
return err
}
return nil
}

38
v2/old_constant.go Normal file
View File

@@ -0,0 +1,38 @@
package v2
import pb "github.com/hiddify/libcore/hiddifyrpc"
const (
Stopped = "Stopped"
Starting = "Starting"
Started = "Started"
Stopping = "Stopping"
)
const (
EmptyConfiguration = "EmptyConfiguration"
StartCommandServer = "StartCommandServer"
CreateService = "CreateService"
)
func convert2OldState(newStatus pb.CoreState) string {
if newStatus == pb.CoreState_STOPPED {
return Stopped
}
if newStatus == pb.CoreState_STARTED {
return Started
}
if newStatus == pb.CoreState_STARTING {
return Starting
}
if newStatus == pb.CoreState_STOPPING {
return Stopping
}
return "Invalid"
}
type StatusMessage struct {
Status string `json:"status"`
Alert *string `json:"alert"`
Message *string `json:"message"`
}

View File

@@ -2,13 +2,16 @@ package v2
import ( import (
"context" "context"
"io"
"os" "os"
"runtime" "runtime"
runtimeDebug "runtime/debug" runtimeDebug "runtime/debug"
"time"
B "github.com/sagernet/sing-box" B "github.com/sagernet/sing-box"
"github.com/sagernet/sing-box/common/urltest" "github.com/sagernet/sing-box/common/urltest"
"github.com/sagernet/sing-box/experimental/libbox" "github.com/sagernet/sing-box/experimental/libbox"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/service" "github.com/sagernet/sing/service"
@@ -17,13 +20,15 @@ import (
) )
var ( var (
sWorkingPath string sWorkingPath string
sTempPath string sTempPath string
sUserID int sUserID int
sGroupID int sGroupID int
statusPropagationPort int64
) )
func Setup(basePath string, workingPath string, tempPath string) { func Setup(basePath string, workingPath string, tempPath string, statusPort int64, debug bool) error {
statusPropagationPort = int64(statusPort)
tcpConn := runtime.GOOS == "windows" //TODO add TVOS tcpConn := runtime.GOOS == "windows" //TODO add TVOS
libbox.Setup(basePath, workingPath, tempPath, tcpConn) libbox.Setup(basePath, workingPath, tempPath, tcpConn)
sWorkingPath = workingPath sWorkingPath = workingPath
@@ -31,6 +36,19 @@ func Setup(basePath string, workingPath string, tempPath string) {
sTempPath = tempPath sTempPath = tempPath
sUserID = os.Getuid() sUserID = os.Getuid()
sGroupID = os.Getgid() sGroupID = os.Getgid()
var defaultWriter io.Writer
if !debug {
defaultWriter = io.Discard
}
factory, err := log.New(
log.Options{
DefaultWriter: defaultWriter,
BaseTime: time.Now(),
Observable: false,
})
logFactory = &factory
return err
} }
func NewService(options option.Options) (*libbox.BoxService, error) { func NewService(options option.Options) (*libbox.BoxService, error) {

44
v2/system_proxy.go Normal file
View File

@@ -0,0 +1,44 @@
package v2
import (
"context"
pb "github.com/hiddify/libcore/hiddifyrpc"
"github.com/sagernet/sing-box/experimental/libbox"
)
func (s *CoreService) GetSystemProxyStatus(ctx context.Context, empty *pb.Empty) (*pb.SystemProxyStatus, error) {
return GetSystemProxyStatus(ctx, empty)
}
func GetSystemProxyStatus(ctx context.Context, empty *pb.Empty) (*pb.SystemProxyStatus, error) {
status, err := libbox.NewStandaloneCommandClient().GetSystemProxyStatus()
if err != nil {
return nil, err
}
return &pb.SystemProxyStatus{
Available: status.Available,
Enabled: status.Enabled,
}, nil
}
func (s *CoreService) SetSystemProxyEnabled(ctx context.Context, in *pb.SetSystemProxyEnabledRequest) (*pb.Response, error) {
return SetSystemProxyEnabled(ctx, in)
}
func SetSystemProxyEnabled(ctx context.Context, in *pb.SetSystemProxyEnabledRequest) (*pb.Response, error) {
err := libbox.NewStandaloneCommandClient().SetSystemProxyEnabled(in.IsEnabled)
if err != nil {
return &pb.Response{
ResponseCode: pb.ResponseCode_FAILED,
Message: err.Error(),
}, err
}
return &pb.Response{
ResponseCode: pb.ResponseCode_OK,
Message: "",
}, nil
}

View File

@@ -5,10 +5,12 @@ import (
"github.com/hiddify/libcore/config" "github.com/hiddify/libcore/config"
pb "github.com/hiddify/libcore/hiddifyrpc" pb "github.com/hiddify/libcore/hiddifyrpc"
"github.com/sagernet/sing-box/experimental/libbox"
) )
func (s *server) GenerateWarpConfig(ctx context.Context, in *pb.GenerateWarpConfigRequest) (*pb.WarpGenerationResponse, error) { func (s *CoreService) GenerateWarpConfig(ctx context.Context, in *pb.GenerateWarpConfigRequest) (*pb.WarpGenerationResponse, error) {
return GenerateWarpConfig(in)
}
func GenerateWarpConfig(in *pb.GenerateWarpConfigRequest) (*pb.WarpGenerationResponse, error) {
account, log, wg, err := config.GenerateWarpInfo(in.LicenseKey, in.AccountId, in.AccessToken) account, log, wg, err := config.GenerateWarpInfo(in.LicenseKey, in.AccountId, in.AccessToken)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -27,39 +29,3 @@ func (s *server) GenerateWarpConfig(ctx context.Context, in *pb.GenerateWarpConf
Log: log, Log: log,
}, nil }, nil
} }
// Implement the GetSystemProxyStatus method
func (s *server) GetSystemProxyStatus(ctx context.Context, empty *pb.Empty) (*pb.SystemProxyStatus, error) {
status, err := libbox.NewStandaloneCommandClient().GetSystemProxyStatus()
if err != nil {
return nil, err
}
return &pb.SystemProxyStatus{
Available: status.Available,
Enabled: status.Enabled,
}, nil
}
// Implement the SetSystemProxyEnabled method
func (s *server) SetSystemProxyEnabled(ctx context.Context, in *pb.SetSystemProxyEnabledRequest) (*pb.Response, error) {
err := libbox.NewStandaloneCommandClient().SetSystemProxyEnabled(in.IsEnabled)
if err != nil {
return nil, err
}
if err != nil {
return &pb.Response{
ResponseCode: pb.ResponseCode_FAILED,
Message: err.Error(),
}, err
}
return &pb.Response{
ResponseCode: pb.ResponseCode_OK,
Message: "",
}, nil
}