From eee361dcbf49ae0d594e065e0b98a716f9bb426e Mon Sep 17 00:00:00 2001 From: nite07 Date: Wed, 20 Mar 2024 20:54:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E9=A1=B9=E7=9B=AE=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/handler/convert.go | 8 +- cmd/convert.go | 5 +- {pkg/util => common}/convert.go | 73 +++++----- {internal/model => model}/config.go | 134 +++++++++--------- {internal/model => model}/country_code_map.go | 0 {internal/model => model}/hysteria.go | 0 {internal/model => model}/hysteria2.go | 0 {internal/model => model}/multiplex.go | 0 {internal/model => model}/proxy.go | 0 {internal/model => model}/shadowsocks.go | 0 {internal/model => model}/sort.go | 0 {internal/model => model}/tls.go | 0 {internal/model => model}/trojan.go | 0 {internal/model => model}/tuic.go | 0 {internal/model => model}/udp_over_tcp.go | 0 {internal/model => model}/v2ray_transport.go | 4 +- {internal/model => model}/vless.go | 0 {internal/model => model}/vmess.go | 0 {pkg/parser => parser}/hysteria.go | 20 +-- {pkg/parser => parser}/hysteria2.go | 20 +-- {pkg/parser => parser}/parsers_map.go | 2 +- {pkg/parser => parser}/shadowsocks.go | 24 ++-- {pkg/parser => parser}/trojan.go | 42 +++--- {pkg/parser => parser}/vless.go | 48 +++---- {pkg/parser => parser}/vmess.go | 42 +++--- {internal/util => util}/base64.go | 0 {internal/util => util}/fetch.go | 0 27 files changed, 210 insertions(+), 212 deletions(-) rename {pkg/util => common}/convert.go (79%) rename {internal/model => model}/config.go (77%) rename {internal/model => model}/country_code_map.go (100%) rename {internal/model => model}/hysteria.go (100%) rename {internal/model => model}/hysteria2.go (100%) rename {internal/model => model}/multiplex.go (100%) rename {internal/model => model}/proxy.go (100%) rename {internal/model => model}/shadowsocks.go (100%) rename {internal/model => model}/sort.go (100%) rename {internal/model => model}/tls.go (100%) rename {internal/model => model}/trojan.go (100%) rename {internal/model => model}/tuic.go (100%) rename {internal/model => model}/udp_over_tcp.go (100%) rename {internal/model => model}/v2ray_transport.go (95%) rename {internal/model => model}/vless.go (100%) rename {internal/model => model}/vmess.go (100%) rename {pkg/parser => parser}/hysteria.go (81%) rename {pkg/parser => parser}/hysteria2.go (73%) rename {pkg/parser => parser}/parsers_map.go (92%) rename {pkg/parser => parser}/shadowsocks.go (65%) rename {pkg/parser => parser}/trojan.go (68%) rename {pkg/parser => parser}/vless.go (69%) rename {pkg/parser => parser}/vmess.go (69%) rename {internal/util => util}/base64.go (100%) rename {internal/util => util}/fetch.go (100%) diff --git a/api/handler/convert.go b/api/handler/convert.go index 15020c3..3e6dac3 100644 --- a/api/handler/convert.go +++ b/api/handler/convert.go @@ -3,8 +3,8 @@ package handler import ( "encoding/json" "sub2sing-box/api/model" - iutil "sub2sing-box/internal/util" - putil "sub2sing-box/pkg/util" + "sub2sing-box/common" + putil "sub2sing-box/util" "github.com/gin-gonic/gin" ) @@ -17,7 +17,7 @@ func Convert(c *gin.Context) { }) return } - j, err := iutil.DecodeBase64(c.Query("data")) + j, err := putil.DecodeBase64(c.Query("data")) if err != nil { c.JSON(400, gin.H{ "error": "Invalid data", @@ -38,7 +38,7 @@ func Convert(c *gin.Context) { }) return } - result, err := putil.Convert( + result, err := common.Convert( data.Subscriptions, data.Proxies, data.Template, diff --git a/cmd/convert.go b/cmd/convert.go index 6e9171b..82d8942 100644 --- a/cmd/convert.go +++ b/cmd/convert.go @@ -2,10 +2,9 @@ package cmd import ( "fmt" - "os" - . "sub2sing-box/pkg/util" - "github.com/spf13/cobra" + "os" + . "sub2sing-box/common" ) var subscriptions []string diff --git a/pkg/util/convert.go b/common/convert.go similarity index 79% rename from pkg/util/convert.go rename to common/convert.go index 0f8db5e..f1e4574 100644 --- a/pkg/util/convert.go +++ b/common/convert.go @@ -1,4 +1,4 @@ -package util +package common import ( "encoding/json" @@ -9,10 +9,9 @@ import ( "regexp" "sort" "strings" - - "sub2sing-box/internal/model" - "sub2sing-box/internal/util" - "sub2sing-box/pkg/parser" + model2 "sub2sing-box/model" + "sub2sing-box/parser" + "sub2sing-box/util" ) func Convert( @@ -57,14 +56,14 @@ func Convert( keep := make(map[int]bool) set := make(map[string]struct { - Proxy model.Proxy + Proxy model2.Proxy Count int }) for i, p := range proxyList { if _, exists := set[p.Tag]; !exists { keep[i] = true set[p.Tag] = struct { - Proxy model.Proxy + Proxy model2.Proxy Count int }{p, 0} } else { @@ -72,7 +71,7 @@ func Convert( p2, _ := json.Marshal(set[p.Tag]) if string(p1) != string(p2) { set[p.Tag] = struct { - Proxy model.Proxy + Proxy model2.Proxy Count int }{p, set[p.Tag].Count + 1} keep[i] = true @@ -82,14 +81,14 @@ func Convert( } } } - var newProxyList []model.Proxy + var newProxyList []model2.Proxy for i, p := range proxyList { if keep[i] { newProxyList = append(newProxyList, p) } } proxyList = newProxyList - var outbounds []model.Outbound + var outbounds []model2.Outbound ps, err := json.Marshal(&proxyList) if err != nil { return "", err @@ -117,16 +116,16 @@ func Convert( return string(result), nil } -func AddCountryGroup(proxies []model.Outbound, groupType string, sortKey string, sortType string) []model.Outbound { - newGroup := make(map[string]model.Outbound) +func AddCountryGroup(proxies []model2.Outbound, groupType string, sortKey string, sortType string) []model2.Outbound { + newGroup := make(map[string]model2.Outbound) for _, p := range proxies { if p.Type != "selector" && p.Type != "urltest" { - country := model.GetContryName(p.Tag) + country := model2.GetContryName(p.Tag) if group, ok := newGroup[country]; ok { group.Outbounds = append(group.Outbounds, p.Tag) newGroup[country] = group } else { - newGroup[country] = model.Outbound{ + newGroup[country] = model2.Outbound{ Tag: country, Type: groupType, Outbounds: []string{p.Tag}, @@ -135,34 +134,34 @@ func AddCountryGroup(proxies []model.Outbound, groupType string, sortKey string, } } } - var groups []model.Outbound + var groups []model2.Outbound for _, p := range newGroup { groups = append(groups, p) } if sortType == "asc" { switch sortKey { case "tag": - sort.Sort(model.SortByTag(groups)) + sort.Sort(model2.SortByTag(groups)) case "num": - sort.Sort(model.SortByNumber(groups)) + sort.Sort(model2.SortByNumber(groups)) default: - sort.Sort(model.SortByTag(groups)) + sort.Sort(model2.SortByTag(groups)) } } else { switch sortKey { case "tag": - sort.Sort(sort.Reverse(model.SortByTag(groups))) + sort.Sort(sort.Reverse(model2.SortByTag(groups))) case "num": - sort.Sort(sort.Reverse(model.SortByNumber(groups))) + sort.Sort(sort.Reverse(model2.SortByNumber(groups))) default: - sort.Sort(sort.Reverse(model.SortByTag(groups))) + sort.Sort(sort.Reverse(model2.SortByTag(groups))) } } return append(proxies, groups...) } -func MergeTemplate(outbounds []model.Outbound, template string) (string, error) { - var config model.Config +func MergeTemplate(outbounds []model2.Outbound, template string) (string, error) { + var config model2.Config var err error if strings.HasPrefix(template, "http") { data, err := util.Fetch(template, 3) @@ -183,12 +182,12 @@ func MergeTemplate(outbounds []model.Outbound, template string) (string, error) } proxyTags := make([]string, 0) groupTags := make([]string, 0) - groups := make(map[string]model.Outbound) + groups := make(map[string]model2.Outbound) if err != nil { return "", err } for _, p := range outbounds { - if model.IsCountryGroup(p.Tag) { + if model2.IsCountryGroup(p.Tag) { groupTags = append(groupTags, p.Tag) reg := regexp.MustCompile("[A-Za-z]{2}") country := reg.FindString(p.Tag) @@ -224,17 +223,17 @@ func MergeTemplate(outbounds []model.Outbound, template string) (string, error) return string(data), nil } -func ConvertCProxyToSProxy(proxy string) (model.Proxy, error) { +func ConvertCProxyToSProxy(proxy string) (model2.Proxy, error) { for prefix, parseFunc := range parser.ParserMap { if strings.HasPrefix(proxy, prefix) { proxy, err := parseFunc(proxy) if err != nil { - return model.Proxy{}, err + return model2.Proxy{}, err } return proxy, nil } } - return model.Proxy{}, errors.New("Unknown proxy format") + return model2.Proxy{}, errors.New("Unknown proxy format") } func ConvertCProxyToJson(proxy string) (string, error) { @@ -249,8 +248,8 @@ func ConvertCProxyToJson(proxy string) (string, error) { return string(data), nil } -func ConvertSubscriptionsToSProxy(urls []string) ([]model.Proxy, error) { - proxyList := make([]model.Proxy, 0) +func ConvertSubscriptionsToSProxy(urls []string) ([]model2.Proxy, error) { + proxyList := make([]model2.Proxy, 0) for _, url := range urls { data, err := util.Fetch(url, 3) if err != nil { @@ -288,25 +287,25 @@ func ConvertSubscriptionsToJson(urls []string) (string, error) { return string(result), nil } -func ReadTemplate(path string) (model.Config, error) { +func ReadTemplate(path string) (model2.Config, error) { data, err := os.ReadFile(path) if err != nil { - return model.Config{}, err + return model2.Config{}, err } - var res model.Config + var res model2.Config err = json.Unmarshal(data, &res) if err != nil { - return model.Config{}, err + return model2.Config{}, err } return res, nil } -func DeleteProxy(proxies []model.Proxy, regex string) ([]model.Proxy, error) { +func DeleteProxy(proxies []model2.Proxy, regex string) ([]model2.Proxy, error) { reg, err := regexp.Compile(regex) if err != nil { return nil, err } - var newProxies []model.Proxy + var newProxies []model2.Proxy for _, p := range proxies { if !reg.MatchString(p.Tag) { newProxies = append(newProxies, p) @@ -315,7 +314,7 @@ func DeleteProxy(proxies []model.Proxy, regex string) ([]model.Proxy, error) { return newProxies, nil } -func RenameProxy(proxies []model.Proxy, regex string, replaceText string) ([]model.Proxy, error) { +func RenameProxy(proxies []model2.Proxy, regex string, replaceText string) ([]model2.Proxy, error) { reg, err := regexp.Compile(regex) if err != nil { return nil, err diff --git a/internal/model/config.go b/model/config.go similarity index 77% rename from internal/model/config.go rename to model/config.go index fdf0e2c..b587140 100644 --- a/internal/model/config.go +++ b/model/config.go @@ -65,12 +65,12 @@ type LogOptions struct { } type DNSOptions struct { - Servers Listable[DNSServerOptions] `json:"servers,omitempty"` - Rules Listable[DNSRule] `json:"rules,omitempty"` - Final string `json:"final,omitempty"` - ReverseMapping bool `json:"reverse_mapping,omitempty"` - FakeIP *DNSFakeIPOptions `json:"fakeip,omitempty"` - Strategy string `json:"strategy,omitempty"` + Servers Listable[DNSServerOptions] `json:"servers,omitempty"` + Rules Listable[DNSRule] `json:"rules,omitempty"` + Final string `json:"final,omitempty"` + ReverseMapping bool `json:"reverse_mapping,omitempty"` + FakeIP *DNSFakeIPOptions `json:"fakeip,omitempty"` + Strategy string `json:"strategy,omitempty"` DisableCache bool `json:"disable_cache,omitempty"` DisableExpire bool `json:"disable_expire,omitempty"` IndependentCache bool `json:"independent_cache,omitempty"` @@ -162,29 +162,29 @@ type Inbound struct { Tag string `json:"tag,omitempty"` InterfaceName string `json:"interface_name,omitempty"` MTU uint32 `json:"mtu,omitempty"` - GSO bool `json:"gso,omitempty"` - Inet4Address Listable[string] `json:"inet4_address,omitempty"` - Inet6Address Listable[string] `json:"inet6_address,omitempty"` - AutoRoute bool `json:"auto_route,omitempty"` - StrictRoute bool `json:"strict_route,omitempty"` - Inet4RouteAddress Listable[string] `json:"inet4_route_address,omitempty"` - Inet6RouteAddress Listable[string] `json:"inet6_route_address,omitempty"` - Inet4RouteExcludeAddress Listable[string] `json:"inet4_route_exclude_address,omitempty"` - Inet6RouteExcludeAddress Listable[string] `json:"inet6_route_exclude_address,omitempty"` - IncludeInterface Listable[string] `json:"include_interface,omitempty"` - ExcludeInterface Listable[string] `json:"exclude_interface,omitempty"` - IncludeUID Listable[uint32] `json:"include_uid,omitempty"` - IncludeUIDRange Listable[string] `json:"include_uid_range,omitempty"` - ExcludeUID Listable[uint32] `json:"exclude_uid,omitempty"` - ExcludeUIDRange Listable[string] `json:"exclude_uid_range,omitempty"` - IncludeAndroidUser Listable[int] `json:"include_android_user,omitempty"` - IncludePackage Listable[string] `json:"include_package,omitempty"` - ExcludePackage Listable[string] `json:"exclude_package,omitempty"` - EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"` + GSO bool `json:"gso,omitempty"` + Inet4Address Listable[string] `json:"inet4_address,omitempty"` + Inet6Address Listable[string] `json:"inet6_address,omitempty"` + AutoRoute bool `json:"auto_route,omitempty"` + StrictRoute bool `json:"strict_route,omitempty"` + Inet4RouteAddress Listable[string] `json:"inet4_route_address,omitempty"` + Inet6RouteAddress Listable[string] `json:"inet6_route_address,omitempty"` + Inet4RouteExcludeAddress Listable[string] `json:"inet4_route_exclude_address,omitempty"` + Inet6RouteExcludeAddress Listable[string] `json:"inet6_route_exclude_address,omitempty"` + IncludeInterface Listable[string] `json:"include_interface,omitempty"` + ExcludeInterface Listable[string] `json:"exclude_interface,omitempty"` + IncludeUID Listable[uint32] `json:"include_uid,omitempty"` + IncludeUIDRange Listable[string] `json:"include_uid_range,omitempty"` + ExcludeUID Listable[uint32] `json:"exclude_uid,omitempty"` + ExcludeUIDRange Listable[string] `json:"exclude_uid_range,omitempty"` + IncludeAndroidUser Listable[int] `json:"include_android_user,omitempty"` + IncludePackage Listable[string] `json:"include_package,omitempty"` + ExcludePackage Listable[string] `json:"exclude_package,omitempty"` + EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"` UDPTimeout string `json:"udp_timeout,omitempty"` - Stack string `json:"stack,omitempty"` - Platform *TunPlatformOptions `json:"platform,omitempty"` - SniffEnabled bool `json:"sniff,omitempty"` + Stack string `json:"stack,omitempty"` + Platform *TunPlatformOptions `json:"platform,omitempty"` + SniffEnabled bool `json:"sniff,omitempty"` SniffOverrideDestination bool `json:"sniff_override_destination,omitempty"` SniffTimeout string `json:"sniff_timeout,omitempty"` DomainStrategy string `json:"domain_strategy,omitempty"` @@ -227,53 +227,53 @@ type Outbound struct { Version string `json:"version,omitempty"` Username string `json:"username,omitempty"` Password string `json:"password,omitempty"` - Network string `json:"network,omitempty"` - UDPOverTCP *UDPOverTCPOptions `json:"udp_over_tcp,omitempty"` - TLS *OutboundTLSOptions `json:"tls,omitempty"` - Path string `json:"path,omitempty"` - Headers map[string]Listable[string] `json:"headers,omitempty"` - Method string `json:"method,omitempty"` + Network string `json:"network,omitempty"` + UDPOverTCP *UDPOverTCPOptions `json:"udp_over_tcp,omitempty"` + TLS *OutboundTLSOptions `json:"tls,omitempty"` + Path string `json:"path,omitempty"` + Headers map[string]Listable[string] `json:"headers,omitempty"` + Method string `json:"method,omitempty"` Plugin string `json:"plugin,omitempty"` - PluginOptions string `json:"plugin_opts,omitempty"` - Multiplex *OutboundMultiplexOptions `json:"multiplex,omitempty"` - UUID string `json:"uuid,omitempty"` + PluginOptions string `json:"plugin_opts,omitempty"` + Multiplex *OutboundMultiplexOptions `json:"multiplex,omitempty"` + UUID string `json:"uuid,omitempty"` Security string `json:"security,omitempty"` AlterId int `json:"alter_id,omitempty"` GlobalPadding bool `json:"global_padding,omitempty"` AuthenticatedLength bool `json:"authenticated_length,omitempty"` - PacketEncoding string `json:"packet_encoding,omitempty"` - Transport *V2RayTransportOptions `json:"transport,omitempty"` - SystemInterface bool `json:"system_interface,omitempty"` + PacketEncoding string `json:"packet_encoding,omitempty"` + Transport *V2RayTransportOptions `json:"transport,omitempty"` + SystemInterface bool `json:"system_interface,omitempty"` GSO bool `json:"gso,omitempty"` - InterfaceName string `json:"interface_name,omitempty"` - LocalAddress Listable[string] `json:"local_address,omitempty"` - PrivateKey string `json:"private_key,omitempty"` - Peers Listable[WireGuardPeer] `json:"peers,omitempty"` - PeerPublicKey string `json:"peer_public_key,omitempty"` - PreSharedKey string `json:"pre_shared_key,omitempty"` - Reserved Listable[uint8] `json:"reserved,omitempty"` - Workers int `json:"workers,omitempty"` + InterfaceName string `json:"interface_name,omitempty"` + LocalAddress Listable[string] `json:"local_address,omitempty"` + PrivateKey string `json:"private_key,omitempty"` + Peers Listable[WireGuardPeer] `json:"peers,omitempty"` + PeerPublicKey string `json:"peer_public_key,omitempty"` + PreSharedKey string `json:"pre_shared_key,omitempty"` + Reserved Listable[uint8] `json:"reserved,omitempty"` + Workers int `json:"workers,omitempty"` MTU uint32 `json:"mtu,omitempty"` Up string `json:"up,omitempty"` UpMbps int `json:"up_mbps,omitempty"` Down string `json:"down,omitempty"` - DownMbps int `json:"down_mbps,omitempty"` - Obfs *Obfs `json:"obfs,omitempty"` - Auth Listable[byte] `json:"auth,omitempty"` - AuthString string `json:"auth_str,omitempty"` + DownMbps int `json:"down_mbps,omitempty"` + Obfs *Obfs `json:"obfs,omitempty"` + Auth Listable[byte] `json:"auth,omitempty"` + AuthString string `json:"auth_str,omitempty"` ReceiveWindowConn uint64 `json:"recv_window_conn,omitempty"` ReceiveWindow uint64 `json:"recv_window,omitempty"` DisableMTUDiscovery bool `json:"disable_mtu_discovery,omitempty"` - ExecutablePath string `json:"executable_path,omitempty"` - ExtraArgs Listable[string] `json:"extra_args,omitempty"` - DataDirectory string `json:"data_directory,omitempty"` + ExecutablePath string `json:"executable_path,omitempty"` + ExtraArgs Listable[string] `json:"extra_args,omitempty"` + DataDirectory string `json:"data_directory,omitempty"` Options map[string]string `json:"torrc,omitempty"` User string `json:"user,omitempty"` PrivateKeyPath string `json:"private_key_path,omitempty"` - PrivateKeyPassphrase string `json:"private_key_passphrase,omitempty"` - HostKey Listable[string] `json:"host_key,omitempty"` - HostKeyAlgorithms Listable[string] `json:"host_key_algorithms,omitempty"` - ClientVersion string `json:"client_version,omitempty"` + PrivateKeyPassphrase string `json:"private_key_passphrase,omitempty"` + HostKey Listable[string] `json:"host_key,omitempty"` + HostKeyAlgorithms Listable[string] `json:"host_key_algorithms,omitempty"` + ClientVersion string `json:"client_version,omitempty"` ObfsParam string `json:"obfs_param,omitempty"` Protocol string `json:"protocol,omitempty"` ProtocolParam string `json:"protocol_param,omitempty"` @@ -284,9 +284,9 @@ type Outbound struct { ZeroRTTHandshake bool `json:"zero_rtt_handshake,omitempty"` Heartbeat string `json:"heartbeat,omitempty"` BrutalDebug bool `json:"brutal_debug,omitempty"` - Default string `json:"default,omitempty"` - Outbounds Listable[string] `json:"outbounds,omitempty"` - URL string `json:"url,omitempty"` + Default string `json:"default,omitempty"` + Outbounds Listable[string] `json:"outbounds,omitempty"` + URL string `json:"url,omitempty"` Interval string `json:"interval,omitempty"` Tolerance uint16 `json:"tolerance,omitempty"` IdleTimeout string `json:"idle_timeout,omitempty"` @@ -303,11 +303,11 @@ type WireGuardPeer struct { } type RouteOptions struct { - GeoIP *GeoIPOptions `json:"geoip,omitempty"` - Geosite *GeositeOptions `json:"geosite,omitempty"` - Rules Listable[Rule] `json:"rules,omitempty"` - RuleSet Listable[RuleSet] `json:"rule_set,omitempty"` - Final string `json:"final,omitempty"` + GeoIP *GeoIPOptions `json:"geoip,omitempty"` + Geosite *GeositeOptions `json:"geosite,omitempty"` + Rules Listable[Rule] `json:"rules,omitempty"` + RuleSet Listable[RuleSet] `json:"rule_set,omitempty"` + Final string `json:"final,omitempty"` FindProcess bool `json:"find_process,omitempty"` AutoDetectInterface bool `json:"auto_detect_interface,omitempty"` OverrideAndroidVPN bool `json:"override_android_vpn,omitempty"` diff --git a/internal/model/country_code_map.go b/model/country_code_map.go similarity index 100% rename from internal/model/country_code_map.go rename to model/country_code_map.go diff --git a/internal/model/hysteria.go b/model/hysteria.go similarity index 100% rename from internal/model/hysteria.go rename to model/hysteria.go diff --git a/internal/model/hysteria2.go b/model/hysteria2.go similarity index 100% rename from internal/model/hysteria2.go rename to model/hysteria2.go diff --git a/internal/model/multiplex.go b/model/multiplex.go similarity index 100% rename from internal/model/multiplex.go rename to model/multiplex.go diff --git a/internal/model/proxy.go b/model/proxy.go similarity index 100% rename from internal/model/proxy.go rename to model/proxy.go diff --git a/internal/model/shadowsocks.go b/model/shadowsocks.go similarity index 100% rename from internal/model/shadowsocks.go rename to model/shadowsocks.go diff --git a/internal/model/sort.go b/model/sort.go similarity index 100% rename from internal/model/sort.go rename to model/sort.go diff --git a/internal/model/tls.go b/model/tls.go similarity index 100% rename from internal/model/tls.go rename to model/tls.go diff --git a/internal/model/trojan.go b/model/trojan.go similarity index 100% rename from internal/model/trojan.go rename to model/trojan.go diff --git a/internal/model/tuic.go b/model/tuic.go similarity index 100% rename from internal/model/tuic.go rename to model/tuic.go diff --git a/internal/model/udp_over_tcp.go b/model/udp_over_tcp.go similarity index 100% rename from internal/model/udp_over_tcp.go rename to model/udp_over_tcp.go diff --git a/internal/model/v2ray_transport.go b/model/v2ray_transport.go similarity index 95% rename from internal/model/v2ray_transport.go rename to model/v2ray_transport.go index 46ac7a6..945014e 100644 --- a/internal/model/v2ray_transport.go +++ b/model/v2ray_transport.go @@ -53,8 +53,8 @@ func (o *V2RayTransportOptions) MarshalJSON() ([]byte, error) { } type V2RayHTTPOptions struct { - Host Listable[string] `json:"host,omitempty"` - Path string `json:"path,omitempty"` + Host Listable[string] `json:"host,omitempty"` + Path string `json:"path,omitempty"` Method string `json:"method,omitempty"` Headers map[string]string `json:"headers,omitempty"` IdleTimeout string `json:"idle_timeout,omitempty"` diff --git a/internal/model/vless.go b/model/vless.go similarity index 100% rename from internal/model/vless.go rename to model/vless.go diff --git a/internal/model/vmess.go b/model/vmess.go similarity index 100% rename from internal/model/vmess.go rename to model/vmess.go diff --git a/pkg/parser/hysteria.go b/parser/hysteria.go similarity index 81% rename from pkg/parser/hysteria.go rename to parser/hysteria.go index bcfebfe..ab1fbb9 100644 --- a/pkg/parser/hysteria.go +++ b/parser/hysteria.go @@ -5,7 +5,7 @@ import ( "net/url" "strconv" "strings" - "sub2sing-box/internal/model" + model2 "sub2sing-box/model" ) //hysteria://host:port?protocol=udp&auth=123456&peer=sni.domain&insecure=1&upmbps=100&downmbps=100&alpn=hysteria&obfs=xplus&obfsParam=123456#remarks @@ -23,23 +23,23 @@ import ( //- obfsParam: Obfuscation password (optional) //- remarks: remarks (optional) -func ParseHysteria(proxy string) (model.Proxy, error) { +func ParseHysteria(proxy string) (model2.Proxy, error) { if !strings.HasPrefix(proxy, "hysteria://") { - return model.Proxy{}, errors.New("invalid hysteria Url") + return model2.Proxy{}, errors.New("invalid hysteria Url") } parts := strings.SplitN(strings.TrimPrefix(proxy, "hysteria://"), "?", 2) serverInfo := strings.SplitN(parts[0], ":", 2) if len(serverInfo) != 2 { - return model.Proxy{}, errors.New("invalid hysteria Url") + return model2.Proxy{}, errors.New("invalid hysteria Url") } params, err := url.ParseQuery(parts[1]) if err != nil { - return model.Proxy{}, errors.New("invalid hysteria Url") + return model2.Proxy{}, errors.New("invalid hysteria Url") } host := serverInfo[0] port, err := strconv.Atoi(serverInfo[1]) if err != nil { - return model.Proxy{}, errors.New("invalid hysteria Url") + return model2.Proxy{}, errors.New("invalid hysteria Url") } protocol := params.Get("protocol") auth := params.Get("auth") @@ -64,12 +64,12 @@ func ParseHysteria(proxy string) (model.Proxy, error) { } insecureBool, err := strconv.ParseBool(insecure) if err != nil { - return model.Proxy{}, errors.New("invalid hysteria Url") + return model2.Proxy{}, errors.New("invalid hysteria Url") } - result := model.Proxy{ + result := model2.Proxy{ Type: "hysteria", Tag: remarks, - Hysteria: model.Hysteria{ + Hysteria: model2.Hysteria{ Server: host, ServerPort: uint16(port), Up: upmbps, @@ -77,7 +77,7 @@ func ParseHysteria(proxy string) (model.Proxy, error) { Auth: []byte(auth), Obfs: obfs, Network: protocol, - TLS: &model.OutboundTLSOptions{ + TLS: &model2.OutboundTLSOptions{ Enabled: true, Insecure: insecureBool, ALPN: alpn, diff --git a/pkg/parser/hysteria2.go b/parser/hysteria2.go similarity index 73% rename from pkg/parser/hysteria2.go rename to parser/hysteria2.go index c1ce410..7d1cc45 100644 --- a/pkg/parser/hysteria2.go +++ b/parser/hysteria2.go @@ -5,14 +5,14 @@ import ( "net/url" "strconv" "strings" - "sub2sing-box/internal/model" + model2 "sub2sing-box/model" ) // hysteria2://letmein@example.com/?insecure=1&obfs=salamander&obfs-password=gawrgura&pinSHA256=deadbeef&sni=real.example.com -func ParseHysteria2(proxy string) (model.Proxy, error) { +func ParseHysteria2(proxy string) (model2.Proxy, error) { if !strings.HasPrefix(proxy, "hysteria2://") && !strings.HasPrefix(proxy, "hy2://") { - return model.Proxy{}, errors.New("invalid hysteria2 Url") + return model2.Proxy{}, errors.New("invalid hysteria2 Url") } parts := strings.SplitN(strings.TrimPrefix(proxy, "hysteria2://"), "@", 2) serverInfo := strings.SplitN(parts[1], "/?", 2) @@ -20,32 +20,32 @@ func ParseHysteria2(proxy string) (model.Proxy, error) { if len(serverAndPort) == 1 { serverAndPort = append(serverAndPort, "443") } else if len(serverAndPort) != 2 { - return model.Proxy{}, errors.New("invalid hysteria2 Url") + return model2.Proxy{}, errors.New("invalid hysteria2 Url") } params, err := url.ParseQuery(serverInfo[1]) if err != nil { - return model.Proxy{}, errors.New("invalid hysteria2 Url") + return model2.Proxy{}, errors.New("invalid hysteria2 Url") } port, err := strconv.Atoi(serverAndPort[1]) if err != nil { - return model.Proxy{}, errors.New("invalid hysteria2 Url") + return model2.Proxy{}, errors.New("invalid hysteria2 Url") } remarks := params.Get("name") server := serverAndPort[0] password := parts[0] network := params.Get("network") - result := model.Proxy{ + result := model2.Proxy{ Type: "hysteria2", Tag: remarks, - Hysteria2: model.Hysteria2{ + Hysteria2: model2.Hysteria2{ Server: server, ServerPort: uint16(port), Password: password, - Obfs: &model.Hysteria2Obfs{ + Obfs: &model2.Hysteria2Obfs{ Type: params.Get("obfs"), Password: params.Get("obfs-password"), }, - TLS: &model.OutboundTLSOptions{ + TLS: &model2.OutboundTLSOptions{ Enabled: params.Get("pinSHA256") != "", Insecure: params.Get("insecure") == "1", ServerName: params.Get("sni"), diff --git a/pkg/parser/parsers_map.go b/parser/parsers_map.go similarity index 92% rename from pkg/parser/parsers_map.go rename to parser/parsers_map.go index 06082c1..8fb615f 100644 --- a/pkg/parser/parsers_map.go +++ b/parser/parsers_map.go @@ -1,7 +1,7 @@ package parser import ( - "sub2sing-box/internal/model" + "sub2sing-box/model" ) var ParserMap map[string]func(string) (model.Proxy, error) = map[string]func(string) (model.Proxy, error){ diff --git a/pkg/parser/shadowsocks.go b/parser/shadowsocks.go similarity index 65% rename from pkg/parser/shadowsocks.go rename to parser/shadowsocks.go index 7b28579..0c2f184 100644 --- a/pkg/parser/shadowsocks.go +++ b/parser/shadowsocks.go @@ -5,43 +5,43 @@ import ( "net/url" "strconv" "strings" - "sub2sing-box/internal/model" - "sub2sing-box/internal/util" + model2 "sub2sing-box/model" + "sub2sing-box/util" ) -func ParseShadowsocks(proxy string) (model.Proxy, error) { +func ParseShadowsocks(proxy string) (model2.Proxy, error) { if !strings.HasPrefix(proxy, "ss://") { - return model.Proxy{}, errors.New("invalid ss Url") + return model2.Proxy{}, errors.New("invalid ss Url") } parts := strings.SplitN(strings.TrimPrefix(proxy, "ss://"), "@", 2) if len(parts) != 2 { - return model.Proxy{}, errors.New("invalid ss Url") + return model2.Proxy{}, errors.New("invalid ss Url") } if !strings.Contains(parts[0], ":") { decoded, err := util.DecodeBase64(parts[0]) if err != nil { - return model.Proxy{}, errors.New("invalid ss Url" + err.Error()) + return model2.Proxy{}, errors.New("invalid ss Url" + err.Error()) } parts[0] = decoded } credentials := strings.SplitN(parts[0], ":", 2) if len(credentials) != 2 { - return model.Proxy{}, errors.New("invalid ss Url") + return model2.Proxy{}, errors.New("invalid ss Url") } serverInfo := strings.SplitN(parts[1], "#", 2) serverAndPort := strings.SplitN(serverInfo[0], ":", 2) if len(serverAndPort) != 2 { - return model.Proxy{}, errors.New("invalid ss Url") + return model2.Proxy{}, errors.New("invalid ss Url") } port, err := strconv.Atoi(strings.TrimSpace(serverAndPort[1])) if err != nil { - return model.Proxy{}, errors.New("invalid ss Url" + err.Error()) + return model2.Proxy{}, errors.New("invalid ss Url" + err.Error()) } remarks := "" if len(serverInfo) == 2 { unescape, err := url.QueryUnescape(serverInfo[1]) if err != nil { - return model.Proxy{}, errors.New("invalid ss Url" + err.Error()) + return model2.Proxy{}, errors.New("invalid ss Url" + err.Error()) } remarks = strings.TrimSpace(unescape) } else { @@ -50,10 +50,10 @@ func ParseShadowsocks(proxy string) (model.Proxy, error) { method := credentials[0] password := credentials[1] server := strings.TrimSpace(serverAndPort[0]) - result := model.Proxy{ + result := model2.Proxy{ Type: "shadowsocks", Tag: remarks, - Shadowsocks: model.Shadowsocks{ + Shadowsocks: model2.Shadowsocks{ Method: method, Password: password, Server: server, diff --git a/pkg/parser/trojan.go b/parser/trojan.go similarity index 68% rename from pkg/parser/trojan.go rename to parser/trojan.go index dd1ab3b..4d8b896 100644 --- a/pkg/parser/trojan.go +++ b/parser/trojan.go @@ -5,30 +5,30 @@ import ( "net/url" "strconv" "strings" - "sub2sing-box/internal/model" + model2 "sub2sing-box/model" ) -func ParseTrojan(proxy string) (model.Proxy, error) { +func ParseTrojan(proxy string) (model2.Proxy, error) { if !strings.HasPrefix(proxy, "trojan://") { - return model.Proxy{}, errors.New("invalid trojan Url") + return model2.Proxy{}, errors.New("invalid trojan Url") } parts := strings.SplitN(strings.TrimPrefix(proxy, "trojan://"), "@", 2) if len(parts) != 2 { - return model.Proxy{}, errors.New("invalid trojan Url") + return model2.Proxy{}, errors.New("invalid trojan Url") } serverInfo := strings.SplitN(parts[1], "#", 2) serverAndPortAndParams := strings.SplitN(serverInfo[0], "?", 2) serverAndPort := strings.SplitN(serverAndPortAndParams[0], ":", 2) params, err := url.ParseQuery(serverAndPortAndParams[1]) if err != nil { - return model.Proxy{}, err + return model2.Proxy{}, err } if len(serverAndPort) != 2 { - return model.Proxy{}, errors.New("invalid trojan Url") + return model2.Proxy{}, errors.New("invalid trojan Url") } port, err := strconv.Atoi(strings.TrimSpace(serverAndPort[1])) if err != nil { - return model.Proxy{}, err + return model2.Proxy{}, err } remarks := "" if len(serverInfo) == 2 { @@ -38,10 +38,10 @@ func ParseTrojan(proxy string) (model.Proxy, error) { } server := strings.TrimSpace(serverAndPort[0]) password := strings.TrimSpace(parts[0]) - result := model.Proxy{ + result := model2.Proxy{ Type: "trojan", Tag: remarks, - Trojan: model.Trojan{ + Trojan: model2.Trojan{ Server: server, ServerPort: uint16(port), Password: password, @@ -55,31 +55,31 @@ func ParseTrojan(proxy string) (model.Proxy, error) { } else { alpn = nil } - result.Trojan.TLS = &model.OutboundTLSOptions{ + result.Trojan.TLS = &model2.OutboundTLSOptions{ Enabled: true, ALPN: alpn, ServerName: params.Get("sni"), } } if params.Get("security") == "reality" { - result.Trojan.TLS = &model.OutboundTLSOptions{ + result.Trojan.TLS = &model2.OutboundTLSOptions{ Enabled: true, ServerName: params.Get("sni"), - Reality: &model.OutboundRealityOptions{ + Reality: &model2.OutboundRealityOptions{ Enabled: true, PublicKey: params.Get("pbk"), ShortID: params.Get("sid"), }, - UTLS: &model.OutboundUTLSOptions{ + UTLS: &model2.OutboundUTLSOptions{ Enabled: params.Get("fp") != "", Fingerprint: params.Get("fp"), }, } } if params.Get("type") == "ws" { - result.Trojan.Transport = &model.V2RayTransportOptions{ + result.Trojan.Transport = &model2.V2RayTransportOptions{ Type: "ws", - WebsocketOptions: model.V2RayWebsocketOptions{ + WebsocketOptions: model2.V2RayWebsocketOptions{ Path: params.Get("path"), Headers: map[string]string{ "Host": params.Get("host"), @@ -88,24 +88,24 @@ func ParseTrojan(proxy string) (model.Proxy, error) { } } if params.Get("type") == "http" { - result.Trojan.Transport = &model.V2RayTransportOptions{ + result.Trojan.Transport = &model2.V2RayTransportOptions{ Type: "http", - HTTPOptions: model.V2RayHTTPOptions{ + HTTPOptions: model2.V2RayHTTPOptions{ Host: []string{params.Get("host")}, Path: params.Get("path"), }, } } if params.Get("type") == "quic" { - result.Trojan.Transport = &model.V2RayTransportOptions{ + result.Trojan.Transport = &model2.V2RayTransportOptions{ Type: "quic", - QUICOptions: model.V2RayQUICOptions{}, + QUICOptions: model2.V2RayQUICOptions{}, } } if params.Get("type") == "grpc" { - result.Trojan.Transport = &model.V2RayTransportOptions{ + result.Trojan.Transport = &model2.V2RayTransportOptions{ Type: "grpc", - GRPCOptions: model.V2RayGRPCOptions{ + GRPCOptions: model2.V2RayGRPCOptions{ ServiceName: params.Get("serviceName"), }, } diff --git a/pkg/parser/vless.go b/parser/vless.go similarity index 69% rename from pkg/parser/vless.go rename to parser/vless.go index a7767dc..4ac80b5 100644 --- a/pkg/parser/vless.go +++ b/parser/vless.go @@ -5,30 +5,30 @@ import ( "net/url" "strconv" "strings" - "sub2sing-box/internal/model" + model2 "sub2sing-box/model" ) -func ParseVless(proxy string) (model.Proxy, error) { +func ParseVless(proxy string) (model2.Proxy, error) { if !strings.HasPrefix(proxy, "vless://") { - return model.Proxy{}, errors.New("invalid vless Url") + return model2.Proxy{}, errors.New("invalid vless Url") } parts := strings.SplitN(strings.TrimPrefix(proxy, "vless://"), "@", 2) if len(parts) != 2 { - return model.Proxy{}, errors.New("invalid vless Url") + return model2.Proxy{}, errors.New("invalid vless Url") } serverInfo := strings.SplitN(parts[1], "#", 2) serverAndPortAndParams := strings.SplitN(serverInfo[0], "?", 2) serverAndPort := strings.SplitN(serverAndPortAndParams[0], ":", 2) params, err := url.ParseQuery(serverAndPortAndParams[1]) if err != nil { - return model.Proxy{}, err + return model2.Proxy{}, err } if len(serverAndPort) != 2 { - return model.Proxy{}, errors.New("invalid vless Url") + return model2.Proxy{}, errors.New("invalid vless Url") } port, err := strconv.Atoi(strings.TrimSpace(serverAndPort[1])) if err != nil { - return model.Proxy{}, err + return model2.Proxy{}, err } remarks := "" if len(serverInfo) == 2 { @@ -37,21 +37,21 @@ func ParseVless(proxy string) (model.Proxy, error) { } else { remarks, err = url.QueryUnescape(serverInfo[1]) if err != nil { - return model.Proxy{}, err + return model2.Proxy{}, err } } } else { remarks, err = url.QueryUnescape(serverAndPort[0]) if err != nil { - return model.Proxy{}, err + return model2.Proxy{}, err } } server := strings.TrimSpace(serverAndPort[0]) uuid := strings.TrimSpace(parts[0]) - result := model.Proxy{ + result := model2.Proxy{ Type: "vless", Tag: remarks, - VLESS: model.VLESS{ + VLESS: model2.VLESS{ Server: server, ServerPort: uint16(port), UUID: uuid, @@ -65,7 +65,7 @@ func ParseVless(proxy string) (model.Proxy, error) { } else { alpn = nil } - result.VLESS.TLS = &model.OutboundTLSOptions{ + result.VLESS.TLS = &model2.OutboundTLSOptions{ Enabled: true, ALPN: alpn, Insecure: params.Get("allowInsecure") == "1", @@ -78,14 +78,14 @@ func ParseVless(proxy string) (model.Proxy, error) { } else { alpn = nil } - result.VLESS.TLS = &model.OutboundTLSOptions{ + result.VLESS.TLS = &model2.OutboundTLSOptions{ Enabled: true, ServerName: params.Get("sni"), - UTLS: &model.OutboundUTLSOptions{ + UTLS: &model2.OutboundUTLSOptions{ Enabled: params.Get("fp") != "", Fingerprint: params.Get("fp"), }, - Reality: &model.OutboundRealityOptions{ + Reality: &model2.OutboundRealityOptions{ Enabled: true, PublicKey: params.Get("pbk"), ShortID: params.Get("sid"), @@ -94,9 +94,9 @@ func ParseVless(proxy string) (model.Proxy, error) { } } if params.Get("type") == "ws" { - result.VLESS.Transport = &model.V2RayTransportOptions{ + result.VLESS.Transport = &model2.V2RayTransportOptions{ Type: "ws", - WebsocketOptions: model.V2RayWebsocketOptions{ + WebsocketOptions: model2.V2RayWebsocketOptions{ Path: params.Get("path"), Headers: map[string]string{ "Host": params.Get("host"), @@ -105,15 +105,15 @@ func ParseVless(proxy string) (model.Proxy, error) { } } if params.Get("type") == "quic" { - result.VLESS.Transport = &model.V2RayTransportOptions{ + result.VLESS.Transport = &model2.V2RayTransportOptions{ Type: "quic", - QUICOptions: model.V2RayQUICOptions{}, + QUICOptions: model2.V2RayQUICOptions{}, } } if params.Get("type") == "grpc" { - result.VLESS.Transport = &model.V2RayTransportOptions{ + result.VLESS.Transport = &model2.V2RayTransportOptions{ Type: "grpc", - GRPCOptions: model.V2RayGRPCOptions{ + GRPCOptions: model2.V2RayGRPCOptions{ ServiceName: params.Get("serviceName"), }, } @@ -121,11 +121,11 @@ func ParseVless(proxy string) (model.Proxy, error) { if params.Get("type") == "http" { host, err := url.QueryUnescape(params.Get("host")) if err != nil { - return model.Proxy{}, err + return model2.Proxy{}, err } - result.VLESS.Transport = &model.V2RayTransportOptions{ + result.VLESS.Transport = &model2.V2RayTransportOptions{ Type: "http", - HTTPOptions: model.V2RayHTTPOptions{ + HTTPOptions: model2.V2RayHTTPOptions{ Host: strings.Split(host, ","), }, } diff --git a/pkg/parser/vmess.go b/parser/vmess.go similarity index 69% rename from pkg/parser/vmess.go rename to parser/vmess.go index a00ff00..051db02 100644 --- a/pkg/parser/vmess.go +++ b/parser/vmess.go @@ -6,29 +6,29 @@ import ( "net/url" "strconv" "strings" - "sub2sing-box/internal/model" - "sub2sing-box/internal/util" + model2 "sub2sing-box/model" + "sub2sing-box/util" ) -func ParseVmess(proxy string) (model.Proxy, error) { +func ParseVmess(proxy string) (model2.Proxy, error) { if !strings.HasPrefix(proxy, "vmess://") { - return model.Proxy{}, errors.New("invalid vmess url") + return model2.Proxy{}, errors.New("invalid vmess url") } base64, err := util.DecodeBase64(strings.TrimPrefix(proxy, "vmess://")) if err != nil { - return model.Proxy{}, errors.New("invalid vmess url" + err.Error()) + return model2.Proxy{}, errors.New("invalid vmess url" + err.Error()) } - var vmess model.VmessJson + var vmess model2.VmessJson err = json.Unmarshal([]byte(base64), &vmess) if err != nil { - return model.Proxy{}, errors.New("invalid vmess url" + err.Error()) + return model2.Proxy{}, errors.New("invalid vmess url" + err.Error()) } port := 0 switch vmess.Port.(type) { case string: port, err = strconv.Atoi(vmess.Port.(string)) if err != nil { - return model.Proxy{}, errors.New("invalid vmess url" + err.Error()) + return model2.Proxy{}, errors.New("invalid vmess url" + err.Error()) } case float64: port = int(vmess.Port.(float64)) @@ -38,7 +38,7 @@ func ParseVmess(proxy string) (model.Proxy, error) { case string: aid, err = strconv.Atoi(vmess.Aid.(string)) if err != nil { - return model.Proxy{}, errors.New("invalid vmess url" + err.Error()) + return model2.Proxy{}, errors.New("invalid vmess url" + err.Error()) } case float64: aid = int(vmess.Aid.(float64)) @@ -52,10 +52,10 @@ func ParseVmess(proxy string) (model.Proxy, error) { name = vmess.Ps } - result := model.Proxy{ + result := model2.Proxy{ Type: "vmess", Tag: name, - VMess: model.VMess{ + VMess: model2.VMess{ Server: vmess.Add, ServerPort: uint16(port), UUID: vmess.Id, @@ -71,9 +71,9 @@ func ParseVmess(proxy string) (model.Proxy, error) { } else { alpn = nil } - tls := model.OutboundTLSOptions{ + tls := model2.OutboundTLSOptions{ Enabled: true, - UTLS: &model.OutboundUTLSOptions{ + UTLS: &model2.OutboundUTLSOptions{ Fingerprint: vmess.Fp, }, ALPN: alpn, @@ -88,13 +88,13 @@ func ParseVmess(proxy string) (model.Proxy, error) { if vmess.Host == "" { vmess.Host = vmess.Add } - ws := model.V2RayWebsocketOptions{ + ws := model2.V2RayWebsocketOptions{ Path: vmess.Path, Headers: map[string]string{ "Host": vmess.Host, }, } - transport := model.V2RayTransportOptions{ + transport := model2.V2RayTransportOptions{ Type: "ws", WebsocketOptions: ws, } @@ -102,8 +102,8 @@ func ParseVmess(proxy string) (model.Proxy, error) { } if vmess.Net == "quic" { - quic := model.V2RayQUICOptions{} - transport := model.V2RayTransportOptions{ + quic := model2.V2RayQUICOptions{} + transport := model2.V2RayTransportOptions{ Type: "quic", QUICOptions: quic, } @@ -111,11 +111,11 @@ func ParseVmess(proxy string) (model.Proxy, error) { } if vmess.Net == "grpc" { - grpc := model.V2RayGRPCOptions{ + grpc := model2.V2RayGRPCOptions{ ServiceName: vmess.Path, PermitWithoutStream: true, } - transport := model.V2RayTransportOptions{ + transport := model2.V2RayTransportOptions{ Type: "grpc", GRPCOptions: grpc, } @@ -123,11 +123,11 @@ func ParseVmess(proxy string) (model.Proxy, error) { } if vmess.Net == "h2" { - httpOps := model.V2RayHTTPOptions{ + httpOps := model2.V2RayHTTPOptions{ Host: strings.Split(vmess.Host, ","), Path: vmess.Path, } - transport := model.V2RayTransportOptions{ + transport := model2.V2RayTransportOptions{ Type: "http", HTTPOptions: httpOps, } diff --git a/internal/util/base64.go b/util/base64.go similarity index 100% rename from internal/util/base64.go rename to util/base64.go diff --git a/internal/util/fetch.go b/util/fetch.go similarity index 100% rename from internal/util/fetch.go rename to util/fetch.go