package config // Mode defines a routing mode with its specific rules. type Mode struct { Name string Final string // "direct" or "proxy" Rules []Rule } // Rule represents a single sing-box routing rule. type Rule struct { DomainSuffix []string `json:"domain_suffix,omitempty"` DomainRegex []string `json:"domain_regex,omitempty"` IPCIDR []string `json:"ip_cidr,omitempty"` RuleSet []string `json:"rule_set,omitempty"` Network []string `json:"network,omitempty"` PortRange []string `json:"port_range,omitempty"` Outbound string `json:"outbound"` } // Discord IPs — ported 1:1 from vpn.py. var DiscordIPs = []string{ "162.159.130.234/32", "162.159.134.234/32", "162.159.133.234/32", "162.159.135.234/32", "162.159.136.234/32", "162.159.137.232/32", "162.159.135.232/32", "162.159.136.232/32", "162.159.138.232/32", "162.159.128.233/32", "198.244.231.90/32", "162.159.129.233/32", "162.159.130.233/32", "162.159.133.233/32", "162.159.134.233/32", "162.159.135.233/32", "162.159.138.234/32", "162.159.137.234/32", "162.159.134.232/32", "162.159.130.235/32", "162.159.129.235/32", "162.159.129.232/32", "162.159.128.235/32", "162.159.130.232/32", "162.159.133.232/32", "162.159.128.232/32", "34.126.226.51/32", // Voice "66.22.243.0/24", "64.233.165.94/32", "35.207.188.57/32", "35.207.81.249/32", "35.207.171.222/32", "195.62.89.0/24", "66.22.192.0/18", "66.22.196.0/24", "66.22.197.0/24", "66.22.198.0/24", "66.22.199.0/24", "66.22.216.0/24", "66.22.217.0/24", "66.22.237.0/24", "66.22.238.0/24", "66.22.241.0/24", "66.22.242.0/24", "66.22.244.0/24", "64.71.8.96/29", "34.0.240.0/24", "34.0.241.0/24", "34.0.242.0/24", "34.0.243.0/24", "34.0.244.0/24", "34.0.245.0/24", "34.0.246.0/24", "34.0.247.0/24", "34.0.248.0/24", "34.0.249.0/24", "34.0.250.0/24", "34.0.251.0/24", "12.129.184.160/29", "138.128.136.0/21", "162.158.0.0/15", "172.64.0.0/13", "34.0.0.0/15", "34.2.0.0/15", "35.192.0.0/12", "35.208.0.0/12", "5.200.14.128/25", } var DiscordDomains = []string{ "discord.com", "discord.gg", "discordapp.com", "discord.media", "discordapp.net", "discord.net", } var DiscordDomainRegex = []string{".*discord.*"} var TeamsDomains = []string{ "teams.microsoft.com", "teams.cloud.microsoft", "lync.com", "skype.com", "keydelivery.mediaservices.windows.net", "streaming.mediaservices.windows.net", } var TeamsIPs = []string{ "52.112.0.0/14", "52.122.0.0/15", } var TeamsDomainRegex = []string{ `.*teams\.microsoft.*`, ".*lync.*", ".*skype.*", } var LovenseDomains = []string{ "lovense-api.com", "lovense.com", "lovense.club", } var LovenseDomainRegex = []string{".*lovense.*"} var OBSDomains = []string{"obsproject.com"} var OBSDomainRegex = []string{".*obsproject.*"} var AnyDeskDomains = []string{ "anydesk.com", "anydesk.com.cn", "net.anydesk.com", } var AnyDeskDomainRegex = []string{".*anydesk.*"} // AllModes returns all available routing modes. func AllModes() []Mode { baseDomains := append(append(append( LovenseDomains, OBSDomains...), AnyDeskDomains...), IPCheckDomains...) baseRegex := append(append( LovenseDomainRegex, OBSDomainRegex...), AnyDeskDomainRegex...) discordDomains := append(append([]string{}, baseDomains...), DiscordDomains...) discordRegex := append(append([]string{}, baseRegex...), DiscordDomainRegex...) teamsDomains := append(append([]string{}, discordDomains...), TeamsDomains...) teamsRegex := append(append([]string{}, discordRegex...), TeamsDomainRegex...) return []Mode{ { Name: "Lovense + OBS + AnyDesk", Final: "direct", Rules: []Rule{ {DomainSuffix: baseDomains, DomainRegex: baseRegex, Outbound: "proxy"}, }, }, { Name: "Lovense + OBS + AnyDesk + Discord", Final: "direct", Rules: []Rule{ {DomainSuffix: discordDomains, DomainRegex: discordRegex, Outbound: "proxy"}, {IPCIDR: DiscordIPs, Outbound: "proxy"}, {Network: []string{"udp"}, PortRange: []string{"50000:65535"}, Outbound: "proxy"}, }, }, { Name: "Lovense + OBS + AnyDesk + Discord + Teams", Final: "direct", Rules: []Rule{ {DomainSuffix: teamsDomains, DomainRegex: teamsRegex, Outbound: "proxy"}, {IPCIDR: append(append([]string{}, DiscordIPs...), TeamsIPs...), Outbound: "proxy"}, {Network: []string{"udp"}, PortRange: []string{"3478:3481", "50000:65535"}, Outbound: "proxy"}, }, }, { Name: "Discord Only", Final: "direct", Rules: []Rule{ {DomainSuffix: append(append([]string{}, DiscordDomains...), IPCheckDomains...), DomainRegex: DiscordDomainRegex, Outbound: "proxy"}, {IPCIDR: DiscordIPs, Outbound: "proxy"}, {Network: []string{"udp"}, PortRange: []string{"50000:65535"}, Outbound: "proxy"}, }, }, { Name: "Full (All Traffic)", Final: "proxy", Rules: nil, }, { Name: "Re-filter (обход блокировок РФ)", Final: "direct", Rules: []Rule{ {RuleSet: []string{"refilter-domains", "refilter-ip", "discord-voice"}, Outbound: "proxy"}, }, }, { Name: "Комбо (приложения + Re-filter)", Final: "direct", Rules: []Rule{ {DomainSuffix: discordDomains, DomainRegex: discordRegex, Outbound: "proxy"}, {IPCIDR: DiscordIPs, Outbound: "proxy"}, {Network: []string{"udp"}, PortRange: []string{"50000:65535"}, Outbound: "proxy"}, {RuleSet: []string{"refilter-domains", "refilter-ip", "discord-voice"}, Outbound: "proxy"}, }, }, } } // ModeByName finds a mode by name, returns nil if not found. func ModeByName(name string) *Mode { for _, m := range AllModes() { if m.Name == name { return &m } } return nil } // ModeNames returns all available mode names. func ModeNames() []string { modes := AllModes() names := make([]string, len(modes)) for i, m := range modes { names[i] = m.Name } return names }