Compare commits

..

30 Commits

Author SHA1 Message Date
2dust 26f1f7099b up 1.8.2 2023-04-01 18:08:11 +08:00
2dust 613e9ac8bf Add permission POST_NOTIFICATIONS and READ_MEDIA_IMAGES 2023-03-31 13:48:40 +08:00
2dust ea979f02b5 update gradle 2023-03-30 20:45:37 +08:00
2dust 383f55f809 update org.jetbrains.kotlin.android to 1.8.0 2023-03-30 13:21:36 +08:00
2dust ce61f177dc Adjust build gradle 2023-03-30 11:54:15 +08:00
2dust 6a64157537 update kotlinx-coroutines to 1.6.4 2023-03-29 16:15:43 +08:00
2dust de83302c8a update buildtoolsversion & targetSdkversion to 33 2023-03-29 15:54:35 +08:00
2dust 68553d3807 update kotlin version to 1.7.20 2023-03-29 15:25:54 +08:00
2dust 3d7ed12d4b Added the function of deleting duplicate configurations 2023-03-25 21:16:21 +08:00
2dust f70be5bce9 routing domainMatcher is set to null 2023-03-25 18:10:29 +08:00
2dust 405667697e REALITY show false 2023-03-25 18:09:53 +08:00
2dust 3aeda7de81 Merge pull request #2122 from justlovediaodiao/master
fix a crash when adding custom config
2023-03-24 09:15:01 +08:00
yangxing 8a775d662a fix a crash when adding empty custom config 2023-03-23 22:25:07 +08:00
2dust ec0ccbca76 up 1.8.1 2023-03-21 17:17:51 +08:00
2dust 6cdcbb0096 Add REALITY share link 2023-03-21 10:04:03 +08:00
2dust 79e3881704 hide alpn in reality 2023-03-21 09:19:21 +08:00
2dust 4cf2d429f0 Adjust string 2023-03-21 09:18:46 +08:00
2dust fa51952bfa up 1.8.0 2023-03-10 11:17:25 +08:00
2dust b2c4c0a67e Adjust string 2023-03-10 10:00:34 +08:00
2dust cf2c58637b Merge pull request #2036 from yuhan6665/reality
Add reality and remove legacy xtls settings
2023-02-21 20:26:58 +08:00
yuhan6665 a2c262441e Add reality and remove legacy xtls settings
No sharing support for Reality yet
2023-02-20 21:25:33 -05:00
2dust 237be79680 up 1.7.38 2023-02-08 20:07:30 +08:00
2dust 441a64b8c6 add more fingerprint 2023-02-08 20:07:12 +08:00
2dust 2128488658 up 1.7.37 (rollback core to 1.7.2) 2023-02-03 12:04:39 +08:00
2dust d9dc8317f5 up 1.7.36 2023-02-03 10:47:28 +08:00
2dust 6eda2180e4 Update strings.xml 2023-02-03 10:42:24 +08:00
2dust 57a2f0bebf share link to add fingerprint 2023-02-03 10:11:40 +08:00
2dust 1fd3ccaa0c Merge pull request #1959 from user09283/patch-2
Update strings.xml
2023-01-29 20:23:23 +08:00
user09283 528597d0c7 Update strings.xml 2023-01-29 16:22:31 +07:00
user09283 37411e3e6b Update strings.xml 2023-01-29 16:13:38 +07:00
24 changed files with 377 additions and 215 deletions
+23 -55
View File
@@ -1,8 +1,7 @@
apply plugin: 'com.android.application' plugins {
apply plugin: 'kotlin-android' id 'com.android.application'
id 'org.jetbrains.kotlin.android'
Properties props = new Properties() }
props.load(new FileInputStream(new File('local.properties')))
android { android {
compileSdkVersion Integer.parseInt("$compileSdkVer") compileSdkVersion Integer.parseInt("$compileSdkVer")
@@ -18,25 +17,8 @@ android {
minSdkVersion 21 minSdkVersion 21
targetSdkVersion Integer.parseInt("$targetSdkVer") targetSdkVersion Integer.parseInt("$targetSdkVer")
multiDexEnabled true multiDexEnabled true
versionCode 498 versionCode 510
versionName "1.7.35" versionName "1.8.2"
}
if (props["sign"]) {
signingConfigs {
release {
storeFile file("../key.jks")
keyAlias 'ang'
keyPassword '123456'
storePassword '123456'
}
debug {
storeFile file("../key.jks")
keyAlias 'ang'
keyPassword '123456'
storePassword '123456'
}
}
} }
buildTypes { buildTypes {
@@ -44,19 +26,12 @@ android {
minifyEnabled false minifyEnabled false
zipAlignEnabled false zipAlignEnabled false
shrinkResources false shrinkResources false
if (props["sign"]) {
signingConfig signingConfigs.release
}
ndk.abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' ndk.abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
} }
debug { debug {
minifyEnabled false minifyEnabled false
zipAlignEnabled false zipAlignEnabled false
shrinkResources false shrinkResources false
if (props["sign"]) {
signingConfig signingConfigs.release
}
ndk.abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' ndk.abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
} }
} }
@@ -98,6 +73,8 @@ android {
buildFeatures { buildFeatures {
viewBinding true viewBinding true
} }
namespace 'com.v2ray.ang'
testNamespace 'com.v2ray.angTest'
} }
dependencies { dependencies {
@@ -107,29 +84,29 @@ dependencies {
// Androidx // Androidx
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.appcompat:appcompat:1.4.2' implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.6.1' implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.preference:preference-ktx:1.2.0' implementation 'androidx.preference:preference-ktx:1.2.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'androidx.recyclerview:recyclerview:1.3.0'
implementation 'androidx.fragment:fragment-ktx:1.5.2' implementation 'androidx.fragment:fragment-ktx:1.5.6'
implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01' implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
// Androidx ktx // Androidx ktx
implementation 'androidx.activity:activity-ktx:1.5.1' implementation 'androidx.activity:activity-ktx:1.7.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1' implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
//kotlin //kotlin
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" implementation "org.jetbrains.kotlin:kotlin-reflect:1.8.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
implementation 'com.tencent:mmkv-static:1.2.12' implementation 'com.tencent:mmkv-static:1.2.15'
implementation 'com.google.code.gson:gson:2.8.9' implementation 'com.google.code.gson:gson:2.10.1'
implementation 'io.reactivex:rxjava:1.3.4' implementation 'io.reactivex:rxjava:1.3.8'
implementation 'io.reactivex:rxandroid:1.2.1' implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'com.tbruyelle.rxpermissions:rxpermissions:0.9.4@aar' implementation 'com.tbruyelle.rxpermissions:rxpermissions:0.9.4@aar'
implementation 'me.dm7.barcodescanner:core:1.9.8' implementation 'me.dm7.barcodescanner:core:1.9.8'
@@ -139,13 +116,4 @@ dependencies {
implementation 'com.blacksquircle.ui:editorkit:2.1.1' implementation 'com.blacksquircle.ui:editorkit:2.1.1'
implementation 'com.blacksquircle.ui:language-base:2.1.1' implementation 'com.blacksquircle.ui:language-base:2.1.1'
implementation 'com.blacksquircle.ui:language-json:2.1.1' implementation 'com.blacksquircle.ui:language-json:2.1.1'
} }
//buildscript {
// repositories {
// google()
// mavenCentral()
// maven { url 'https://maven.google.com' }
// maven { url 'https://jitpack.io' }
// }
//}
+4 -2
View File
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools">
package="com.v2ray.ang">
<supports-screens <supports-screens
android:anyDensity="true" android:anyDensity="true"
@@ -24,6 +23,9 @@
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> --> <!-- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<application <application
android:name=".AngApplication" android:name=".AngApplication"
@@ -29,7 +29,7 @@ data class V2rayConfig(
const val DEFAULT_NETWORK = "tcp" const val DEFAULT_NETWORK = "tcp"
const val TLS = "tls" const val TLS = "tls"
const val XTLS = "xtls" const val REALITY = "reality"
const val HTTP = "http" const val HTTP = "http"
} }
@@ -130,7 +130,7 @@ data class V2rayConfig(
var httpSettings: HttpSettingsBean? = null, var httpSettings: HttpSettingsBean? = null,
var tlsSettings: TlsSettingsBean? = null, var tlsSettings: TlsSettingsBean? = null,
var quicSettings: QuicSettingBean? = null, var quicSettings: QuicSettingBean? = null,
var xtlsSettings: TlsSettingsBean? = null, var realitySettings: TlsSettingsBean? = null,
var grpcSettings: GrpcSettingsBean? = null, var grpcSettings: GrpcSettingsBean? = null,
val dsSettings: Any? = null, val dsSettings: Any? = null,
val sockopt: Any? = null val sockopt: Any? = null
@@ -189,7 +189,12 @@ data class V2rayConfig(
val fingerprint: String? = null, val fingerprint: String? = null,
val certificates: List<Any>? = null, val certificates: List<Any>? = null,
val disableSystemRoot: Boolean? = null, val disableSystemRoot: Boolean? = null,
val enableSessionResumption: Boolean? = null) val enableSessionResumption: Boolean? = null,
// REALITY settings
val show: Boolean = false,
var publicKey: String? = null,
var shortId: String? = null,
var spiderX: String? = null)
data class QuicSettingBean(var security: String = "none", data class QuicSettingBean(var security: String = "none",
var key: String = "", var key: String = "",
@@ -265,20 +270,24 @@ data class V2rayConfig(
return sni return sni
} }
fun populateTlsSettings(streamSecurity: String, allowInsecure: Boolean, sni: String, fingerprint: String?, alpns: String?) { fun populateTlsSettings(streamSecurity: String, allowInsecure: Boolean, sni: String, fingerprint: String?, alpns: String?,
publicKey: String?, shortId: String?, spiderX: String?) {
security = streamSecurity security = streamSecurity
val tlsSetting = TlsSettingsBean( val tlsSetting = TlsSettingsBean(
allowInsecure = allowInsecure, allowInsecure = allowInsecure,
serverName = sni, serverName = sni,
fingerprint = fingerprint, fingerprint = fingerprint,
alpn = if (alpns.isNullOrEmpty()) null else alpns.split(",").map { it.trim() }.filter { it.isNotEmpty() } alpn = if (alpns.isNullOrEmpty()) null else alpns.split(",").map { it.trim() }.filter { it.isNotEmpty() },
publicKey = publicKey,
shortId = shortId,
spiderX = spiderX
) )
if (security == TLS) { if (security == TLS) {
tlsSettings = tlsSetting tlsSettings = tlsSetting
xtlsSettings = null realitySettings = null
} else if (security == XTLS) { } else if (security == REALITY) {
tlsSettings = null tlsSettings = null
xtlsSettings = tlsSetting realitySettings = tlsSetting
} }
} }
} }
@@ -438,7 +447,7 @@ data class V2rayConfig(
var poolSize: Int = 10000) // roughly 10 times smaller than total ip pool var poolSize: Int = 10000) // roughly 10 times smaller than total ip pool
fun getProxyOutbound(): OutboundBean? { fun getProxyOutbound(): OutboundBean? {
outbounds.forEach { outbound -> outbounds?.forEach { outbound ->
EConfigType.values().forEach { EConfigType.values().forEach {
if (outbound.protocol.equals(it.name, true)) { if (outbound.protocol.equals(it.name, true)) {
return outbound return outbound
@@ -13,4 +13,5 @@ data class VmessQRCode(var v: String = "",
var path: String = "", var path: String = "",
var tls: String = "", var tls: String = "",
var sni: String = "", var sni: String = "",
var alpn: String = "") var alpn: String = "",
var fp: String = "")
@@ -14,6 +14,7 @@ import android.text.TextUtils
import android.view.KeyEvent import android.view.KeyEvent
import com.v2ray.ang.AppConfig import com.v2ray.ang.AppConfig
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.os.Build
import com.google.android.material.navigation.NavigationView import com.google.android.material.navigation.NavigationView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.GravityCompat import androidx.core.view.GravityCompat
@@ -107,6 +108,15 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
setupViewModel() setupViewModel()
copyAssets() copyAssets()
migrateLegacy() migrateLegacy()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
RxPermissions(this)
.request(Manifest.permission.POST_NOTIFICATIONS)
.subscribe {
if (!it)
toast(R.string.toast_permission_denied)
}
}
} }
private fun setupViewModel() { private fun setupViewModel() {
@@ -297,7 +307,14 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
.show() .show()
true true
} }
R.id.del_duplicate_config-> {
AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
.setPositiveButton(android.R.string.ok) { _, _ ->
mainViewModel.removeDuplicateServer()
}
.show()
true
}
R.id.del_invalid_config -> { R.id.del_invalid_config -> {
AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm) AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
.setPositiveButton(android.R.string.ok) { _, _ -> .setPositiveButton(android.R.string.ok) { _, _ ->
@@ -620,11 +637,13 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
} }
} }
@Deprecated("Deprecated in Java")
override fun onBackPressed() { override fun onBackPressed() {
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) { if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
binding.drawerLayout.closeDrawer(GravityCompat.START) binding.drawerLayout.closeDrawer(GravityCompat.START)
} else { } else {
super.onBackPressed() //super.onBackPressed()
onBackPressedDispatcher.onBackPressed()
} }
} }
@@ -7,6 +7,7 @@ import com.google.zxing.Result
import me.dm7.barcodescanner.zxing.ZXingScannerView import me.dm7.barcodescanner.zxing.ZXingScannerView
import android.content.Intent import android.content.Intent
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.os.Build
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
@@ -70,18 +71,23 @@ class ScannerActivity : BaseActivity(), ZXingScannerView.ResultHandler {
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
R.id.select_photo -> { R.id.select_photo -> {
val permission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
Manifest.permission.READ_MEDIA_IMAGES
} else {
Manifest.permission.READ_EXTERNAL_STORAGE
}
RxPermissions(this) RxPermissions(this)
.request(Manifest.permission.READ_EXTERNAL_STORAGE) .request(permission)
.subscribe { .subscribe {
if (it) { if (it) {
try { try {
showFileChooser() showFileChooser()
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
} else } else
toast(R.string.toast_permission_denied) toast(R.string.toast_permission_denied)
} }
true true
} }
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)
@@ -15,6 +15,7 @@ import com.v2ray.ang.dto.EConfigType
import com.v2ray.ang.dto.ServerConfig import com.v2ray.ang.dto.ServerConfig
import com.v2ray.ang.dto.V2rayConfig import com.v2ray.ang.dto.V2rayConfig
import com.v2ray.ang.dto.V2rayConfig.Companion.DEFAULT_PORT import com.v2ray.ang.dto.V2rayConfig.Companion.DEFAULT_PORT
import com.v2ray.ang.dto.V2rayConfig.Companion.TLS
import com.v2ray.ang.extension.toast import com.v2ray.ang.extension.toast
import com.v2ray.ang.util.MmkvManager import com.v2ray.ang.util.MmkvManager
import com.v2ray.ang.util.MmkvManager.ID_MAIN import com.v2ray.ang.util.MmkvManager.ID_MAIN
@@ -84,14 +85,24 @@ class ServerActivity : BaseActivity() {
private val sp_security: Spinner? by lazy { findViewById(R.id.sp_security) } private val sp_security: Spinner? by lazy { findViewById(R.id.sp_security) }
private val sp_stream_security: Spinner? by lazy { findViewById(R.id.sp_stream_security) } 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 sp_allow_insecure: Spinner? by lazy { findViewById(R.id.sp_allow_insecure) }
private val container_allow_insecure: LinearLayout? by lazy { findViewById(R.id.l5) }
private val et_sni: EditText? by lazy { findViewById(R.id.et_sni) } private val et_sni: EditText? by lazy { findViewById(R.id.et_sni) }
private val container_sni: LinearLayout? by lazy { findViewById(R.id.l2) }
private val sp_stream_fingerprint: Spinner? by lazy { findViewById(R.id.sp_stream_fingerprint) } //uTLS private val sp_stream_fingerprint: Spinner? by lazy { findViewById(R.id.sp_stream_fingerprint) } //uTLS
private val container_fingerprint: LinearLayout? by lazy { findViewById(R.id.l3) }
private val sp_network: Spinner? by lazy { findViewById(R.id.sp_network) } 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: 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) } private val sp_header_type_title: TextView? by lazy { findViewById(R.id.sp_header_type_title) }
private val et_request_host: EditText? by lazy { findViewById(R.id.et_request_host) } private val et_request_host: EditText? by lazy { findViewById(R.id.et_request_host) }
private val et_path: EditText? by lazy { findViewById(R.id.et_path) } private val et_path: EditText? by lazy { findViewById(R.id.et_path) }
private val sp_stream_alpn: Spinner? by lazy { findViewById(R.id.sp_stream_alpn) } //uTLS private val sp_stream_alpn: Spinner? by lazy { findViewById(R.id.sp_stream_alpn) } //uTLS
private val container_alpn: LinearLayout? by lazy { findViewById(R.id.l4) }
private val et_public_key: EditText? by lazy { findViewById(R.id.et_public_key) }
private val container_public_key: LinearLayout? by lazy { findViewById(R.id.l6) }
private val et_short_id: EditText? by lazy { findViewById(R.id.et_short_id) }
private val container_short_id: LinearLayout? by lazy { findViewById(R.id.l7) }
private val et_spider_x: EditText? by lazy { findViewById(R.id.et_spider_x) }
private val container_spider_x: LinearLayout? by lazy { findViewById(R.id.l8) }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -105,6 +116,7 @@ class ServerActivity : BaseActivity() {
EConfigType.SOCKS -> setContentView(R.layout.activity_server_socks) EConfigType.SOCKS -> setContentView(R.layout.activity_server_socks)
EConfigType.VLESS -> setContentView(R.layout.activity_server_vless) EConfigType.VLESS -> setContentView(R.layout.activity_server_vless)
EConfigType.TROJAN -> setContentView(R.layout.activity_server_trojan) EConfigType.TROJAN -> setContentView(R.layout.activity_server_trojan)
else -> setContentView(R.layout.activity_server_vmess)
} }
sp_network?.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { sp_network?.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
@@ -126,6 +138,38 @@ class ServerActivity : BaseActivity() {
// do nothing // do nothing
} }
} }
sp_stream_security?.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
if (streamSecuritys[position].isBlank()) {
container_sni?.visibility = View.GONE
container_fingerprint?.visibility = View.GONE
container_alpn?.visibility = View.GONE
container_allow_insecure?.visibility = View.GONE
container_public_key?.visibility = View.GONE
container_short_id?.visibility = View.GONE
container_spider_x?.visibility = View.GONE
} else {
container_sni?.visibility = View.VISIBLE
container_fingerprint?.visibility = View.VISIBLE
container_alpn?.visibility = View.VISIBLE
if (streamSecuritys[position] == TLS) {
container_allow_insecure?.visibility = View.VISIBLE
container_public_key?.visibility = View.GONE
container_short_id?.visibility = View.GONE
container_spider_x?.visibility = View.GONE
} else {
container_allow_insecure?.visibility = View.GONE
container_alpn?.visibility = View.GONE
container_public_key?.visibility = View.VISIBLE
container_short_id?.visibility = View.VISIBLE
container_spider_x?.visibility = View.VISIBLE
}
}
}
override fun onNothingSelected(p0: AdapterView<*>?) {
// do nothing
}
}
if (config != null) { if (config != null) {
bindingServer(config) bindingServer(config)
} else { } else {
@@ -169,13 +213,11 @@ class ServerActivity : BaseActivity() {
val streamSecurity = Utils.arrayFind(streamSecuritys, streamSetting.security) val streamSecurity = Utils.arrayFind(streamSecuritys, streamSetting.security)
if (streamSecurity >= 0) { if (streamSecurity >= 0) {
sp_stream_security?.setSelection(streamSecurity) sp_stream_security?.setSelection(streamSecurity)
(streamSetting.tlsSettings?: streamSetting.xtlsSettings)?.let { tlsSetting -> (streamSetting.tlsSettings?: streamSetting.realitySettings)?.let { tlsSetting ->
val allowinsecure = Utils.arrayFind(allowinsecures, tlsSetting.allowInsecure.toString()) container_sni?.visibility = View.VISIBLE
if (allowinsecure >= 0) { container_fingerprint?.visibility = View.VISIBLE
sp_allow_insecure?.setSelection(allowinsecure) container_alpn?.visibility = View.VISIBLE
}
et_sni?.text = Utils.getEditable(tlsSetting.serverName) et_sni?.text = Utils.getEditable(tlsSetting.serverName)
tlsSetting.fingerprint?.let { tlsSetting.fingerprint?.let {
val utlsIndex = Utils.arrayFind(uTlsItems, tlsSetting.fingerprint) val utlsIndex = Utils.arrayFind(uTlsItems, tlsSetting.fingerprint)
sp_stream_fingerprint?.setSelection(utlsIndex) sp_stream_fingerprint?.setSelection(utlsIndex)
@@ -184,7 +226,33 @@ class ServerActivity : BaseActivity() {
val alpnIndex = Utils.arrayFind(alpns, Utils.removeWhiteSpace(tlsSetting.alpn.joinToString())!!) val alpnIndex = Utils.arrayFind(alpns, Utils.removeWhiteSpace(tlsSetting.alpn.joinToString())!!)
sp_stream_alpn?.setSelection(alpnIndex) sp_stream_alpn?.setSelection(alpnIndex)
} }
if (streamSetting.tlsSettings != null) {
container_allow_insecure?.visibility = View.VISIBLE
val allowinsecure = Utils.arrayFind(allowinsecures, tlsSetting.allowInsecure.toString())
if (allowinsecure >= 0) {
sp_allow_insecure?.setSelection(allowinsecure)
}
container_public_key?.visibility = View.GONE
container_short_id?.visibility = View.GONE
container_spider_x?.visibility = View.GONE
} else { // reality settings
container_public_key?.visibility = View.VISIBLE
et_public_key?.text = Utils.getEditable(tlsSetting.publicKey.orEmpty())
container_short_id?.visibility = View.VISIBLE
et_short_id?.text = Utils.getEditable(tlsSetting.shortId.orEmpty())
container_spider_x?.visibility = View.VISIBLE
et_spider_x?.text = Utils.getEditable(tlsSetting.spiderX.orEmpty())
container_allow_insecure?.visibility = View.GONE
}
}
if (streamSetting.tlsSettings == null && streamSetting.realitySettings == null) {
container_sni?.visibility = View.GONE
container_fingerprint?.visibility = View.GONE
container_alpn?.visibility = View.GONE
container_allow_insecure?.visibility = View.GONE
container_public_key?.visibility = View.GONE
container_short_id?.visibility = View.GONE
container_spider_x?.visibility = View.GONE
} }
} }
val network = Utils.arrayFind(networks, streamSetting.network) val network = Utils.arrayFind(networks, streamSetting.network)
@@ -304,12 +372,6 @@ class ServerActivity : BaseActivity() {
} }
} else if (config.configType == EConfigType.TROJAN) { } else if (config.configType == EConfigType.TROJAN) {
server.password = et_id.text.toString().trim() server.password = et_id.text.toString().trim()
server.flow =
if (streamSecuritys[sp_stream_security?.selectedItemPosition ?: 0] == V2rayConfig.XTLS) {
flows[sp_flow?.selectedItemPosition ?: 0]
} else {
""
}
} }
} }
@@ -321,8 +383,11 @@ class ServerActivity : BaseActivity() {
val sniField = et_sni?.text?.toString()?.trim() ?: return val sniField = et_sni?.text?.toString()?.trim() ?: return
val allowInsecureField = sp_allow_insecure?.selectedItemPosition ?: return val allowInsecureField = sp_allow_insecure?.selectedItemPosition ?: return
val streamSecurity = sp_stream_security?.selectedItemPosition ?: return val streamSecurity = sp_stream_security?.selectedItemPosition ?: return
var utlsIndex = sp_stream_fingerprint?.selectedItemPosition ?: return val utlsIndex = sp_stream_fingerprint?.selectedItemPosition ?: return
var alpnIndex = sp_stream_alpn?.selectedItemPosition ?: return val alpnIndex = sp_stream_alpn?.selectedItemPosition ?: return
val publicKey = et_public_key?.text?.toString()?.trim() ?: return
val shortId = et_short_id?.text?.toString()?.trim() ?: return
val spiderX = et_spider_x?.text?.toString()?.trim() ?: return
var sni = streamSetting.populateTransportSettings( var sni = streamSetting.populateTransportSettings(
transport = networks[network], transport = networks[network],
@@ -344,18 +409,32 @@ class ServerActivity : BaseActivity() {
allowinsecures[allowInsecureField].toBoolean() allowinsecures[allowInsecureField].toBoolean()
} }
streamSetting.populateTlsSettings(streamSecuritys[streamSecurity], allowInsecure, sni, uTlsItems[utlsIndex], alpns[alpnIndex]) streamSetting.populateTlsSettings(
streamSecurity = streamSecuritys[streamSecurity],
allowInsecure = allowInsecure,
sni = sni,
fingerprint = uTlsItems[utlsIndex],
alpns = alpns[alpnIndex],
publicKey = publicKey,
shortId = shortId,
spiderX = spiderX
)
} }
private fun transportTypes(network: String?): Array<out String> { private fun transportTypes(network: String?): Array<out String> {
return if (network == "tcp") { return when (network) {
tcpTypes "tcp" -> {
} else if (network == "kcp" || network == "quic") { tcpTypes
kcpAndQuicTypes }
} else if (network == "grpc") { "kcp", "quic" -> {
grpcModes kcpAndQuicTypes
} else { }
arrayOf("---") "grpc" -> {
grpcModes
}
else -> {
arrayOf("---")
}
} }
} }
@@ -364,7 +443,7 @@ class ServerActivity : BaseActivity() {
*/ */
private fun deleteServer(): Boolean { private fun deleteServer(): Boolean {
if (editGuid.isNotEmpty()) { if (editGuid.isNotEmpty()) {
if (editGuid != mainStorage?.decodeString(MmkvManager.KEY_SELECTED_SERVER)) { if (editGuid != mainStorage?.decodeString(KEY_SELECTED_SERVER)) {
if (settingsStorage?.decodeBool(AppConfig.PREF_CONFIRM_REMOVE) == true) { if (settingsStorage?.decodeBool(AppConfig.PREF_CONFIRM_REMOVE) == true) {
AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm) AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
.setPositiveButton(android.R.string.ok) { _, _ -> .setPositiveButton(android.R.string.ok) { _, _ ->
@@ -145,7 +145,7 @@ object AngConfigManager {
} }
var fingerprint = streamSetting.tlsSettings?.fingerprint var fingerprint = streamSetting.tlsSettings?.fingerprint
streamSetting.populateTlsSettings(vmessBean.streamSecurity, allowInsecure, streamSetting.populateTlsSettings(vmessBean.streamSecurity, allowInsecure,
vmessBean.sni.ifBlank { sni }, fingerprint, null) vmessBean.sni.ifBlank { sni }, fingerprint, null, null, null, null)
} }
} }
val key = MmkvManager.encodeServerConfig(vmessBean.guid, config) val key = MmkvManager.encodeServerConfig(vmessBean.guid, config)
@@ -186,8 +186,6 @@ object AngConfigManager {
config = ServerConfig.create(EConfigType.VMESS) config = ServerConfig.create(EConfigType.VMESS)
val streamSetting = config.outboundBean?.streamSettings ?: return -1 val streamSetting = config.outboundBean?.streamSettings ?: return -1
var fingerprint = streamSetting.tlsSettings?.fingerprint
if (!tryParseNewVmess(str, config, allowInsecure)) { if (!tryParseNewVmess(str, config, allowInsecure)) {
if (str.indexOf("?") > 0) { if (str.indexOf("?") > 0) {
@@ -221,9 +219,10 @@ object AngConfigManager {
val sni = streamSetting.populateTransportSettings(vmessQRCode.net, vmessQRCode.type, vmessQRCode.host, val sni = streamSetting.populateTransportSettings(vmessQRCode.net, vmessQRCode.type, vmessQRCode.host,
vmessQRCode.path, vmessQRCode.path, vmessQRCode.host, vmessQRCode.path, vmessQRCode.type, vmessQRCode.path) vmessQRCode.path, vmessQRCode.path, vmessQRCode.host, vmessQRCode.path, vmessQRCode.type, vmessQRCode.path)
val fingerprint = vmessQRCode.fp ?: streamSetting.tlsSettings?.fingerprint
streamSetting.populateTlsSettings(vmessQRCode.tls, allowInsecure, streamSetting.populateTlsSettings(vmessQRCode.tls, allowInsecure,
if (TextUtils.isEmpty(vmessQRCode.sni)) sni else vmessQRCode.sni, fingerprint, vmessQRCode.alpn) if (TextUtils.isEmpty(vmessQRCode.sni)) sni else vmessQRCode.sni,
fingerprint, vmessQRCode.alpn, null, null, null)
} }
} }
} else if (str.startsWith(EConfigType.SHADOWSOCKS.protocolScheme)) { } else if (str.startsWith(EConfigType.SHADOWSOCKS.protocolScheme)) {
@@ -306,11 +305,14 @@ object AngConfigManager {
val sni = config.outboundBean?.streamSettings?.populateTransportSettings(queryParam["type"] ?: "tcp", queryParam["headerType"], val sni = config.outboundBean?.streamSettings?.populateTransportSettings(queryParam["type"] ?: "tcp", queryParam["headerType"],
queryParam["host"], queryParam["path"], queryParam["seed"], queryParam["quicSecurity"], queryParam["key"], queryParam["host"], queryParam["path"], queryParam["seed"], queryParam["quicSecurity"], queryParam["key"],
queryParam["mode"], queryParam["serviceName"]) queryParam["mode"], queryParam["serviceName"])
config.outboundBean?.streamSettings?.populateTlsSettings(queryParam["security"] ?: TLS, allowInsecure, queryParam["sni"] ?: sni!!, fingerprint, queryParam["alpn"]) fingerprint = queryParam["fp"] ?: ""
config.outboundBean?.streamSettings?.populateTlsSettings(queryParam["security"] ?: TLS,
allowInsecure, queryParam["sni"] ?: sni!!, fingerprint, queryParam["alpn"],
null, null, null)
flow = queryParam["flow"] ?: "" flow = queryParam["flow"] ?: ""
} else { } else {
config.outboundBean?.streamSettings?.populateTlsSettings(TLS, allowInsecure, "",
config.outboundBean?.streamSettings?.populateTlsSettings(TLS, allowInsecure, "", fingerprint, null) fingerprint, null, null, null, null)
} }
config.outboundBean?.settings?.servers?.get(0)?.let { server -> config.outboundBean?.settings?.servers?.get(0)?.let { server ->
@@ -339,7 +341,12 @@ object AngConfigManager {
val sni = streamSetting.populateTransportSettings(queryParam["type"] ?: "tcp", queryParam["headerType"], val sni = streamSetting.populateTransportSettings(queryParam["type"] ?: "tcp", queryParam["headerType"],
queryParam["host"], queryParam["path"], queryParam["seed"], queryParam["quicSecurity"], queryParam["key"], queryParam["host"], queryParam["path"], queryParam["seed"], queryParam["quicSecurity"], queryParam["key"],
queryParam["mode"], queryParam["serviceName"]) queryParam["mode"], queryParam["serviceName"])
streamSetting.populateTlsSettings(queryParam["security"] ?: "", allowInsecure, queryParam["sni"] ?: sni, fingerprint, queryParam["alpn"]) fingerprint = queryParam["fp"] ?: ""
val pbk = queryParam["pbk"] ?: ""
val sid = queryParam["sid"] ?: ""
val spx = Utils.urlDecode(queryParam["spx"] ?: "")
streamSetting.populateTlsSettings(queryParam["security"] ?: "", allowInsecure,
queryParam["sni"] ?: sni, fingerprint, queryParam["alpn"], pbk, sid, spx)
} }
if (config == null){ if (config == null){
return R.string.toast_incorrect_protocol return R.string.toast_incorrect_protocol
@@ -384,7 +391,8 @@ object AngConfigManager {
queryParam["host"]?.split("|")?.get(0) ?: "", queryParam["host"]?.split("|")?.get(0) ?: "",
queryParam["path"]?.takeIf { it.trim() != "/" } ?: "", queryParam["seed"], queryParam["security"], queryParam["path"]?.takeIf { it.trim() != "/" } ?: "", queryParam["seed"], queryParam["security"],
queryParam["key"], queryParam["mode"], queryParam["serviceName"]) queryParam["key"], queryParam["mode"], queryParam["serviceName"])
streamSetting.populateTlsSettings(if (tls) TLS else "", allowInsecure, sni, fingerprint, null) streamSetting.populateTlsSettings(if (tls) TLS else "", allowInsecure, sni, fingerprint, null,
null, null, null)
true true
}.getOrElse { false } }.getOrElse { false }
} }
@@ -478,6 +486,7 @@ object AngConfigManager {
vmessQRCode.tls = streamSetting.security vmessQRCode.tls = streamSetting.security
vmessQRCode.sni = streamSetting.tlsSettings?.serverName.orEmpty() vmessQRCode.sni = streamSetting.tlsSettings?.serverName.orEmpty()
vmessQRCode.alpn = Utils.removeWhiteSpace(streamSetting.tlsSettings?.alpn?.joinToString()).orEmpty() vmessQRCode.alpn = Utils.removeWhiteSpace(streamSetting.tlsSettings?.alpn?.joinToString()).orEmpty()
vmessQRCode.fp = streamSetting.tlsSettings?.fingerprint.orEmpty()
outbound.getTransportSettingDetails()?.let { transportDetails -> outbound.getTransportSettingDetails()?.let { transportDetails ->
vmessQRCode.type = transportDetails[0] vmessQRCode.type = transportDetails[0]
vmessQRCode.host = transportDetails[1] vmessQRCode.host = transportDetails[1]
@@ -528,13 +537,25 @@ object AngConfigManager {
} }
dicQuery["security"] = streamSetting.security.ifEmpty { "none" } dicQuery["security"] = streamSetting.security.ifEmpty { "none" }
(streamSetting.tlsSettings?: streamSetting.xtlsSettings)?.let { tlsSetting -> (streamSetting.tlsSettings?: streamSetting.realitySettings)?.let { tlsSetting ->
if (!TextUtils.isEmpty(tlsSetting.serverName)) { if (!TextUtils.isEmpty(tlsSetting.serverName)) {
dicQuery["sni"] = tlsSetting.serverName dicQuery["sni"] = tlsSetting.serverName
} }
if (!tlsSetting.alpn.isNullOrEmpty() && tlsSetting.alpn.isNotEmpty()) { if (!tlsSetting.alpn.isNullOrEmpty() && tlsSetting.alpn.isNotEmpty()) {
dicQuery["alpn"] = Utils.removeWhiteSpace(tlsSetting.alpn.joinToString()).orEmpty() dicQuery["alpn"] = Utils.removeWhiteSpace(tlsSetting.alpn.joinToString()).orEmpty()
} }
if (!TextUtils.isEmpty(tlsSetting.fingerprint)) {
dicQuery["fp"] = tlsSetting.fingerprint!!
}
if (!TextUtils.isEmpty(tlsSetting.publicKey)) {
dicQuery["pbk"] = tlsSetting.publicKey!!
}
if (!TextUtils.isEmpty(tlsSetting.shortId)) {
dicQuery["sid"] = tlsSetting.shortId!!
}
if (!TextUtils.isEmpty(tlsSetting.spiderX)) {
dicQuery["spx"] = Utils.urlEncode(tlsSetting.spiderX!!)
}
} }
dicQuery["type"] = streamSetting.network.ifEmpty { V2rayConfig.DEFAULT_NETWORK } dicQuery["type"] = streamSetting.network.ifEmpty { V2rayConfig.DEFAULT_NETWORK }
@@ -151,7 +151,7 @@ object V2rayConfigUtil {
v2rayConfig.routing.domainStrategy = settingsStorage?.decodeString(AppConfig.PREF_ROUTING_DOMAIN_STRATEGY) v2rayConfig.routing.domainStrategy = settingsStorage?.decodeString(AppConfig.PREF_ROUTING_DOMAIN_STRATEGY)
?: "IPIfNonMatch" ?: "IPIfNonMatch"
v2rayConfig.routing.domainMatcher = "mph" // v2rayConfig.routing.domainMatcher = "mph"
val routingMode = settingsStorage?.decodeString(AppConfig.PREF_ROUTING_MODE) ?: ERoutingMode.GLOBAL_PROXY.value val routingMode = settingsStorage?.decodeString(AppConfig.PREF_ROUTING_MODE) ?: ERoutingMode.GLOBAL_PROXY.value
// Hardcode googleapis.cn // Hardcode googleapis.cn
@@ -201,6 +201,27 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
return -1 return -1
} }
fun removeDuplicateServer() {
val deleteServer = mutableListOf<String>()
serversCache.forEachIndexed { index, it ->
val outbound = it.config.getProxyOutbound()
serversCache.forEachIndexed { index2, it2 ->
if(index2 > index){
val outbound2 = it2.config.getProxyOutbound()
if( outbound == outbound2 && !deleteServer.contains(it2.guid))
{
deleteServer.add(it2.guid)
}
}
}
}
for(it in deleteServer){
MmkvManager.removeServer(it)
}
reloadServerList()
getApplication<AngApplication>().toast(getApplication<AngApplication>().getString(R.string.title_del_duplicate_config_count, deleteServer.count()))
}
private val mMsgReceiver = object : BroadcastReceiver() { private val mMsgReceiver = object : BroadcastReceiver() {
override fun onReceive(ctx: Context?, intent: Intent?) { override fun onReceive(ctx: Context?, intent: Intent?) {
when (intent?.getIntExtra("key", 0)) { when (intent?.getIntExtra("key", 0)) {
@@ -98,24 +98,6 @@
</LinearLayout> </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_flow" />
<Spinner
android:id="@+id/sp_flow"
android:layout_width="match_parent"
android:layout_height="@dimen/edit_height"
android:entries="@array/flows" />
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -104,5 +104,64 @@
android:layout_height="@dimen/edit_height" android:layout_height="@dimen/edit_height"
android:entries="@array/allowinsecures" /> android:entries="@array/allowinsecures" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/l6"
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_public_key" />
<EditText
android:id="@+id/et_public_key"
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/l7"
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_short_id" />
<EditText
android:id="@+id/et_short_id"
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/l8"
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_spider_x" />
<EditText
android:id="@+id/et_spider_x"
android:layout_width="match_parent"
android:layout_height="@dimen/edit_height"
android:inputType="text"
android:nextFocusDown="@+id/sp_stream_fingerprint" />
</LinearLayout>
</LinearLayout> </LinearLayout>
@@ -73,6 +73,11 @@
android:icon="@drawable/ic_delete_white_24dp" android:icon="@drawable/ic_delete_white_24dp"
android:title="@string/title_del_all_config" android:title="@string/title_del_all_config"
app:showAsAction="never" /> app:showAsAction="never" />
<item
android:id="@+id/del_duplicate_config"
android:icon="@drawable/ic_delete_white_24dp"
android:title="@string/title_del_duplicate_config"
app:showAsAction="never" />
<item <item
android:id="@+id/del_invalid_config" android:id="@+id/del_invalid_config"
android:icon="@drawable/ic_delete_white_24dp" android:icon="@drawable/ic_delete_white_24dp"
@@ -48,9 +48,7 @@
<string name="server_lab_mode_type">حالت gRPC</string> <string name="server_lab_mode_type">حالت gRPC</string>
<string name="server_lab_request_host">درخواست میزبان (میزبان/میزبان ws/ میزبان h2)/امنیت QUIC</string> <string name="server_lab_request_host">درخواست میزبان (میزبان/میزبان ws/ میزبان h2)/امنیت QUIC</string>
<string name="server_lab_path">مسیر (مسیر ws/ مسیر h2) کلید QUIC/دانه kcp/نام‌خدمات gRPC</string> <string name="server_lab_path">مسیر (مسیر ws/ مسیر h2) کلید QUIC/دانه kcp/نام‌خدمات gRPC</string>
<string name="server_lab_stream_security">tls</string> <string name="server_lab_stream_security">TLS</string>
<string name="server_lab_stream_fingerprint" translatable="false">uTLS</string>
<string name="server_lab_stream_alpn" translatable="false">alpn</string>
<string name="server_lab_allow_insecure">allowInsecure</string> <string name="server_lab_allow_insecure">allowInsecure</string>
<string name="server_lab_sni">SNI</string> <string name="server_lab_sni">SNI</string>
<string name="server_lab_address3">نشانی</string> <string name="server_lab_address3">نشانی</string>
@@ -167,6 +165,7 @@
<string name="logcat_clear">پاک کردن</string> <string name="logcat_clear">پاک کردن</string>
<string name="title_service_restart">راه‌اندازی مجدد خدمات</string> <string name="title_service_restart">راه‌اندازی مجدد خدمات</string>
<string name="title_del_all_config">حذف تمام پیکربندی</string> <string name="title_del_all_config">حذف تمام پیکربندی</string>
<string name="title_del_duplicate_config">Delete duplicate config</string>
<string name="title_del_invalid_config">تنظیمات نامعتبر را حذف کنید (ابتدا آزمایش کنید)</string> <string name="title_del_invalid_config">تنظیمات نامعتبر را حذف کنید (ابتدا آزمایش کنید)</string>
<string name="title_export_all">خروجی گرفتن پیکربندی‌های غیرسفارشی در کلیپ‌بورد</string> <string name="title_export_all">خروجی گرفتن پیکربندی‌های غیرسفارشی در کلیپ‌بورد</string>
<string name="title_sub_setting">تنظیمات گروه‌ی اشتراک</string> <string name="title_sub_setting">تنظیمات گروه‌ی اشتراک</string>
@@ -180,6 +179,7 @@
<string name="title_sort_by_test_results">مرتب‌سازی بر اساس نتایج آزمایش</string> <string name="title_sort_by_test_results">مرتب‌سازی بر اساس نتایج آزمایش</string>
<string name="title_filter_config">فیلتر پرونده پیکربندی</string> <string name="title_filter_config">فیلتر پرونده پیکربندی</string>
<string name="filter_config_all">همه گروه‌های اشتراک</string> <string name="filter_config_all">همه گروه‌های اشتراک</string>
<string name="title_del_duplicate_config_count">Delete %d duplicate configurations</string>
<string name="tasker_start_service">شروع خدمات</string> <string name="tasker_start_service">شروع خدمات</string>
<string name="tasker_setting_confirm">تایید</string> <string name="tasker_setting_confirm">تایید</string>
@@ -49,8 +49,6 @@
<string name="server_lab_request_host">Запрос узла (WS/H2) / Шифрование QUIC</string> <string name="server_lab_request_host">Запрос узла (WS/H2) / Шифрование QUIC</string>
<string name="server_lab_path">Путь (WS/H2) / Ключ QUIC / Сид KCP / Сервис gRPC</string> <string name="server_lab_path">Путь (WS/H2) / Ключ QUIC / Сид KCP / Сервис gRPC</string>
<string name="server_lab_stream_security">TLS</string> <string name="server_lab_stream_security">TLS</string>
<string name="server_lab_stream_fingerprint">uTLS</string>
<string name="server_lab_stream_alpn" translatable="false">alpn</string>
<string name="server_lab_allow_insecure">Разрешать небезопасные</string> <string name="server_lab_allow_insecure">Разрешать небезопасные</string>
<string name="server_lab_sni">SNI</string> <string name="server_lab_sni">SNI</string>
<string name="server_lab_address3">Адрес</string> <string name="server_lab_address3">Адрес</string>
@@ -167,6 +165,7 @@
<string name="logcat_clear">Очистить</string> <string name="logcat_clear">Очистить</string>
<string name="title_service_restart">Перезапуск службы</string> <string name="title_service_restart">Перезапуск службы</string>
<string name="title_del_all_config">Удалить все профили</string> <string name="title_del_all_config">Удалить все профили</string>
<string name="title_del_duplicate_config">Delete duplicate config</string>
<string name="title_del_invalid_config">Удалить сбойные профили (после проверки)</string> <string name="title_del_invalid_config">Удалить сбойные профили (после проверки)</string>
<string name="title_export_all">Экспорт всех профилей в буфер обмена</string> <string name="title_export_all">Экспорт всех профилей в буфер обмена</string>
<string name="title_sub_setting">Группы</string> <string name="title_sub_setting">Группы</string>
@@ -180,6 +179,7 @@
<string name="title_sort_by_test_results">Сортировка по результатам теста</string> <string name="title_sort_by_test_results">Сортировка по результатам теста</string>
<string name="title_filter_config">Фильтр профилей</string> <string name="title_filter_config">Фильтр профилей</string>
<string name="filter_config_all">Все группы</string> <string name="filter_config_all">Все группы</string>
<string name="title_del_duplicate_config_count">Delete %d duplicate configurations</string>
<string name="tasker_start_service">Запуск службы</string> <string name="tasker_start_service">Запуск службы</string>
<string name="tasker_setting_confirm">Подтвердить</string> <string name="tasker_setting_confirm">Подтвердить</string>
@@ -94,10 +94,10 @@
<string name="title_advanced">Cài đặt nâng cao</string> <string name="title_advanced">Cài đặt nâng cao</string>
<string name="title_vpn_settings">Cài đặt VPN</string> <string name="title_vpn_settings">Cài đặt VPN</string>
<string name="title_pref_per_app_proxy">Proxy ứng dụng</string> <string name="title_pref_per_app_proxy">Proxy ứng dụng</string>
<string name="summary_pref_per_app_proxy">Chung: Ứng dụng đã chọn sẽ kết nối Proxy, chưa lựa chọn sẽ kết nối trực tiếp; \nBỏ qua kết nối: Ứng dụng được chọn sẽ trực tiếp kết nối, không lựa chọn sẽ kết nối qua Proxy. \nLựa chọn để tự động chọn ứng dụng Proxy trong Menu.</string> <string name="summary_pref_per_app_proxy">- Chung: Ứng dụng đã chọn sẽ kết nối Proxy, chưa lựa chọn sẽ kết nối trực tiếp. \n- Bỏ qua kết nối: Ứng dụng được chọn sẽ trực tiếp kết nối, không lựa chọn sẽ kết nối qua Proxy. \n- Lựa chọn để tự động chọn ứng dụng Proxy trong Menu.</string>
<string name="title_pref_mux_enabled">Cho phép Mux</string> <string name="title_pref_mux_enabled">Cho phép Mux</string>
<string name="summary_pref_mux_enabled">Bật lên có thể làm tăng tốc độ mạng và chuyển mạng nhanh hơn!</string> <string name="summary_pref_mux_enabled">Bật lên có thể làm tăng tốc độ mạng và chuyển mạng nhanh hơn.</string>
<string name="title_pref_speed_enabled">Cho phép hiển thị tốc độ mạng</string> <string name="title_pref_speed_enabled">Cho phép hiển thị tốc độ mạng</string>
<string name="summary_pref_speed_enabled">Hiển thị tốc độ mạng hiện tại trên thanh thông báo.\nBiểu tượng trên thanh trạng thái có thể thay đổi tùy vào mức sử dụng.</string> <string name="summary_pref_speed_enabled">Hiển thị tốc độ mạng hiện tại trên thanh thông báo.\nBiểu tượng trên thanh trạng thái có thể thay đổi tùy vào mức sử dụng.</string>
@@ -129,10 +129,10 @@
<string name="title_pref_proxy_sharing_enabled">Cho phép kết nối từ mạng LAN</string> <string name="title_pref_proxy_sharing_enabled">Cho phép kết nối từ mạng LAN</string>
<string name="summary_pref_proxy_sharing_enabled">Các thiết bị khác có thể kết nối đến Proxy bởi địa chỉ IP thông qua Socks/HTTP, chỉ bật khi bạn tin tưởng kết nối đó.</string> <string name="summary_pref_proxy_sharing_enabled">Các thiết bị khác có thể kết nối đến Proxy bởi địa chỉ IP thông qua Socks/HTTP, chỉ bật khi bạn tin tưởng kết nối đó.</string>
<string name="toast_warning_pref_proxysharing_short">Cho phép kết nối từ mạng LAN, Đảm bảo rằng bạn tin tưởng kết nối hiện tại.</string> <string name="toast_warning_pref_proxysharing_short">Cho phép kết nối từ mạng LAN, đảm bảo rằng bạn tin tưởng kết nối hiện tại!</string>
<string name="title_pref_allow_insecure">Cho phép đặt lại Bỏ qua xác minh chứng chỉ</string> <string name="title_pref_allow_insecure">Cho phép đặt lại Bỏ qua xác minh chứng chỉ</string>
<string name="summary_pref_allow_insecure">Khi kết nối TLS, đặt cài đặt Bỏ qua xác minh chứng chỉ thành mặc định</string> <string name="summary_pref_allow_insecure">Khi kết nối TLS, đặt cài đặt Bỏ qua xác minh chứng chỉ thành mặc định.</string>
<string name="title_pref_socks_port">Cổng Proxy SOCKS5</string> <string name="title_pref_socks_port">Cổng Proxy SOCKS5</string>
<string name="summary_pref_socks_port">Cổng Proxy SOCKS5</string> <string name="summary_pref_socks_port">Cổng Proxy SOCKS5</string>
@@ -144,7 +144,7 @@
<string name="summary_pref_local_dns_port">Cổng DNS cục bộ</string> <string name="summary_pref_local_dns_port">Cổng DNS cục bộ</string>
<string name="title_pref_confirm_remove">Hiển thị thông báo xác nhận xoá cấu hình</string> <string name="title_pref_confirm_remove">Hiển thị thông báo xác nhận xoá cấu hình</string>
<string name="summary_pref_confirm_remove">Hiển thị thông báo xác nhận xoá cấu hình khi bạn xoá một cấu hình!</string> <string name="summary_pref_confirm_remove">Hiển thị thông báo xác nhận xoá cấu hình khi bạn xoá một cấu hình.</string>
<string name="title_pref_feedback">Phản hồi lỗi</string> <string name="title_pref_feedback">Phản hồi lỗi</string>
<string name="summary_pref_feedback">Phản hồi cải tiến hoặc lỗi lên GitHub</string> <string name="summary_pref_feedback">Phản hồi cải tiến hoặc lỗi lên GitHub</string>
@@ -164,6 +164,7 @@
<string name="logcat_clear">Xoá nhật ký</string> <string name="logcat_clear">Xoá nhật ký</string>
<string name="title_service_restart">Kết nối lại v2rayNG</string> <string name="title_service_restart">Kết nối lại v2rayNG</string>
<string name="title_del_all_config">Xoá tất cả cấu hình</string> <string name="title_del_all_config">Xoá tất cả cấu hình</string>
<string name="title_del_duplicate_config">Delete duplicate config</string>
<string name="title_del_invalid_config">Xoá cấu hình lỗi (Kiểm tra trước)</string> <string name="title_del_invalid_config">Xoá cấu hình lỗi (Kiểm tra trước)</string>
<string name="title_export_all">Xuất và sao chép tất cả cấu hình</string> <string name="title_export_all">Xuất và sao chép tất cả cấu hình</string>
<string name="title_sub_setting">Các gói đăng ký</string> <string name="title_sub_setting">Các gói đăng ký</string>
@@ -177,6 +178,7 @@
<string name="title_sort_by_test_results">Sắp xếp lại theo lần kiểm tra cuối cùng</string> <string name="title_sort_by_test_results">Sắp xếp lại theo lần kiểm tra cuối cùng</string>
<string name="title_filter_config">Lọc cấu hình theo các gói đăng ký</string> <string name="title_filter_config">Lọc cấu hình theo các gói đăng ký</string>
<string name="filter_config_all">Hiển thị tất cả các gói đăng ký</string> <string name="filter_config_all">Hiển thị tất cả các gói đăng ký</string>
<string name="title_del_duplicate_config_count">Delete %d duplicate configurations</string>
<string name="tasker_start_service">Bắt đầu v2rayNG</string> <string name="tasker_start_service">Bắt đầu v2rayNG</string>
<string name="tasker_setting_confirm">Xác nhận</string> <string name="tasker_setting_confirm">Xác nhận</string>
@@ -191,12 +193,12 @@
<string name="connection_test_pending">Kiểm tra kết nối</string> <string name="connection_test_pending">Kiểm tra kết nối</string>
<string name="connection_test_testing">Đang kiểm tra kết nối mạng...</string> <string name="connection_test_testing">Đang kiểm tra kết nối mạng...</string>
<string name="connection_test_available">kiểm tra kết nối mạng thành công! Ping hiện tại là %d</string> <string name="connection_test_available">Kiểm tra kết nối mạng thành công! Ping hiện tại là %d</string>
<string name="connection_test_error">Lỗi kết nối mạng, hãy thử đổi cấu hình hoặc kiểm tra lại! Mã lỗi: %s</string> <string name="connection_test_error">Lỗi kết nối mạng, hãy thử đổi cấu hình hoặc kiểm tra lại! Mã lỗi: %s</string>
<string name="connection_test_fail">Không có kết nối mạng!</string> <string name="connection_test_fail">Không có kết nối mạng!</string>
<string name="connection_test_error_status_code">Mã lỗi: #%d</string> <string name="connection_test_error_status_code">Mã lỗi: #%d</string>
<string name="connection_connected">Đã kết nối, hãy nhấn vào đây để kiểm tra kết nối mạng!</string> <string name="connection_connected">Đã kết nối, hãy nhấn vào đây để kiểm tra kết nối mạng!</string>
<string name="connection_not_connected">Chưa kết nối, hãy thêm một cấu hình để kết nối!</string> <string name="connection_not_connected">Chưa kết nối, hãy chọn một cấu hình để kết nối!</string>
<string-array name="share_method"> <string-array name="share_method">
<item>Xuất ra mã QR (Chụp màn hình để lưu)</item> <item>Xuất ra mã QR (Chụp màn hình để lưu)</item>
@@ -44,10 +44,10 @@
<string name="server_lab_network">传输协议(network)</string> <string name="server_lab_network">传输协议(network)</string>
<string name="server_lab_more_function">底层传输方式(transport)</string> <string name="server_lab_more_function">底层传输方式(transport)</string>
<string name="server_lab_head_type">伪装类型(type)</string> <string name="server_lab_head_type">伪装类型(type)</string>
<string name="server_lab_mode_type">gRPC 传输模式 (mode)</string> <string name="server_lab_mode_type">gRPC 传输模式(mode)</string>
<string name="server_lab_request_host">伪装域名(host)(host/ws host/h2 host)/QUIC 加密方式</string> <string name="server_lab_request_host">伪装域名(host)(host/ws host/h2 host)/QUIC 加密方式</string>
<string name="server_lab_path">path(ws path/h2 path)/QUIC 加密密钥/kcp seed/gRPC serviceName</string> <string name="server_lab_path">path(ws path/h2 path)/QUIC 加密密钥/kcp seed/gRPC serviceName</string>
<string name="server_lab_stream_security">传输层安全(tls)</string> <string name="server_lab_stream_security">传输层安全(TLS)</string>
<string name="server_lab_allow_insecure">跳过证书验证(allowInsecure)</string> <string name="server_lab_allow_insecure">跳过证书验证(allowInsecure)</string>
<string name="server_lab_sni">SNI</string> <string name="server_lab_sni">SNI</string>
<string name="server_lab_address3">服务器地址</string> <string name="server_lab_address3">服务器地址</string>
@@ -56,7 +56,7 @@
<string name="server_lab_security3">加密方式</string> <string name="server_lab_security3">加密方式</string>
<string name="server_lab_id4">密码(可选)</string> <string name="server_lab_id4">密码(可选)</string>
<string name="server_lab_security4">用户名(可选)</string> <string name="server_lab_security4">用户名(可选)</string>
<string name="server_lab_encryption">加密(encryption)</string> <string name="server_lab_encryption">加密方式(encryption)</string>
<string name="server_lab_flow">流控(flow)</string> <string name="server_lab_flow">流控(flow)</string>
<string name="toast_success">成功</string> <string name="toast_success">成功</string>
<string name="toast_failure">失败</string> <string name="toast_failure">失败</string>
@@ -164,6 +164,7 @@
<string name="logcat_clear">清除</string> <string name="logcat_clear">清除</string>
<string name="title_service_restart">服务重启</string> <string name="title_service_restart">服务重启</string>
<string name="title_del_all_config">删除全部配置</string> <string name="title_del_all_config">删除全部配置</string>
<string name="title_del_duplicate_config">删除重复配置</string>
<string name="title_del_invalid_config">删除无效配置(先测试)</string> <string name="title_del_invalid_config">删除无效配置(先测试)</string>
<string name="title_export_all">导出全部(非自定义)配置至剪贴板</string> <string name="title_export_all">导出全部(非自定义)配置至剪贴板</string>
<string name="title_sub_setting">订阅分组设置</string> <string name="title_sub_setting">订阅分组设置</string>
@@ -177,6 +178,7 @@
<string name="title_sort_by_test_results">按测试结果排序</string> <string name="title_sort_by_test_results">按测试结果排序</string>
<string name="title_filter_config">过滤配置文件</string> <string name="title_filter_config">过滤配置文件</string>
<string name="filter_config_all">所有订阅分组</string> <string name="filter_config_all">所有订阅分组</string>
<string name="title_del_duplicate_config_count">删除 %d 个重复配置</string>
<string name="tasker_start_service">启动服务</string> <string name="tasker_start_service">启动服务</string>
<string name="tasker_setting_confirm">确定</string> <string name="tasker_setting_confirm">确定</string>
@@ -47,7 +47,7 @@
<string name="server_lab_mode_type">gRPC 傳輸模式 (mode)</string> <string name="server_lab_mode_type">gRPC 傳輸模式 (mode)</string>
<string name="server_lab_request_host">要求主機 (host)(host/ws host/h2 host)/QUIC 加密方式</string> <string name="server_lab_request_host">要求主機 (host)(host/ws host/h2 host)/QUIC 加密方式</string>
<string name="server_lab_path">path(ws path/h2 path)/QUIC 加密金鑰/kcp seed/gRPC serviceName</string> <string name="server_lab_path">path(ws path/h2 path)/QUIC 加密金鑰/kcp seed/gRPC serviceName</string>
<string name="server_lab_stream_security">傳輸層安全 (tls)</string> <string name="server_lab_stream_security">傳輸層安全 (TLS)</string>
<string name="server_lab_allow_insecure">跳過憑證驗證 (allowInsecure)</string> <string name="server_lab_allow_insecure">跳過憑證驗證 (allowInsecure)</string>
<string name="server_lab_sni">SNI</string> <string name="server_lab_sni">SNI</string>
<string name="server_lab_address3">伺服器位址</string> <string name="server_lab_address3">伺服器位址</string>
@@ -164,6 +164,7 @@
<string name="logcat_clear">清除</string> <string name="logcat_clear">清除</string>
<string name="title_service_restart">服務重啟</string> <string name="title_service_restart">服務重啟</string>
<string name="title_del_all_config">刪除全部組態</string> <string name="title_del_all_config">刪除全部組態</string>
<string name="title_del_duplicate_config">刪除重複組態</string>
<string name="title_del_invalid_config">刪除無效組態 (先偵測)</string> <string name="title_del_invalid_config">刪除無效組態 (先偵測)</string>
<string name="title_export_all">匯出全部 (非自訂) 組態至剪貼簿</string> <string name="title_export_all">匯出全部 (非自訂) 組態至剪貼簿</string>
<string name="title_sub_setting">訂閱分組設定</string> <string name="title_sub_setting">訂閱分組設定</string>
@@ -177,6 +178,7 @@
<string name="title_sort_by_test_results">依偵測結果排序</string> <string name="title_sort_by_test_results">依偵測結果排序</string>
<string name="title_filter_config">過濾組態</string> <string name="title_filter_config">過濾組態</string>
<string name="filter_config_all">所有訂閱分組</string> <string name="filter_config_all">所有訂閱分組</string>
<string name="title_del_duplicate_config_count">Delete %d duplicate configurations</string>
<string name="tasker_start_service">啟動服務</string> <string name="tasker_start_service">啟動服務</string>
<string name="tasker_setting_confirm">確定</string> <string name="tasker_setting_confirm">確定</string>
+7 -7
View File
@@ -57,7 +57,7 @@
<string-array name="streamsecurityxs" translatable="false"> <string-array name="streamsecurityxs" translatable="false">
<item></item> <item></item>
<item>tls</item> <item>tls</item>
<item>xtls</item> <item>reality</item>
</string-array> </string-array>
<string-array name="streamsecurity_utls" translatable="false"> <string-array name="streamsecurity_utls" translatable="false">
@@ -65,6 +65,12 @@
<item>chrome</item> <item>chrome</item>
<item>firefox</item> <item>firefox</item>
<item>safari</item> <item>safari</item>
<item>ios</item>
<item>android</item>
<item>edge</item>
<item>360</item>
<item>qq</item>
<item>random</item>
<item>randomized</item> <item>randomized</item>
</string-array> </string-array>
@@ -110,12 +116,6 @@
<string-array name="flows" translatable="false"> <string-array name="flows" translatable="false">
<item></item> <item></item>
<item>xtls-rprx-origin</item>
<item>xtls-rprx-origin-udp443</item>
<item>xtls-rprx-direct</item>
<item>xtls-rprx-direct-udp443</item>
<item>xtls-rprx-splice</item>
<item>xtls-rprx-splice-udp443</item>
<item>xtls-rprx-vision</item> <item>xtls-rprx-vision</item>
<item>xtls-rprx-vision-udp443</item> <item>xtls-rprx-vision-udp443</item>
</string-array> </string-array>
+9 -4
View File
@@ -30,7 +30,7 @@
<string name="menu_item_import_config_manually_ss">Type manually[Shadowsocks]</string> <string name="menu_item_import_config_manually_ss">Type manually[Shadowsocks]</string>
<string name="menu_item_import_config_manually_socks">Type manually[Socks]</string> <string name="menu_item_import_config_manually_socks">Type manually[Socks]</string>
<string name="menu_item_import_config_manually_trojan">Type manually[Trojan]</string> <string name="menu_item_import_config_manually_trojan">Type manually[Trojan]</string>
<string name="menu_item_import_config_custom">custom config</string> <string name="menu_item_import_config_custom">Custom config</string>
<string name="menu_item_import_config_custom_clipboard">Import custom config from Clipboard</string> <string name="menu_item_import_config_custom_clipboard">Import custom config from Clipboard</string>
<string name="menu_item_import_config_custom_local">Import custom config from locally</string> <string name="menu_item_import_config_custom_local">Import custom config from locally</string>
<string name="menu_item_import_config_custom_url">Import custom config from URL</string> <string name="menu_item_import_config_custom_url">Import custom config from URL</string>
@@ -48,9 +48,9 @@
<string name="server_lab_mode_type">gRPC mode</string> <string name="server_lab_mode_type">gRPC mode</string>
<string name="server_lab_request_host">request host(host/ws host/h2 host)/QUIC security</string> <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_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_security">TLS</string>
<string name="server_lab_stream_fingerprint" translatable="false">uTLS</string> <string name="server_lab_stream_fingerprint" translatable="false">Fingerprint</string>
<string name="server_lab_stream_alpn" translatable="false">alpn</string> <string name="server_lab_stream_alpn" translatable="false">Alpn</string>
<string name="server_lab_allow_insecure">allowInsecure</string> <string name="server_lab_allow_insecure">allowInsecure</string>
<string name="server_lab_sni">SNI</string> <string name="server_lab_sni">SNI</string>
<string name="server_lab_address3">address</string> <string name="server_lab_address3">address</string>
@@ -61,6 +61,9 @@
<string name="server_lab_security4">User(Optional)</string> <string name="server_lab_security4">User(Optional)</string>
<string name="server_lab_encryption">encryption</string> <string name="server_lab_encryption">encryption</string>
<string name="server_lab_flow">flow</string> <string name="server_lab_flow">flow</string>
<string name="server_lab_public_key" translatable="false">PublicKey</string>
<string name="server_lab_short_id" translatable="false">ShortId</string>
<string name="server_lab_spider_x" translatable="false">SpiderX</string>
<string name="toast_success">Success</string> <string name="toast_success">Success</string>
<string name="toast_failure">Failure</string> <string name="toast_failure">Failure</string>
<string name="toast_none_data">There is nothing</string> <string name="toast_none_data">There is nothing</string>
@@ -169,6 +172,7 @@
<string name="logcat_clear">Clear</string> <string name="logcat_clear">Clear</string>
<string name="title_service_restart">Service restart</string> <string name="title_service_restart">Service restart</string>
<string name="title_del_all_config">Delete all config</string> <string name="title_del_all_config">Delete all config</string>
<string name="title_del_duplicate_config">Delete duplicate config</string>
<string name="title_del_invalid_config">Delete invalid config(Test first)</string> <string name="title_del_invalid_config">Delete invalid config(Test first)</string>
<string name="title_export_all">Export non-custom configs to clipboard</string> <string name="title_export_all">Export non-custom configs to clipboard</string>
<string name="title_sub_setting">Subscription group setting</string> <string name="title_sub_setting">Subscription group setting</string>
@@ -182,6 +186,7 @@
<string name="title_sort_by_test_results">Sorting by test results</string> <string name="title_sort_by_test_results">Sorting by test results</string>
<string name="title_filter_config">Filter configuration file</string> <string name="title_filter_config">Filter configuration file</string>
<string name="filter_config_all">All subscription groups</string> <string name="filter_config_all">All subscription groups</string>
<string name="title_del_duplicate_config_count">Delete %d duplicate configurations</string>
<string name="tasker_start_service">Start Service</string> <string name="tasker_start_service">Start Service</string>
<string name="tasker_setting_confirm">Confirm</string> <string name="tasker_setting_confirm">Confirm</string>
+5 -30
View File
@@ -1,31 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
buildscript { id 'com.android.application' version '7.4.2' apply false
repositories { id 'com.android.library' version '7.4.2' apply false
google() id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
mavenCentral() }
maven { url 'https://maven.google.com' }
maven { url 'https://jitpack.io' }
}
dependencies {
classpath 'com.android.tools.build:gradle:7.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://maven.google.com' }
maven { url 'https://jitpack.io' }
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
+7 -19
View File
@@ -1,22 +1,10 @@
## Project-wide Gradle settings.
# buildToolsVer=33.0.2
# For more details on how to configure your build environment visit compileSdkVer=33
# http://www.gradle.org/docs/current/userguide/build_environment.html targetSdkVer=33
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx1024m -XX:MaxPermSize=256m
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Fri Jun 02 14:08:42 CST 2017
kotlinVersion=1.6.21
buildToolsVer=31.0.0
compileSdkVer=31
targetSdkVer=31
kotlin.incremental=true kotlin.incremental=true
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
kotlin.code.style=official
android.nonTransitiveRClass=true
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+1 -1
View File
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
+16
View File
@@ -1 +1,17 @@
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
jcenter()
}
}
rootProject.name = "V2rayNG"
include ':app' include ':app'