Files
umbrix-libcore/custom/custom.go

213 lines
4.5 KiB
Go
Raw Normal View History

2023-08-16 15:16:02 +03:30
package main
/*
#include "stdint.h"
*/
import "C"
import (
2023-09-01 14:52:30 +03:30
"encoding/json"
2023-08-19 14:09:49 +03:30
"os"
2023-08-28 13:08:43 +03:30
"unsafe"
2023-08-19 14:09:49 +03:30
2023-08-28 13:08:43 +03:30
"github.com/hiddify/libcore/bridge"
2023-08-16 15:16:02 +03:30
"github.com/hiddify/libcore/shared"
2023-08-27 13:57:23 +03:30
"github.com/sagernet/sing-box/experimental/libbox"
2023-08-16 15:16:02 +03:30
)
2023-08-27 13:57:23 +03:30
var box *libbox.BoxService
2023-09-01 14:52:30 +03:30
var configOptions *shared.ConfigOptions
2023-09-10 20:18:33 +03:30
var activeConfigPath *string
2023-08-16 15:16:02 +03:30
2023-08-28 13:08:43 +03:30
//export setupOnce
func setupOnce(api unsafe.Pointer) {
bridge.InitializeDartApi(api)
}
2023-08-16 15:16:02 +03:30
//export setup
2023-09-10 20:18:33 +03:30
func setup(baseDir *C.char, workingDir *C.char, tempDir *C.char, statusPort C.longlong) {
2023-08-16 15:16:02 +03:30
Setup(C.GoString(baseDir), C.GoString(workingDir), C.GoString(tempDir))
2023-09-10 20:18:33 +03:30
statusPropagationPort = int64(statusPort)
2023-08-16 15:16:02 +03:30
}
2023-08-19 14:09:49 +03:30
//export parse
2023-10-14 17:22:26 +03:30
func parse(path *C.char, tempPath *C.char, debug bool) (CErr *C.char) {
defer shared.DeferPanicToError("parse", func(err error) {
CErr = C.CString(err.Error())
})
2023-09-22 23:25:38 +03:30
err := shared.ParseConfig(C.GoString(path), C.GoString(tempPath), debug)
2023-08-16 15:16:02 +03:30
if err != nil {
return C.CString(err.Error())
}
return C.CString("")
}
2023-09-01 14:52:30 +03:30
//export changeConfigOptions
2023-10-14 17:22:26 +03:30
func changeConfigOptions(configOptionsJson *C.char) (CErr *C.char) {
defer shared.DeferPanicToError("changeConfigOptions", func(err error) {
CErr = C.CString(err.Error())
})
2023-09-01 14:52:30 +03:30
configOptions = &shared.ConfigOptions{}
err := json.Unmarshal([]byte(C.GoString(configOptionsJson)), configOptions)
if err != nil {
return C.CString(err.Error())
}
return C.CString("")
}
2023-09-10 20:18:33 +03:30
//export start
2023-10-14 17:22:26 +03:30
func start(configPath *C.char) (CErr *C.char) {
defer shared.DeferPanicToError("start", func(err error) {
CErr = C.CString(err.Error())
})
2023-09-10 20:18:33 +03:30
if status != Stopped {
return C.CString("")
}
propagateStatus(Starting)
2023-08-16 15:16:02 +03:30
path := C.GoString(configPath)
2023-09-10 20:18:33 +03:30
activeConfigPath = &path
err := startService()
2023-08-19 14:09:49 +03:30
if err != nil {
return C.CString(err.Error())
}
2023-09-10 20:18:33 +03:30
return C.CString("")
}
func startService() error {
content, err := os.ReadFile(*activeConfigPath)
if err != nil {
return stopAndAlert(EmptyConfiguration, err)
}
2023-08-19 14:09:49 +03:30
options, err := parseConfig(string(content))
2023-08-16 15:16:02 +03:30
if err != nil {
2023-09-10 20:18:33 +03:30
return stopAndAlert(EmptyConfiguration, err)
2023-08-16 15:16:02 +03:30
}
2023-09-01 14:52:30 +03:30
options = shared.BuildConfig(*configOptions, options)
2023-08-22 00:54:58 +03:30
shared.SaveCurrentConfig(sWorkingPath, options)
2023-08-16 15:16:02 +03:30
2023-08-28 13:08:43 +03:30
err = startCommandServer()
if err != nil {
2023-09-10 20:18:33 +03:30
return stopAndAlert(StartCommandServer, err)
2023-08-28 13:08:43 +03:30
}
2023-08-19 14:09:49 +03:30
instance, err := NewService(options)
2023-08-16 15:16:02 +03:30
if err != nil {
2023-09-10 20:18:33 +03:30
return stopAndAlert(CreateService, err)
2023-08-16 15:16:02 +03:30
}
2023-09-10 20:18:33 +03:30
err = instance.Start()
2023-08-28 13:08:43 +03:30
if err != nil {
2023-09-10 20:18:33 +03:30
return stopAndAlert(StartService, err)
2023-08-16 15:16:02 +03:30
}
2023-09-10 20:18:33 +03:30
box = instance
commandServer.SetService(box)
2023-08-16 15:16:02 +03:30
2023-09-10 20:18:33 +03:30
propagateStatus(Started)
return nil
2023-08-16 15:16:02 +03:30
}
//export stop
2023-10-14 17:22:26 +03:30
func stop() (CErr *C.char) {
defer shared.DeferPanicToError("stop", func(err error) {
CErr = C.CString(err.Error())
})
2023-09-10 20:18:33 +03:30
if status != Started {
return C.CString("")
}
2023-08-16 15:16:02 +03:30
if box == nil {
return C.CString("instance not found")
}
2023-09-10 20:18:33 +03:30
propagateStatus(Stopping)
2023-08-16 15:16:02 +03:30
2023-08-28 13:08:43 +03:30
commandServer.SetService(nil)
2023-08-16 15:16:02 +03:30
err := box.Close()
if err != nil {
return C.CString(err.Error())
}
2023-08-28 13:08:43 +03:30
box = nil
err = commandServer.Close()
if err != nil {
return C.CString(err.Error())
}
commandServer = nil
2023-09-10 20:18:33 +03:30
propagateStatus(Stopped)
return C.CString("")
}
//export restart
2023-10-14 17:22:26 +03:30
func restart(configPath *C.char) (CErr *C.char) {
defer shared.DeferPanicToError("restart", func(err error) {
CErr = C.CString(err.Error())
})
2023-09-10 20:18:33 +03:30
if status != Started {
return C.CString("")
}
if box == nil {
return C.CString("instance not found")
}
err := stop()
if C.GoString(err) != "" {
return err
}
err = start(configPath)
if C.GoString(err) != "" {
return err
}
2023-08-28 13:08:43 +03:30
return C.CString("")
}
//export startCommandClient
func startCommandClient(command C.int, port C.longlong) *C.char {
err := StartCommand(int32(command), int64(port))
if err != nil {
return C.CString(err.Error())
}
return C.CString("")
}
//export stopCommandClient
func stopCommandClient(command C.int) *C.char {
err := StopCommand(int32(command))
if err != nil {
return C.CString(err.Error())
}
2023-08-16 15:16:02 +03:30
return C.CString("")
}
2023-08-29 19:10:14 +03:30
//export selectOutbound
2023-10-14 17:22:26 +03:30
func selectOutbound(groupTag *C.char, outboundTag *C.char) (CErr *C.char) {
defer shared.DeferPanicToError("selectOutbound", func(err error) {
CErr = C.CString(err.Error())
})
2023-08-29 19:10:14 +03:30
err := libbox.NewStandaloneCommandClient().SelectOutbound(C.GoString(groupTag), C.GoString(outboundTag))
if err != nil {
return C.CString(err.Error())
}
return C.CString("")
}
//export urlTest
2023-10-14 17:22:26 +03:30
func urlTest(groupTag *C.char) (CErr *C.char) {
defer shared.DeferPanicToError("urlTest", func(err error) {
CErr = C.CString(err.Error())
})
2023-08-29 19:10:14 +03:30
err := libbox.NewStandaloneCommandClient().URLTest(C.GoString(groupTag))
if err != nil {
return C.CString(err.Error())
}
return C.CString("")
}
2023-08-16 15:16:02 +03:30
func main() {}