1
0
mirror of https://github.com/nitezs/sub2sing-box.git synced 2024-12-23 22:14:41 -05:00

️ Improve

This commit is contained in:
Nite07 2024-08-05 15:01:05 +08:00
parent 5afb06bdce
commit 89bb0d03e0
6 changed files with 52 additions and 106 deletions

View File

@ -4,8 +4,8 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"reflect" "reflect"
"strings"
C "sub2sing-box/constant" C "sub2sing-box/constant"
"sub2sing-box/util"
) )
type _Outbound struct { type _Outbound struct {
@ -83,17 +83,41 @@ func (h *Outbound) MarshalJSON() ([]byte, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
result, err := util.MergeAndMarshal(struct { result := make(map[string]any)
Type string `json:"type"` result["type"] = h.Type
Tag string `json:"tag,omitempty"` result["tag"] = h.Tag
}{ optsValue := reflect.ValueOf(rawOptions).Elem()
Type: h.Type, optsType := optsValue.Type()
Tag: h.Tag, for i := 0; i < optsType.NumField(); i++ {
}, rawOptions) field := optsValue.Field(i)
if err != nil { fieldType := optsType.Field(i)
return nil, err if fieldType.Anonymous {
embeddedFields := reflect.ValueOf(field.Interface())
if field.Kind() == reflect.Struct {
for j := 0; j < embeddedFields.NumField(); j++ {
embeddedField := embeddedFields.Field(j)
embeddedFieldType := embeddedFields.Type().Field(j)
processField(embeddedField, embeddedFieldType, result)
}
}
} else {
processField(field, fieldType, result)
}
} }
return []byte(result), nil return json.Marshal(result)
}
func processField(field reflect.Value, fieldType reflect.StructField, result map[string]any) {
jsonTag := fieldType.Tag.Get("json")
if jsonTag == "-" {
return
}
tagParts := strings.Split(jsonTag, ",")
tagName := tagParts[0]
if len(tagParts) > 1 && tagParts[1] == "omitempty" && field.IsZero() {
return
}
result[tagName] = field.Interface()
} }
func (h *Outbound) UnmarshalJSON(bytes []byte) error { func (h *Outbound) UnmarshalJSON(bytes []byte) error {

View File

@ -9,11 +9,9 @@ type ParseError struct {
type ParseErrorType string type ParseErrorType string
const ( const (
ErrInvalidPrefix ParseErrorType = "invalid url prefix" ErrInvalidPrefix ParseErrorType = "invalid url prefix"
ErrInvalidStruct ParseErrorType = "invalid struct" ErrInvalidStruct ParseErrorType = "invalid struct"
ErrInvalidPort ParseErrorType = "invalid port number" ErrInvalidPort ParseErrorType = "invalid port number"
ErrCannotParseParams ParseErrorType = "cannot parse query parameters"
ErrInvalidBase64 ParseErrorType = "invalid base64"
) )
func (e *ParseError) Error() string { func (e *ParseError) Error() string {

View File

@ -72,6 +72,8 @@ func ParseShadowsocks(proxy string) (model.Outbound, error) {
Raw: proxy, Raw: proxy,
} }
} }
method := methodAndPass[0]
password := methodAndPass[1]
query := link.Query() query := link.Query()
pluginStr := query.Get("plugin") pluginStr := query.Get("plugin")
@ -99,8 +101,8 @@ func ParseShadowsocks(proxy string) (model.Outbound, error) {
Server: server, Server: server,
ServerPort: port, ServerPort: port,
}, },
Method: methodAndPass[0], Method: method,
Password: methodAndPass[1], Password: password,
Plugin: plugin, Plugin: plugin,
PluginOptions: options, PluginOptions: options,
}, },

View File

