V2rayConfig.kt 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. package com.v2ray.ang.dto
  2. import com.google.gson.annotations.SerializedName
  3. import com.v2ray.ang.AppConfig
  4. import com.v2ray.ang.util.Utils
  5. data class V2rayConfig(
  6. var remarks: String? = null,
  7. var stats: Any? = null,
  8. val log: LogBean,
  9. var policy: PolicyBean? = null,
  10. val inbounds: ArrayList<InboundBean>,
  11. var outbounds: ArrayList<OutboundBean>,
  12. var dns: DnsBean? = null,
  13. val routing: RoutingBean,
  14. val api: Any? = null,
  15. val transport: Any? = null,
  16. val reverse: Any? = null,
  17. var fakedns: Any? = null,
  18. val browserForwarder: Any? = null,
  19. var observatory: Any? = null,
  20. var burstObservatory: Any? = null
  21. ) {
  22. data class LogBean(
  23. val access: String? = null,
  24. val error: String? = null,
  25. var loglevel: String? = null,
  26. val dnsLog: Boolean? = null
  27. )
  28. data class InboundBean(
  29. var tag: String,
  30. var port: Int,
  31. var protocol: String,
  32. var listen: String? = null,
  33. val settings: Any? = null,
  34. val sniffing: SniffingBean? = null,
  35. val streamSettings: Any? = null,
  36. val allocate: Any? = null
  37. ) {
  38. data class InSettingsBean(
  39. val auth: String? = null,
  40. val udp: Boolean? = null,
  41. val userLevel: Int? = null,
  42. val address: String? = null,
  43. val port: Int? = null,
  44. val network: String? = null
  45. )
  46. data class SniffingBean(
  47. var enabled: Boolean,
  48. val destOverride: ArrayList<String>,
  49. val metadataOnly: Boolean? = null,
  50. var routeOnly: Boolean? = null
  51. )
  52. }
  53. data class OutboundBean(
  54. var tag: String = "proxy",
  55. var protocol: String,
  56. var settings: OutSettingsBean? = null,
  57. var streamSettings: StreamSettingsBean? = null,
  58. val proxySettings: Any? = null,
  59. val sendThrough: String? = null,
  60. var mux: MuxBean? = MuxBean(false)
  61. ) {
  62. data class OutSettingsBean(
  63. var vnext: List<VnextBean>? = null,
  64. var fragment: FragmentBean? = null,
  65. var noises: List<NoiseBean>? = null,
  66. var servers: List<ServersBean>? = null,
  67. /*Blackhole*/
  68. var response: Response? = null,
  69. /*DNS*/
  70. val network: String? = null,
  71. var address: Any? = null,
  72. val port: Int? = null,
  73. /*Freedom*/
  74. var domainStrategy: String? = null,
  75. val redirect: String? = null,
  76. val userLevel: Int? = null,
  77. /*Loopback*/
  78. val inboundTag: String? = null,
  79. /*Wireguard*/
  80. var secretKey: String? = null,
  81. val peers: List<WireGuardBean>? = null,
  82. var reserved: List<Int>? = null,
  83. var mtu: Int? = null,
  84. var obfsPassword: String? = null,
  85. ) {
  86. data class VnextBean(
  87. var address: String = "",
  88. var port: Int = AppConfig.DEFAULT_PORT,
  89. var users: List<UsersBean>
  90. ) {
  91. data class UsersBean(
  92. var id: String = "",
  93. var alterId: Int? = null,
  94. var security: String? = null,
  95. var level: Int = AppConfig.DEFAULT_LEVEL,
  96. var encryption: String? = null,
  97. var flow: String? = null
  98. )
  99. }
  100. data class FragmentBean(
  101. var packets: String? = null,
  102. var length: String? = null,
  103. var interval: String? = null
  104. )
  105. data class NoiseBean(
  106. var type: String? = null,
  107. var packet: String? = null,
  108. var delay: String? = null
  109. )
  110. data class ServersBean(
  111. var address: String = "",
  112. var method: String? = null,
  113. var ota: Boolean = false,
  114. var password: String? = null,
  115. var port: Int = AppConfig.DEFAULT_PORT,
  116. var level: Int = AppConfig.DEFAULT_LEVEL,
  117. val email: String? = null,
  118. var flow: String? = null,
  119. val ivCheck: Boolean? = null,
  120. var users: List<SocksUsersBean>? = null
  121. ) {
  122. data class SocksUsersBean(
  123. var user: String = "",
  124. var pass: String = "",
  125. var level: Int = AppConfig.DEFAULT_LEVEL
  126. )
  127. }
  128. data class Response(var type: String)
  129. data class WireGuardBean(
  130. var publicKey: String = "",
  131. var preSharedKey: String? = null,
  132. var endpoint: String = ""
  133. )
  134. }
  135. data class StreamSettingsBean(
  136. var network: String = AppConfig.DEFAULT_NETWORK,
  137. var security: String? = null,
  138. var tcpSettings: TcpSettingsBean? = null,
  139. var kcpSettings: KcpSettingsBean? = null,
  140. var wsSettings: WsSettingsBean? = null,
  141. var httpupgradeSettings: HttpupgradeSettingsBean? = null,
  142. var xhttpSettings: XhttpSettingsBean? = null,
  143. var httpSettings: HttpSettingsBean? = null,
  144. var tlsSettings: TlsSettingsBean? = null,
  145. var quicSettings: QuicSettingBean? = null,
  146. var realitySettings: TlsSettingsBean? = null,
  147. var grpcSettings: GrpcSettingsBean? = null,
  148. var hy2steriaSettings: Hy2steriaSettingsBean? = null,
  149. val dsSettings: Any? = null,
  150. var sockopt: SockoptBean? = null
  151. ) {
  152. data class TcpSettingsBean(
  153. var header: HeaderBean = HeaderBean(),
  154. val acceptProxyProtocol: Boolean? = null
  155. ) {
  156. data class HeaderBean(
  157. var type: String = "none",
  158. var request: RequestBean? = null,
  159. var response: Any? = null
  160. ) {
  161. data class RequestBean(
  162. var path: List<String> = ArrayList(),
  163. var headers: HeadersBean = HeadersBean(),
  164. val version: String? = null,
  165. val method: String? = null
  166. ) {
  167. data class HeadersBean(
  168. var Host: List<String>? = ArrayList(),
  169. @SerializedName("User-Agent")
  170. val userAgent: List<String>? = null,
  171. @SerializedName("Accept-Encoding")
  172. val acceptEncoding: List<String>? = null,
  173. val Connection: List<String>? = null,
  174. val Pragma: String? = null
  175. )
  176. }
  177. }
  178. }
  179. data class KcpSettingsBean(
  180. var mtu: Int = 1350,
  181. var tti: Int = 50,
  182. var uplinkCapacity: Int = 12,
  183. var downlinkCapacity: Int = 100,
  184. var congestion: Boolean = false,
  185. var readBufferSize: Int = 1,
  186. var writeBufferSize: Int = 1,
  187. var header: HeaderBean = HeaderBean(),
  188. var seed: String? = null
  189. ) {
  190. data class HeaderBean(
  191. var type: String = "none",
  192. var domain: String? = null
  193. )
  194. }
  195. data class WsSettingsBean(
  196. var path: String? = null,
  197. var headers: HeadersBean = HeadersBean(),
  198. val maxEarlyData: Int? = null,
  199. val useBrowserForwarding: Boolean? = null,
  200. val acceptProxyProtocol: Boolean? = null
  201. ) {
  202. data class HeadersBean(var Host: String = "")
  203. }
  204. data class HttpupgradeSettingsBean(
  205. var path: String? = null,
  206. var host: String? = null,
  207. val acceptProxyProtocol: Boolean? = null
  208. )
  209. data class XhttpSettingsBean(
  210. var path: String? = null,
  211. var host: String? = null,
  212. var mode: String? = null,
  213. var extra: Any? = null,
  214. )
  215. data class HttpSettingsBean(
  216. var host: List<String> = ArrayList(),
  217. var path: String? = null
  218. )
  219. data class SockoptBean(
  220. var TcpNoDelay: Boolean? = null,
  221. var tcpKeepAliveIdle: Int? = null,
  222. var tcpFastOpen: Boolean? = null,
  223. var tproxy: String? = null,
  224. var mark: Int? = null,
  225. var dialerProxy: String? = null,
  226. var domainStrategy: String? = null,
  227. var happyEyeballs: happyEyeballsBean? = null,
  228. )
  229. data class happyEyeballsBean(
  230. var prioritizeIPv6: Boolean? = null,
  231. var maxConcurrentTry: Int? = 4,
  232. var tryDelayMs: Int? = 250, // ms
  233. var interleave: Int? = null,
  234. )
  235. data class TlsSettingsBean(
  236. var allowInsecure: Boolean = false,
  237. var serverName: String? = null,
  238. val alpn: List<String>? = null,
  239. val minVersion: String? = null,
  240. val maxVersion: String? = null,
  241. val preferServerCipherSuites: Boolean? = null,
  242. val cipherSuites: String? = null,
  243. val fingerprint: String? = null,
  244. val certificates: List<Any>? = null,
  245. val disableSystemRoot: Boolean? = null,
  246. val enableSessionResumption: Boolean? = null,
  247. // REALITY settings
  248. val show: Boolean = false,
  249. var publicKey: String? = null,
  250. var shortId: String? = null,
  251. var spiderX: String? = null,
  252. var mldsa65Verify: String? = null
  253. )
  254. data class QuicSettingBean(
  255. var security: String = "none",
  256. var key: String = "",
  257. var header: HeaderBean = HeaderBean()
  258. ) {
  259. data class HeaderBean(var type: String = "none")
  260. }
  261. data class GrpcSettingsBean(
  262. var serviceName: String = "",
  263. var authority: String? = null,
  264. var multiMode: Boolean? = null,
  265. var idle_timeout: Int? = null,
  266. var health_check_timeout: Int? = null
  267. )
  268. data class Hy2steriaSettingsBean(
  269. var password: String? = null,
  270. var use_udp_extension: Boolean? = true,
  271. var congestion: Hy2CongestionBean? = null
  272. ) {
  273. data class Hy2CongestionBean(
  274. var type: String? = "bbr",
  275. var up_mbps: Int? = null,
  276. var down_mbps: Int? = null,
  277. )
  278. }
  279. }
  280. data class MuxBean(
  281. var enabled: Boolean,
  282. var concurrency: Int? = null,
  283. var xudpConcurrency: Int? = null,
  284. var xudpProxyUDP443: String? = null,
  285. )
  286. fun getServerAddress(): String? {
  287. if (protocol.equals(EConfigType.VMESS.name, true)
  288. || protocol.equals(EConfigType.VLESS.name, true)
  289. ) {
  290. return settings?.vnext?.first()?.address
  291. } else if (protocol.equals(EConfigType.SHADOWSOCKS.name, true)
  292. || protocol.equals(EConfigType.SOCKS.name, true)
  293. || protocol.equals(EConfigType.HTTP.name, true)
  294. || protocol.equals(EConfigType.TROJAN.name, true)
  295. || protocol.equals(EConfigType.HYSTERIA2.name, true)
  296. ) {
  297. return settings?.servers?.first()?.address
  298. } else if (protocol.equals(EConfigType.WIREGUARD.name, true)) {
  299. return settings?.peers?.first()?.endpoint?.substringBeforeLast(":")
  300. }
  301. return null
  302. }
  303. fun getServerPort(): Int? {
  304. if (protocol.equals(EConfigType.VMESS.name, true)
  305. || protocol.equals(EConfigType.VLESS.name, true)
  306. ) {
  307. return settings?.vnext?.first()?.port
  308. } else if (protocol.equals(EConfigType.SHADOWSOCKS.name, true)
  309. || protocol.equals(EConfigType.SOCKS.name, true)
  310. || protocol.equals(EConfigType.HTTP.name, true)
  311. || protocol.equals(EConfigType.TROJAN.name, true)
  312. || protocol.equals(EConfigType.HYSTERIA2.name, true)
  313. ) {
  314. return settings?.servers?.first()?.port
  315. } else if (protocol.equals(EConfigType.WIREGUARD.name, true)) {
  316. return settings?.peers?.first()?.endpoint?.substringAfterLast(":")?.toInt()
  317. }
  318. return null
  319. }
  320. fun getServerAddressAndPort(): String {
  321. val address = getServerAddress().orEmpty()
  322. val port = getServerPort()
  323. return Utils.getIpv6Address(address) + ":" + port
  324. }
  325. fun getPassword(): String? {
  326. if (protocol.equals(EConfigType.VMESS.name, true)
  327. || protocol.equals(EConfigType.VLESS.name, true)
  328. ) {
  329. return settings?.vnext?.first()?.users?.first()?.id
  330. } else if (protocol.equals(EConfigType.SHADOWSOCKS.name, true)
  331. || protocol.equals(EConfigType.TROJAN.name, true)
  332. || protocol.equals(EConfigType.HYSTERIA2.name, true)
  333. ) {
  334. return settings?.servers?.first()?.password
  335. } else if (protocol.equals(EConfigType.SOCKS.name, true)
  336. || protocol.equals(EConfigType.HTTP.name, true)
  337. ) {
  338. return settings?.servers?.first()?.users?.first()?.pass
  339. } else if (protocol.equals(EConfigType.WIREGUARD.name, true)) {
  340. return settings?.secretKey
  341. }
  342. return null
  343. }
  344. fun getSecurityEncryption(): String? {
  345. return when {
  346. protocol.equals(EConfigType.VMESS.name, true) -> settings?.vnext?.first()?.users?.first()?.security
  347. protocol.equals(EConfigType.VLESS.name, true) -> settings?.vnext?.first()?.users?.first()?.encryption
  348. protocol.equals(EConfigType.SHADOWSOCKS.name, true) -> settings?.servers?.first()?.method
  349. else -> null
  350. }
  351. }
  352. fun getTransportSettingDetails(): List<String?>? {
  353. if (protocol.equals(EConfigType.VMESS.name, true)
  354. || protocol.equals(EConfigType.VLESS.name, true)
  355. || protocol.equals(EConfigType.TROJAN.name, true)
  356. || protocol.equals(EConfigType.SHADOWSOCKS.name, true)
  357. ) {
  358. val transport = streamSettings?.network ?: return null
  359. return when (transport) {
  360. NetworkType.TCP.type -> {
  361. val tcpSetting = streamSettings?.tcpSettings ?: return null
  362. listOf(
  363. tcpSetting.header.type,
  364. tcpSetting.header.request?.headers?.Host?.joinToString(",").orEmpty(),
  365. tcpSetting.header.request?.path?.joinToString(",").orEmpty()
  366. )
  367. }
  368. NetworkType.KCP.type -> {
  369. val kcpSetting = streamSettings?.kcpSettings ?: return null
  370. listOf(
  371. kcpSetting.header.type,
  372. "",
  373. kcpSetting.seed.orEmpty()
  374. )
  375. }
  376. NetworkType.WS.type -> {
  377. val wsSetting = streamSettings?.wsSettings ?: return null
  378. listOf(
  379. "",
  380. wsSetting.headers.Host,
  381. wsSetting.path
  382. )
  383. }
  384. NetworkType.HTTP_UPGRADE.type -> {
  385. val httpupgradeSetting = streamSettings?.httpupgradeSettings ?: return null
  386. listOf(
  387. "",
  388. httpupgradeSetting.host,
  389. httpupgradeSetting.path
  390. )
  391. }
  392. NetworkType.XHTTP.type -> {
  393. val xhttpSettings = streamSettings?.xhttpSettings ?: return null
  394. listOf(
  395. "",
  396. xhttpSettings.host,
  397. xhttpSettings.path
  398. )
  399. }
  400. NetworkType.H2.type -> {
  401. val h2Setting = streamSettings?.httpSettings ?: return null
  402. listOf(
  403. "",
  404. h2Setting.host.joinToString(","),
  405. h2Setting.path
  406. )
  407. }
  408. // "quic" -> {
  409. // val quicSetting = streamSettings?.quicSettings ?: return null
  410. // listOf(
  411. // quicSetting.header.type,
  412. // quicSetting.security,
  413. // quicSetting.key
  414. // )
  415. // }
  416. NetworkType.GRPC.type -> {
  417. val grpcSetting = streamSettings?.grpcSettings ?: return null
  418. listOf(
  419. if (grpcSetting.multiMode == true) "multi" else "gun",
  420. grpcSetting.authority.orEmpty(),
  421. grpcSetting.serviceName
  422. )
  423. }
  424. else -> null
  425. }
  426. }
  427. return null
  428. }
  429. fun ensureSockopt(): V2rayConfig.OutboundBean.StreamSettingsBean.SockoptBean {
  430. val stream = streamSettings ?: V2rayConfig.OutboundBean.StreamSettingsBean().also {
  431. streamSettings = it
  432. }
  433. val sockopt = stream.sockopt ?: V2rayConfig.OutboundBean.StreamSettingsBean.SockoptBean().also {
  434. stream.sockopt = it
  435. }
  436. return sockopt
  437. }
  438. }
  439. data class DnsBean(
  440. var servers: ArrayList<Any>? = null,
  441. var hosts: Map<String, Any>? = null,
  442. val clientIp: String? = null,
  443. val disableCache: Boolean? = null,
  444. val queryStrategy: String? = null,
  445. val tag: String? = null
  446. ) {
  447. data class ServersBean(
  448. var address: String = "",
  449. var port: Int? = null,
  450. var domains: List<String>? = null,
  451. var expectIPs: List<String>? = null,
  452. val clientIp: String? = null,
  453. val skipFallback: Boolean? = null,
  454. val tag: String? = null,
  455. )
  456. }
  457. data class RoutingBean(
  458. var domainStrategy: String,
  459. var domainMatcher: String? = null,
  460. var rules: ArrayList<RulesBean>,
  461. var balancers: List<BalancerBean>? = null
  462. ) {
  463. data class RulesBean(
  464. var type: String = "field",
  465. var ip: ArrayList<String>? = null,
  466. var domain: ArrayList<String>? = null,
  467. var outboundTag: String? = null,
  468. var balancerTag: String? = null,
  469. var port: String? = null,
  470. val sourcePort: String? = null,
  471. val network: String? = null,
  472. val source: List<String>? = null,
  473. val user: List<String>? = null,
  474. var inboundTag: List<String>? = null,
  475. val protocol: List<String>? = null,
  476. val attrs: String? = null,
  477. val domainMatcher: String? = null
  478. )
  479. data class BalancerBean(
  480. val tag: String,
  481. val selector: List<String>,
  482. val fallbackTag: String? = null,
  483. val strategy: StrategyObject? = null
  484. )
  485. data class StrategyObject(
  486. val type: String = "random", // "random" | "roundRobin" | "leastPing" | "leastLoad"
  487. val settings: StrategySettingsObject? = null
  488. )
  489. data class StrategySettingsObject(
  490. val expected: Int? = null,
  491. val maxRTT: String? = null,
  492. val tolerance: Double? = null,
  493. val baselines: List<String>? = null,
  494. val costs: List<CostObject>? = null
  495. )
  496. data class CostObject(
  497. val regexp: Boolean = false,
  498. val match: String,
  499. val value: Double
  500. )
  501. }
  502. data class PolicyBean(
  503. var levels: Map<String, LevelBean>,
  504. var system: Any? = null
  505. ) {
  506. data class LevelBean(
  507. var handshake: Int? = null,
  508. var connIdle: Int? = null,
  509. var uplinkOnly: Int? = null,
  510. var downlinkOnly: Int? = null,
  511. val statsUserUplink: Boolean? = null,
  512. val statsUserDownlink: Boolean? = null,
  513. var bufferSize: Int? = null
  514. )
  515. }
  516. data class ObservatoryObject(
  517. val subjectSelector: List<String>,
  518. val probeUrl: String,
  519. val probeInterval: String,
  520. val enableConcurrency: Boolean = false
  521. )
  522. data class BurstObservatoryObject(
  523. val subjectSelector: List<String>,
  524. val pingConfig: PingConfigObject
  525. ) {
  526. data class PingConfigObject(
  527. val destination: String,
  528. val connectivity: String? = null,
  529. val interval: String,
  530. val sampling: Int,
  531. val timeout: String? = null
  532. )
  533. }
  534. data class FakednsBean(
  535. var ipPool: String = "198.18.0.0/15",
  536. var poolSize: Int = 10000
  537. ) // roughly 10 times smaller than total ip pool
  538. fun getProxyOutbound(): OutboundBean? {
  539. outbounds.forEach { outbound ->
  540. EConfigType.entries.forEach {
  541. if (outbound.protocol.equals(it.name, true)) {
  542. return outbound
  543. }
  544. }
  545. }
  546. return null
  547. }
  548. fun getAllProxyOutbound(): List<OutboundBean> {
  549. return outbounds.filter { outbound ->
  550. EConfigType.entries.any { it.name.equals(outbound.protocol, ignoreCase = true) }
  551. }
  552. }
  553. }