owenclave / app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt

github - dev - back to tree - upstream
/****************************************************************************** * * * Copyright (C) 2021 by nekohasekai * * Copyright (C) 2021 by Max Lv * * Copyright (C) 2021 by Mygod Studio * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * ******************************************************************************/ package io.nekohasekai.sagernet.database import android.content.Intent import android.os.Binder import android.os.Build import android.os.LocaleList import androidx.preference.PreferenceDataStore import io.nekohasekai.sagernet.* import io.nekohasekai.sagernet.SagerNet.Companion.application import io.nekohasekai.sagernet.bg.VpnService import io.nekohasekai.sagernet.database.preference.InMemoryDatabase import io.nekohasekai.sagernet.database.preference.OnPreferenceDataStoreChangeListener import io.nekohasekai.sagernet.database.preference.PublicDatabase import io.nekohasekai.sagernet.database.preference.RoomPreferenceDataStore import io.nekohasekai.sagernet.ktx.* import java.io.BufferedReader import java.io.StringReader import java.util.Locale import java.util.Properties object DataStore : OnPreferenceDataStoreChangeListener { val configurationStore = RoomPreferenceDataStore(PublicDatabase.kvPairDao) val profileCacheStore = RoomPreferenceDataStore(InMemoryDatabase.kvPairDao) fun init() { configurationStore.registerChangeListener(this) // migrate from 0.14.10 val ipv6Mode0 = configurationStore.getString("ipv6Mode0")?.toIntOrNull() // 0: Disable, 1: Enable, 2: Prefer, 3: Only if (configurationStore.getBoolean("enableVPNInterfaceIPv6Address") == null) { when (ipv6Mode0) { 0 -> configurationStore.putBoolean("enableVPNInterfaceIPv6Address", false) 1, 2, 3 -> configurationStore.putBoolean("enableVPNInterfaceIPv6Address", true) } } if (configurationStore.getBoolean("resolveDestination") == true && configurationStore.getString("outboundDomainStrategy") == null) { when (ipv6Mode0) { 0 -> configurationStore.putString("outboundDomainStrategy", "UseIPv4") 1 -> configurationStore.putString("outboundDomainStrategy", "PreferIPv4") 2 -> configurationStore.putString("outboundDomainStrategy", "PreferIPv6") 3 -> configurationStore.putString("outboundDomainStrategy", "UseIPv6") } } if (configurationStore.getBoolean("resolveDestinationForDirect") == true && configurationStore.getString("outboundDomainStrategyForDirect") == null) { when (ipv6Mode0) { 0 -> configurationStore.putString("outboundDomainStrategyForDirect", "UseIPv4") 1 -> configurationStore.putString("outboundDomainStrategyForDirect", "PreferIPv4") 2 -> configurationStore.putString("outboundDomainStrategyForDirect", "PreferIPv6") 3 -> configurationStore.putString("outboundDomainStrategyForDirect", "UseIPv6") } } // migrate from 0.14.14 val outboundDomainStrategy = configurationStore.getString("outboundDomainStrategy") if (outboundDomainStrategy != null && outboundDomainStrategy != "AsIs" && configurationStore.getString("outboundDomainStrategyForServer") == null) { configurationStore.putString("outboundDomainStrategyForServer", outboundDomainStrategy) } } var selectedProxy by configurationStore.long(Key.PROFILE_ID) var currentProfile by configurationStore.long(Key.PROFILE_CURRENT) var startedProfile by configurationStore.long(Key.PROFILE_STARTED) var selectedGroup by configurationStore.long(Key.PROFILE_GROUP) { SagerNet.currentProfile?.groupId ?: 0L } fun currentGroupId(): Long { val currentSelected = selectedGroup if (currentSelected > 0L) return currentSelected val groups = SagerDatabase.groupDao.allGroups() if (groups.isNotEmpty()) { val groupId = groups[0].id selectedGroup = groupId return groupId } val groupId = SagerDatabase.groupDao.createGroup(ProxyGroup(ungrouped = true)) selectedGroup = groupId return groupId } fun currentGroup(): ProxyGroup { var group: ProxyGroup? = null val currentSelected = selectedGroup if (currentSelected > 0L) { group = SagerDatabase.groupDao.getById(currentSelected) } if (group != null) return group val groups = SagerDatabase.groupDao.allGroups() if (groups.isEmpty()) { group = ProxyGroup(ungrouped = true).apply { id = SagerDatabase.groupDao.createGroup(this) } } else { group = groups[0] } selectedGroup = group.id return group } fun selectedGroupForImport(): Long { val current = currentGroup() if (current.type == GroupType.BASIC) return current.id val groups = SagerDatabase.groupDao.allGroups() return groups.find { it.type == GroupType.BASIC }!!.id } var appTheme by configurationStore.int(Key.APP_THEME) { 21 } var appLogo by configurationStore.int(Key.APP_LOGO) { 0 } var nightTheme by configurationStore.stringToInt(Key.NIGHT_THEME) { 1 } var serviceMode by configurationStore.string(Key.SERVICE_MODE) { Key.MODE_VPN } var domainStrategy by configurationStore.string(Key.DOMAIN_STRATEGY) { "AsIs" } var trafficSniffing by configurationStore.boolean(Key.TRAFFIC_SNIFFING) { true } var destinationOverride by configurationStore.boolean(Key.DESTINATION_OVERRIDE) var outboundDomainStrategy by configurationStore.string(Key.OUTBOUND_DOMAIN_STRATEGY) { "AsIs" } var outboundDomainStrategyForDirect by configurationStore.string(Key.OUTBOUND_DOMAIN_STRATEGY_FOR_DIRECT) { "AsIs" } var outboundDomainStrategyForServer by configurationStore.string(Key.OUTBOUND_DOMAIN_STRATEGY_FOR_SERVER) { "AsIs" } var bypassLan by configurationStore.boolean(Key.BYPASS_LAN) { true } var allowAccess by configurationStore.boolean(Key.ALLOW_ACCESS) var speedInterval by configurationStore.stringToInt(Key.SPEED_INTERVAL) { 3 } var remoteDns by configurationStore.stringNotBlack(Key.REMOTE_DNS) { "tcp://1.1.1.1" } var directDns by configurationStore.stringNotBlack(Key.DIRECT_DNS) { val locale = when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> SagerNet.locale.systemLocales[0]!! Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> LocaleList.getDefault().get(0) else -> Locale.getDefault() } when (locale.country) { "CN" -> "tcp://223.5.5.5" "IR" -> "tcp://178.22.122.100" "RU" -> "tcp://77.88.8.8" else -> "tcp://1.1.1.1" } } var bootstrapDns by configurationStore.stringNotBlack(Key.BOOTSTRAP_DNS) var useLocalDnsAsDirectDns by configurationStore.boolean(Key.USE_LOCAL_DNS_AS_DIRECT_DNS) { Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q } var useLocalDnsAsBootstrapDns by configurationStore.boolean(Key.USE_LOCAL_DNS_AS_BOOTSTRAP_DNS) { true } var enableFakeDns by configurationStore.boolean(Key.ENABLE_FAKEDNS) var hijackDns by configurationStore.boolean(Key.HIJACK_DNS) var hosts by configurationStore.string(Key.DNS_HOSTS) var enableDnsRouting by configurationStore.boolean(Key.ENABLE_DNS_ROUTING) { true } var remoteDnsQueryStrategy by configurationStore.string(Key.REMOTE_DNS_QUERY_STRATEGY) { "UseIP" } var directDnsQueryStrategy by configurationStore.string(Key.DIRECT_DNS_QUERY_STRATEGY) { "UseIP" } var ednsClientIp by configurationStore.string(Key.EDNS_CLIENT_IP) var routeMode by configurationStore.stringToInt(Key.ROUTE_MODE) var rulesProvider by configurationStore.stringToInt(Key.RULES_PROVIDER) var rulesGeositeUrl by configurationStore.string(Key.RULES_GEOSITE_URL) { "https://github.com/v2fly/domain-list-community/releases/latest/download/dlc.dat" } var rulesGeoipUrl by configurationStore.string(Key.RULES_GEOIP_URL) { "https://github.com/v2fly/geoip/releases/latest/download/geoip.dat" } var logLevel by configurationStore.stringToInt(Key.LOG_LEVEL) { 1 } var logLevelDebugWarningDisable by configurationStore.boolean(Key.LOG_LEVEL_DEBUG_WARNING_DISABLE) var enableDebug by configurationStore.boolean(Key.ENABLE_DEBUG) { BuildConfig.DEBUG } var pprofServer by configurationStore.string(Key.PPROF_SERVER) var enablePcap by configurationStore.boolean(Key.ENABLE_PCAP) var allowAppsBypassVpn by configurationStore.boolean(Key.ALLOW_APPS_BYPASS_VPN) var acquireWakeLock by configurationStore.boolean(Key.ACQUIRE_WAKE_LOCK) var stunServers by configurationStore.string(Key.STUN_SERVERS) var fabStyle by configurationStore.stringToInt(Key.FAB_STYLE) { 1 } var useIECUnit by configurationStore.boolean(Key.USE_IEC_UNIT) var queryAllPackagesAlternativeMethod by configurationStore.boolean(Key.QUERY_ALL_PACKAGES_ALTERNATIVE_METHOD) var enableFragment by configurationStore.boolean(Key.ENABLE_FRAGMENT) var enableFragmentForDirect by configurationStore.boolean(Key.ENABLE_FRAGMENT_FOR_DIRECT) var fragmentMethod by configurationStore.stringToInt(Key.FRAGMENT_METHOD) var realityDisableX25519Mlkem768 by configurationStore.boolean(Key.REALITY_DISABLE_X25519MLKEM768) var hysteria2OmitMaxDatagramFrameSize by configurationStore.boolean(Key.HYSTERIA2_OMIT_MAX_DATAGRAM_FRAME_SIZE) var grpcServiceNameCompat by configurationStore.boolean(Key.GRPC_SERVICE_NAME_COMPAT) var profileSecurityAdvisory by configurationStore.boolean(Key.PROFILE_SECURITY_ADVISORY) { true } var socksProxyChainEnabled by configurationStore.boolean(Key.SOCKS_PROXY_CHAIN_ENABLED) var socksProxyChainHost by configurationStore.string(Key.SOCKS_PROXY_CHAIN_HOST) var socksProxyChainPort by configurationStore.stringToInt(Key.SOCKS_PROXY_CHAIN_PORT) var socksProxyChainUsername by configurationStore.string(Key.SOCKS_PROXY_CHAIN_USERNAME) var socksProxyChainPassword by configurationStore.string(Key.SOCKS_PROXY_CHAIN_PASSWORD) var enableTwps2 by configurationStore.boolean(Key.ENABLE_TWPS2) var twps2Strategy by configurationStore.string(Key.TWPS2_STRATEGY) { "auto" } var enableUnlockRu by configurationStore.boolean(Key.ENABLE_UNLOCK_RU) var directProxyMode by configurationStore.boolean(Key.DIRECT_PROXY_MODE) // hopefully hashCode = mHandle doesn't change, currently this is true from KitKat to Nougat private val userIndex by lazy { Binder.getCallingUserHandle().hashCode() } var socksPort: Int get() = getLocalPort(Key.SOCKS_PORT, 2080) set(value) = saveLocalPort(Key.SOCKS_PORT, value) var localDNSPort: Int get() = getLocalPort(Key.LOCAL_DNS_PORT, 6450) set(value) { saveLocalPort(Key.LOCAL_DNS_PORT, value) } var httpPort: Int get() = getLocalPort(Key.HTTP_PORT, 9080) set(value) = saveLocalPort(Key.HTTP_PORT, value) var transproxyPort: Int get() = getLocalPort(Key.TRANSPROXY_PORT, 9200) set(value) = saveLocalPort(Key.TRANSPROXY_PORT, value) fun initGlobal() { if (configurationStore.getString(Key.SOCKS_PORT) == null) { socksPort = socksPort } if (configurationStore.getString(Key.LOCAL_DNS_PORT) == null) { localDNSPort = localDNSPort } if (configurationStore.getString(Key.HTTP_PORT) == null) { httpPort = httpPort } if (configurationStore.getString(Key.TRANSPROXY_PORT) == null) { transproxyPort = transproxyPort } if (configurationStore.getString(Key.DNS_HOSTS) == null) { hosts = hosts } if (configurationStore.getString(Key.REMOTE_DNS).isNullOrBlank()) { remoteDns = remoteDns } if (configurationStore.getString(Key.DIRECT_DNS).isNullOrBlank()) { directDns = directDns } if (configurationStore.getString(Key.MTU).isNullOrBlank()) { mtu = mtu } } private fun getLocalPort(key: String, default: Int): Int { return parsePort(configurationStore.getString(key), default + userIndex) } private fun saveLocalPort(key: String, value: Int) { configurationStore.putString(key, "$value") } var enableVPNInterfaceIPv6Address by configurationStore.boolean(Key.ENABLE_VPN_INTERFACE_IPV6_ADDRESS) var meteredNetwork by configurationStore.boolean(Key.METERED_NETWORK) var proxyApps by configurationStore.boolean(Key.PROXY_APPS) var bypass by configurationStore.boolean(Key.BYPASS_MODE) { true } var individual by configurationStore.string(Key.INDIVIDUAL) var showDirectSpeed by configurationStore.boolean(Key.SHOW_DIRECT_SPEED) var persistAcrossReboot by configurationStore.boolean(Key.PERSIST_ACROSS_REBOOT) var requireSocks by configurationStore.boolean(Key.REQUIRE_SOCKS) { true } var socksUsername by configurationStore.string(Key.SOCKS_USERNAME) var socksPassword by configurationStore.string(Key.SOCKS_PASSWORD) var socksUDP by configurationStore.boolean(Key.SOCKS_UDP) { true } var socksUDPWarningDisable by configurationStore.boolean(Key.SOCKS_UDP_WARNING_DISABLE) var requireHttp by configurationStore.boolean(Key.REQUIRE_HTTP) { false } var httpUsername by configurationStore.string(Key.HTTP_USERNAME) var httpPassword by configurationStore.string(Key.HTTP_PASSWORD) var appendHttpProxy by configurationStore.boolean(Key.APPEND_HTTP_PROXY) { true } var httpProxyException by configurationStore.string(Key.HTTP_PROXY_EXCEPTION) var requireTransproxy by configurationStore.boolean(Key.REQUIRE_TRANSPROXY) // var transproxyMode by configurationStore.stringToInt(Key.TRANSPROXY_MODE) var requireDnsInbound by configurationStore.boolean(Key.REQUIRE_DNS_INBOUND) var connectionTestURL by configurationStore.string(Key.CONNECTION_TEST_URL) { CONNECTION_TEST_URL } var alwaysShowAddress by configurationStore.boolean(Key.ALWAYS_SHOW_ADDRESS) var showGroupName by configurationStore.boolean(Key.SHOW_GROUP_NAME) var tunImplementation by configurationStore.stringToInt(Key.TUN_IMPLEMENTATION) { TunImplementation.GVISOR } var mtu by configurationStore.stringToInt(Key.MTU) { VpnService.DEFAULT_MTU } var discardICMP by configurationStore.boolean(Key.DISCARD_ICMP) { true } var appTrafficStatistics by configurationStore.boolean(Key.APP_TRAFFIC_STATISTICS) var profileTrafficStatistics by configurationStore.boolean(Key.PROFILE_TRAFFIC_STATISTICS) { true } // protocol var providerRootCA by configurationStore.stringToInt(Key.PROVIDER_ROOT_CA) { 0 } var interruptReusedConnections by configurationStore.boolean(Key.INTERRUPT_REUSED_CONNECTIONS) { true } // cache var editingId by profileCacheStore.long(Key.PROFILE_ID) var editingGroup by profileCacheStore.long(Key.PROFILE_GROUP) var profileName by profileCacheStore.string(Key.PROFILE_NAME) var serverAddress by profileCacheStore.string(Key.SERVER_ADDRESS) var serverPort by profileCacheStore.stringToInt(Key.SERVER_PORT) var serverUsername by profileCacheStore.string(Key.SERVER_USERNAME) var serverPassword by profileCacheStore.string(Key.SERVER_PASSWORD) var serverPassword1 by profileCacheStore.string(Key.SERVER_PASSWORD1) var serverMethod by profileCacheStore.string(Key.SERVER_METHOD) var serverPlugin by profileCacheStore.string(Key.SERVER_PLUGIN) var serverProtocol by profileCacheStore.string(Key.SERVER_PROTOCOL) var serverProtocolParam by profileCacheStore.string(Key.SERVER_PROTOCOL_PARAM) var serverObfs by profileCacheStore.string(Key.SERVER_OBFS) var serverObfsParam by profileCacheStore.string(Key.SERVER_OBFS_PARAM) var serverUserId by profileCacheStore.string(Key.SERVER_USER_ID) var serverAlterId by profileCacheStore.stringToInt(Key.SERVER_ALTER_ID) var serverSecurity by profileCacheStore.string(Key.SERVER_SECURITY) var serverNetwork by profileCacheStore.string(Key.SERVER_NETWORK) var serverHeader by profileCacheStore.string(Key.SERVER_HEADER) var serverHost by profileCacheStore.string(Key.SERVER_HOST) var serverPath by profileCacheStore.string(Key.SERVER_PATH) var serverSNI by profileCacheStore.string(Key.SERVER_SNI) var serverEncryption by profileCacheStore.string(Key.SERVER_ENCRYPTION) var serverEncryptionForVless by profileCacheStore.string(Key.SERVER_ENCRYPTION_FOR_VLESS) var serverALPN by profileCacheStore.string(Key.SERVER_ALPN) var serverCertificates by profileCacheStore.string(Key.SERVER_CERTIFICATES) var serverPinnedCertificateChain by profileCacheStore.string(Key.SERVER_PINNED_CERTIFICATE_CHAIN) var serverPinnedCertificatePublicKey by profileCacheStore.string(Key.SERVER_PINNED_CERTIFICATE_PUBLIC_KEY) var serverPinnedCertificate by profileCacheStore.string(Key.SERVER_PINNED_CERTIFICATE) var serverMtlsCertificate by profileCacheStore.string(Key.SERVER_MTLS_CERTIFICATE) var serverMtlsCertificatePrivateKey by profileCacheStore.string(Key.SERVER_MTLS_CERTIFICATE_PRIVATE_KEY) var serverFlow by profileCacheStore.string(Key.SERVER_FLOW) var serverQuicSecurity by profileCacheStore.string(Key.SERVER_QUIC_SECURITY) var serverWsMaxEarlyData by profileCacheStore.stringToInt(Key.SERVER_WS_MAX_EARLY_DATA) var serverSplithttpMode by profileCacheStore.string(Key.SERVER_SPLITHTTP_MODE) var serverSplithttpExtra by profileCacheStore.string(Key.SERVER_SPLITHTTP_EXTRA) var serverWsBrowserForwarding by profileCacheStore.boolean(Key.SERVER_WS_BROWSER_FORWARDING) var serverShBrowserForwarding by profileCacheStore.boolean(Key.SERVER_SH_BROWSER_FORWARDING) var serverEarlyDataHeaderName by profileCacheStore.string(Key.SERVER_EARLY_DATA_HEADER_NAME) var serverHeaders by profileCacheStore.string(Key.SERVER_HEADERS) var serverAllowInsecure by profileCacheStore.boolean(Key.SERVER_ALLOW_INSECURE) var serverPacketEncoding by profileCacheStore.string(Key.SERVER_PACKET_ENCODING) var serverUTLSFingerprint by profileCacheStore.string(Key.SERVER_UTLS_FINGERPRINT) var serverEchEnabled by profileCacheStore.boolean(Key.SERVER_ECH_ENABLED) var serverEchConfig by profileCacheStore.string(Key.SERVER_ECH_CONFIG) var serverRealityPublicKey by profileCacheStore.string(Key.SERVER_REALITY_PUBLIC_KEY) var serverRealityShortId by profileCacheStore.string(Key.SERVER_REALITY_SHORT_ID) var serverRealityMldsa65Verify by profileCacheStore.string(Key.SERVER_REALITY_MLDSA65_VERIFY) var serverRealityFingerprint by profileCacheStore.string(Key.SERVER_REALITY_FINGERPRINT) var serverRealityDisableX25519Mlkem768 by profileCacheStore.boolean(Key.SERVER_REALITY_DISABLE_X25519MLKEM768) var serverGrpcServiceNameCompat by profileCacheStore.boolean(Key.SERVER_GRPC_SERVICE_NAME_COMPAT) var serverGrpcMultiMode by profileCacheStore.boolean(Key.SERVER_GRPC_MULTI_MODE) var serverMekyaKcpSeed by profileCacheStore.string(Key.SERVER_MEKYA_KCP_SEED) var serverMekyaKcpHeaderType by profileCacheStore.string(Key.SERVER_MEKYA_KCP_HEADER_TYPE) var serverMekyaUrl by profileCacheStore.string(Key.SERVER_MEKYA_URL) var serverPorts by profileCacheStore.string(Key.SERVER_PORTS) var serverHopInterval by profileCacheStore.stringToLong(Key.SERVER_HOP_INTERVAL) var serverHopIntervalMin by profileCacheStore.stringToLong(Key.SERVER_HOP_INTERVAL_MIN) var serverHopIntervalMax by profileCacheStore.stringToLong(Key.SERVER_HOP_INTERVAL_MAX) var serverHysteria2BBRProfile by profileCacheStore.string(Key.SERVER_HYSTERIA2_BBR_PROFILE) var serverHysteria2ObfsType by profileCacheStore.string(Key.SERVER_HYSTERIA2_OBFS_TYPE) var serverHysteria2GeckoMinPacketSize by profileCacheStore.stringToInt(Key.SERVER_HYSTERIA2_GECKO_MIN_PACKET_SIZE) var serverHysteria2GeckoMaxPacketSize by profileCacheStore.stringToInt(Key.SERVER_HYSTERIA2_GECKO_MAX_PACKET_SIZE) var serverSnellVersion by profileCacheStore.stringToInt(Key.SERVER_SNELL_VERSION) var serverSnellReuse by profileCacheStore.boolean(Key.SERVER_SNELL_REUSE) var serverSnellPSK by profileCacheStore.string(Key.SERVER_SNELL_PSK) var serverSnellUserKey by profileCacheStore.string(Key.SERVER_SNELL_USER_KEY) var serverSnellObfsMode by profileCacheStore.string(Key.SERVER_SNELL_OBFS_MODE) var serverSnellObfsHost by profileCacheStore.string(Key.SERVER_SNELL_OBFS_HOST) var serverSnellMode by profileCacheStore.string(Key.SERVER_SNELL_MODE) var serverOlcrtcAuthProvider by profileCacheStore.string(Key.SERVER_OLCRTC_AUTH_PROVIDER) { "jitsi" } var serverOlcrtcTransport by profileCacheStore.string(Key.SERVER_OLCRTC_TRANSPORT) { "datachannel" } var serverOlcrtcRoomId by profileCacheStore.string(Key.SERVER_OLCRTC_ROOM_ID) var serverOlcrtcEncryptionKey by profileCacheStore.string(Key.SERVER_OLCRTC_ENCRYPTION_KEY) var serverOlcrtcDnsServer by profileCacheStore.string(Key.SERVER_OLCRTC_DNS_SERVER) { "8.8.8.8:53" } var serverOlcrtcSocksHost by profileCacheStore.string(Key.SERVER_OLCRTC_SOCKS_HOST) { "127.0.0.1" } var serverOlcrtcSocksPort by profileCacheStore.stringToInt(Key.SERVER_OLCRTC_SOCKS_PORT) { 8808 } var serverVMessExperimentalAuthenticatedLength by profileCacheStore.boolean(Key.SERVER_VMESS_EXPERIMENTAL_AUTHENTICATED_LENGTH) var serverVMessExperimentalNoTerminationSignal by profileCacheStore.boolean(Key.SERVER_VMESS_EXPERIMENTAL_NO_TERMINATION_SIGNAL) var serverMux by profileCacheStore.boolean(Key.SERVER_MUX) var serverMuxConcurrency by profileCacheStore.stringToInt(Key.SERVER_MUX_CONCURRENCY) { 8 } var serverMuxPacketEncoding by profileCacheStore.string(Key.SERVER_MUX_PACKET_ENCODING) var serverAuthType by profileCacheStore.stringToInt(Key.SERVER_AUTH_TYPE) var serverUploadSpeed by profileCacheStore.stringToLong(Key.SERVER_UPLOAD_SPEED) var serverDownloadSpeed by profileCacheStore.stringToLong(Key.SERVER_DOWNLOAD_SPEED) var serverProtocolVersion by profileCacheStore.stringToInt(Key.SERVER_PROTOCOL) var serverPrivateKey by profileCacheStore.string(Key.SERVER_PRIVATE_KEY) var serverLocalAddress by profileCacheStore.string(Key.SERVER_LOCAL_ADDRESS) var serverInsecureConcurrency by profileCacheStore.stringToInt(Key.SERVER_INSECURE_CONCURRENCY) var serverMTU by profileCacheStore.stringToInt(Key.SERVER_MTU) var serverReducedIvHeadEntropy by profileCacheStore.boolean(Key.SERVER_REDUCED_IV_HEAD_ENTROPY) var serverBrookUdpOverStream by profileCacheStore.boolean(Key.SERVER_BROOK_UDP_OVER_STREAM) var serverUDPRelayMode by profileCacheStore.string(Key.SERVER_UDP_RELAY_MODE) var serverCongestionController by profileCacheStore.string(Key.SERVER_CONGESTION_CONTROLLER) var serverDisableSNI by profileCacheStore.boolean(Key.SERVER_DISABLE_SNI) var serverReduceRTT by profileCacheStore.boolean(Key.SERVER_REDUCE_RTT) var serverMieruMuxLevel by profileCacheStore.stringToInt(Key.SERVER_MIERU_MUX_LEVEL) var serverMieruHandshakeMode by profileCacheStore.stringToInt(Key.SERVER_MIERU_HANDSHAKE_MODE) var serverMieruTrafficPattern by profileCacheStore.string(Key.SERVER_MIERU_TRAFFIC_PATTERN) var serverWireGuardReserved by profileCacheStore.string(Key.SERVER_WIREGUARD_RESERVED) var serverWireGuardKeepaliveInterval by profileCacheStore.stringToInt(Key.SERVER_WIREGUARD_KEEPALIVE_INTERVAL) var serverAnyTLSIdleSessionCheckInterval by profileCacheStore.stringToInt(Key.SERVER_ANYTLS_IDLE_SESSION_CHECK_INTERVAL) { 30 } var serverAnyTLSIdleSessionTimeout by profileCacheStore.stringToInt(Key.SERVER_ANYTLS_IDLE_SESSION_TIMEOUT) { 30 } var serverAnyTLSMinIdleSession by profileCacheStore.stringToInt(Key.SERVER_ANYTLS_MIN_IDLE_SESSION) var serverAnyTLSDisableReuse by profileCacheStore.boolean(Key.SERVER_ANYTLS_DISABLE_REUSE) var serverServerNameToVerify by profileCacheStore.string(Key.SERVER_SERVER_NAME_TO_VERIFY) var serverHysteria2OmitMaxDatagramFrameSize by profileCacheStore.boolean(Key.SERVER_HYSTERIA2_OMIT_MAX_DATAGRAM_FRAME_SIZE) var serverSSHKeepaliveInterval by profileCacheStore.stringToInt(Key.SERVER_SSH_KEEPALIVE_INTERVAL) var serverNaiveNoPostQuantum by profileCacheStore.boolean(Key.SERVER_NAIVE_NO_POST_QUANTUM) var serverShadowQUICDisableALPN by profileCacheStore.boolean(Key.SERVER_SHADOWQUIC_DISABLE_ALPN) var serverShadowQUICUseSunnyQUIC by profileCacheStore.boolean(Key.SERVER_SHADOWQUIC_USE_SUNNYQUIC) var serverSingUot by profileCacheStore.boolean(Key.SERVER_SING_UOT) var serverSingMux by profileCacheStore.boolean(Key.SERVER_SING_MUX) var serverSingMuxProtocol by profileCacheStore.string(Key.SERVER_SING_MUX_PROTOCOL) var serverSingMuxMaxConnections by profileCacheStore.stringToInt(Key.SERVER_SING_MUX_MAX_CONNECTIONS) var serverSingMuxMinStreams by profileCacheStore.stringToInt(Key.SERVER_SING_MUX_MIN_STREAMS) var serverSingMuxMaxStreams by profileCacheStore.stringToInt(Key.SERVER_SING_MUX_MAX_STREAMS) var serverSingMuxPadding by profileCacheStore.boolean(Key.SERVER_SING_MUX_PADDING) var experimentalFlags by configurationStore.string(Key.EXPERIMENTAL_FLAGS) var balancerType by profileCacheStore.stringToInt(Key.BALANCER_TYPE) var balancerGroup by profileCacheStore.stringToLong(Key.BALANCER_GROUP) var balancerStrategy by profileCacheStore.string(Key.BALANCER_STRATEGY) var balancerProbeUrl by profileCacheStore.string(Key.PROBE_URL) var balancerProbeInterval by profileCacheStore.stringToInt(Key.PROBE_INTERVAL) { 300 } var balancerNameFilter by profileCacheStore.string(Key.BALANCER_NAME_FILTER) var balancerNameFilter1 by profileCacheStore.string(Key.BALANCER_NAME_FILTER1) var balancerUseLandingProxy by profileCacheStore.boolean(Key.BALANCER_USE_LANDING_PROXY) var balancerUseFrontProxy by profileCacheStore.boolean(Key.BALANCER_USE_FRONT_PROXY) var routeName by profileCacheStore.string(Key.ROUTE_NAME) var routeDomain by profileCacheStore.string(Key.ROUTE_DOMAIN) var routeIP by profileCacheStore.string(Key.ROUTE_IP) var routePort by profileCacheStore.string(Key.ROUTE_PORT) var routeSourcePort by profileCacheStore.string(Key.ROUTE_SOURCE_PORT) var routeNetwork by profileCacheStore.string(Key.ROUTE_NETWORK) var routeSource by profileCacheStore.string(Key.ROUTE_SOURCE) var routeProtocol by profileCacheStore.string(Key.ROUTE_PROTOCOL) var routeAttrs by profileCacheStore.string(Key.ROUTE_ATTRS) var routeOutbound by profileCacheStore.stringToInt(Key.ROUTE_OUTBOUND) var routeOutboundRule by profileCacheStore.long(Key.ROUTE_OUTBOUND_RULE) var routePackages by profileCacheStore.string(Key.ROUTE_PACKAGES) var routeCustomPackageNameOrUid by profileCacheStore.string(Key.ROUTE_CUSTOM_PACKAGE_NAME_OR_UID) var routeNetworkType by profileCacheStore.stringSet(Key.ROUTE_NETWORK_TYPE) var routeSSID by profileCacheStore.string(Key.ROUTE_SSID) var frontProxyOutbound by profileCacheStore.long(Key.GROUP_FRONT_PROXY_OUTBOUND) var landingProxyOutbound by profileCacheStore.long(Key.GROUP_LANDING_PROXY_OUTBOUND) var frontProxy by profileCacheStore.stringToInt(Key.GROUP_FRONT_PROXY) var landingProxy by profileCacheStore.stringToInt(Key.GROUP_LANDING_PROXY) var serverConfig by profileCacheStore.string(Key.SERVER_CONFIG) var groupName by profileCacheStore.string(Key.GROUP_NAME) var groupType by profileCacheStore.stringToInt(Key.GROUP_TYPE) var groupOrder by profileCacheStore.stringToInt(Key.GROUP_ORDER) var subscriptionType by profileCacheStore.stringToInt(Key.SUBSCRIPTION_TYPE) var subscriptionLink by profileCacheStore.string(Key.SUBSCRIPTION_LINK) var subscriptionDeduplication by profileCacheStore.boolean(Key.SUBSCRIPTION_DEDUPLICATION) var subscriptionUpdateWhenConnectedOnly by profileCacheStore.boolean(Key.SUBSCRIPTION_UPDATE_WHEN_CONNECTED_ONLY) var subscriptionUserAgent by profileCacheStore.string(Key.SUBSCRIPTION_USER_AGENT) var subscriptionAutoUpdate by profileCacheStore.boolean(Key.SUBSCRIPTION_AUTO_UPDATE) var subscriptionAutoUpdateDelay by profileCacheStore.stringToInt(Key.SUBSCRIPTION_AUTO_UPDATE_DELAY) { 1440 } var subscriptionLastUpdated by profileCacheStore.long(Key.SUBSCRIPTION_LAST_UPDATED) var subscriptionBytesUsed by profileCacheStore.long(Key.SUBSCRIPTION_BYTES_USED) var subscriptionBytesRemaining by profileCacheStore.long(Key.SUBSCRIPTION_BYTES_REMAINING) var subscriptionExpiryDate by profileCacheStore.long(Key.SUBSCRIPTION_EXPIRY_DATE) var subscriptionNameFilter by profileCacheStore.string(Key.SUBSCRIPTION_NAME_FILTER) var subscriptionNameFilter1 by profileCacheStore.string(Key.SUBSCRIPTION_NAME_FILTER1) var subscriptionHTTPHeaders by profileCacheStore.string(Key.SUBSCRIPTION_HTTP_HEADERS) var subscriptionAgePrivateKey by profileCacheStore.string(Key.SUBSCRIPTION_AGE_PRIVATE_KEY) var editingAssetName by profileCacheStore.string(Key.EDITING_ASSET_NAME) var assetName by profileCacheStore.string(Key.ASSET_NAME) var assetUrl by profileCacheStore.string(Key.ASSET_URL) var taskerAction by profileCacheStore.stringToInt(Key.TASKER_ACTION) var taskerProfile by profileCacheStore.stringToInt(Key.TASKER_PROFILE) var taskerProfileId by profileCacheStore.long(Key.TASKER_PROFILE_ID) { -1L } var rulesFirstCreate by configurationStore.boolean(Key.RULES_FIRST_CREATE) var doNotShowRuleExportWarning by configurationStore.boolean(Key.DO_NOT_SHOW_RULE_EXPORT_WARNING) var getInstalledPackagesInited by configurationStore.boolean("getInstalledPackagesInited") var postNotificationsPermissionRequested by configurationStore.boolean("postNotificationsPermissionRequested") var accessLocalNetworkPermissionRequested by configurationStore.boolean("accessLocalNetworkPermissionRequested") var experimentalFlagsProperties = Properties().apply { load(BufferedReader(StringReader(experimentalFlags))) } override fun onPreferenceDataStoreChanged(store: PreferenceDataStore, key: String) { when (key) { Key.PROFILE_ID -> {} Key.APP_THEME -> { application.sendBroadcast(Intent(Action.THEME_CHANGED).setPackage(application.packageName)) } Key.EXPERIMENTAL_FLAGS -> { experimentalFlagsProperties = Properties().apply { load(BufferedReader(StringReader(experimentalFlags))) } } } } }