Files
umbrix-libcore/config/parser.go

76 lines
2.1 KiB
Go
Raw Normal View History

2024-01-15 17:17:05 +03:30
package config
2023-08-19 14:08:39 +03:30
import (
2024-01-19 22:19:53 +03:30
"bytes"
2023-08-20 23:50:13 +03:30
_ "embed"
2024-01-17 15:31:23 +03:30
"encoding/json"
2023-08-19 14:08:39 +03:30
"fmt"
2024-01-25 23:09:24 +01:00
2023-08-19 14:08:39 +03:30
"os"
2023-09-09 20:05:05 +00:00
"github.com/hiddify/ray2sing/ray2sing"
2023-08-19 14:08:39 +03:30
"github.com/sagernet/sing-box/experimental/libbox"
2024-01-21 10:40:21 +00:00
SJ "github.com/sagernet/sing/common/json"
2023-08-19 14:08:39 +03:30
"github.com/xmdhs/clash2singbox/convert"
"github.com/xmdhs/clash2singbox/model/clash"
"gopkg.in/yaml.v3"
)
2023-08-20 23:50:13 +03:30
//go:embed config.json.template
var configByte []byte
2024-01-15 17:59:45 +03:30
func ParseConfig(path string, debug bool) ([]byte, error) {
content, err := os.ReadFile(path)
2023-08-19 14:08:39 +03:30
if err != nil {
2024-01-15 17:59:45 +03:30
return nil, err
2023-08-19 14:08:39 +03:30
}
2024-01-17 15:31:23 +03:30
var jsonObj map[string]interface{}
2024-01-25 23:09:24 +01:00
fmt.Printf("Convert using json\n")
2024-01-19 22:19:53 +03:30
jsonDecoder := json.NewDecoder(SJ.NewCommentFilter(bytes.NewReader(content)))
if err := jsonDecoder.Decode(&jsonObj); err == nil {
2024-01-17 15:31:23 +03:30
if jsonObj["outbounds"] == nil {
return nil, fmt.Errorf("[SingboxParser] no outbounds found")
2023-10-12 00:16:55 +03:30
}
jsonObj = map[string]interface{}{
"outbounds": jsonObj["outbounds"],
}
2024-01-25 23:09:24 +01:00
newContent, _ := json.MarshalIndent(jsonObj, "", " ")
return validateResult(newContent, "SingboxParser")
2023-08-19 14:08:39 +03:30
}
2024-01-25 23:09:24 +01:00
fmt.Printf("Convert using v2ray\n")
2024-01-17 15:31:23 +03:30
v2rayStr, err := ray2sing.Ray2Singbox(string(content))
if err == nil {
return validateResult([]byte(v2rayStr), "V2rayParser")
2023-09-09 14:06:54 +00:00
}
2024-01-25 23:09:24 +01:00
fmt.Printf("Convert using clash\n")
2024-01-17 15:31:23 +03:30
clashObj := clash.Clash{}
if err := yaml.Unmarshal(content, &clashObj); err == nil && clashObj.Proxies != nil {
if len(clashObj.Proxies) == 0 {
return nil, fmt.Errorf("[ClashParser] no outbounds found")
}
converted, err := convert.Clash2sing(clashObj)
if err != nil {
return nil, fmt.Errorf("[ClashParser] converting clash to sing-box error: %w", err)
}
output := configByte
output, err = convert.Patch(output, converted, "", "", nil)
if err != nil {
return nil, fmt.Errorf("[ClashParser] patching clash config error: %w", err)
}
return validateResult(output, "ClashParser")
2023-08-19 14:08:39 +03:30
}
2024-01-17 15:31:23 +03:30
return nil, fmt.Errorf("unable to determine config format")
2023-08-19 14:08:39 +03:30
}
2023-10-12 00:16:55 +03:30
2024-01-17 15:31:23 +03:30
func validateResult(content []byte, name string) ([]byte, error) {
err := libbox.CheckConfig(string(content))
2024-01-16 23:57:58 +00:00
if err != nil {
2024-01-17 15:31:23 +03:30
return nil, fmt.Errorf("[%s] invalid sing-box config: %w", name, err)
2023-10-12 00:16:55 +03:30
}
return content, nil
}