This commit is contained in:
2025-03-14 19:08:25 +08:00
parent daadb1f9ea
commit de0e18a27e
2 changed files with 262 additions and 169 deletions

View File

@@ -10,7 +10,7 @@ import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import util.newObjectNode import util.newObjectNode
data class Config( data class Config(
val proxies: List<Clash.Proxy> val fakeIPs: Int
) )
fun main() { fun main() {
@@ -34,8 +34,10 @@ fun main() {
// """.trimIndent() // """.trimIndent()
// val proxies = yamlMapper.readValue<Config>(yamlStr) // val proxies = yamlMapper.readValue<Config>(yamlStr)
// println(yamlMapper.writeValueAsString(proxies)) // println(yamlMapper.writeValueAsString(proxies))
val clash = Clash.parseFromFile("/Users/rainbus/Projects/Join/Java/subconverter4j/src/main/resources/taishan.yaml") // val clash = Clash.parseFromFile("/Users/rainbus/Projects/Join/Java/subconverter4j/src/main/resources/taishan.yaml")
println(yamlMapper.writeValueAsString(clash)) // println(yamlMapper.writeValueAsString(clash))
val config = Config(fakeIPs = 1)
println(yamlMapper.writeValueAsString(config))
} }
// //
//import com.fasterxml.jackson.annotation.JsonSubTypes //import com.fasterxml.jackson.annotation.JsonSubTypes

View File

@@ -96,9 +96,9 @@ data class Clash(
data class Experimental( data class Experimental(
val fingerprints: List<String>? = null, val fingerprints: List<String>? = null,
val quicGoDisableGSO: Boolean? = null, val quicGoDisableGso: Boolean? = null,
val quicGoDisableECN: Boolean? = null, val quicGoDisableEcn: Boolean? = null,
val ip4pEnable: Boolean? = null, val dialerIp4pConvert: Boolean? = null,
) )
data class Profile( data class Profile(
@@ -110,6 +110,10 @@ data class Clash(
val stack: String? = null, val stack: String? = null,
val autoRoute: Boolean? = null, val autoRoute: Boolean? = null,
val autoRedirect: Boolean? = null, val autoRedirect: Boolean? = null,
val autoRedirectInputMark: Int? = null,
val autoRedirectOutputMark: Int? = null,
@Deprecated("") val inet4Address: List<String>? = null,
val inet6Address: List<String>? = null,
val autoDetectInterface: Boolean? = null, val autoDetectInterface: Boolean? = null,
val dnsHijack: List<String>? = null, val dnsHijack: List<String>? = null,
val device: String? = null, val device: String? = null,
@@ -134,6 +138,7 @@ data class Clash(
val includeAndroidUser: List<Int>? = null, val includeAndroidUser: List<Int>? = null,
val includePackage: List<String>? = null, val includePackage: List<String>? = null,
val excludePackage: List<String>? = null, val excludePackage: List<String>? = null,
val fileDescriptor: Int? = null,
@Deprecated("") val inet4RouteAddress: List<String>? = null, @Deprecated("") val inet4RouteAddress: List<String>? = null,
@Deprecated("") val inet6RouteAddress: List<String>? = null, @Deprecated("") val inet6RouteAddress: List<String>? = null,
@Deprecated("") val inet4RouteExcludeAddress: List<String>? = null, @Deprecated("") val inet4RouteExcludeAddress: List<String>? = null,
@@ -179,9 +184,9 @@ data class Clash(
val fallbackFilter: FallbackFilter? = null, val fallbackFilter: FallbackFilter? = null,
val listen: String? = null, val listen: String? = null,
val enhancedMode: String? = null, val enhancedMode: String? = null,
val fakeIPRange: String? = null, val fakeIpRange: String? = null,
val fakeIPFilter: List<String>? = null, val fakeIpFilter: List<String>? = null,
val fakeIPFilterMode: String? = null, val fakeIpFilterMode: String? = null,
val defaultNameserver: List<String>? = null, val defaultNameserver: List<String>? = null,
val cacheAlgorithm: String? = null, val cacheAlgorithm: String? = null,
val nameserverPolicy: LinkedHashMap<String, List<String>>? = null, val nameserverPolicy: LinkedHashMap<String, List<String>>? = null,
@@ -190,7 +195,7 @@ data class Clash(
val directNameserverFollowPolicy: Boolean? = null val directNameserverFollowPolicy: Boolean? = null
) )
data class FallbackFilter( data class FallbackFilter(
val geoip: Boolean? = null, val geoip: Boolean? = null,
val geoipCode: String? = null, val geoipCode: String? = null,
val ipcidr: List<String>? = null, val ipcidr: List<String>? = null,
@@ -219,7 +224,7 @@ data class Clash(
JsonSubTypes.Type(value = Proxy.MieruProxy::class, name = "mieru"), JsonSubTypes.Type(value = Proxy.MieruProxy::class, name = "mieru"),
JsonSubTypes.Type(value = Proxy.AnyTLSOption::class, name = "anytls") JsonSubTypes.Type(value = Proxy.AnyTLSOption::class, name = "anytls")
) )
abstract class Proxy { sealed class Proxy {
abstract val tfo: Boolean? abstract val tfo: Boolean?
abstract val mptcp: Boolean? abstract val mptcp: Boolean?
abstract val interfaceName: String? abstract val interfaceName: String?
@@ -316,11 +321,11 @@ data class Clash(
val skipCertVerify: Boolean? = null, val skipCertVerify: Boolean? = null,
val fingerprint: String? = null, val fingerprint: String? = null,
val alpn: List<String>? = null, val alpn: List<String>? = null,
val customCA: String? = null, val ca: String? = null,
val customCAString: String? = null, val caStr: String? = null,
val receiveWindowConn: Int? = null, val recvWindowConn: Int? = null,
val receiveWindow: Int? = null, val recvWindow: Int? = null,
val disableMTUDiscovery: Boolean? = null, val disableMtuDiscovery: Boolean? = null,
val fastOpen: Boolean? = null, val fastOpen: Boolean? = null,
val hopInterval: Int? = null, val hopInterval: Int? = null,
override val tfo: Boolean? = null, override val tfo: Boolean? = null,
@@ -524,11 +529,11 @@ data class Clash(
val cwnd: Int? = null, val cwnd: Int? = null,
val skipCertVerify: Boolean? = null, val skipCertVerify: Boolean? = null,
val fingerprint: String? = null, val fingerprint: String? = null,
val customCA: String? = null, val ca: String? = null,
val customCAString: String? = null, val caStr: String? = null,
val receiveWindowConn: Int? = null, val recvWindowConn: Int? = null,
val receiveWindow: Int? = null, val recvWindow: Int? = null,
val disableMTUDiscovery: Boolean? = null, val disableMtuDiscovery: Boolean? = null,
val maxDatagramFrameSize: Int? = null, val maxDatagramFrameSize: Int? = null,
val sni: String? = null, val sni: String? = null,
val udpOverStream: Boolean? = null, val udpOverStream: Boolean? = null,
@@ -557,14 +562,14 @@ data class Clash(
val network: String? = null, val network: String? = null,
val realityOpts: RealityOptions? = null, val realityOpts: RealityOptions? = null,
val httpOpts: HTTPOptions? = null, val httpOpts: HTTPOptions? = null,
val http2Opts: HTTP2Options? = null, val h2Opts: HTTP2Options? = null,
val grpcOpts: GrpcOptions? = null, val grpcOpts: GrpcOptions? = null,
val wsOpts: WSOptions? = null, val wsOpts: WSOptions? = null,
val wsPath: String? = null, val wsPath: String? = null,
val wsHeaders: Map<String, String>? = null, val wsHeaders: Map<String, String>? = null,
val skipCertVerify: Boolean? = null, val skipCertVerify: Boolean? = null,
val fingerprint: String? = null, val fingerprint: String? = null,
val serverName: String? = null, val servername: String? = null,
val clientFingerprint: String? = null, val clientFingerprint: String? = null,
override val tfo: Boolean? = null, override val tfo: Boolean? = null,
override val mptcp: Boolean? = null, override val mptcp: Boolean? = null,
@@ -591,7 +596,7 @@ data class Clash(
val serverName: String? = null, val serverName: String? = null,
val realityOpts: RealityOptions? = null, val realityOpts: RealityOptions? = null,
val httpOpts: HTTPOptions? = null, val httpOpts: HTTPOptions? = null,
val http2Opts: HTTP2Options? = null, val h2Opts: HTTP2Options? = null,
val grpcOpts: GrpcOptions? = null, val grpcOpts: GrpcOptions? = null,
val wsOpts: WSOptions? = null, val wsOpts: WSOptions? = null,
val packetAddr: Boolean? = null, val packetAddr: Boolean? = null,
@@ -618,11 +623,19 @@ data class Clash(
val mtu: Int? = null, val mtu: Int? = null,
val udp: Boolean? = null, val udp: Boolean? = null,
val persistentKeepalive: Int? = null, val persistentKeepalive: Int? = null,
val amneziaWGOption: AmneziaWGOption? = null, val amneziaWgOption: AmneziaWGOption? = null,
val peers: List<WireGuardPeerOption>? = null, val peers: List<WireGuardPeerOption>? = null,
val remoteDnsResolve: Boolean? = null, val remoteDnsResolve: Boolean? = null,
val dns: List<String>? = null, val dns: List<String>? = null,
val refreshServerIPInterval: Int? = null, val refreshServerIpInterval: Int? = null,
val server: String? = null,
val port: Int? = null,
val publicKey: String? = null,
val preSharedKey: String? = null,
val reserved: List<Byte>? = null,
val allowedIps: List<String>? = null,
override val tfo: Boolean? = null, override val tfo: Boolean? = null,
override val mptcp: Boolean? = null, override val mptcp: Boolean? = null,
override val interfaceName: String? = null, override val interfaceName: String? = null,
@@ -634,7 +647,7 @@ data class Clash(
data class RealityOptions( data class RealityOptions(
val publicKey: String? = null, val publicKey: String? = null,
val shortID: String? = null, val shortId: String? = null,
) )
data class GrpcOptions( data class GrpcOptions(
@@ -673,13 +686,13 @@ data class Clash(
val publicKey: String? = null, val publicKey: String? = null,
val preSharedKey: String? = null, val preSharedKey: String? = null,
val reserved: List<Byte>? = null, val reserved: List<Byte>? = null,
val allowedIPs: List<String>? = null, val allowedIps: List<String>? = null,
) )
data class AmneziaWGOption( data class AmneziaWGOption(
val jc: Int? = null, val jc: Int? = null,
val jMin: Int? = null, val jmin: Int? = null,
val jMax: Int? = null, val jmax: Int? = null,
val s1: Int? = null, val s1: Int? = null,
val s2: Int? = null, val s2: Int? = null,
val h1: UInt? = null, val h1: UInt? = null,
@@ -712,6 +725,14 @@ data class Clash(
) )
} }
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes(
JsonSubTypes.Type(value = ProxyGroup.UrlTest::class, name = "url-test"),
JsonSubTypes.Type(value = ProxyGroup.Select::class, name = "select"),
JsonSubTypes.Type(value = ProxyGroup.Fallback::class, name = "fallback"),
JsonSubTypes.Type(value = ProxyGroup.LoadBalance::class, name = "load-balance"),
JsonSubTypes.Type(value = ProxyGroup.Relay::class, name = "relay")
)
sealed class ProxyGroup { sealed class ProxyGroup {
abstract val name: String? abstract val name: String?
abstract val proxies: List<String>? abstract val proxies: List<String>?
@@ -721,9 +742,11 @@ data class Clash(
abstract val lazy: Boolean? abstract val lazy: Boolean?
abstract val timeout: Int? abstract val timeout: Int?
abstract val maxFailedTimes: Int? abstract val maxFailedTimes: Int?
abstract val disableUDP: Boolean? abstract val disableUdp: Boolean?
@Deprecated("") abstract val interfaceName: String? @Deprecated("")
@Deprecated("") abstract val routingMark: Int? abstract val interfaceName: String?
@Deprecated("")
abstract val routingMark: Int?
abstract val includeAll: Boolean? abstract val includeAll: Boolean?
abstract val includeAllProxies: Boolean? abstract val includeAllProxies: Boolean?
abstract val includeAllProviders: Boolean? abstract val includeAllProviders: Boolean?
@@ -743,7 +766,7 @@ data class Clash(
override val lazy: Boolean? = null, override val lazy: Boolean? = null,
override val timeout: Int? = null, override val timeout: Int? = null,
override val maxFailedTimes: Int? = null, override val maxFailedTimes: Int? = null,
override val disableUDP: Boolean? = null, override val disableUdp: Boolean? = null,
override val interfaceName: String? = null, override val interfaceName: String? = null,
override val routingMark: Int? = null, override val routingMark: Int? = null,
override val includeAll: Boolean? = null, override val includeAll: Boolean? = null,
@@ -767,7 +790,7 @@ data class Clash(
override val lazy: Boolean? = null, override val lazy: Boolean? = null,
override val timeout: Int? = null, override val timeout: Int? = null,
override val maxFailedTimes: Int? = null, override val maxFailedTimes: Int? = null,
override val disableUDP: Boolean? = null, override val disableUdp: Boolean? = null,
override val interfaceName: String? = null, override val interfaceName: String? = null,
override val routingMark: Int? = null, override val routingMark: Int? = null,
override val includeAll: Boolean? = null, override val includeAll: Boolean? = null,
@@ -790,7 +813,7 @@ data class Clash(
override val lazy: Boolean? = null, override val lazy: Boolean? = null,
override val timeout: Int? = null, override val timeout: Int? = null,
override val maxFailedTimes: Int? = null, override val maxFailedTimes: Int? = null,
override val disableUDP: Boolean? = null, override val disableUdp: Boolean? = null,
override val interfaceName: String? = null, override val interfaceName: String? = null,
override val routingMark: Int? = null, override val routingMark: Int? = null,
override val includeAll: Boolean? = null, override val includeAll: Boolean? = null,
@@ -813,7 +836,7 @@ data class Clash(
override val lazy: Boolean? = null, override val lazy: Boolean? = null,
override val timeout: Int? = null, override val timeout: Int? = null,
override val maxFailedTimes: Int? = null, override val maxFailedTimes: Int? = null,
override val disableUDP: Boolean? = null, override val disableUdp: Boolean? = null,
override val interfaceName: String? = null, override val interfaceName: String? = null,
override val routingMark: Int? = null, override val routingMark: Int? = null,
override val includeAll: Boolean? = null, override val includeAll: Boolean? = null,
@@ -837,7 +860,7 @@ data class Clash(
override val lazy: Boolean? = null, override val lazy: Boolean? = null,
override val timeout: Int? = null, override val timeout: Int? = null,
override val maxFailedTimes: Int? = null, override val maxFailedTimes: Int? = null,
override val disableUDP: Boolean? = null, override val disableUdp: Boolean? = null,
override val interfaceName: String? = null, override val interfaceName: String? = null,
override val routingMark: Int? = null, override val routingMark: Int? = null,
override val includeAll: Boolean? = null, override val includeAll: Boolean? = null,
@@ -852,8 +875,13 @@ data class Clash(
) : ProxyGroup() ) : ProxyGroup()
} }
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes(
JsonSubTypes.Type(value = ProxyProvider.FileProvider::class, name = "file"),
JsonSubTypes.Type(value = ProxyProvider.HttpProvider::class, name = "http"),
JsonSubTypes.Type(value = ProxyProvider.InlineProvider::class, name = "inline")
)
sealed class ProxyProvider { sealed class ProxyProvider {
abstract val name: String?
abstract val interval: Int? abstract val interval: Int?
abstract val filter: String? abstract val filter: String?
abstract val excludeFilter: String? abstract val excludeFilter: String?
@@ -863,7 +891,6 @@ data class Clash(
abstract val override: Override? abstract val override: Override?
data class FileProvider( data class FileProvider(
override val name: String? = null,
override val interval: Int? = null, override val interval: Int? = null,
override val filter: String? = null, override val filter: String? = null,
override val excludeFilter: String? = null, override val excludeFilter: String? = null,
@@ -875,7 +902,6 @@ data class Clash(
) : ProxyProvider() ) : ProxyProvider()
data class HttpProvider( data class HttpProvider(
override val name: String? = null,
override val interval: Int? = null, override val interval: Int? = null,
override val filter: String? = null, override val filter: String? = null,
override val excludeFilter: String? = null, override val excludeFilter: String? = null,
@@ -891,7 +917,6 @@ data class Clash(
) : ProxyProvider() ) : ProxyProvider()
data class InlineProvider( data class InlineProvider(
override val name: String? = null,
override val interval: Int? = null, override val interval: Int? = null,
override val filter: String? = null, override val filter: String? = null,
override val excludeFilter: String? = null, override val excludeFilter: String? = null,
@@ -934,6 +959,12 @@ data class Clash(
) )
} }
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes(
JsonSubTypes.Type(value = RuleProvider.FileProvider::class, name = "file"),
JsonSubTypes.Type(value = RuleProvider.HttpProvider::class, name = "http"),
JsonSubTypes.Type(value = RuleProvider.InlineProvider::class, name = "inline")
)
sealed class RuleProvider { sealed class RuleProvider {
abstract val behavior: String? abstract val behavior: String?
@@ -960,45 +991,22 @@ data class Clash(
) : RuleProvider() ) : RuleProvider()
} }
data class Header( @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
val userAgent: List<String>? = null, val accept: List<String>? = null, val authorization: List<String>? = null @JsonSubTypes(
JsonSubTypes.Type(value = Listener.AnyTLSListener::class, name = "anytls"),
JsonSubTypes.Type(value = Listener.HTTPListener::class, name = "http"),
JsonSubTypes.Type(value = Listener.Hysteria2Listener::class, name = "hysteria2"),
JsonSubTypes.Type(value = Listener.RedirListener::class, name = "redir"),
JsonSubTypes.Type(value = Listener.ShadowSocksListener::class, name = "shadowsocks"),
JsonSubTypes.Type(value = Listener.SocksListener::class, name = "socks"),
JsonSubTypes.Type(value = Listener.TProxyListener::class, name = "tproxy"),
JsonSubTypes.Type(value = Listener.TrojanListener::class, name = "trojan"),
JsonSubTypes.Type(value = Listener.TuicListener::class, name = "tuic"),
JsonSubTypes.Type(value = Listener.TunListener::class, name = "tun"),
JsonSubTypes.Type(value = Listener.TunnelListener::class, name = "tunnel"),
JsonSubTypes.Type(value = Listener.VlessListener::class, name = "vless"),
JsonSubTypes.Type(value = Listener.VmessListener::class, name = "vmess")
) )
data class HealthCheck(
val enable: Boolean? = null,
val interval: Int? = null,
val lazy: Boolean? = null,
val url: String? = null,
val expectedStatus: Int? = null
)
data class Override(
val skipCertVerify: Boolean? = null,
val udp: Boolean? = null,
val down: String? = null,
val up: String? = null,
val dialerProxy: String? = null,
val interfaceName: String? = null,
val routingMark: Int? = null,
val ipVersion: String? = null,
val additionalPrefix: String? = null,
val additionalSuffix: String? = null,
val proxyName: List<ProxyName>? = null
)
data class ProxyName(
val pattern: String? = null, val target: String? = null
)
data class Payload(
val name: String? = null,
val type: String? = null,
val server: String? = null,
val port: Int? = null,
val cipher: String? = null,
val password: String? = null
)
sealed class Listener { sealed class Listener {
abstract val name: String? abstract val name: String?
abstract val port: Int? abstract val port: Int?
@@ -1006,39 +1014,54 @@ data class Clash(
abstract val rule: String? abstract val rule: String?
abstract val proxy: String? abstract val proxy: String?
data class HttpListener( data class AnyTLSListener(
override val name: String? = null, override val name: String? = null,
override val port: Int? = null, override val port: Int? = null,
override val listen: String? = null, override val listen: String? = null,
override val rule: String? = null, override val rule: String? = null,
override val proxy: String? = null, override val proxy: String? = null,
val users: List<User>? = null, val users: Map<String, String>? = null,
val certificate: String? = null, val certificate: String? = null,
val privateKey: String? = null val privateKey: String? = null,
val paddingScheme: String? = null
) : Listener() ) : Listener()
data class SocksListener( data class HTTPListener(
override val name: String? = null, override val name: String? = null,
override val port: Int? = null, override val port: Int? = null,
override val listen: String? = null, override val listen: String? = null,
override val rule: String? = null, override val rule: String? = null,
override val proxy: String? = null, override val proxy: String? = null,
val udp: Boolean? = null, val users: List<AuthUser>? = null,
val users: List<User>? = null,
val certificate: String? = null, val certificate: String? = null,
val privateKey: String? = null val privateKey: String? = null,
val realityConfig: RealityConfig? = null
) : Listener() ) : Listener()
data class MixedListener( data class Hysteria2Listener(
override val name: String? = null, override val name: String? = null,
override val port: Int? = null, override val port: Int? = null,
override val listen: String? = null, override val listen: String? = null,
override val rule: String? = null, override val rule: String? = null,
override val proxy: String? = null, override val proxy: String? = null,
val udp: Boolean? = null, val users: Map<String, String>? = null,
val users: List<User>? = null, val obfs: String? = null,
val obfsPassword: String? = null,
val certificate: String? = null, val certificate: String? = null,
val privateKey: String? = null val privateKey: String? = null,
val maxIdleTime: Int? = null,
val alpn: List<String>? = null,
val up: String? = null,
val down: String? = null,
val ignoreClientBandwidth: Boolean? = null,
val masquerade: String? = null,
val cwnd: Int? = null,
val udpMtu: Int? = null,
val muxOption: MuxOption? = null,
val initialStreamReceiveWindow: ULong? = null,
val maxStreamReceiveWindow: ULong? = null,
val initialConnectionReceiveWindow: ULong? = null,
val maxConnectionReceiveWindow: ULong? = null
) : Listener() ) : Listener()
data class RedirListener( data class RedirListener(
@@ -1049,6 +1072,31 @@ data class Clash(
override val proxy: String? = null override val proxy: String? = null
) : Listener() ) : Listener()
data class ShadowSocksListener(
override val name: String? = null,
override val port: Int? = null,
override val listen: String? = null,
override val rule: String? = null,
override val proxy: String? = null,
val password: String? = null,
val cipher: String? = null,
val udp: Boolean? = null,
val muxOption: MuxOption? = null
) : Listener()
data class SocksListener(
override val name: String? = null,
override val port: Int? = null,
override val listen: String? = null,
override val rule: String? = null,
override val proxy: String? = null,
val users: List<AuthUser>? = null,
val udp: Boolean? = null,
val certificate: String? = null,
val privateKey: String? = null,
val realityConfig: RealityConfig? = null
) : Listener()
data class TProxyListener( data class TProxyListener(
override val name: String? = null, override val name: String? = null,
override val port: Int? = null, override val port: Int? = null,
@@ -1058,54 +1106,20 @@ data class Clash(
val udp: Boolean? = null val udp: Boolean? = null
) : Listener() ) : Listener()
data class TunListener( data class TrojanListener(
override val name: String? = null, override val name: String? = null,
override val port: Int? = null, override val port: Int? = null,
override val listen: String? = null, override val listen: String? = null,
override val rule: String? = null, override val rule: String? = null,
override val proxy: String? = null, override val proxy: String? = null,
val stack: String? = null, val users: List<TrojanUser>? = null,
val dnsHijack: List<String>? = null,
val inet4Address: List<String>? = null,
val inet6Address: List<String>? = null,
val autoDetectInterface: Boolean? = null,
val autoRoute: Boolean? = null,
val mtu: Int? = null,
val strictRoute: Boolean? = null,
val inet4RouteAddress: List<String>? = null,
val inet6RouteAddress: List<String>? = null,
val endpointIndependentNat: Boolean? = null,
val includeUid: List<Int>? = null,
val includeUidRange: List<String>? = null,
val excludeUid: List<Int>? = null,
val excludeUidRange: List<String>? = null,
val includeAndroidUser: List<Int>? = null,
val includePackage: List<String>? = null,
val excludePackage: List<String>? = null
) : Listener()
data class ShadowsocksListener(
override val name: String? = null,
override val port: Int? = null,
override val listen: String? = null,
override val rule: String? = null,
override val proxy: String? = null,
val password: String? = null,
val cipher: String? = null,
val udp: Boolean? = null
) : Listener()
data class VmessListener(
override val name: String? = null,
override val port: Int? = null,
override val listen: String? = null,
override val rule: String? = null,
override val proxy: String? = null,
val users: List<VmessUser>? = null,
val privateKey: String? = null,
val certificate: String? = null,
val wsPath: String? = null, val wsPath: String? = null,
val realityConfig: RealityConfig? = null val grpcServiceName: String? = null,
val certificate: String? = null,
val privateKey: String? = null,
val realityConfig: RealityConfig? = null,
val muxOption: MuxOption? = null,
val ssOption: TrojanSSOption? = null
) : Listener() ) : Listener()
data class TuicListener( data class TuicListener(
@@ -1122,25 +1136,53 @@ data class Clash(
val maxIdleTime: Int? = null, val maxIdleTime: Int? = null,
val authenticationTimeout: Int? = null, val authenticationTimeout: Int? = null,
val alpn: List<String>? = null, val alpn: List<String>? = null,
val maxUdpRelayPacketSize: Int? = null val maxUdpRelayPacketSize: Int? = null,
val cwnd: Int? = null,
val muxOption: MuxOption? = null
) : Listener() ) : Listener()
data class Hysteria2Listener( data class TunListener(
override val name: String? = null, override val name: String? = null,
override val port: Int? = null, override val port: Int? = null,
override val listen: String? = null, override val listen: String? = null,
override val rule: String? = null, override val rule: String? = null,
override val proxy: String? = null, override val proxy: String? = null,
val users: Map<String, String>? = null, val device: String? = null,
val up: Int? = null, val stack: String? = null,
val down: Int? = null, val dnsHijack: List<String>? = null,
val ignoreClientBandwidth: Boolean? = null, val autoRoute: Boolean? = null,
val obfs: String? = null, val autoDetectInterface: Boolean? = null,
val obfsPassword: String? = null, val mtu: UInt? = null,
val masquerade: String? = null, val gso: Boolean? = null,
val alpn: List<String>? = null, val gsoMaxSize: UInt? = null,
val certificate: String? = null, val inet4Address: List<String>? = null,
val privateKey: String? = null val inet6Address: List<String>? = null,
val ipRoute2TableIndex: Int? = null,
val ipRoute2RuleIndex: Int? = null,
val autoRedirect: Boolean? = null,
val autoRedirectInputMark: UInt? = null,
val autoRedirectOutputMark: UInt? = null,
val strictRoute: Boolean? = null,
val routeAddress: List<String>? = null,
val routeAddressSet: List<String>? = null,
val routeExcludeAddress: List<String>? = null,
val routeExcludeAddressSet: List<String>? = null,
val includeInterface: List<String>? = null,
val excludeInterface: List<String>? = null,
val includeUid: List<UInt>? = null,
val includeUidRange: List<String>? = null,
val excludeUid: List<UInt>? = null,
val excludeUidRange: List<String>? = null,
val includeAndroidUser: List<Int>? = null,
val includePackage: List<String>? = null,
val excludePackage: List<String>? = null,
val endpointIndependentNat: Boolean? = null,
val udpTimeout: Long? = null,
val fileDescriptor: Int? = null,
val inet4RouteAddress: List<String>? = null,
val inet6RouteAddress: List<String>? = null,
val inet4RouteExcludeAddress: List<String>? = null,
val inet6RouteExcludeAddress: List<String>? = null
) : Listener() ) : Listener()
data class TunnelListener( data class TunnelListener(
@@ -1161,28 +1203,74 @@ data class Clash(
override val proxy: String? = null, override val proxy: String? = null,
val users: List<VlessUser>? = null, val users: List<VlessUser>? = null,
val wsPath: String? = null, val wsPath: String? = null,
val grpcServiceName: String? = null,
val certificate: String? = null, val certificate: String? = null,
val privateKey: String? = null, val privateKey: String? = null,
val realityConfig: RealityConfig? = null val realityConfig: RealityConfig? = null,
val muxOption: MuxOption? = null
) : Listener() ) : Listener()
data class User( data class VmessListener(
val username: String? = null, val password: String? = null override val name: String? = null,
override val port: Int? = null,
override val listen: String? = null,
override val rule: String? = null,
override val proxy: String? = null,
val users: List<VmessUser>? = null,
val wsPath: String? = null,
val grpcServiceName: String? = null,
val certificate: String? = null,
val privateKey: String? = null,
val realityConfig: RealityConfig? = null,
val muxOption: MuxOption? = null
) : Listener()
data class AuthUser(
val username: String? = null,
val password: String? = null
) )
data class VmessUser( data class TrojanUser(
val username: String? = null, val uuid: String? = null, val alterId: Int? = null val username: String? = null,
val password: String? = null
) )
data class VlessUser( data class VlessUser(
val username: String? = null, val uuid: String? = null, val flow: String? = null val username: String? = null,
val uuid: String? = null,
val flow: String? = null
)
data class VmessUser(
val username: String? = null,
val uuid: String? = null,
val alterId: Int? = null
) )
data class RealityConfig( data class RealityConfig(
val dest: String? = null, val dest: String? = null,
val privateKey: String? = null, val privateKey: String? = null,
val shortId: List<String>? = null, val shortId: List<String>? = null,
val serverNames: List<String>? = null val serverNames: List<String>? = null,
val maxTimeDifference: Int? = null,
val proxy: String? = null
)
data class TrojanSSOption(
val enabled: Boolean? = null,
val method: String? = null,
val password: String? = null
)
data class BrutalOptions(
val enabled: Boolean? = null,
val up: String? = null,
val down: String? = null
)
data class MuxOption(
val padding: Boolean? = null,
val brutal: BrutalOptions? = null
) )
} }
@@ -1226,10 +1314,11 @@ data class Clash(
companion object { companion object {
private val yamlMapper: ObjectMapper = ObjectMapper(YAMLFactory().disable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID)).apply { private val yamlMapper: ObjectMapper =
registerKotlinModule() ObjectMapper(YAMLFactory().disable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID)).apply {
propertyNamingStrategy = PropertyNamingStrategies.KEBAB_CASE registerKotlinModule()
} propertyNamingStrategy = PropertyNamingStrategies.KEBAB_CASE
}
private fun preprocessYamlNode(yamlNode: JsonNode) { private fun preprocessYamlNode(yamlNode: JsonNode) {
preprocessHostsNode(yamlNode) preprocessHostsNode(yamlNode)
@@ -1241,11 +1330,11 @@ data class Clash(
private fun preprocessHostsNode(yamlNode: JsonNode) { private fun preprocessHostsNode(yamlNode: JsonNode) {
(yamlNode["hosts"] as? ObjectNode)?.let { hostsNode -> (yamlNode["hosts"] as? ObjectNode)?.let { hostsNode ->
hostsNode.fields().forEach { (k, v) -> hostsNode.fields().forEach { (k, v) ->
if (v is TextNode) { if (v is TextNode) {
hostsNode.replace(k, v.toArrayNode()) hostsNode.replace(k, v.toArrayNode())
} }
} }
} }
} }
@@ -1257,12 +1346,14 @@ data class Clash(
val tunnelText = element.textValue() val tunnelText = element.textValue()
val parts = tunnelText.split(",").map { it.trim() } val parts = tunnelText.split(",").map { it.trim() }
require(parts.size == 4) { "Tunnel configuration must have 4 comma-separated values: $tunnelText" } require(parts.size == 4) { "Tunnel configuration must have 4 comma-separated values: $tunnelText" }
val tunnelObject = util.newObjectNode(mapOf( val tunnelObject = util.newObjectNode(
"network" to util.newArrayNode(parts[0].split("/").map { util.newTextNode(it.trim()) }), mapOf(
"address" to util.newTextNode(parts[1]), "network" to util.newArrayNode(parts[0].split("/").map { util.newTextNode(it.trim()) }),
"target" to util.newTextNode(parts[2]), "address" to util.newTextNode(parts[1]),
"proxy" to util.newTextNode(parts[3]) "target" to util.newTextNode(parts[2]),
)) "proxy" to util.newTextNode(parts[3])
)
)
tunnelsArray.set(index, tunnelObject) tunnelsArray.set(index, tunnelObject)
} }
} }
@@ -1300,15 +1391,15 @@ data class Clash(
} }
jsonNode.fields().forEach { (_, value) -> preprocessKeyCase(value) } jsonNode.fields().forEach { (_, value) -> preprocessKeyCase(value) }
} }
is ArrayNode -> jsonNode.forEach { preprocessKeyCase(it) } is ArrayNode -> jsonNode.forEach { preprocessKeyCase(it) }
} }
} }
@JvmStatic @JvmStatic
fun parseFromString(yamlStr: String): Clash { fun parseFromString(yamlStr: String): Clash {
val yamlNode = yamlMapper.readTree(yamlStr); val yamlNode = yamlMapper.readTree(yamlStr)
preprocessYamlNode(yamlNode) preprocessYamlNode(yamlNode)
return yamlMapper.treeToValue(yamlNode, Clash::class.java) return yamlMapper.treeToValue(yamlNode, Clash::class.java)
} }