new: add hiddifyrpc
This commit is contained in:
232
v2/custom.go
Normal file
232
v2/custom.go
Normal file
@@ -0,0 +1,232 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/hiddify/libcore/config"
|
||||
pb "github.com/hiddify/libcore/hiddifyrpc"
|
||||
"github.com/sagernet/sing-box/experimental/libbox"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
)
|
||||
|
||||
var Box *libbox.BoxService
|
||||
var configOptions *config.ConfigOptions
|
||||
var activeConfigPath *string
|
||||
var logFactory *log.Factory
|
||||
|
||||
func stopAndAlert(msgType pb.MessageType, message string) {
|
||||
SetCoreStatus(pb.CoreState_STOPPED, msgType, message)
|
||||
config.DeactivateTunnelService()
|
||||
// if commandServer != nil {
|
||||
// commandServer.SetService(nil)
|
||||
// }
|
||||
if Box != nil {
|
||||
Box.Close()
|
||||
Box = nil
|
||||
}
|
||||
// if commandServer != nil {
|
||||
// commandServer.Close()
|
||||
// }
|
||||
}
|
||||
|
||||
func (s *server) Start(ctx context.Context, in *pb.StartRequest) (*pb.CoreInfoResponse, error) {
|
||||
defer config.DeferPanicToError("start", func(err error) {
|
||||
Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error())
|
||||
stopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error())
|
||||
})
|
||||
|
||||
if CoreState != pb.CoreState_STOPPED {
|
||||
return &pb.CoreInfoResponse{
|
||||
CoreState: CoreState,
|
||||
MessageType: pb.MessageType_INSTANCE_NOT_STOPPED,
|
||||
}, fmt.Errorf("instance not stopped")
|
||||
}
|
||||
SetCoreStatus(pb.CoreState_STARTING, pb.MessageType_EMPTY, "")
|
||||
|
||||
libbox.SetMemoryLimit(!in.DisableMemoryLimit)
|
||||
resp, err := s.StartService(ctx, in)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Implement the StartService method
|
||||
func (s *server) StartService(ctx context.Context, in *pb.StartRequest) (*pb.CoreInfoResponse, error) {
|
||||
|
||||
content := in.ConfigContent
|
||||
if content != "" {
|
||||
fileContent, err := os.ReadFile(*activeConfigPath)
|
||||
if err != nil {
|
||||
resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_ERROR_READING_CONFIG, err.Error())
|
||||
return &resp, err
|
||||
}
|
||||
content = string(fileContent)
|
||||
}
|
||||
|
||||
parsedContent, err := parseConfig(content)
|
||||
if err != nil {
|
||||
resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_ERROR_PARSING_CONFIG, err.Error())
|
||||
return &resp, err
|
||||
}
|
||||
var patchedOptions *option.Options
|
||||
patchedOptions, err = config.BuildConfig(*configOptions, parsedContent)
|
||||
if err != nil {
|
||||
resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_ERROR_BUILDING_CONFIG, err.Error())
|
||||
return &resp, err
|
||||
}
|
||||
|
||||
config.SaveCurrentConfig(filepath.Join(sWorkingPath, "current-config.json"), *patchedOptions)
|
||||
|
||||
// err = startCommandServer(*logFactory)
|
||||
// if err != nil {
|
||||
// resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_START_COMMAND_SERVER, err.Error())
|
||||
// return &resp, err
|
||||
// }
|
||||
|
||||
instance, err := NewService(*patchedOptions)
|
||||
if err != nil {
|
||||
resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_CREATE_SERVICE, err.Error())
|
||||
return &resp, err
|
||||
}
|
||||
|
||||
if in.DelayStart {
|
||||
<-time.After(250 * time.Millisecond)
|
||||
}
|
||||
|
||||
err = instance.Start()
|
||||
if err != nil {
|
||||
resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_START_SERVICE, err.Error())
|
||||
return &resp, err
|
||||
}
|
||||
Box = instance
|
||||
// commandServer.SetService(box)
|
||||
|
||||
resp := SetCoreStatus(pb.CoreState_STARTED, pb.MessageType_EMPTY, "")
|
||||
return &resp, nil
|
||||
|
||||
}
|
||||
|
||||
func (s *server) Parse(ctx context.Context, in *pb.ParseRequest) (*pb.ParseResponse, error) {
|
||||
defer config.DeferPanicToError("parse", func(err error) {
|
||||
Log(pb.LogLevel_FATAL, pb.LogType_CONFIG, err.Error())
|
||||
stopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error())
|
||||
})
|
||||
|
||||
config, err := config.ParseConfigContent(in.Content, true)
|
||||
if err != nil {
|
||||
return &pb.ParseResponse{
|
||||
ResponseCode: pb.ResponseCode_FAILED,
|
||||
Message: err.Error(),
|
||||
}, err
|
||||
}
|
||||
return &pb.ParseResponse{
|
||||
ResponseCode: pb.ResponseCode_OK,
|
||||
Content: string(config),
|
||||
Message: "",
|
||||
}, err
|
||||
}
|
||||
|
||||
// func (s *server) ChangeConfigOptions(ctx context.Context, in *pb.ChangeConfigOptionsRequest) (*pb.CoreInfoResponse, error) {
|
||||
// // Implement your change config options logic
|
||||
// // Return a CoreInfoResponse
|
||||
// }
|
||||
|
||||
// func (s *server) GenerateConfig(ctx context.Context, 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)
|
||||
// if err != nil {
|
||||
// return C.CString("error" + err.Error())
|
||||
// }
|
||||
// return C.CString(config)
|
||||
// }
|
||||
|
||||
// Implement the Stop method
|
||||
func (s *server) Stop(ctx context.Context, empty *pb.Empty) (*pb.CoreInfoResponse, error) {
|
||||
defer config.DeferPanicToError("stop", func(err error) {
|
||||
Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error())
|
||||
stopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error())
|
||||
})
|
||||
config.DeactivateTunnelService()
|
||||
if CoreState != pb.CoreState_STARTED {
|
||||
Log(pb.LogLevel_FATAL, pb.LogType_CORE, "Core is not started")
|
||||
return &pb.CoreInfoResponse{
|
||||
CoreState: CoreState,
|
||||
MessageType: pb.MessageType_INSTANCE_NOT_STARTED,
|
||||
Message: "instance is not started",
|
||||
}, fmt.Errorf("instance not started")
|
||||
}
|
||||
if Box == nil {
|
||||
return &pb.CoreInfoResponse{
|
||||
CoreState: CoreState,
|
||||
MessageType: pb.MessageType_INSTANCE_NOT_FOUND,
|
||||
Message: "instance is not found",
|
||||
}, fmt.Errorf("instance not found")
|
||||
}
|
||||
SetCoreStatus(pb.CoreState_STOPPING, pb.MessageType_EMPTY, "")
|
||||
// commandServer.SetService(nil)
|
||||
|
||||
err := Box.Close()
|
||||
if err != nil {
|
||||
return &pb.CoreInfoResponse{
|
||||
CoreState: CoreState,
|
||||
MessageType: pb.MessageType_UNEXPECTED_ERROR,
|
||||
Message: "Error while stopping the service.",
|
||||
}, fmt.Errorf("Error while stopping the service.")
|
||||
}
|
||||
Box = nil
|
||||
// err = commandServer.Close()
|
||||
// if err != nil {
|
||||
// return &pb.CoreInfoResponse{
|
||||
// CoreState: CoreState,
|
||||
// MessageType: pb.MessageType_UNEXPECTED_ERROR,
|
||||
// Message: "Error while Closing the comand server.",
|
||||
// }, fmt.Errorf("Error while Closing the comand server.")
|
||||
|
||||
// }
|
||||
// commandServer = nil
|
||||
resp := SetCoreStatus(pb.CoreState_STOPPED, pb.MessageType_EMPTY, "")
|
||||
return &resp, nil
|
||||
|
||||
}
|
||||
|
||||
func (s *server) Restart(ctx context.Context, in *pb.StartRequest) (*pb.CoreInfoResponse, error) {
|
||||
defer config.DeferPanicToError("restart", func(err error) {
|
||||
Log(pb.LogLevel_FATAL, pb.LogType_CORE, err.Error())
|
||||
stopAndAlert(pb.MessageType_UNEXPECTED_ERROR, err.Error())
|
||||
})
|
||||
log.Debug("[Service] Restarting")
|
||||
|
||||
if CoreState != pb.CoreState_STARTED {
|
||||
return &pb.CoreInfoResponse{
|
||||
CoreState: CoreState,
|
||||
MessageType: pb.MessageType_INSTANCE_NOT_STARTED,
|
||||
Message: "instance is not started",
|
||||
}, fmt.Errorf("instance not started")
|
||||
}
|
||||
if Box == nil {
|
||||
return &pb.CoreInfoResponse{
|
||||
CoreState: CoreState,
|
||||
MessageType: pb.MessageType_INSTANCE_NOT_FOUND,
|
||||
Message: "instance is not found",
|
||||
}, fmt.Errorf("instance not found")
|
||||
}
|
||||
|
||||
resp, err := s.Stop(ctx, &pb.Empty{})
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
SetCoreStatus(pb.CoreState_STARTING, pb.MessageType_EMPTY, "")
|
||||
<-time.After(250 * time.Millisecond)
|
||||
|
||||
libbox.SetMemoryLimit(!in.DisableMemoryLimit)
|
||||
resp, gErr := s.StartService(ctx, in)
|
||||
return resp, gErr
|
||||
}
|
||||
Reference in New Issue
Block a user