From f1d1029c95019cd80350e034676a009bcab67a3e Mon Sep 17 00:00:00 2001 From: nite07 Date: Mon, 11 Mar 2024 19:28:22 +0800 Subject: [PATCH] update --- .gitignore | 3 +- cmd/convert.go | 34 +++- model/config.go | 478 +++++++++++++++++++++++++-------------------- model/hysteria2.go | 26 --- 4 files changed, 295 insertions(+), 246 deletions(-) diff --git a/.gitignore b/.gitignore index 9f8a715..da2ac96 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .vscode dist -*test.go \ No newline at end of file +*test.go +template.json \ No newline at end of file diff --git a/cmd/convert.go b/cmd/convert.go index f71cf2c..a0376cb 100644 --- a/cmd/convert.go +++ b/cmd/convert.go @@ -24,12 +24,25 @@ var convertCmd = &cobra.Command{ proxies, _ := cmd.Flags().GetStringSlice("proxy") template, _ := cmd.Flags().GetString("template") if template == "" { - result, err := ConvertSubscriptionsToJson(subscriptions) + proxyList, err := ConvertSubscriptionsToSProxy(subscriptions) if err != nil { fmt.Println(err) return } - fmt.Println(result) + for _, p := range proxies { + result, err := ConvertCProxyToSProxy(p) + if err != nil { + fmt.Println(err) + return + } + proxyList = append(proxyList, result) + } + result, err := json.Marshal(proxyList) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(result)) } else { config, err := ConvertWithTemplate(subscriptions, proxies, template) if err != nil { @@ -73,6 +86,7 @@ func Convert(urls []string, proxies []string) ([]model.Proxy, error) { func ConvertWithTemplate(urls []string, proxies []string, template string) (model.Config, error) { proxyList := make([]model.Proxy, 0) newProxies, err := ConvertSubscriptionsToSProxy(urls) + newOutboundTagList := make([]string, 0) if err != nil { return model.Config{}, err } @@ -97,7 +111,23 @@ func ConvertWithTemplate(urls []string, proxies []string, template string) (mode if err != nil { return model.Config{}, err } + for _, outbound := range newOutbounds { + newOutboundTagList = append(newOutboundTagList, outbound.Tag) + } config.Outbounds = append(config.Outbounds, newOutbounds...) + for i, outbound := range config.Outbounds { + if outbound.Type == "urltest" || outbound.Type == "selector" { + var parsedOutbound []string = make([]string, 0) + for _, o := range outbound.Outbounds { + if o == "" { + parsedOutbound = append(parsedOutbound, newOutboundTagList...) + } else { + parsedOutbound = append(parsedOutbound, o) + } + } + config.Outbounds[i].Outbounds = parsedOutbound + } + } return config, nil } diff --git a/model/config.go b/model/config.go index 1a40dad..48b405a 100644 --- a/model/config.go +++ b/model/config.go @@ -1,11 +1,58 @@ package model +import "encoding/json" + +type Listable[T any] []T + +func (l *Listable[T]) UnmarshalJSON(data []byte) error { + var arr []T + if err := json.Unmarshal(data, &arr); err == nil { + *l = arr + return nil + } + var v T + if err := json.Unmarshal(data, &v); err == nil { + *l = []T{v} + return nil + } + return nil +} + +type Obfs struct { + Str string + Obfs *Hysteria2Obfs + IsStr bool +} + +func (o *Obfs) UnmarshalJSON(data []byte) error { + var str string + if err := json.Unmarshal(data, &str); err == nil { + o.Str = str + o.IsStr = true + return nil + } + var obfs Hysteria2Obfs + if err := json.Unmarshal(data, &obfs); err == nil { + o.IsStr = false + o.Obfs = &obfs + return nil + } + return nil +} + +func (o Obfs) MarshalJSON() ([]byte, error) { + if o.IsStr { + return json.Marshal(o.Str) + } + return json.Marshal(o.Obfs) +} + type Config struct { Log *LogOptions `json:"log,omitempty"` DNS *DNSOptions `json:"dns,omitempty"` NTP *NTPOptions `json:"ntp,omitempty"` - Inbounds []Inbound `json:"inbounds,omitempty"` - Outbounds []Outbound `json:"outbounds,omitempty"` + Inbounds Listable[Inbound] `json:"inbounds,omitempty"` + Outbounds Listable[Outbound] `json:"outbounds,omitempty"` Route *RouteOptions `json:"route,omitempty"` Experimental *ExperimentalOptions `json:"experimental,omitempty"` } @@ -18,16 +65,16 @@ type LogOptions struct { } type DNSOptions struct { - Servers []DNSServerOptions `json:"servers,omitempty"` - Rules []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"` - ClientSubnet string `json:"client_subnet,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"` + ClientSubnet string `json:"client_subnet,omitempty"` } type DNSServerOptions struct { @@ -41,46 +88,46 @@ type DNSServerOptions struct { } type DNSRule struct { - Type string `json:"type,omitempty"` - Inbound []string `json:"inbound,omitempty"` - IPVersion int `json:"ip_version,omitempty"` - QueryType []string `json:"query_type,omitempty"` - Network []string `json:"network,omitempty"` - AuthUser []string `json:"auth_user,omitempty"` - Protocol []string `json:"protocol,omitempty"` - Domain []string `json:"domain,omitempty"` - DomainSuffix []string `json:"domain_suffix,omitempty"` - DomainKeyword []string `json:"domain_keyword,omitempty"` - DomainRegex []string `json:"domain_regex,omitempty"` - Geosite []string `json:"geosite,omitempty"` - SourceGeoIP []string `json:"source_geoip,omitempty"` - GeoIP []string `json:"geoip,omitempty"` - IPCIDR []string `json:"ip_cidr,omitempty"` - IPIsPrivate bool `json:"ip_is_private,omitempty"` - SourceIPCIDR []string `json:"source_ip_cidr,omitempty"` - SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"` - SourcePort []uint16 `json:"source_port,omitempty"` - SourcePortRange []string `json:"source_port_range,omitempty"` - Port []uint16 `json:"port,omitempty"` - PortRange []string `json:"port_range,omitempty"` - ProcessName []string `json:"process_name,omitempty"` - ProcessPath []string `json:"process_path,omitempty"` - PackageName []string `json:"package_name,omitempty"` - User []string `json:"user,omitempty"` - UserID []int32 `json:"user_id,omitempty"` - Outbound []string `json:"outbound,omitempty"` - ClashMode string `json:"clash_mode,omitempty"` - WIFISSID []string `json:"wifi_ssid,omitempty"` - WIFIBSSID []string `json:"wifi_bssid,omitempty"` - RuleSet []string `json:"rule_set,omitempty"` - RuleSetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"` - Invert bool `json:"invert,omitempty"` - Server string `json:"server,omitempty"` - DisableCache bool `json:"disable_cache,omitempty"` - RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"` - ClientSubnet string `json:"client_subnet,omitempty"` - Mode string `json:"mode"` - Rules []DNSRule `json:"rules,omitempty"` + Type string `json:"type,omitempty"` + Inbound Listable[string] `json:"inbound,omitempty"` + IPVersion int `json:"ip_version,omitempty"` + QueryType Listable[uint16] `json:"query_type,omitempty"` + Network Listable[string] `json:"network,omitempty"` + AuthUser Listable[string] `json:"auth_user,omitempty"` + Protocol Listable[string] `json:"protocol,omitempty"` + Domain Listable[string] `json:"domain,omitempty"` + DomainSuffix Listable[string] `json:"domain_suffix,omitempty"` + DomainKeyword Listable[string] `json:"domain_keyword,omitempty"` + DomainRegex Listable[string] `json:"domain_regex,omitempty"` + Geosite Listable[string] `json:"geosite,omitempty"` + SourceGeoIP Listable[string] `json:"source_geoip,omitempty"` + GeoIP Listable[string] `json:"geoip,omitempty"` + IPCIDR Listable[string] `json:"ip_cidr,omitempty"` + IPIsPrivate bool `json:"ip_is_private,omitempty"` + SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"` + SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"` + SourcePort Listable[uint16] `json:"source_port,omitempty"` + SourcePortRange Listable[string] `json:"source_port_range,omitempty"` + Port Listable[uint16] `json:"port,omitempty"` + PortRange Listable[string] `json:"port_range,omitempty"` + ProcessName Listable[string] `json:"process_name,omitempty"` + ProcessPath Listable[string] `json:"process_path,omitempty"` + PackageName Listable[string] `json:"package_name,omitempty"` + User Listable[string] `json:"user,omitempty"` + UserID Listable[int32] `json:"user_id,omitempty"` + Outbound Listable[string] `json:"outbound,omitempty"` + ClashMode string `json:"clash_mode,omitempty"` + WIFISSID Listable[string] `json:"wifi_ssid,omitempty"` + WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"` + RuleSet Listable[string] `json:"rule_set,omitempty"` + RuleSetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"` + Invert bool `json:"invert,omitempty"` + Server string `json:"server,omitempty"` + DisableCache bool `json:"disable_cache,omitempty"` + RewriteTTL uint32 `json:"rewrite_ttl,omitempty"` + ClientSubnet string `json:"client_subnet,omitempty"` + Mode string `json:"mode"` + Rules Listable[DNSRule] `json:"rules,omitempty"` } type DNSFakeIPOptions struct { @@ -116,23 +163,23 @@ type Inbound struct { InterfaceName string `json:"interface_name,omitempty"` MTU uint32 `json:"mtu,omitempty"` GSO bool `json:"gso,omitempty"` - Inet4Address []string `json:"inet4_address,omitempty"` - Inet6Address []string `json:"inet6_address,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 []string `json:"inet4_route_address,omitempty"` - Inet6RouteAddress []string `json:"inet6_route_address,omitempty"` - Inet4RouteExcludeAddress []string `json:"inet4_route_exclude_address,omitempty"` - Inet6RouteExcludeAddress []string `json:"inet6_route_exclude_address,omitempty"` - IncludeInterface []string `json:"include_interface,omitempty"` - ExcludeInterface []string `json:"exclude_interface,omitempty"` - IncludeUID []uint32 `json:"include_uid,omitempty"` - IncludeUIDRange []string `json:"include_uid_range,omitempty"` - ExcludeUID []uint32 `json:"exclude_uid,omitempty"` - ExcludeUIDRange []string `json:"exclude_uid_range,omitempty"` - IncludeAndroidUser []int `json:"include_android_user,omitempty"` - IncludePackage []string `json:"include_package,omitempty"` - ExcludePackage []string `json:"exclude_package,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"` @@ -149,164 +196,161 @@ type TunPlatformOptions struct { } type HTTPProxyOptions struct { - Enabled bool `json:"enabled,omitempty"` - Server string `json:"server"` - ServerPort uint16 `json:"server_port"` - BypassDomain []string `json:"bypass_domain,omitempty"` - MatchDomain []string `json:"match_domain,omitempty"` + Enabled bool `json:"enabled,omitempty"` + Server string `json:"server"` + ServerPort uint16 `json:"server_port"` + BypassDomain Listable[string] `json:"bypass_domain,omitempty"` + MatchDomain Listable[string] `json:"match_domain,omitempty"` } type Outbound struct { - Type string `json:"type"` - Tag string `json:"tag,omitempty"` - Detour string `json:"detour,omitempty"` - BindInterface string `json:"bind_interface,omitempty"` - Inet4BindAddress string `json:"inet4_bind_address,omitempty"` - Inet6BindAddress string `json:"inet6_bind_address,omitempty"` - ProtectPath string `json:"protect_path,omitempty"` - RoutingMark int `json:"routing_mark,omitempty"` - ReuseAddr bool `json:"reuse_addr,omitempty"` - ConnectTimeout string `json:"connect_timeout,omitempty"` - TCPFastOpen bool `json:"tcp_fast_open,omitempty"` - TCPMultiPath bool `json:"tcp_multi_path,omitempty"` - UDPFragment *bool `json:"udp_fragment,omitempty"` - DomainStrategy string `json:"domain_strategy,omitempty"` - FallbackDelay string `json:"fallback_delay,omitempty"` - OverrideAddress string `json:"override_address,omitempty"` - OverridePort uint16 `json:"override_port,omitempty"` - ProxyProtocol uint8 `json:"proxy_protocol,omitempty"` - Server string `json:"server"` - ServerPort uint16 `json:"server_port"` - 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][]string `json:"headers,omitempty"` - Method string `json:"method"` - Plugin string `json:"plugin,omitempty"` - PluginOptions string `json:"plugin_opts,omitempty"` - Multiplex *OutboundMultiplexOptions `json:"multiplex,omitempty"` - UUID string `json:"uuid"` - Security string `json:"security"` - 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"` - GSO bool `json:"gso,omitempty"` - InterfaceName string `json:"interface_name,omitempty"` - LocalAddress []string `json:"local_address"` - PrivateKey string `json:"private_key"` - Peers []WireGuardPeer `json:"peers,omitempty"` - PeerPublicKey string `json:"peer_public_key"` - PreSharedKey string `json:"pre_shared_key,omitempty"` - Reserved []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 struct { - string - *Hysteria2Obfs - } `json:"obfs,omitempty"` - Auth []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 []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 []string `json:"host_key,omitempty"` - HostKeyAlgorithms []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"` - Flow string `json:"flow,omitempty"` - CongestionControl string `json:"congestion_control,omitempty"` - UDPRelayMode string `json:"udp_relay_mode,omitempty"` - UDPOverStream bool `json:"udp_over_stream,omitempty"` - ZeroRTTHandshake bool `json:"zero_rtt_handshake,omitempty"` - Heartbeat string `json:"heartbeat,omitempty"` - BrutalDebug bool `json:"brutal_debug,omitempty"` - Default string `json:"default,omitempty"` - Outbounds []string `json:"outbounds"` - URL string `json:"url,omitempty"` - Interval string `json:"interval,omitempty"` - Tolerance uint16 `json:"tolerance,omitempty"` - IdleTimeout string `json:"idle_timeout,omitempty"` - InterruptExistConnections bool `json:"interrupt_exist_connections,omitempty"` + Type string `json:"type"` + Tag string `json:"tag,omitempty"` + Detour string `json:"detour,omitempty"` + BindInterface string `json:"bind_interface,omitempty"` + Inet4BindAddress string `json:"inet4_bind_address,omitempty"` + Inet6BindAddress string `json:"inet6_bind_address,omitempty"` + ProtectPath string `json:"protect_path,omitempty"` + RoutingMark int `json:"routing_mark,omitempty"` + ReuseAddr bool `json:"reuse_addr,omitempty"` + ConnectTimeout string `json:"connect_timeout,omitempty"` + TCPFastOpen bool `json:"tcp_fast_open,omitempty"` + TCPMultiPath bool `json:"tcp_multi_path,omitempty"` + UDPFragment *bool `json:"udp_fragment,omitempty"` + DomainStrategy string `json:"domain_strategy,omitempty"` + FallbackDelay string `json:"fallback_delay,omitempty"` + OverrideAddress string `json:"override_address,omitempty"` + OverridePort uint16 `json:"override_port,omitempty"` + ProxyProtocol uint8 `json:"proxy_protocol,omitempty"` + Server string `json:"server,omitempty"` + ServerPort uint16 `json:"server_port,omitempty"` + 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"` + Plugin string `json:"plugin,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"` + 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"` + 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"` + 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"` + 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"` + ObfsParam string `json:"obfs_param,omitempty"` + Protocol string `json:"protocol,omitempty"` + ProtocolParam string `json:"protocol_param,omitempty"` + Flow string `json:"flow,omitempty"` + CongestionControl string `json:"congestion_control,omitempty"` + UDPRelayMode string `json:"udp_relay_mode,omitempty"` + UDPOverStream bool `json:"udp_over_stream,omitempty"` + 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"` + Interval string `json:"interval,omitempty"` + Tolerance uint16 `json:"tolerance,omitempty"` + IdleTimeout string `json:"idle_timeout,omitempty"` + InterruptExistConnections bool `json:"interrupt_exist_connections,omitempty"` } type WireGuardPeer struct { - Server string `json:"server"` - ServerPort uint16 `json:"server_port"` - PublicKey string `json:"public_key,omitempty"` - PreSharedKey string `json:"pre_shared_key,omitempty"` - AllowedIPs []string `json:"allowed_ips,omitempty"` - Reserved []uint8 `json:"reserved,omitempty"` + Server string `json:"server"` + ServerPort uint16 `json:"server_port"` + PublicKey string `json:"public_key,omitempty"` + PreSharedKey string `json:"pre_shared_key,omitempty"` + AllowedIPs Listable[string] `json:"allowed_ips,omitempty"` + Reserved Listable[uint8] `json:"reserved,omitempty"` } type RouteOptions struct { - GeoIP *GeoIPOptions `json:"geoip,omitempty"` - Geosite *GeositeOptions `json:"geosite,omitempty"` - Rules []Rule `json:"rules,omitempty"` - RuleSet []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"` - DefaultInterface string `json:"default_interface,omitempty"` - DefaultMark int `json:"default_mark,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"` + DefaultInterface string `json:"default_interface,omitempty"` + DefaultMark int `json:"default_mark,omitempty"` } type Rule struct { - Type string `json:"type,omitempty"` - Inbound []string `json:"inbound,omitempty"` - IPVersion int `json:"ip_version,omitempty"` - Network []string `json:"network,omitempty"` - AuthUser []string `json:"auth_user,omitempty"` - Protocol []string `json:"protocol,omitempty"` - Domain []string `json:"domain,omitempty"` - DomainSuffix []string `json:"domain_suffix,omitempty"` - DomainKeyword []string `json:"domain_keyword,omitempty"` - DomainRegex []string `json:"domain_regex,omitempty"` - Geosite []string `json:"geosite,omitempty"` - SourceGeoIP []string `json:"source_geoip,omitempty"` - GeoIP []string `json:"geoip,omitempty"` - SourceIPCIDR []string `json:"source_ip_cidr,omitempty"` - SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"` - IPCIDR []string `json:"ip_cidr,omitempty"` - IPIsPrivate bool `json:"ip_is_private,omitempty"` - SourcePort []uint16 `json:"source_port,omitempty"` - SourcePortRange []string `json:"source_port_range,omitempty"` - Port []uint16 `json:"port,omitempty"` - PortRange []string `json:"port_range,omitempty"` - ProcessName []string `json:"process_name,omitempty"` - ProcessPath []string `json:"process_path,omitempty"` - PackageName []string `json:"package_name,omitempty"` - User []string `json:"user,omitempty"` - UserID []int32 `json:"user_id,omitempty"` - ClashMode string `json:"clash_mode,omitempty"` - WIFISSID []string `json:"wifi_ssid,omitempty"` - WIFIBSSID []string `json:"wifi_bssid,omitempty"` - RuleSet []string `json:"rule_set,omitempty"` - RuleSetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"` - Invert bool `json:"invert,omitempty"` - Outbound string `json:"outbound,omitempty"` - Mode string `json:"mode"` - Rules []Rule `json:"rules,omitempty"` + Type string `json:"type,omitempty"` + Inbound Listable[string] `json:"inbound,omitempty"` + IPVersion int `json:"ip_version,omitempty"` + Network Listable[string] `json:"network,omitempty"` + AuthUser Listable[string] `json:"auth_user,omitempty"` + Protocol string `json:"protocol,omitempty"` + Domain Listable[string] `json:"domain,omitempty"` + DomainSuffix Listable[string] `json:"domain_suffix,omitempty"` + DomainKeyword Listable[string] `json:"domain_keyword,omitempty"` + DomainRegex Listable[string] `json:"domain_regex,omitempty"` + Geosite Listable[string] `json:"geosite,omitempty"` + SourceGeoIP Listable[string] `json:"source_geoip,omitempty"` + GeoIP Listable[string] `json:"geoip,omitempty"` + SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"` + SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"` + IPCIDR Listable[string] `json:"ip_cidr,omitempty"` + IPIsPrivate bool `json:"ip_is_private,omitempty"` + SourcePort Listable[uint16] `json:"source_port,omitempty"` + SourcePortRange Listable[string] `json:"source_port_range,omitempty"` + Port Listable[uint16] `json:"port,omitempty"` + PortRange Listable[string] `json:"port_range,omitempty"` + ProcessName Listable[string] `json:"process_name,omitempty"` + ProcessPath Listable[string] `json:"process_path,omitempty"` + PackageName Listable[string] `json:"package_name,omitempty"` + User Listable[string] `json:"user,omitempty"` + UserID Listable[int32] `json:"user_id,omitempty"` + ClashMode string `json:"clash_mode,omitempty"` + WIFISSID Listable[string] `json:"wifi_ssid,omitempty"` + WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"` + RuleSet Listable[string] `json:"rule_set,omitempty"` + RuleSetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"` + Invert bool `json:"invert,omitempty"` + Outbound string `json:"outbound,omitempty"` + Mode string `json:"mode,omitempty"` + Rules Listable[Rule] `json:"rules,omitempty"` } type GeoIPOptions struct { @@ -372,8 +416,8 @@ type V2RayAPIOptions struct { } type V2RayStatsServiceOptions struct { - Enabled bool `json:"enabled,omitempty"` - Inbounds []string `json:"inbounds,omitempty"` - Outbounds []string `json:"outbounds,omitempty"` - Users []string `json:"users,omitempty"` + Enabled bool `json:"enabled,omitempty"` + Inbounds Listable[string] `json:"inbounds,omitempty"` + Outbounds Listable[string] `json:"outbounds,omitempty"` + Users Listable[string] `json:"users,omitempty"` } diff --git a/model/hysteria2.go b/model/hysteria2.go index b57f894..32263f7 100644 --- a/model/hysteria2.go +++ b/model/hysteria2.go @@ -18,29 +18,3 @@ type Hysteria2 struct { TLS *OutboundTLSOptions `json:"tls,omitempty"` BrutalDebug bool `json:"brutal_debug,omitempty"` } - -// func (h *Hysteria2OutboundOptions) MarshalJSON() ([]byte, error) { -// val := reflect.ValueOf(h) -// out := make(map[string]interface{}) -// typ := val.Type() -// for i := 0; i < val.NumField(); i++ { -// field := val.Field(i) -// fieldType := typ.Field(i) -// if field.Kind() == reflect.Struct { -// for j := 0; j < field.NumField(); j++ { -// subField := field.Field(j) -// subFieldType := fieldType.Type.Field(j) -// jsonTag := subFieldType.Tag.Get("json") -// if jsonTag != "" && jsonTag != "-" { -// out[jsonTag] = subField.Interface() -// } -// } -// } else { -// jsonTag := fieldType.Tag.Get("json") -// if jsonTag != "" && jsonTag != "-" { -// out[jsonTag] = field.Interface() -// } -// } -// } -// return json.Marshal(out) -// }