Merge pull request #2839 from vfarid/add_fragment_preferences
Added fragment to the preferences settings
This commit is contained in:
@@ -44,6 +44,10 @@ object AppConfig {
|
||||
const val PREF_MUX_CONCURRENCY = "pref_mux_concurency"
|
||||
const val PREF_MUX_XUDP_CONCURRENCY = "pref_mux_xudp_concurency"
|
||||
const val PREF_MUX_XUDP_QUIC = "pref_mux_xudp_quic"
|
||||
const val PREF_FRAGMENT_ENABLED = "pref_fragment_enabled"
|
||||
const val PREF_FRAGMENT_PACKETS = "pref_fragment_packets"
|
||||
const val PREF_FRAGMENT_LENGTH = "pref_fragment_length"
|
||||
const val PREF_FRAGMENT_INTERVAL = "pref_fragment_interval"
|
||||
|
||||
const val HTTP_PROTOCOL: String = "http://"
|
||||
const val HTTPS_PROTOCOL: String = "https://"
|
||||
|
||||
@@ -56,6 +56,10 @@ data class ServerConfig(
|
||||
return fullConfig?.getProxyOutbound()
|
||||
}
|
||||
|
||||
fun getFragmentOutbound(): V2rayConfig.OutboundBean? {
|
||||
return fullConfig?.getFragmentOutbound()
|
||||
}
|
||||
|
||||
fun getAllOutboundTags(): MutableList<String> {
|
||||
if (configType != EConfigType.CUSTOM) {
|
||||
return mutableListOf(TAG_AGENT, TAG_DIRECT, TAG_BLOCKED)
|
||||
|
||||
@@ -61,13 +61,13 @@ data class V2rayConfig(
|
||||
val metadataOnly: Boolean? = null)
|
||||
}
|
||||
|
||||
data class OutboundBean(val tag: String = "proxy",
|
||||
data class OutboundBean(var tag: String = "proxy",
|
||||
var protocol: String,
|
||||
var settings: OutSettingsBean? = null,
|
||||
var streamSettings: StreamSettingsBean? = null,
|
||||
val proxySettings: Any? = null,
|
||||
val sendThrough: String? = null,
|
||||
val mux: MuxBean? = MuxBean(false)) {
|
||||
var mux: MuxBean? = MuxBean(false)) {
|
||||
|
||||
data class OutSettingsBean(var vnext: List<VnextBean>? = null,
|
||||
var fragment: FragmentBean? = null,
|
||||
@@ -141,7 +141,7 @@ data class V2rayConfig(
|
||||
var realitySettings: TlsSettingsBean? = null,
|
||||
var grpcSettings: GrpcSettingsBean? = null,
|
||||
val dsSettings: Any? = null,
|
||||
val sockopt: SockoptBean? = null
|
||||
var sockopt: SockoptBean? = null
|
||||
) {
|
||||
|
||||
data class TcpSettingsBean(var header: HeaderBean = HeaderBean(),
|
||||
@@ -475,6 +475,15 @@ data class V2rayConfig(
|
||||
return null
|
||||
}
|
||||
|
||||
fun getFragmentOutbound(): OutboundBean? {
|
||||
outbounds.forEach { outbound ->
|
||||
if (outbound.protocol == "freedom" && outbound.tag == "fragment") {
|
||||
return outbound
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun toPrettyPrinting(): String {
|
||||
return GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
|
||||
@@ -41,6 +41,10 @@ class SettingsActivity : BaseActivity() {
|
||||
private val muxXudpConcurrency by lazy { findPreference<EditTextPreference>(AppConfig.PREF_MUX_XUDP_CONCURRENCY) }
|
||||
private val muxXudpQuic by lazy { findPreference<ListPreference>(AppConfig.PREF_MUX_XUDP_QUIC) }
|
||||
|
||||
private val fragment by lazy { findPreference<CheckBoxPreference>(AppConfig.PREF_FRAGMENT_ENABLED) }
|
||||
private val fragmentPackets by lazy { findPreference<ListPreference>(AppConfig.PREF_FRAGMENT_PACKETS) }
|
||||
private val fragmentLength by lazy { findPreference<EditTextPreference>(AppConfig.PREF_FRAGMENT_LENGTH) }
|
||||
private val fragmentInterval by lazy { findPreference<EditTextPreference>(AppConfig.PREF_FRAGMENT_INTERVAL) }
|
||||
|
||||
// val autoRestart by lazy { findPreference(PREF_AUTO_RESTART) as CheckBoxPreference }
|
||||
private val remoteDns by lazy { findPreference<EditTextPreference>(AppConfig.PREF_REMOTE_DNS) }
|
||||
@@ -168,6 +172,23 @@ class SettingsActivity : BaseActivity() {
|
||||
updateMuxXudpConcurrency(newValue as String)
|
||||
true
|
||||
}
|
||||
|
||||
fragment?.setOnPreferenceChangeListener { _, newValue ->
|
||||
updateFragment(newValue as Boolean)
|
||||
true
|
||||
}
|
||||
fragmentPackets?.setOnPreferenceChangeListener { _, newValue ->
|
||||
updateFragmentPackets(newValue as String)
|
||||
true
|
||||
}
|
||||
fragmentLength?.setOnPreferenceChangeListener { _, newValue ->
|
||||
updateFragmentLength(newValue as String)
|
||||
true
|
||||
}
|
||||
fragmentInterval?.setOnPreferenceChangeListener { _, newValue ->
|
||||
updateFragmentInterval(newValue as String)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
@@ -184,6 +205,10 @@ class SettingsActivity : BaseActivity() {
|
||||
updateMux(defaultSharedPreferences.getBoolean(AppConfig.PREF_MUX_ENABLED, false))
|
||||
muxConcurrency?.summary = defaultSharedPreferences.getString(AppConfig.PREF_MUX_CONCURRENCY, "8")
|
||||
muxXudpConcurrency?.summary = defaultSharedPreferences.getString(AppConfig.PREF_MUX_XUDP_CONCURRENCY, "8")
|
||||
updateFragment(defaultSharedPreferences.getBoolean(AppConfig.PREF_FRAGMENT_ENABLED, false))
|
||||
fragmentPackets?.summary = defaultSharedPreferences.getString(AppConfig.PREF_FRAGMENT_PACKETS, "tlshello")
|
||||
fragmentLength?.summary = defaultSharedPreferences.getString(AppConfig.PREF_FRAGMENT_LENGTH, "50-100")
|
||||
fragmentInterval?.summary = defaultSharedPreferences.getString(AppConfig.PREF_FRAGMENT_INTERVAL, "10-20")
|
||||
autoUpdateInterval?.summary = defaultSharedPreferences.getString(AppConfig.SUBSCRIPTION_AUTO_UPDATE_INTERVAL,AppConfig.SUBSCRIPTION_DEFAULT_UPDATE_INTERVAL)
|
||||
autoUpdateInterval?.isEnabled = defaultSharedPreferences.getBoolean(AppConfig.SUBSCRIPTION_AUTO_UPDATE, false)
|
||||
|
||||
@@ -261,9 +286,9 @@ class SettingsActivity : BaseActivity() {
|
||||
|
||||
private fun updateMux(enabled: Boolean) {
|
||||
val defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity())
|
||||
muxConcurrency?.isEnabled = enabled
|
||||
muxXudpConcurrency?.isEnabled = enabled
|
||||
muxXudpQuic?.isEnabled = enabled
|
||||
muxConcurrency?.isVisible = enabled
|
||||
muxXudpConcurrency?.isVisible = enabled
|
||||
muxXudpQuic?.isVisible = enabled
|
||||
if (enabled) {
|
||||
updateMuxConcurrency(defaultSharedPreferences.getString(AppConfig.PREF_MUX_CONCURRENCY, "8"))
|
||||
updateMuxXudpConcurrency(defaultSharedPreferences.getString(AppConfig.PREF_MUX_XUDP_CONCURRENCY, "8"))
|
||||
@@ -287,6 +312,27 @@ class SettingsActivity : BaseActivity() {
|
||||
muxXudpQuic?.isEnabled = concurrency >= 0
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateFragment(enabled: Boolean) {
|
||||
val defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity())
|
||||
fragmentPackets?.isVisible = enabled
|
||||
fragmentLength?.isVisible = enabled
|
||||
fragmentInterval?.isVisible = enabled
|
||||
if (enabled) {
|
||||
updateFragmentPackets(defaultSharedPreferences.getString(AppConfig.PREF_FRAGMENT_PACKETS, "tlshello"))
|
||||
updateFragmentLength(defaultSharedPreferences.getString(AppConfig.PREF_FRAGMENT_LENGTH, "50-100"))
|
||||
updateFragmentInterval(defaultSharedPreferences.getString(AppConfig.PREF_FRAGMENT_INTERVAL, "10-20"))
|
||||
}
|
||||
}
|
||||
private fun updateFragmentPackets(value: String?) {
|
||||
fragmentPackets?.summary = value.toString()
|
||||
}
|
||||
private fun updateFragmentLength(value: String?) {
|
||||
fragmentLength?.summary = value.toString()
|
||||
}
|
||||
private fun updateFragmentInterval(value: String?) {
|
||||
fragmentInterval?.summary = value.toString()
|
||||
}
|
||||
}
|
||||
|
||||
fun onModeHelpClicked(view: View) {
|
||||
|
||||
@@ -38,7 +38,8 @@ object V2rayConfigUtil {
|
||||
return Result(true, customConfig)
|
||||
}
|
||||
val outbound = config.getProxyOutbound() ?: return Result(false, "")
|
||||
val result = getV2rayNonCustomConfig(context, outbound)
|
||||
val fragmentOutbound = config.getFragmentOutbound() ?: V2rayConfig.OutboundBean(protocol = "freedom")
|
||||
val result = getV2rayNonCustomConfig(context, outbound, fragmentOutbound)
|
||||
//Log.d(ANG_PACKAGE, result.content)
|
||||
return result
|
||||
} catch (e: Exception) {
|
||||
@@ -50,7 +51,7 @@ object V2rayConfigUtil {
|
||||
/**
|
||||
* 生成v2ray的客户端配置文件
|
||||
*/
|
||||
private fun getV2rayNonCustomConfig(context: Context, outbound: V2rayConfig.OutboundBean): Result {
|
||||
private fun getV2rayNonCustomConfig(context: Context, outbound: V2rayConfig.OutboundBean, fragmentOutbound: V2rayConfig.OutboundBean): Result {
|
||||
val result = Result(false, "")
|
||||
//取得默认配置
|
||||
val assets = Utils.readTextFromAssets(context, "v2ray_config.json")
|
||||
@@ -66,9 +67,12 @@ object V2rayConfigUtil {
|
||||
|
||||
inbounds(v2rayConfig)
|
||||
|
||||
updateOutboundWithGlobalSettings(outbound)
|
||||
updateOutboundWithGlobalSettings(outbound, fragmentOutbound)
|
||||
|
||||
v2rayConfig.outbounds[0] = outbound
|
||||
if (fragmentOutbound.tag == "fragment") {
|
||||
v2rayConfig.outbounds[1] = fragmentOutbound
|
||||
}
|
||||
|
||||
routing(v2rayConfig)
|
||||
|
||||
@@ -401,7 +405,7 @@ object V2rayConfigUtil {
|
||||
return true
|
||||
}
|
||||
|
||||
private fun updateOutboundWithGlobalSettings(outbound: V2rayConfig.OutboundBean): Boolean {
|
||||
private fun updateOutboundWithGlobalSettings(outbound: V2rayConfig.OutboundBean, fragmentOutbound: V2rayConfig.OutboundBean): Boolean {
|
||||
try {
|
||||
var muxEnabled = settingsStorage?.decodeBool(AppConfig.PREF_MUX_ENABLED, false)
|
||||
val protocol = outbound.protocol
|
||||
@@ -463,11 +467,29 @@ object V2rayConfigUtil {
|
||||
outbound.streamSettings?.tcpSettings?.header?.request?.headers?.Host = host!!
|
||||
}
|
||||
|
||||
if(settingsStorage?.decodeBool(AppConfig.PREF_FRAGMENT_ENABLED, false) == true) {
|
||||
fragmentOutbound.tag = "fragment"
|
||||
fragmentOutbound.mux = null
|
||||
fragmentOutbound.settings = V2rayConfig.OutboundBean.OutSettingsBean(
|
||||
fragment = V2rayConfig.OutboundBean.OutSettingsBean.FragmentBean(
|
||||
packets = settingsStorage?.decodeString(AppConfig.PREF_FRAGMENT_PACKETS) ?: "tlshello",
|
||||
length = settingsStorage?.decodeString(AppConfig.PREF_FRAGMENT_LENGTH) ?: "50-100",
|
||||
interval = settingsStorage?.decodeString(AppConfig.PREF_FRAGMENT_INTERVAL) ?: "10-20"))
|
||||
fragmentOutbound.streamSettings = V2rayConfig.OutboundBean.StreamSettingsBean(
|
||||
sockopt = V2rayConfig.OutboundBean.StreamSettingsBean.SockoptBean(
|
||||
TcpNoDelay = true,
|
||||
mark = 255))
|
||||
}
|
||||
if (fragmentOutbound.tag == "fragment") {
|
||||
val sockopt = outbound.streamSettings?.sockopt ?: V2rayConfig.OutboundBean.StreamSettingsBean.SockoptBean()
|
||||
sockopt.dialerProxy = "fragment"
|
||||
sockopt.mark = 255
|
||||
outbound.streamSettings?.sockopt = sockopt
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,6 +41,9 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
|
||||
AppConfig.PREF_V2RAY_ROUTING_BLOCKED,
|
||||
AppConfig.PREF_V2RAY_ROUTING_DIRECT,
|
||||
AppConfig.SUBSCRIPTION_AUTO_UPDATE_INTERVAL,
|
||||
AppConfig.PREF_FRAGMENT_PACKETS,
|
||||
AppConfig.PREF_FRAGMENT_LENGTH,
|
||||
AppConfig.PREF_FRAGMENT_INTERVAL,
|
||||
AppConfig.PREF_MUX_XUDP_QUIC, -> {
|
||||
settingsStorage?.encode(key, sharedPreferences.getString(key, ""))
|
||||
}
|
||||
@@ -55,6 +58,7 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
|
||||
AppConfig.PREF_CONFIRM_REMOVE,
|
||||
AppConfig.PREF_START_SCAN_IMMEDIATE,
|
||||
AppConfig.SUBSCRIPTION_AUTO_UPDATE,
|
||||
AppConfig.PREF_FRAGMENT_ENABLED,
|
||||
AppConfig.PREF_MUX_ENABLED, -> {
|
||||
settingsStorage?.encode(key, sharedPreferences.getBoolean(key, false))
|
||||
}
|
||||
|
||||
@@ -60,6 +60,10 @@
|
||||
<item>reality</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="fragment_packets" translatable="false">
|
||||
<item>tlshello</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="streamsecurity_utls" translatable="false">
|
||||
<item></item>
|
||||
<item>chrome</item>
|
||||
|
||||
@@ -240,6 +240,10 @@
|
||||
|
||||
<string name="import_subscription_success">Subscription imported Successfully</string>
|
||||
<string name="import_subscription_failure">Import subscription failed</string>
|
||||
<string name="title_pref_fragment_packets">Fragment Packets</string>
|
||||
<string name="title_pref_fragment_length">Fragment Length (min-max)</string>
|
||||
<string name="title_pref_fragment_interval">Fragment Interval (min-max)</string>
|
||||
<string name="title_pref_fragment_enabled">Enable Fragment</string>
|
||||
|
||||
<string-array name="share_method">
|
||||
<item>QRcode</item>
|
||||
|
||||
@@ -32,6 +32,28 @@
|
||||
android:summary="%s"
|
||||
android:title="@string/title_pref_mux_xudp_quic" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="pref_fragment_enabled"
|
||||
android:title="@string/title_pref_fragment_enabled"/>
|
||||
|
||||
<ListPreference
|
||||
android:key="pref_fragment_packets"
|
||||
android:defaultValue="tlshello"
|
||||
android:entries="@array/fragment_packets"
|
||||
android:entryValues="@array/fragment_packets"
|
||||
android:summary="%s"
|
||||
android:title="@string/title_pref_fragment_packets" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="pref_fragment_length"
|
||||
android:summary="50-100"
|
||||
android:title="@string/title_pref_fragment_length" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="pref_fragment_interval"
|
||||
android:summary="10-20"
|
||||
android:title="@string/title_pref_fragment_interval" />
|
||||
|
||||
<PreferenceCategory android:title="@string/title_vpn_settings">
|
||||
<CheckBoxPreference
|
||||
android:key="pref_per_app_proxy"
|
||||
|
||||
Reference in New Issue
Block a user