@ -78,10 +78,6 @@ func ParseVless(proxy string) (model.Outbound, error) {
ALPN: alpn, ALPN: alpn,
ServerName: sni, ServerName: sni,
Insecure: insecureBool, Insecure: insecureBool,
UTLS: &model.OutboundUTLSOptions{
Enabled: enableUTLS,
Fingerprint: fp,
},
}, },
} }
} }
@ -93,10 +89,6 @@ func ParseVless(proxy string) (model.Outbound, error) {
ALPN: alpn, ALPN: alpn,
ServerName: sni, ServerName: sni,
Insecure: insecureBool, Insecure: insecureBool,
UTLS: &model.OutboundUTLSOptions{
Enabled: enableUTLS,
Fingerprint: fp,
},
Reality: &model.OutboundRealityOptions{ Reality: &model.OutboundRealityOptions{
Enabled: true, Enabled: true,
PublicKey: pbk, PublicKey: pbk,
@ -141,7 +133,7 @@ func ParseVless(proxy string) (model.Outbound, error) {
hosts, err := url.QueryUnescape(host) hosts, err := url.QueryUnescape(host)
if err != nil { if err != nil {
return model.Outbound{}, &ParseError{ return model.Outbound{}, &ParseError{
Type: ErrCannotParseParams, Type: ErrInvalidStruct,
Raw: proxy, Raw: proxy,
Message: err.Error(), Message: err.Error(),
} }
@ -153,5 +145,13 @@ func ParseVless(proxy string) (model.Outbound, error) {
}, },
} }
} }
if enableUTLS {
result.VLESSOptions.OutboundTLSOptionsContainer.TLS.UTLS = &model.OutboundUTLSOptions{
Enabled: enableUTLS,
Fingerprint: fp,
}
}
return result, nil return result, nil
} }

View File

@ -18,7 +18,7 @@ func ParseVmess(proxy string) (model.Outbound, error) {
proxy = strings.TrimPrefix(proxy, constant.VMessPrefix) proxy = strings.TrimPrefix(proxy, constant.VMessPrefix)
base64, err := util.DecodeBase64(proxy) base64, err := util.DecodeBase64(proxy)
if err != nil { if err != nil {
return model.Outbound{}, &ParseError{Type: ErrInvalidBase64, Raw: proxy, Message: err.Error()} return model.Outbound{}, &ParseError{Type: ErrInvalidStruct, Raw: proxy, Message: err.Error()}
} }
var vmess model.VmessJson var vmess model.VmessJson

View File

@ -1,78 +0,0 @@
package util
import (
"encoding/json"
"fmt"
"reflect"
)
func MergeAndMarshal(s1, s2 any) (string, error) {
merged, err := mergeStructs(s1, s2)
if err != nil {
return "", err
}
jsonBytes, err := json.Marshal(merged)
if err != nil {
return "", err
}
return string(jsonBytes), nil
}
func mergeStructs(s1, s2 any) (any, error) {
v1 := reflect.ValueOf(s1)
v2 := reflect.ValueOf(s2)
if v1.Kind() == reflect.Pointer {
v1 = v1.Elem()
}
if v2.Kind() == reflect.Pointer {
v2 = v2.Elem()
}
if v1.Kind() != reflect.Struct || v2.Kind() != reflect.Struct {
return nil, fmt.Errorf("both arguments must be structs")
}
t1 := v1.Type()
t2 := v2.Type()
var fields []reflect.StructField
var fieldsSet = make(map[string]reflect.Type)
for i := 0; i < t1.NumField(); i++ {
field := t1.Field(i)
fields = append(fields, field)
fieldsSet[field.Name] = field.Type
}
for i := 0; i < t2.NumField(); i++ {
field := t2.Field(i)
if existingType, ok := fieldsSet[field.Name]; ok {
if existingType != field.Type {
return nil, fmt.Errorf("field %s has conflicting types: %s and %s", field.Name, existingType, field.Type)
}
} else {
fields = append(fields, field)
fieldsSet[field.Name] = field.Type
}
}
newType := reflect.StructOf(fields)
newValue := reflect.New(newType).Elem()
for i := 0; i < t1.NumField(); i++ {
valueField := newValue.FieldByName(t1.Field(i).Name)
if valueField.IsValid() {
valueField.Set(v1.Field(i))
}
}
for i := 0; i < t2.NumField(); i++ {
valueField := newValue.FieldByName(t2.Field(i).Name)
if valueField.IsValid() {
valueField.Set(v2.Field(i))
}
}
return newValue.Interface(), nil
}