Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 13480b0077 | |||
| 1987880294 | |||
| 0ae459a70e | |||
| 02bc46634d | |||
| cfdaa0c54b | |||
| cbe6c1e3e0 | |||
| 3cd6f12b94 | |||
| 516235cd6a | |||
| 236923d0a0 | |||
| a4816b8251 | |||
| 2c2bc86457 | |||
| 68a03a93b5 | |||
| 5127a30ae9 | |||
| 8b76a7a4f4 | |||
| b6aec3fd63 | |||
| 18e0dc4546 | |||
| 129c1db995 |
@@ -13,6 +13,9 @@ A V2Ray client for Android, support [Xray core](https://github.com/XTLS/Xray-cor
|
||||
<img alt="Get it on Google Play" src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" width="165" height="64" />
|
||||
</a>
|
||||
|
||||
### Telegram Channel
|
||||
[github_2dust](https://t.me/github_2dust)
|
||||
|
||||
### Usage
|
||||
|
||||
#### Geoip and Geosite
|
||||
|
||||
+15
-16
@@ -18,8 +18,8 @@ android {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion Integer.parseInt("$targetSdkVer")
|
||||
multiDexEnabled true
|
||||
versionCode 470
|
||||
versionName "1.7.17"
|
||||
versionCode 476
|
||||
versionName "1.7.21"
|
||||
}
|
||||
|
||||
if (props["sign"]) {
|
||||
@@ -112,15 +112,15 @@ dependencies {
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.preference:preference-ktx:1.2.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||
implementation 'androidx.fragment:fragment-ktx:1.5.0'
|
||||
implementation 'androidx.fragment:fragment-ktx:1.5.2'
|
||||
implementation 'androidx.multidex:multidex:2.0.1'
|
||||
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
|
||||
|
||||
// Androidx ktx
|
||||
implementation 'androidx.activity:activity-ktx:1.5.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.0'
|
||||
implementation 'androidx.activity:activity-ktx:1.5.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
|
||||
|
||||
//kotlin
|
||||
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
|
||||
@@ -141,12 +141,11 @@ dependencies {
|
||||
implementation 'com.blacksquircle.ui:language-json:2.1.1'
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url 'https://maven.google.com' }
|
||||
maven { url 'https://jitpack.io' }
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
//buildscript {
|
||||
// repositories {
|
||||
// google()
|
||||
// mavenCentral()
|
||||
// maven { url 'https://maven.google.com' }
|
||||
// maven { url 'https://jitpack.io' }
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -259,11 +259,12 @@ data class V2rayConfig(
|
||||
return sni
|
||||
}
|
||||
|
||||
fun populateTlsSettings(streamSecurity: String, allowInsecure: Boolean, sni: String) {
|
||||
fun populateTlsSettings(streamSecurity: String, allowInsecure: Boolean, sni: String, fingerprint: String?) {
|
||||
security = streamSecurity
|
||||
val tlsSetting = TlsSettingsBean(
|
||||
allowInsecure = allowInsecure,
|
||||
serverName = sni
|
||||
serverName = sni,
|
||||
fingerprint = fingerprint
|
||||
)
|
||||
if (security == TLS) {
|
||||
tlsSettings = tlsSetting
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.v2ray.ang.ui
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.text.TextUtils
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import android.view.LayoutInflater
|
||||
@@ -153,7 +154,9 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
|
||||
val selected = mainStorage?.decodeString(MmkvManager.KEY_SELECTED_SERVER)
|
||||
if (guid != selected) {
|
||||
mainStorage?.encode(MmkvManager.KEY_SELECTED_SERVER, guid)
|
||||
notifyItemChanged(mActivity.mainViewModel.getPosition(selected!!))
|
||||
if (!TextUtils.isEmpty(selected)) {
|
||||
notifyItemChanged(mActivity.mainViewModel.getPosition(selected!!))
|
||||
}
|
||||
notifyItemChanged(mActivity.mainViewModel.getPosition(guid))
|
||||
if (isRunning) {
|
||||
mActivity.showCircle()
|
||||
|
||||
@@ -67,7 +67,9 @@ class ServerActivity : BaseActivity() {
|
||||
private val allowinsecures: Array<out String> by lazy {
|
||||
resources.getStringArray(R.array.allowinsecures)
|
||||
}
|
||||
|
||||
private val uTlsItems: Array<out String> by lazy {
|
||||
resources.getStringArray(R.array.streamsecurity_utls)
|
||||
}
|
||||
// Kotlin synthetics was used, but since it is removed in 1.8. We switch to old manual approach.
|
||||
// We don't use AndroidViewBinding because, it is better to share similar logics for different
|
||||
// protocols. Use findViewById manually ensures the xml are de-coupled with the activity logic.
|
||||
@@ -82,6 +84,7 @@ class ServerActivity : BaseActivity() {
|
||||
private val sp_stream_security: Spinner? by lazy { findViewById(R.id.sp_stream_security) }
|
||||
private val sp_allow_insecure: Spinner? by lazy { findViewById(R.id.sp_allow_insecure) }
|
||||
private val et_sni: EditText? by lazy { findViewById(R.id.et_sni) }
|
||||
private val sp_stream_fingerprint: Spinner? by lazy { findViewById(R.id.sp_stream_fingerprint) } //uTLS
|
||||
private val sp_network: Spinner? by lazy { findViewById(R.id.sp_network) }
|
||||
private val sp_header_type: Spinner? by lazy { findViewById(R.id.sp_header_type) }
|
||||
private val sp_header_type_title: TextView? by lazy { findViewById(R.id.sp_header_type_title) }
|
||||
@@ -170,6 +173,12 @@ class ServerActivity : BaseActivity() {
|
||||
sp_allow_insecure?.setSelection(allowinsecure)
|
||||
}
|
||||
et_sni?.text = Utils.getEditable(tlsSetting.serverName)
|
||||
|
||||
tlsSetting.fingerprint?.let {
|
||||
val utlsIndex = Utils.arrayFind(uTlsItems, tlsSetting.fingerprint)
|
||||
sp_stream_fingerprint?.setSelection(utlsIndex)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
val network = Utils.arrayFind(networks, streamSetting.network)
|
||||
@@ -310,6 +319,7 @@ class ServerActivity : BaseActivity() {
|
||||
val sniField = et_sni?.text?.toString()?.trim() ?: return
|
||||
val allowInsecureField = sp_allow_insecure?.selectedItemPosition ?: return
|
||||
val streamSecurity = sp_stream_security?.selectedItemPosition ?: return
|
||||
var utlsIndex = sp_stream_fingerprint?.selectedItemPosition ?: return
|
||||
|
||||
var sni = streamSetting.populateTransportSettings(
|
||||
transport = networks[network],
|
||||
@@ -330,7 +340,8 @@ class ServerActivity : BaseActivity() {
|
||||
} else {
|
||||
allowinsecures[allowInsecureField].toBoolean()
|
||||
}
|
||||
streamSetting.populateTlsSettings(streamSecuritys[streamSecurity], allowInsecure, sni)
|
||||
|
||||
streamSetting.populateTlsSettings(streamSecuritys[streamSecurity], allowInsecure, sni, uTlsItems[utlsIndex])
|
||||
}
|
||||
|
||||
private fun transportTypes(network: String?): Array<out String> {
|
||||
|
||||
@@ -141,10 +141,10 @@ class UserAssetActivity : BaseActivity() {
|
||||
val result = downloadGeo(it, 60000, httpPort)
|
||||
launch(Dispatchers.Main) {
|
||||
if (result) {
|
||||
toast(getString(R.string.toast_success) + it)
|
||||
toast(getString(R.string.toast_success) + " " + it)
|
||||
binding.recyclerView.adapter?.notifyDataSetChanged()
|
||||
} else {
|
||||
toast(getString(R.string.toast_failure) + it)
|
||||
toast(getString(R.string.toast_failure) + " " + it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,8 +143,9 @@ object AngConfigManager {
|
||||
} else {
|
||||
vmessBean.allowInsecure.toBoolean()
|
||||
}
|
||||
var fingerprint = streamSetting.tlsSettings?.fingerprint
|
||||
streamSetting.populateTlsSettings(vmessBean.streamSecurity, allowInsecure,
|
||||
vmessBean.sni.ifBlank { sni })
|
||||
vmessBean.sni.ifBlank { sni }, fingerprint)
|
||||
}
|
||||
}
|
||||
val key = MmkvManager.encodeServerConfig(vmessBean.guid, config)
|
||||
@@ -185,6 +186,9 @@ object AngConfigManager {
|
||||
config = ServerConfig.create(EConfigType.VMESS)
|
||||
val streamSetting = config.outboundBean?.streamSettings ?: return -1
|
||||
|
||||
var fingerprint = streamSetting.tlsSettings?.fingerprint
|
||||
|
||||
|
||||
if (!tryParseNewVmess(str, config, allowInsecure)) {
|
||||
if (str.indexOf("?") > 0) {
|
||||
if (!tryResolveVmess4Kitsunebi(str, config)) {
|
||||
@@ -216,8 +220,10 @@ object AngConfigManager {
|
||||
}
|
||||
val sni = streamSetting.populateTransportSettings(vmessQRCode.net, vmessQRCode.type, vmessQRCode.host,
|
||||
vmessQRCode.path, vmessQRCode.path, vmessQRCode.host, vmessQRCode.path, vmessQRCode.type, vmessQRCode.path)
|
||||
|
||||
|
||||
streamSetting.populateTlsSettings(vmessQRCode.tls, allowInsecure,
|
||||
if (TextUtils.isEmpty(vmessQRCode.sni)) sni else vmessQRCode.sni)
|
||||
if (TextUtils.isEmpty(vmessQRCode.sni)) sni else vmessQRCode.sni, fingerprint)
|
||||
}
|
||||
}
|
||||
} else if (str.startsWith(EConfigType.SHADOWSOCKS.protocolScheme)) {
|
||||
@@ -292,6 +298,7 @@ object AngConfigManager {
|
||||
config.remarks = Utils.urlDecode(uri.fragment ?: "")
|
||||
|
||||
var flow = ""
|
||||
var fingerprint = config.outboundBean?.streamSettings?.tlsSettings?.fingerprint
|
||||
if (uri.rawQuery != null) {
|
||||
val queryParam = uri.rawQuery.split("&")
|
||||
.associate { it.split("=").let { (k, v) -> k to Utils.urlDecode(v) } }
|
||||
@@ -299,10 +306,11 @@ object AngConfigManager {
|
||||
val sni = config.outboundBean?.streamSettings?.populateTransportSettings(queryParam["type"] ?: "tcp", queryParam["headerType"],
|
||||
queryParam["host"], queryParam["path"], queryParam["seed"], queryParam["quicSecurity"], queryParam["key"],
|
||||
queryParam["mode"], queryParam["serviceName"])
|
||||
config.outboundBean?.streamSettings?.populateTlsSettings(queryParam["security"] ?: TLS, allowInsecure, queryParam["sni"] ?: sni!!)
|
||||
config.outboundBean?.streamSettings?.populateTlsSettings(queryParam["security"] ?: TLS, allowInsecure, queryParam["sni"] ?: sni!!, fingerprint)
|
||||
flow = queryParam["flow"] ?: ""
|
||||
} else {
|
||||
config.outboundBean?.streamSettings?.populateTlsSettings(TLS, allowInsecure, "")
|
||||
|
||||
config.outboundBean?.streamSettings?.populateTlsSettings(TLS, allowInsecure, "", fingerprint)
|
||||
}
|
||||
|
||||
config.outboundBean?.settings?.servers?.get(0)?.let { server ->
|
||||
@@ -317,6 +325,8 @@ object AngConfigManager {
|
||||
.associate { it.split("=").let { (k, v) -> k to Utils.urlDecode(v) } }
|
||||
config = ServerConfig.create(EConfigType.VLESS)
|
||||
val streamSetting = config.outboundBean?.streamSettings ?: return -1
|
||||
var fingerprint = streamSetting.tlsSettings?.fingerprint
|
||||
|
||||
config.remarks = Utils.urlDecode(uri.fragment ?: "")
|
||||
config.outboundBean?.settings?.vnext?.get(0)?.let { vnext ->
|
||||
vnext.address = uri.idnHost
|
||||
@@ -329,7 +339,7 @@ object AngConfigManager {
|
||||
val sni = streamSetting.populateTransportSettings(queryParam["type"] ?: "tcp", queryParam["headerType"],
|
||||
queryParam["host"], queryParam["path"], queryParam["seed"], queryParam["quicSecurity"], queryParam["key"],
|
||||
queryParam["mode"], queryParam["serviceName"])
|
||||
streamSetting.populateTlsSettings(queryParam["security"] ?: "", allowInsecure, queryParam["sni"] ?: sni)
|
||||
streamSetting.populateTlsSettings(queryParam["security"] ?: "", allowInsecure, queryParam["sni"] ?: sni, fingerprint)
|
||||
}
|
||||
if (config == null){
|
||||
return R.string.toast_incorrect_protocol
|
||||
@@ -369,12 +379,12 @@ object AngConfigManager {
|
||||
vnext.users[0].security = DEFAULT_SECURITY
|
||||
vnext.users[0].alterId = alterId.toInt()
|
||||
}
|
||||
|
||||
var fingerprint = streamSetting.tlsSettings?.fingerprint
|
||||
val sni = streamSetting.populateTransportSettings(protocol, queryParam["type"],
|
||||
queryParam["host"]?.split("|")?.get(0) ?: "",
|
||||
queryParam["path"]?.takeIf { it.trim() != "/" } ?: "", queryParam["seed"], queryParam["security"],
|
||||
queryParam["key"], queryParam["mode"], queryParam["serviceName"])
|
||||
streamSetting.populateTlsSettings(if (tls) TLS else "", allowInsecure, sni)
|
||||
streamSetting.populateTlsSettings(if (tls) TLS else "", allowInsecure, sni, fingerprint)
|
||||
true
|
||||
}.getOrElse { false }
|
||||
}
|
||||
|
||||
@@ -54,12 +54,8 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
fun reloadServerList() {
|
||||
serverList = MmkvManager.decodeServerList()
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
updateCache()
|
||||
launch(Dispatchers.Main) {
|
||||
updateListAction.value = -1
|
||||
}
|
||||
}
|
||||
updateCache()
|
||||
updateListAction.value = -1
|
||||
}
|
||||
|
||||
fun removeServer(guid: String) {
|
||||
|
||||
@@ -202,64 +202,7 @@
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_margin_top_height"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/server_lab_stream_security" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/sp_stream_security"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/edit_height"
|
||||
android:entries="@array/streamsecurityxs"
|
||||
android:nextFocusDown="@+id/et_sni" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_margin_top_height"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/server_lab_sni" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_sni"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/edit_height"
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_margin_top_height"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/server_lab_allow_insecure" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/sp_allow_insecure"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/edit_height"
|
||||
android:entries="@array/allowinsecures"
|
||||
android:nextFocusUp="@+id/et_sni" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/tls_layout" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -223,63 +223,7 @@
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_margin_top_height"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/server_lab_stream_security" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/sp_stream_security"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/edit_height"
|
||||
android:entries="@array/streamsecurityxs"
|
||||
android:nextFocusDown="@+id/et_sni" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_margin_top_height"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/server_lab_sni" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_sni"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/edit_height"
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_margin_top_height"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/server_lab_allow_insecure" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/sp_allow_insecure"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/edit_height"
|
||||
android:entries="@array/allowinsecures"
|
||||
android:nextFocusUp="@+id/et_sni" />
|
||||
|
||||
</LinearLayout>
|
||||
<include layout="@layout/tls_layout" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -222,64 +222,7 @@
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_margin_top_height"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/server_lab_stream_security" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/sp_stream_security"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/edit_height"
|
||||
android:entries="@array/streamsecuritys"
|
||||
android:nextFocusDown="@+id/et_sni" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_margin_top_height"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/server_lab_sni" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_sni"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/edit_height"
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_margin_top_height"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/server_lab_allow_insecure" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/sp_allow_insecure"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/edit_height"
|
||||
android:entries="@array/allowinsecures"
|
||||
android:nextFocusUp="@+id/et_sni" />
|
||||
|
||||
</LinearLayout>
|
||||
<include layout="@layout/tls_layout" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/activity_horizontal_margin"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/l1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/activity_horizontal_margin"
|
||||
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/server_lab_stream_security" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/sp_stream_security"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/edit_height"
|
||||
android:entries="@array/streamsecurityxs"
|
||||
android:nextFocusDown="@+id/et_sni" />
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/l2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/activity_horizontal_margin"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/server_lab_sni" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_sni"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/edit_height"
|
||||
android:inputType="text"
|
||||
android:nextFocusDown="@+id/sp_stream_fingerprint" />
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/l3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="@dimen/activity_horizontal_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/server_lab_stream_fingerprint" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/sp_stream_fingerprint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/edit_height"
|
||||
android:entries="@array/streamsecurity_utls"
|
||||
android:nextFocusDown="@+id/sp_allow_insecure" />
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/l4"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/server_lab_allow_insecure" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/sp_allow_insecure"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/edit_height"
|
||||
android:entries="@array/allowinsecures" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -31,7 +31,7 @@
|
||||
<string name="menu_item_import_config_manually_trojan">手動鍵入 [Trojan]</string>
|
||||
<string name="menu_item_import_config_custom">自訂組態</string>
|
||||
<string name="menu_item_import_config_custom_clipboard">從剪貼簿匯入自訂組態</string>
|
||||
<string name="menu_item_import_config_custom_local">從 URL 匯入自訂組態</string>
|
||||
<string name="menu_item_import_config_custom_local">從本地匯入自訂組態</string>
|
||||
<string name="menu_item_import_config_custom_url">從 URL 匯入自訂組態</string>
|
||||
<string name="menu_item_import_config_custom_url_scan">掃描 URL 匯入自訂組態</string>
|
||||
<string name="del_config_comfirm">確定刪除?</string>
|
||||
|
||||
@@ -60,6 +60,14 @@
|
||||
<item>xtls</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="streamsecurity_utls" translatable="false">
|
||||
<item></item>
|
||||
<item>chrome</item>
|
||||
<item>firefox</item>
|
||||
<item>safari</item>
|
||||
<item>randomized</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="allowinsecures" translatable="false">
|
||||
<item></item>
|
||||
<item>true</item>
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
<string name="server_lab_request_host">request host(host/ws host/h2 host)/QUIC security</string>
|
||||
<string name="server_lab_path">path(ws path/h2 path)/QUIC key/kcp seed/gRPC serviceName</string>
|
||||
<string name="server_lab_stream_security">tls</string>
|
||||
<string name="server_lab_stream_fingerprint">uTLS</string>
|
||||
<string name="server_lab_allow_insecure">allowInsecure</string>
|
||||
<string name="server_lab_sni">SNI</string>
|
||||
<string name="server_lab_address3">address</string>
|
||||
|
||||
@@ -6,7 +6,6 @@ buildscript {
|
||||
mavenCentral()
|
||||
maven { url 'https://maven.google.com' }
|
||||
maven { url 'https://jitpack.io' }
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.2.1'
|
||||
|
||||
Reference in New Issue
Block a user