Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
337889c5f1 | ||
|
|
244d2d3866 | ||
|
|
c0fed0ba4f | ||
|
|
affb107b9d | ||
|
|
f96073af99 | ||
|
|
496a0483d2 | ||
|
|
e11dca00bb | ||
|
|
fde39bf34e | ||
|
|
4f11bae238 | ||
|
|
f6282ba71f | ||
|
|
3edf1f4e1b | ||
|
|
41bc064083 | ||
|
|
eb8562e6b0 | ||
|
|
68fbdd92c3 | ||
|
|
02038a5d93 | ||
|
|
4fb8c2f4b2 | ||
|
|
7afffa60c3 | ||
|
|
0e6c860360 | ||
|
|
ebfbbfa08b | ||
|
|
b5f182dfec | ||
|
|
4cf28d0ad0 | ||
|
|
149bb049a5 | ||
|
|
124702f0a2 | ||
|
|
c1cebe578b | ||
|
|
e46c1ee849 | ||
|
|
70f1743114 | ||
|
|
54d520727e | ||
|
|
1f1e4db486 | ||
|
|
e536236634 | ||
|
|
140c236da5 | ||
|
|
69ede34274 | ||
|
|
fcf6e22132 | ||
|
|
7438ee8308 | ||
|
|
f01cf7fcb5 | ||
|
|
7a852f78e4 | ||
|
|
0923659a49 | ||
|
|
f9feb08607 | ||
|
|
3b43fe39e5 | ||
|
|
de30fa15b3 | ||
|
|
25a4d7c14d | ||
|
|
c8d3607efe | ||
|
|
a0e73a9aa9 | ||
|
|
eaccf237a4 | ||
|
|
5124266346 | ||
|
|
5cf2ea5a1e | ||
|
|
7a1af5914e | ||
|
|
e61f5eeb76 | ||
|
|
6d92106f9d | ||
|
|
8b06745e86 | ||
|
|
85ad999975 | ||
|
|
4c0f2d84cc | ||
|
|
6fc9803431 | ||
|
|
59a710bae5 | ||
|
|
98c642e1a8 | ||
|
|
e91f4470fb | ||
|
|
b33cc5284f |
136
.github/workflows/build.yml
vendored
136
.github/workflows/build.yml
vendored
@@ -1,13 +1,14 @@
|
||||
name: Build APK
|
||||
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
XRAY_CORE_VERSION:
|
||||
description: 'Xray core version or commit hash'
|
||||
release_tag:
|
||||
required: false
|
||||
|
||||
type: string
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -17,77 +18,124 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Prepare build dir
|
||||
run: |
|
||||
mkdir ${{ github.workspace }}/build
|
||||
|
||||
- name: Fetch AndroidLibV2rayLite
|
||||
run: |
|
||||
cd ${{ github.workspace }}/build
|
||||
git clone --depth=1 -b master https://github.com/2dust/AndroidLibV2rayLite.git
|
||||
cd AndroidLibV2rayLite
|
||||
git submodule update --init
|
||||
|
||||
- name: Restore cached libtun2socks
|
||||
id: cache-libtun2socks-restore
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/build/AndroidLibV2rayLite/libs
|
||||
key: libtun2socks-${{ runner.os }}-${{ hashFiles('build/AndroidLibV2rayLite/.git/refs/heads/master') }}-${{ hashFiles('build/AndroidLibV2rayLite/.git/modules/badvpn/HEAD') }}-${{ hashFiles('build/AndroidLibV2rayLite/.git/modules/libancillary/HEAD') }}
|
||||
|
||||
- name: Setup Android NDK
|
||||
if: steps.cache-libtun2socks-restore.outputs.cache-hit != 'true'
|
||||
uses: nttld/setup-ndk@v1
|
||||
id: setup-ndk
|
||||
# Same version as https://gitlab.com/fdroid/fdroiddata/metadata/com.v2ray.ang.yml
|
||||
with:
|
||||
ndk-version: r27
|
||||
add-to-path: true
|
||||
link-to-sdk: true
|
||||
local-cache: true
|
||||
|
||||
- name: Restore Android Symlinks
|
||||
if: steps.cache-libtun2socks-restore.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
directory="${{ steps.setup-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin"
|
||||
find "$directory" -type l | while read link; do
|
||||
current_target=$(readlink "$link")
|
||||
new_target="$directory/$(basename "$current_target")"
|
||||
ln -sf "$new_target" "$link"
|
||||
echo "Changed $(basename "$link") from $current_target to $new_target"
|
||||
done
|
||||
|
||||
- name: Build libtun2socks
|
||||
if: steps.cache-libtun2socks-restore.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd ${{ github.workspace }}/build/AndroidLibV2rayLite
|
||||
bash compile-tun2socks.sh
|
||||
tar -xvzf libtun2socks.so.tgz
|
||||
cp -r libs/* ${{ github.workspace }}/V2rayNG/app/libs/
|
||||
env:
|
||||
NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
|
||||
- name: Save libtun2socks
|
||||
if: steps.cache-libtun2socks-restore.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/build/AndroidLibV2rayLite/libs
|
||||
key: libtun2socks-${{ runner.os }}-${{ hashFiles('build/AndroidLibV2rayLite/.git/refs/heads/master') }}-${{ hashFiles('build/AndroidLibV2rayLite/.git/modules/badvpn/HEAD') }}-${{ hashFiles('build/AndroidLibV2rayLite/.git/modules/libancillary/HEAD') }}
|
||||
|
||||
- name: Copy libtun2socks
|
||||
run: |
|
||||
cp -r ${{ github.workspace }}/build/AndroidLibV2rayLite/libs/* ${{ github.workspace }}/V2rayNG/app/libs/
|
||||
|
||||
- name: Download libv2ray
|
||||
uses: robinraju/release-downloader@v1
|
||||
with:
|
||||
repository: '2dust/AndroidLibXrayLite'
|
||||
latest: true
|
||||
fileName: 'libv2ray.aar'
|
||||
out-file-path: V2rayNG/app/libs/
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '21'
|
||||
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23.2'
|
||||
cache: false
|
||||
|
||||
- name: Patch Go use 600296
|
||||
#https://go-review.googlesource.com/c/go/+/600296
|
||||
run: |
|
||||
cd "$(go env GOROOT)"
|
||||
curl "https://go-review.googlesource.com/changes/go~600296/revisions/5/patch" | base64 -d | patch --verbose -p 1
|
||||
|
||||
- name: Install gomobile
|
||||
run: |
|
||||
go install golang.org/x/mobile/cmd/gomobile@v0.0.0-20240806205939-81131f6468ab
|
||||
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Setup Android environment
|
||||
uses: android-actions/setup-android@v3
|
||||
|
||||
- name: Build dependencies
|
||||
run: |
|
||||
mkdir ${{ github.workspace }}/build
|
||||
cd ${{ github.workspace }}/build
|
||||
git clone --depth=1 -b main https://github.com/2dust/AndroidLibXrayLite.git
|
||||
cd AndroidLibXrayLite
|
||||
go get github.com/xtls/xray-core@${{ github.event.inputs.XRAY_CORE_VERSION }} || true
|
||||
gomobile init
|
||||
go mod tidy -v
|
||||
gomobile bind -v -androidapi 21 -ldflags='-s -w' ./
|
||||
cp *.aar ${{ github.workspace }}/V2rayNG/app/libs/
|
||||
- name: Decode Keystore
|
||||
uses: timheuer/base64-to-file@v1
|
||||
id: android_keystore
|
||||
with:
|
||||
fileName: "android_keystore.jks"
|
||||
encodedString: ${{ secrets.APP_KEYSTORE_BASE64 }}
|
||||
|
||||
- name: Build APK
|
||||
run: |
|
||||
cd ${{ github.workspace }}/V2rayNG
|
||||
chmod 755 gradlew
|
||||
./gradlew assembleDebug
|
||||
./gradlew licenseFdroidReleaseReport
|
||||
./gradlew assembleRelease -Pandroid.injected.signing.store.file=${{ steps.android_keystore.outputs.filePath }} -Pandroid.injected.signing.store.password=${{ secrets.APP_KEYSTORE_PASSWORD }} -Pandroid.injected.signing.key.alias=${{ secrets.APP_KEYSTORE_ALIAS }} -Pandroid.injected.signing.key.password=${{ secrets.APP_KEY_PASSWORD }}
|
||||
|
||||
- name: Upload arm64-v8a APK
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
name: arm64-v8a
|
||||
path: ${{ github.workspace }}/V2rayNG/app/build/outputs/apk/debug/*arm64-v8a*.apk
|
||||
path: ${{ github.workspace }}/V2rayNG/app/build/outputs/apk/*/release/*arm64-v8a*.apk
|
||||
|
||||
- name: Upload armeabi-v7a APK
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
name: armeabi-v7a
|
||||
path: ${{ github.workspace }}/V2rayNG/app/build/outputs/apk/debug/*armeabi-v7a*.apk
|
||||
path: ${{ github.workspace }}/V2rayNG/app/build/outputs/apk/*/release/*armeabi-v7a*.apk
|
||||
|
||||
- name: Upload x86 APK
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
name: x86-apk
|
||||
path: ${{ github.workspace }}/V2rayNG/app/build/outputs/apk/debug/*x86*.apk
|
||||
path: ${{ github.workspace }}/V2rayNG/app/build/outputs/apk/*/release/*x86*.apk
|
||||
|
||||
- name: Upload Other APKs
|
||||
uses: actions/upload-artifact@v4
|
||||
- name: Upload to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
if: github.event.inputs.release_tag != ''
|
||||
with:
|
||||
name: others-apk
|
||||
path: |
|
||||
${{ github.workspace }}/V2rayNG/app/build/outputs/apk/debug
|
||||
!${{ github.workspace }}/V2rayNG/app/build/outputs/apk/debug/*arm64-v8a*.apk
|
||||
!${{ github.workspace }}/V2rayNG/app/build/outputs/apk/debug/*armeabi-v7a*.apk
|
||||
!${{ github.workspace }}/V2rayNG/app/build/outputs/apk/debug/*x86*.apk
|
||||
file: ${{ github.workspace }}/V2rayNG/app/build/outputs/apk/*playstore*/release/*.apk
|
||||
tag: ${{ github.event.inputs.release_tag }}
|
||||
file_glob: true
|
||||
prerelease: true
|
||||
|
||||
16
.github/workflows/fastlane.yml
vendored
Normal file
16
.github/workflows/fastlane.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: Validate Fastlane metadata
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
go:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Validate Fastlane Supply Metadata
|
||||
uses: ashutoshgngwr/validate-fastlane-supply-metadata@v2.0.0
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,3 +3,5 @@
|
||||
V2rayNG/app/release/output.json
|
||||
.idea/
|
||||
.gradle/
|
||||
libtun2socks.so
|
||||
libhysteria2.so
|
||||
@@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
id("com.google.android.gms.oss-licenses-plugin")
|
||||
id("com.jaredsburrows.license")
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -12,20 +12,26 @@ android {
|
||||
applicationId = "com.v2ray.ang"
|
||||
minSdk = 21
|
||||
targetSdk = 35
|
||||
versionCode = 618
|
||||
versionName = "1.9.22"
|
||||
versionCode = 624
|
||||
versionName = "1.9.28"
|
||||
multiDexEnabled = true
|
||||
|
||||
val abiFilterList = (properties["ABI_FILTERS"] as? String)?.split(';')
|
||||
splits {
|
||||
abi {
|
||||
isEnable = true
|
||||
reset()
|
||||
if (abiFilterList != null && abiFilterList.isNotEmpty()) {
|
||||
include(*abiFilterList.toTypedArray())
|
||||
} else {
|
||||
include(
|
||||
"arm64-v8a",
|
||||
"armeabi-v7a",
|
||||
"x86_64",
|
||||
"x86"
|
||||
)
|
||||
isUniversalApk = true
|
||||
}
|
||||
isUniversalApk = abiFilterList.isNullOrEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +48,19 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions.add("distribution")
|
||||
productFlavors {
|
||||
create("fdroid") {
|
||||
dimension = "distribution"
|
||||
applicationIdSuffix = ".fdroid"
|
||||
buildConfigField("String", "DISTRIBUTION", "\"F-Droid\"")
|
||||
}
|
||||
create("playstore") {
|
||||
dimension = "distribution"
|
||||
buildConfigField("String", "DISTRIBUTION", "\"Play Store\"")
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
getByName("main") {
|
||||
jniLibs.srcDirs("libs")
|
||||
@@ -50,15 +69,35 @@ android {
|
||||
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_11.toString()
|
||||
jvmTarget = JavaVersion.VERSION_17.toString()
|
||||
}
|
||||
|
||||
applicationVariants.all {
|
||||
val variant = this
|
||||
val isFdroid = variant.productFlavors.any { it.name == "fdroid" }
|
||||
if (isFdroid) {
|
||||
val versionCodes =
|
||||
mapOf("armeabi-v7a" to 2, "arm64-v8a" to 1, "x86" to 4, "x86_64" to 3, "universal" to 0
|
||||
)
|
||||
|
||||
variant.outputs
|
||||
.map { it as com.android.build.gradle.internal.api.ApkVariantOutputImpl }
|
||||
.forEach { output ->
|
||||
val abi = output.getFilter("ABI") ?: "universal"
|
||||
output.outputFileName = "v2rayNG_${variant.versionName}-fdroid_${abi}.apk"
|
||||
if (versionCodes.containsKey(abi)) {
|
||||
output.versionCodeOverride =
|
||||
(100 * variant.versionCode + versionCodes[abi]!!).plus(5000000)
|
||||
} else {
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val versionCodes =
|
||||
mapOf("armeabi-v7a" to 4, "arm64-v8a" to 4, "x86" to 4, "x86_64" to 4, "universal" to 4)
|
||||
|
||||
@@ -79,6 +118,7 @@ android {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
@@ -125,7 +165,7 @@ dependencies {
|
||||
implementation(libs.language.json)
|
||||
|
||||
// Intent and Utility Libraries
|
||||
implementation(libs.quickie.bundled)
|
||||
implementation(libs.quickie.foss)
|
||||
implementation(libs.core)
|
||||
|
||||
// AndroidX Lifecycle and Architecture Components
|
||||
@@ -146,6 +186,5 @@ dependencies {
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
testImplementation(libs.org.mockito.mockito.inline)
|
||||
testImplementation(libs.mockito.kotlin)
|
||||
// Oss Licenses
|
||||
implementation(libs.play.services.oss.licenses)
|
||||
coreLibraryDesugaring(libs.desugar.jdk.libs)
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1285
V2rayNG/app/src/main/assets/open_source_licenses.html
Normal file
1285
V2rayNG/app/src/main/assets/open_source_licenses.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -45,9 +45,4 @@ class AngApplication : MultiDexApplication() {
|
||||
SettingsManager.initRoutingRulesets(this)
|
||||
}
|
||||
|
||||
fun getPackageInfo(packageName: String) = packageManager.getPackageInfo(
|
||||
packageName, if (Build.VERSION.SDK_INT >= 28) PackageManager.GET_SIGNING_CERTIFICATES
|
||||
else @Suppress("DEPRECATION") PackageManager.GET_SIGNATURES
|
||||
)!!
|
||||
|
||||
}
|
||||
|
||||
@@ -48,9 +48,9 @@ object AppConfig {
|
||||
const val PREF_PROXY_SHARING = "pref_proxy_sharing_enabled"
|
||||
const val PREF_ALLOW_INSECURE = "pref_allow_insecure"
|
||||
const val PREF_SOCKS_PORT = "pref_socks_port"
|
||||
const val PREF_HTTP_PORT = "pref_http_port"
|
||||
const val PREF_REMOTE_DNS = "pref_remote_dns"
|
||||
const val PREF_DOMESTIC_DNS = "pref_domestic_dns"
|
||||
const val PREF_DNS_HOSTS = "pref_dns_hosts"
|
||||
const val PREF_DELAY_TEST_URL = "pref_delay_test_url"
|
||||
const val PREF_LOGLEVEL = "pref_core_loglevel"
|
||||
const val PREF_MODE = "pref_mode"
|
||||
@@ -112,7 +112,6 @@ object AppConfig {
|
||||
/** Ports and addresses for various services. */
|
||||
const val PORT_LOCAL_DNS = "10853"
|
||||
const val PORT_SOCKS = "10808"
|
||||
const val PORT_HTTP = "10809"
|
||||
const val WIREGUARD_LOCAL_ADDRESS_V4 = "172.16.0.2/32"
|
||||
const val WIREGUARD_LOCAL_ADDRESS_V6 = "2606:4700:110:8f81:d551:a0:532e:a2b3/128"
|
||||
const val WIREGUARD_LOCAL_MTU = "1420"
|
||||
|
||||
@@ -5,7 +5,6 @@ enum class NetworkType(val type: String) {
|
||||
KCP("kcp"),
|
||||
WS("ws"),
|
||||
HTTP_UPGRADE("httpupgrade"),
|
||||
SPLIT_HTTP("splithttp"),
|
||||
XHTTP("xhttp"),
|
||||
HTTP("http"),
|
||||
H2("h2"),
|
||||
|
||||
@@ -9,5 +9,5 @@ data class RulesetItem(
|
||||
var network: String? = null,
|
||||
var protocol: List<String>? = null,
|
||||
var enabled: Boolean = true,
|
||||
var looked: Boolean? = false,
|
||||
var locked: Boolean? = false,
|
||||
)
|
||||
@@ -404,7 +404,7 @@ data class V2rayConfig(
|
||||
httpupgradeSettings = httpupgradeSetting
|
||||
}
|
||||
|
||||
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> {
|
||||
NetworkType.XHTTP.type -> {
|
||||
val xhttpSetting = XhttpSettingsBean()
|
||||
xhttpSetting.host = host.orEmpty()
|
||||
sni = host
|
||||
@@ -596,7 +596,7 @@ data class V2rayConfig(
|
||||
)
|
||||
}
|
||||
|
||||
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> {
|
||||
NetworkType.XHTTP.type -> {
|
||||
val xhttpSettings = streamSettings?.xhttpSettings ?: return null
|
||||
listOf(
|
||||
"",
|
||||
|
||||
@@ -95,4 +95,4 @@ inline fun <reified T : Serializable> Intent.serializable(key: String): T? = whe
|
||||
else -> @Suppress("DEPRECATION") getSerializableExtra(key) as? T
|
||||
}
|
||||
|
||||
inline fun CharSequence?.isNotNullEmpty(): Boolean = (this != null && this.isNotEmpty())
|
||||
fun CharSequence?.isNotNullEmpty(): Boolean = (this != null && this.isNotEmpty())
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.v2ray.ang.fmt
|
||||
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.dto.NetworkType
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.extension.isNotNullEmpty
|
||||
@@ -31,8 +32,6 @@ open class FmtBase {
|
||||
|
||||
fun getItemFormQuery(config: ProfileItem, queryParam: Map<String, String>, allowInsecure: Boolean) {
|
||||
config.network = queryParam["type"] ?: NetworkType.TCP.type
|
||||
//TODO
|
||||
if (config.network == NetworkType.SPLIT_HTTP.type) config.network = NetworkType.XHTTP.type
|
||||
config.headerType = queryParam["headerType"]
|
||||
config.host = queryParam["host"]
|
||||
config.path = queryParam["path"]
|
||||
@@ -47,6 +46,9 @@ open class FmtBase {
|
||||
config.xhttpExtra = queryParam["extra"]
|
||||
|
||||
config.security = queryParam["security"]
|
||||
if (config.security != AppConfig.TLS && config.security != AppConfig.REALITY) {
|
||||
config.security = null
|
||||
}
|
||||
config.insecure = if (queryParam["allowInsecure"].isNullOrEmpty()) {
|
||||
allowInsecure
|
||||
} else {
|
||||
@@ -91,7 +93,7 @@ open class FmtBase {
|
||||
config.path.let { if (it.isNotNullEmpty()) dicQuery["path"] = it.orEmpty() }
|
||||
}
|
||||
|
||||
NetworkType.SPLIT_HTTP, NetworkType.XHTTP -> {
|
||||
NetworkType.XHTTP -> {
|
||||
config.host.let { if (it.isNotNullEmpty()) dicQuery["host"] = it.orEmpty() }
|
||||
config.path.let { if (it.isNotNullEmpty()) dicQuery["path"] = it.orEmpty() }
|
||||
config.xhttpMode.let { if (it.isNotNullEmpty()) dicQuery["mode"] = it.orEmpty() }
|
||||
|
||||
@@ -138,11 +138,11 @@ object AngConfigManager {
|
||||
if (sb.count() > 0) {
|
||||
Utils.setClipboard(context, sb.toString())
|
||||
}
|
||||
return sb.lines().count()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,6 +170,13 @@ object AngConfigManager {
|
||||
if (guid == null) return -1
|
||||
val result = V2rayConfigManager.getV2rayConfig(context, guid)
|
||||
if (result.status) {
|
||||
val config = MmkvManager.decodeServerConfig(guid)
|
||||
if (config?.configType == EConfigType.HYSTERIA2) {
|
||||
val socksPort = Utils.findFreePort(listOf(100 + SettingsManager.getSocksPort(), 0))
|
||||
val hy2Config = Hysteria2Fmt.toNativeConfig(config, socksPort)
|
||||
Utils.setClipboard(context, JsonUtil.toJsonPretty(hy2Config) + "\n" + result.content)
|
||||
return 0
|
||||
}
|
||||
Utils.setClipboard(context, result.content)
|
||||
} else {
|
||||
return -1
|
||||
|
||||
@@ -164,18 +164,22 @@ object MmkvManager {
|
||||
}
|
||||
}
|
||||
|
||||
fun removeAllServer() {
|
||||
fun removeAllServer(): Int {
|
||||
val count = profileFullStorage.allKeys()?.count() ?: 0
|
||||
mainStorage.clearAll()
|
||||
profileFullStorage.clearAll()
|
||||
//profileStorage.clearAll()
|
||||
serverAffStorage.clearAll()
|
||||
return count
|
||||
}
|
||||
|
||||
fun removeInvalidServer(guid: String) {
|
||||
fun removeInvalidServer(guid: String): Int {
|
||||
var count = 0
|
||||
if (guid.isNotEmpty()) {
|
||||
decodeServerAffiliationInfo(guid)?.let { aff ->
|
||||
if (aff.testDelayMillis < 0L) {
|
||||
removeServer(guid)
|
||||
count++
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -183,10 +187,12 @@ object MmkvManager {
|
||||
decodeServerAffiliationInfo(key)?.let { aff ->
|
||||
if (aff.testDelayMillis < 0L) {
|
||||
removeServer(key)
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
fun encodeServerRaw(guid: String, config: String) {
|
||||
|
||||
@@ -9,9 +9,11 @@ import com.v2ray.ang.AppConfig.ANG_PACKAGE
|
||||
import com.v2ray.ang.AppConfig.GEOIP_PRIVATE
|
||||
import com.v2ray.ang.AppConfig.GEOSITE_PRIVATE
|
||||
import com.v2ray.ang.AppConfig.TAG_DIRECT
|
||||
import com.v2ray.ang.dto.EConfigType
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.dto.RoutingType
|
||||
import com.v2ray.ang.dto.RulesetItem
|
||||
import com.v2ray.ang.dto.V2rayConfig
|
||||
import com.v2ray.ang.handler.MmkvManager.decodeServerConfig
|
||||
import com.v2ray.ang.handler.MmkvManager.decodeServerList
|
||||
import com.v2ray.ang.util.JsonUtil
|
||||
@@ -70,7 +72,7 @@ object SettingsManager {
|
||||
private fun resetRoutingRulesetsCommon(rulesetList: MutableList<RulesetItem>) {
|
||||
val rulesetNew: MutableList<RulesetItem> = mutableListOf()
|
||||
MmkvManager.decodeRoutingRulesets()?.forEach { key ->
|
||||
if (key.looked == true) {
|
||||
if (key.locked == true) {
|
||||
rulesetNew.add(key)
|
||||
}
|
||||
}
|
||||
@@ -91,8 +93,10 @@ object SettingsManager {
|
||||
fun saveRoutingRuleset(index: Int, ruleset: RulesetItem?) {
|
||||
if (ruleset == null) return
|
||||
|
||||
val rulesetList = MmkvManager.decodeRoutingRulesets()
|
||||
if (rulesetList.isNullOrEmpty()) return
|
||||
var rulesetList = MmkvManager.decodeRoutingRulesets()
|
||||
if (rulesetList.isNullOrEmpty()) {
|
||||
rulesetList = mutableListOf()
|
||||
}
|
||||
|
||||
if (index < 0 || index >= rulesetList.count()) {
|
||||
rulesetList.add(0, ruleset)
|
||||
@@ -113,6 +117,17 @@ object SettingsManager {
|
||||
}
|
||||
|
||||
fun routingRulesetsBypassLan(): Boolean {
|
||||
val guid = MmkvManager.getSelectServer() ?: return false
|
||||
val config = MmkvManager.decodeServerConfig(guid) ?: return false
|
||||
if (config.configType == EConfigType.CUSTOM) {
|
||||
val raw = MmkvManager.decodeServerRaw(guid) ?: return false
|
||||
val v2rayConfig = JsonUtil.fromJson(raw, V2rayConfig::class.java)
|
||||
val exist = v2rayConfig.routing.rules.filter { it.outboundTag == TAG_DIRECT }?.any {
|
||||
it.domain?.contains(GEOSITE_PRIVATE) == true || it.ip?.contains(GEOIP_PRIVATE) == true
|
||||
}
|
||||
return exist == true
|
||||
}
|
||||
|
||||
val rulesetItems = MmkvManager.decodeRoutingRulesets()
|
||||
val exist = rulesetItems?.filter { it.enabled && it.outboundTag == TAG_DIRECT }?.any {
|
||||
it.domain?.contains(GEOSITE_PRIVATE) == true || it.ip?.contains(GEOIP_PRIVATE) == true
|
||||
@@ -155,7 +170,7 @@ object SettingsManager {
|
||||
}
|
||||
|
||||
fun getHttpPort(): Int {
|
||||
return parseInt(MmkvManager.decodeSettingsString(AppConfig.PREF_HTTP_PORT), AppConfig.PORT_HTTP.toInt())
|
||||
return getSocksPort() + (if (Utils.isXray()) 0 else 1)
|
||||
}
|
||||
|
||||
fun initAssets(context: Context, assets: AssetManager) {
|
||||
|
||||
@@ -34,10 +34,12 @@ import com.v2ray.ang.AppConfig.WIREGUARD_LOCAL_ADDRESS_V4
|
||||
import com.v2ray.ang.AppConfig.WIREGUARD_LOCAL_ADDRESS_V6
|
||||
import com.v2ray.ang.dto.ConfigResult
|
||||
import com.v2ray.ang.dto.EConfigType
|
||||
import com.v2ray.ang.dto.NetworkType
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.dto.RulesetItem
|
||||
import com.v2ray.ang.dto.V2rayConfig
|
||||
import com.v2ray.ang.dto.V2rayConfig.RoutingBean.RulesBean
|
||||
import com.v2ray.ang.extension.isNotNullEmpty
|
||||
import com.v2ray.ang.fmt.HttpFmt
|
||||
import com.v2ray.ang.fmt.Hysteria2Fmt
|
||||
import com.v2ray.ang.fmt.ShadowsocksFmt
|
||||
@@ -120,7 +122,6 @@ object V2rayConfigManager {
|
||||
private fun inbounds(v2rayConfig: V2rayConfig): Boolean {
|
||||
try {
|
||||
val socksPort = SettingsManager.getSocksPort()
|
||||
val httpPort = SettingsManager.getHttpPort()
|
||||
|
||||
v2rayConfig.inbounds.forEach { curInbound ->
|
||||
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_PROXY_SHARING) != true) {
|
||||
@@ -142,14 +143,13 @@ object V2rayConfigManager {
|
||||
v2rayConfig.inbounds[0].sniffing?.destOverride?.add("fakedns")
|
||||
}
|
||||
|
||||
if (Utils.isXray()) {
|
||||
v2rayConfig.inbounds.removeAt(1)
|
||||
} else {
|
||||
val httpPort = SettingsManager.getHttpPort()
|
||||
v2rayConfig.inbounds[1].port = httpPort
|
||||
}
|
||||
|
||||
// if (httpPort > 0) {
|
||||
// val httpCopy = v2rayConfig.inbounds[0].copy()
|
||||
// httpCopy.port = httpPort
|
||||
// httpCopy.protocol = "http"
|
||||
// v2rayConfig.inbounds.add(httpCopy)
|
||||
// }
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return false
|
||||
@@ -240,7 +240,7 @@ object V2rayConfigManager {
|
||||
|
||||
val rulesetItems = MmkvManager.decodeRoutingRulesets()
|
||||
rulesetItems?.forEach { key ->
|
||||
if (key != null && key.enabled && key.outboundTag == tag && !key.domain.isNullOrEmpty()) {
|
||||
if (key.enabled && key.outboundTag == tag && !key.domain.isNullOrEmpty()) {
|
||||
key.domain?.forEach {
|
||||
if (it != GEOSITE_PRIVATE
|
||||
&& (it.startsWith("geosite:") || it.startsWith("domain:"))
|
||||
@@ -334,7 +334,7 @@ object V2rayConfigManager {
|
||||
remoteDns.forEach {
|
||||
servers.add(it)
|
||||
}
|
||||
if (proxyDomain.size > 0) {
|
||||
if (proxyDomain.isNotEmpty()) {
|
||||
servers.add(
|
||||
V2rayConfig.DnsBean.ServersBean(
|
||||
address = remoteDns.first(),
|
||||
@@ -348,7 +348,7 @@ object V2rayConfigManager {
|
||||
val directDomain = userRule2Domain(TAG_DIRECT)
|
||||
val isCnRoutingMode = directDomain.contains(GEOSITE_CN)
|
||||
val geoipCn = arrayListOf(GEOIP_CN)
|
||||
if (directDomain.size > 0) {
|
||||
if (directDomain.isNotEmpty()) {
|
||||
servers.add(
|
||||
V2rayConfig.DnsBean.ServersBean(
|
||||
address = domesticDns.first(),
|
||||
@@ -370,9 +370,23 @@ object V2rayConfigManager {
|
||||
)
|
||||
}
|
||||
|
||||
//User DNS hosts
|
||||
try {
|
||||
val userHosts = MmkvManager.decodeSettingsString(AppConfig.PREF_DNS_HOSTS)
|
||||
if (userHosts.isNotNullEmpty()) {
|
||||
var userHostsMap = userHosts?.split(",")
|
||||
?.filter { it.isNotEmpty() }
|
||||
?.filter { it.contains(":") }
|
||||
?.associate { it.split(":").let { (k, v) -> k to v } }
|
||||
if (userHostsMap != null) hosts.putAll(userHostsMap)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
//block dns
|
||||
val blkDomain = userRule2Domain(TAG_BLOCKED)
|
||||
if (blkDomain.size > 0) {
|
||||
if (blkDomain.isNotEmpty()) {
|
||||
hosts.putAll(blkDomain.map { it to LOOPBACK })
|
||||
}
|
||||
|
||||
@@ -428,6 +442,8 @@ object V2rayConfigManager {
|
||||
&& outbound.settings?.vnext?.first()?.users?.first()?.flow?.isNotEmpty() == true
|
||||
) {
|
||||
muxEnabled = false
|
||||
} else if (outbound.streamSettings?.network == NetworkType.XHTTP.type) {
|
||||
muxEnabled = false
|
||||
}
|
||||
if (muxEnabled == true) {
|
||||
outbound.mux?.enabled = true
|
||||
|
||||
@@ -222,7 +222,7 @@ object PluginManager {
|
||||
return File(pluginDir, pluginId).absolutePath
|
||||
}
|
||||
|
||||
fun ComponentInfo.loadString(key: String) = when (val value = metaData.get(key)) {
|
||||
fun ComponentInfo.loadString(key: String) = when (val value = metaData.getString(key)) {
|
||||
is String -> value
|
||||
is Int -> AngApplication.application.packageManager.getResourcesForApplication(applicationInfo)
|
||||
.getString(value)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
package com.v2ray.ang.plugin
|
||||
|
||||
import android.content.pm.ComponentInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Build
|
||||
@@ -33,13 +34,18 @@ abstract class ResolvedPlugin(protected val resolveInfo: ResolveInfo) : Plugin()
|
||||
|
||||
override val id by lazy { componentInfo.loadString(PluginContract.METADATA_KEY_ID)!! }
|
||||
override val version by lazy {
|
||||
AngApplication.application.getPackageInfo(componentInfo.packageName).versionCode
|
||||
getPackageInfo(componentInfo.packageName).versionCode
|
||||
}
|
||||
override val versionName: String by lazy {
|
||||
AngApplication.application.getPackageInfo(componentInfo.packageName).versionName!!
|
||||
getPackageInfo(componentInfo.packageName).versionName!!
|
||||
}
|
||||
override val label: CharSequence get() = resolveInfo.loadLabel(AngApplication.application.packageManager)
|
||||
override val icon: Drawable get() = resolveInfo.loadIcon(AngApplication.application.packageManager)
|
||||
override val packageName: String get() = componentInfo.packageName
|
||||
override val directBootAware get() = Build.VERSION.SDK_INT < 24 || componentInfo.directBootAware
|
||||
|
||||
fun getPackageInfo(packageName: String) = AngApplication.application.packageManager.getPackageInfo(
|
||||
packageName, if (Build.VERSION.SDK_INT >= 28) PackageManager.GET_SIGNING_CERTIFICATES
|
||||
else @Suppress("DEPRECATION") PackageManager.GET_SIGNATURES
|
||||
)!!
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.app.Service
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@@ -44,6 +45,7 @@ object V2RayServiceManager {
|
||||
private const val NOTIFICATION_ID = 1
|
||||
private const val NOTIFICATION_PENDING_INTENT_CONTENT = 0
|
||||
private const val NOTIFICATION_PENDING_INTENT_STOP_V2RAY = 1
|
||||
private const val NOTIFICATION_PENDING_INTENT_RESTART_V2RAY = 2
|
||||
private const val NOTIFICATION_ICON_THRESHOLD = 3000
|
||||
|
||||
val v2rayPoint: V2RayPoint = Libv2ray.newV2RayPoint(V2RayCallback(), Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1)
|
||||
@@ -219,11 +221,15 @@ object V2RayServiceManager {
|
||||
}
|
||||
|
||||
AppConfig.MSG_STATE_STOP -> {
|
||||
Log.d(ANG_PACKAGE, "Stop Service")
|
||||
serviceControl.stopService()
|
||||
}
|
||||
|
||||
AppConfig.MSG_STATE_RESTART -> {
|
||||
startV2rayPoint()
|
||||
Log.d(ANG_PACKAGE, "Restart Service")
|
||||
serviceControl.stopService()
|
||||
Thread.sleep(500L)
|
||||
startV2Ray(serviceControl.getService())
|
||||
}
|
||||
|
||||
AppConfig.MSG_MEASURE_DELAY -> {
|
||||
@@ -278,30 +284,24 @@ object V2RayServiceManager {
|
||||
|
||||
private fun showNotification() {
|
||||
val service = serviceControl?.get()?.getService() ?: return
|
||||
val startMainIntent = Intent(service, MainActivity::class.java)
|
||||
val contentPendingIntent = PendingIntent.getActivity(
|
||||
service,
|
||||
NOTIFICATION_PENDING_INTENT_CONTENT, startMainIntent,
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
}
|
||||
)
|
||||
|
||||
val startMainIntent = Intent(service, MainActivity::class.java)
|
||||
val contentPendingIntent = PendingIntent.getActivity(service, NOTIFICATION_PENDING_INTENT_CONTENT, startMainIntent, flags)
|
||||
|
||||
val stopV2RayIntent = Intent(AppConfig.BROADCAST_ACTION_SERVICE)
|
||||
stopV2RayIntent.`package` = ANG_PACKAGE
|
||||
stopV2RayIntent.putExtra("key", AppConfig.MSG_STATE_STOP)
|
||||
val stopV2RayPendingIntent = PendingIntent.getBroadcast(service, NOTIFICATION_PENDING_INTENT_STOP_V2RAY, stopV2RayIntent, flags)
|
||||
|
||||
val stopV2RayPendingIntent = PendingIntent.getBroadcast(
|
||||
service,
|
||||
NOTIFICATION_PENDING_INTENT_STOP_V2RAY, stopV2RayIntent,
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
}
|
||||
)
|
||||
val restartV2RayIntent = Intent(AppConfig.BROADCAST_ACTION_SERVICE)
|
||||
restartV2RayIntent.`package` = ANG_PACKAGE
|
||||
restartV2RayIntent.putExtra("key", AppConfig.MSG_STATE_RESTART)
|
||||
val restartV2RayPendingIntent = PendingIntent.getBroadcast(service, NOTIFICATION_PENDING_INTENT_RESTART_V2RAY, restartV2RayIntent, flags)
|
||||
|
||||
val channelId =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
@@ -325,6 +325,11 @@ object V2RayServiceManager {
|
||||
service.getString(R.string.notification_action_stop_v2ray),
|
||||
stopV2RayPendingIntent
|
||||
)
|
||||
.addAction(
|
||||
R.drawable.ic_delete_24dp,
|
||||
service.getString(R.string.title_service_restart),
|
||||
restartV2RayPendingIntent
|
||||
)
|
||||
//.build()
|
||||
|
||||
//mBuilder?.setDefaults(NotificationCompat.FLAG_ONLY_ALERT_ONCE) //取消震动,铃声其他都不好使
|
||||
@@ -349,7 +354,12 @@ object V2RayServiceManager {
|
||||
|
||||
fun cancelNotification() {
|
||||
val service = serviceControl?.get()?.getService() ?: return
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
service.stopForeground(Service.STOP_FOREGROUND_REMOVE)
|
||||
} else {
|
||||
service.stopForeground(true)
|
||||
}
|
||||
|
||||
mBuilder = null
|
||||
mDisposable?.dispose()
|
||||
mDisposable = null
|
||||
|
||||
@@ -35,10 +35,10 @@ import java.lang.ref.SoftReference
|
||||
class V2RayVpnService : VpnService(), ServiceControl {
|
||||
companion object {
|
||||
private const val VPN_MTU = 1500
|
||||
private const val PRIVATE_VLAN4_CLIENT = "26.26.26.1"
|
||||
private const val PRIVATE_VLAN4_ROUTER = "26.26.26.2"
|
||||
private const val PRIVATE_VLAN6_CLIENT = "da26:2626::1"
|
||||
private const val PRIVATE_VLAN6_ROUTER = "da26:2626::2"
|
||||
private const val PRIVATE_VLAN4_CLIENT = "10.10.10.1"
|
||||
private const val PRIVATE_VLAN4_ROUTER = "10.10.10.2"
|
||||
private const val PRIVATE_VLAN6_CLIENT = "fc00::10:10:10:1"
|
||||
private const val PRIVATE_VLAN6_ROUTER = "fc00::10:10:10:2"
|
||||
private const val TUN2SOCKS = "libtun2socks.so"
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.v2ray.ang.util.ZipUtil
|
||||
import java.io.File
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
|
||||
|
||||
|
||||
class AboutActivity : BaseActivity() {
|
||||
@@ -90,7 +89,12 @@ class AboutActivity : BaseActivity() {
|
||||
Utils.openUri(this, AppConfig.v2rayNGIssues)
|
||||
}
|
||||
binding.layoutOssLicenses.setOnClickListener{
|
||||
startActivity(Intent(this, OssLicensesMenuActivity::class.java))
|
||||
val webView = android.webkit.WebView(this);
|
||||
webView.loadUrl("file:///android_asset/open_source_licenses.html");
|
||||
android.app.AlertDialog.Builder(this)
|
||||
.setTitle("Open source licenses")
|
||||
.setView(webView)
|
||||
.setPositiveButton("OK", android.content.DialogInterface.OnClickListener { dialog, whichButton -> dialog.dismiss() }).show()
|
||||
}
|
||||
|
||||
binding.layoutTgChannel.setOnClickListener {
|
||||
|
||||
@@ -19,19 +19,42 @@ import kotlinx.coroutines.withContext
|
||||
import java.io.IOException
|
||||
|
||||
class LogcatActivity : BaseActivity() {
|
||||
private val binding by lazy {
|
||||
ActivityLogcatBinding.inflate(layoutInflater)
|
||||
}
|
||||
private val binding by lazy { ActivityLogcatBinding.inflate(layoutInflater) }
|
||||
private val throttleManager = ThrottleManager()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(binding.root)
|
||||
|
||||
title = getString(R.string.title_logcat)
|
||||
|
||||
logcat(false)
|
||||
}
|
||||
|
||||
class ThrottleManager {
|
||||
private val throttleMap = mutableMapOf<String, Long>()
|
||||
|
||||
companion object {
|
||||
private const val THROTTLE_DURATION = 1000L
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun shouldProcess(key: String): Boolean {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
val lastProcessTime = throttleMap[key] ?: 0L
|
||||
|
||||
return if (currentTime - lastProcessTime > THROTTLE_DURATION) {
|
||||
throttleMap[key] = currentTime
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun reset(key: String) {
|
||||
throttleMap.remove(key)
|
||||
}
|
||||
}
|
||||
|
||||
private fun logcat(shouldFlushLog: Boolean) {
|
||||
binding.pbWaiting.visibility = View.VISIBLE
|
||||
|
||||
@@ -44,20 +67,23 @@ class LogcatActivity : BaseActivity() {
|
||||
process.waitFor()
|
||||
}
|
||||
}
|
||||
|
||||
val lst = linkedSetOf(
|
||||
"logcat", "-d", "-v", "time", "-s",
|
||||
"GoLog,tun2socks,$ANG_PACKAGE,AndroidRuntime,System.err"
|
||||
)
|
||||
|
||||
val process = withContext(Dispatchers.IO) {
|
||||
Runtime.getRuntime().exec(lst.toTypedArray())
|
||||
}
|
||||
val allText = process.inputStream.bufferedReader().use { it.readText() }
|
||||
|
||||
val allLogs = process.inputStream.bufferedReader().use { it.readLines() }
|
||||
val filteredLogs = processLogs(allLogs)
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
binding.tvLogcat.text = allText
|
||||
binding.tvLogcat.movementMethod = ScrollingMovementMethod()
|
||||
binding.pbWaiting.visibility = View.GONE
|
||||
Handler(Looper.getMainLooper()).post { binding.svLogcat.fullScroll(View.FOCUS_DOWN) }
|
||||
updateLogDisplay(filteredLogs)
|
||||
}
|
||||
|
||||
} catch (e: IOException) {
|
||||
withContext(Dispatchers.Main) {
|
||||
binding.pbWaiting.visibility = View.GONE
|
||||
@@ -68,6 +94,36 @@ class LogcatActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun processLogs(logs: List<String>): List<String> {
|
||||
val processedLogs = mutableListOf<String>()
|
||||
var isNotMatch = false
|
||||
|
||||
for (line in logs) {
|
||||
when {
|
||||
line.contains("zxing.NotFoundException", ignoreCase = true) -> {
|
||||
if (!isNotMatch) {
|
||||
if (throttleManager.shouldProcess("NotFoundException")) {
|
||||
processedLogs.add(line)
|
||||
isNotMatch = true
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> processedLogs.add(line)
|
||||
}
|
||||
}
|
||||
|
||||
return processedLogs.take(500)
|
||||
}
|
||||
|
||||
private fun updateLogDisplay(logs: List<String>) {
|
||||
binding.tvLogcat.text = logs.joinToString("\n")
|
||||
binding.tvLogcat.movementMethod = ScrollingMovementMethod()
|
||||
binding.pbWaiting.visibility = View.GONE
|
||||
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
binding.svLogcat.fullScroll(View.FOCUS_DOWN)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_logcat, menu)
|
||||
@@ -80,12 +136,11 @@ class LogcatActivity : BaseActivity() {
|
||||
toast(R.string.toast_success)
|
||||
true
|
||||
}
|
||||
|
||||
R.id.clear_all -> {
|
||||
throttleManager.reset("zxing.NotFoundException")
|
||||
logcat(true)
|
||||
true
|
||||
}
|
||||
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,8 +346,8 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val ret = mainViewModel.exportAllServer()
|
||||
launch(Dispatchers.Main) {
|
||||
if (ret == 0)
|
||||
toast(R.string.toast_success)
|
||||
if (ret > 0)
|
||||
toast(getString(R.string.title_export_config_count, ret))
|
||||
else
|
||||
toast(R.string.toast_failure)
|
||||
binding.pbWaiting.hide()
|
||||
@@ -358,13 +358,13 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
}
|
||||
|
||||
R.id.ping_all -> {
|
||||
toast(R.string.connection_test_testing)
|
||||
toast(getString(R.string.connection_test_testing_count, mainViewModel.serversCache.count()))
|
||||
mainViewModel.testAllTcping()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.real_ping_all -> {
|
||||
toast(R.string.connection_test_testing)
|
||||
toast(getString(R.string.connection_test_testing_count, mainViewModel.serversCache.count()))
|
||||
mainViewModel.testAllRealPing()
|
||||
true
|
||||
}
|
||||
@@ -379,14 +379,15 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
binding.pbWaiting.show()
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
mainViewModel.removeAllServer()
|
||||
val ret = mainViewModel.removeAllServer()
|
||||
launch(Dispatchers.Main) {
|
||||
mainViewModel.reloadServerList()
|
||||
toast(getString(R.string.title_del_config_count, ret))
|
||||
binding.pbWaiting.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.no) { _, _ ->
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
//do noting
|
||||
}
|
||||
.show()
|
||||
@@ -406,7 +407,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
}
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.no) { _, _ ->
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
//do noting
|
||||
}
|
||||
.show()
|
||||
@@ -418,14 +419,15 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
binding.pbWaiting.show()
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
mainViewModel.removeInvalidServer()
|
||||
val ret = mainViewModel.removeInvalidServer()
|
||||
launch(Dispatchers.Main) {
|
||||
mainViewModel.reloadServerList()
|
||||
toast(getString(R.string.title_del_config_count, ret))
|
||||
binding.pbWaiting.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.no) { _, _ ->
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
//do noting
|
||||
}
|
||||
.show()
|
||||
@@ -517,7 +519,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
withContext(Dispatchers.Main) {
|
||||
when {
|
||||
count > 0 -> {
|
||||
toast(R.string.toast_success)
|
||||
toast(getString(R.string.title_import_config_count, count))
|
||||
mainViewModel.reloadServerList()
|
||||
}
|
||||
|
||||
@@ -623,7 +625,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
delay(500L)
|
||||
launch(Dispatchers.Main) {
|
||||
if (count > 0) {
|
||||
toast(R.string.toast_success)
|
||||
toast(getString(R.string.title_update_config_count, count))
|
||||
mainViewModel.reloadServerList()
|
||||
} else {
|
||||
toast(R.string.toast_failure)
|
||||
|
||||
@@ -143,7 +143,7 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
removeServer(guid, position)
|
||||
}
|
||||
.setNegativeButton(android.R.string.no) { _, _ ->
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
//do noting
|
||||
}
|
||||
.show()
|
||||
|
||||
@@ -37,7 +37,7 @@ class RoutingEditActivity : BaseActivity() {
|
||||
|
||||
private fun bindingServer(rulesetItem: RulesetItem): Boolean {
|
||||
binding.etRemarks.text = Utils.getEditable(rulesetItem.remarks)
|
||||
binding.chkLocked.isChecked = rulesetItem.looked == true
|
||||
binding.chkLocked.isChecked = rulesetItem.locked == true
|
||||
binding.etDomain.text = Utils.getEditable(rulesetItem.domain?.joinToString(","))
|
||||
binding.etIp.text = Utils.getEditable(rulesetItem.ip?.joinToString(","))
|
||||
binding.etPort.text = Utils.getEditable(rulesetItem.port)
|
||||
@@ -60,7 +60,7 @@ class RoutingEditActivity : BaseActivity() {
|
||||
|
||||
rulesetItem.apply {
|
||||
remarks = binding.etRemarks.text.toString()
|
||||
looked = binding.chkLocked.isChecked
|
||||
locked = binding.chkLocked.isChecked
|
||||
domain = binding.etDomain.text.toString().takeIf { it.isNotEmpty() }
|
||||
?.split(",")?.map { it.trim() }?.filter { it.isNotEmpty() }
|
||||
ip = binding.etIp.text.toString().takeIf { it.isNotEmpty() }
|
||||
@@ -95,7 +95,7 @@ class RoutingEditActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.no) { _, _ ->
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
// do nothing
|
||||
}
|
||||
.show()
|
||||
|
||||
@@ -105,7 +105,7 @@ class RoutingSettingActivity : BaseActivity() {
|
||||
|
||||
|
||||
}
|
||||
.setNegativeButton(android.R.string.no) { _, _ ->
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
//do noting
|
||||
}
|
||||
.show()
|
||||
@@ -134,7 +134,7 @@ class RoutingSettingActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.no) { _, _ ->
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
//do nothing
|
||||
}
|
||||
.show()
|
||||
@@ -189,7 +189,7 @@ class RoutingSettingActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.no) { _, _ ->
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
//do nothing
|
||||
}
|
||||
.show()
|
||||
|
||||
@@ -25,7 +25,7 @@ class RoutingSettingRecyclerAdapter(val activity: RoutingSettingActivity) : Recy
|
||||
holder.itemRoutingSettingBinding.domainIp.text = (ruleset.domain ?: ruleset.ip ?: ruleset.port)?.toString()
|
||||
holder.itemRoutingSettingBinding.outboundTag.text = ruleset.outboundTag
|
||||
holder.itemRoutingSettingBinding.chkEnable.isChecked = ruleset.enabled
|
||||
holder.itemRoutingSettingBinding.imgLocked.isVisible = ruleset.looked == true
|
||||
holder.itemRoutingSettingBinding.imgLocked.isVisible = ruleset.locked == true
|
||||
holder.itemView.setBackgroundColor(Color.TRANSPARENT)
|
||||
|
||||
holder.itemRoutingSettingBinding.layoutEdit.setOnClickListener {
|
||||
|
||||
@@ -162,7 +162,7 @@ class ServerActivity : BaseActivity() {
|
||||
sp_header_type_title?.text =
|
||||
when (networks[position]) {
|
||||
NetworkType.GRPC.type -> getString(R.string.server_lab_mode_type)
|
||||
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> getString(R.string.server_lab_xhttp_mode)
|
||||
NetworkType.XHTTP.type -> getString(R.string.server_lab_xhttp_mode)
|
||||
else -> getString(R.string.server_lab_head_type)
|
||||
}.orEmpty()
|
||||
sp_header_type?.setSelection(
|
||||
@@ -170,7 +170,7 @@ class ServerActivity : BaseActivity() {
|
||||
types,
|
||||
when (networks[position]) {
|
||||
NetworkType.GRPC.type -> config?.mode
|
||||
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> config?.xhttpMode
|
||||
NetworkType.XHTTP.type -> config?.xhttpMode
|
||||
else -> config?.headerType
|
||||
}.orEmpty()
|
||||
)
|
||||
@@ -198,7 +198,7 @@ class ServerActivity : BaseActivity() {
|
||||
NetworkType.TCP.type -> R.string.server_lab_request_host_http
|
||||
NetworkType.WS.type -> R.string.server_lab_request_host_ws
|
||||
NetworkType.HTTP_UPGRADE.type -> R.string.server_lab_request_host_httpupgrade
|
||||
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> R.string.server_lab_request_host_xhttp
|
||||
NetworkType.XHTTP.type -> R.string.server_lab_request_host_xhttp
|
||||
NetworkType.H2.type -> R.string.server_lab_request_host_h2
|
||||
//"quic" -> R.string.server_lab_request_host_quic
|
||||
NetworkType.GRPC.type -> R.string.server_lab_request_host_grpc
|
||||
@@ -213,7 +213,7 @@ class ServerActivity : BaseActivity() {
|
||||
NetworkType.KCP.type -> R.string.server_lab_path_kcp
|
||||
NetworkType.WS.type -> R.string.server_lab_path_ws
|
||||
NetworkType.HTTP_UPGRADE.type -> R.string.server_lab_path_httpupgrade
|
||||
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> R.string.server_lab_path_xhttp
|
||||
NetworkType.XHTTP.type -> R.string.server_lab_path_xhttp
|
||||
NetworkType.H2.type -> R.string.server_lab_path_h2
|
||||
//"quic" -> R.string.server_lab_path_quic
|
||||
NetworkType.GRPC.type -> R.string.server_lab_path_grpc
|
||||
@@ -223,14 +223,14 @@ class ServerActivity : BaseActivity() {
|
||||
)
|
||||
et_extra?.text = Utils.getEditable(
|
||||
when (networks[position]) {
|
||||
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> config?.xhttpExtra
|
||||
NetworkType.XHTTP.type -> config?.xhttpExtra
|
||||
else -> null
|
||||
}.orEmpty()
|
||||
)
|
||||
|
||||
layout_extra?.visibility =
|
||||
when (networks[position]) {
|
||||
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> View.VISIBLE
|
||||
NetworkType.XHTTP.type -> View.VISIBLE
|
||||
else -> View.GONE
|
||||
}
|
||||
}
|
||||
@@ -578,7 +578,7 @@ class ServerActivity : BaseActivity() {
|
||||
grpcModes
|
||||
}
|
||||
|
||||
NetworkType.SPLIT_HTTP.type, NetworkType.XHTTP.type -> {
|
||||
NetworkType.XHTTP.type -> {
|
||||
xhttpMode
|
||||
}
|
||||
|
||||
@@ -600,7 +600,7 @@ class ServerActivity : BaseActivity() {
|
||||
MmkvManager.removeServer(editGuid)
|
||||
finish()
|
||||
}
|
||||
.setNegativeButton(android.R.string.no) { _, _ ->
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
// do nothing
|
||||
}
|
||||
.show()
|
||||
|
||||
@@ -106,7 +106,7 @@ class ServerCustomConfigActivity : BaseActivity() {
|
||||
MmkvManager.removeServer(editGuid)
|
||||
finish()
|
||||
}
|
||||
.setNegativeButton(android.R.string.no) { _, _ ->
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
// do nothing
|
||||
}
|
||||
.show()
|
||||
|
||||
@@ -58,9 +58,9 @@ class SettingsActivity : BaseActivity() {
|
||||
private val autoUpdateInterval by lazy { findPreference<EditTextPreference>(AppConfig.SUBSCRIPTION_AUTO_UPDATE_INTERVAL) }
|
||||
|
||||
private val socksPort by lazy { findPreference<EditTextPreference>(AppConfig.PREF_SOCKS_PORT) }
|
||||
private val httpPort by lazy { findPreference<EditTextPreference>(AppConfig.PREF_HTTP_PORT) }
|
||||
private val remoteDns by lazy { findPreference<EditTextPreference>(AppConfig.PREF_REMOTE_DNS) }
|
||||
private val domesticDns by lazy { findPreference<EditTextPreference>(AppConfig.PREF_DOMESTIC_DNS) }
|
||||
private val dnsHosts by lazy { findPreference<EditTextPreference>(AppConfig.PREF_DNS_HOSTS) }
|
||||
private val delayTestUrl by lazy { findPreference<EditTextPreference>(AppConfig.PREF_DELAY_TEST_URL) }
|
||||
private val mode by lazy { findPreference<ListPreference>(AppConfig.PREF_MODE) }
|
||||
|
||||
@@ -142,11 +142,7 @@ class SettingsActivity : BaseActivity() {
|
||||
socksPort?.summary = if (TextUtils.isEmpty(nval)) AppConfig.PORT_SOCKS else nval
|
||||
true
|
||||
}
|
||||
httpPort?.setOnPreferenceChangeListener { _, any ->
|
||||
val nval = any as String
|
||||
httpPort?.summary = if (TextUtils.isEmpty(nval)) AppConfig.PORT_HTTP else nval
|
||||
true
|
||||
}
|
||||
|
||||
remoteDns?.setOnPreferenceChangeListener { _, any ->
|
||||
val nval = any as String
|
||||
remoteDns?.summary = if (nval == "") AppConfig.DNS_PROXY else nval
|
||||
@@ -157,6 +153,11 @@ class SettingsActivity : BaseActivity() {
|
||||
domesticDns?.summary = if (nval == "") AppConfig.DNS_DIRECT else nval
|
||||
true
|
||||
}
|
||||
dnsHosts?.setOnPreferenceChangeListener { _, any ->
|
||||
val nval = any as String
|
||||
dnsHosts?.summary = nval
|
||||
true
|
||||
}
|
||||
delayTestUrl?.setOnPreferenceChangeListener { _, any ->
|
||||
val nval = any as String
|
||||
delayTestUrl?.summary = if (nval == "") AppConfig.DelayTestUrl else nval
|
||||
@@ -197,9 +198,9 @@ class SettingsActivity : BaseActivity() {
|
||||
autoUpdateInterval?.isEnabled = MmkvManager.decodeSettingsBool(AppConfig.SUBSCRIPTION_AUTO_UPDATE, false)
|
||||
|
||||
socksPort?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_SOCKS_PORT, AppConfig.PORT_SOCKS)
|
||||
httpPort?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_HTTP_PORT, AppConfig.PORT_HTTP)
|
||||
remoteDns?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_REMOTE_DNS, AppConfig.DNS_PROXY)
|
||||
domesticDns?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_DOMESTIC_DNS, AppConfig.DNS_DIRECT)
|
||||
dnsHosts?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_DNS_HOSTS)
|
||||
delayTestUrl?.summary = MmkvManager.decodeSettingsString(AppConfig.PREF_DELAY_TEST_URL, AppConfig.DelayTestUrl)
|
||||
|
||||
initSharedPreference()
|
||||
@@ -215,7 +216,6 @@ class SettingsActivity : BaseActivity() {
|
||||
fragmentInterval,
|
||||
autoUpdateInterval,
|
||||
socksPort,
|
||||
httpPort,
|
||||
remoteDns,
|
||||
domesticDns,
|
||||
delayTestUrl
|
||||
|
||||
@@ -113,7 +113,7 @@ class SubEditActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.no) { _, _ ->
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
// do nothing
|
||||
}
|
||||
.show()
|
||||
|
||||
@@ -333,7 +333,7 @@ class UserAssetActivity : BaseActivity() {
|
||||
MmkvManager.removeAssetUrl(item.first)
|
||||
initAssets()
|
||||
}
|
||||
.setNegativeButton(android.R.string.no) { _, _ ->
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
//do noting
|
||||
}
|
||||
.show()
|
||||
|
||||
@@ -116,7 +116,7 @@ class UserAssetUrlActivity : BaseActivity() {
|
||||
MmkvManager.removeAssetUrl(editAssetId)
|
||||
finish()
|
||||
}
|
||||
.setNegativeButton(android.R.string.no) { _, _ ->
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
// do nothing
|
||||
}
|
||||
.show()
|
||||
|
||||
@@ -498,5 +498,7 @@ object Utils {
|
||||
ContextCompat.RECEIVER_NOT_EXPORTED
|
||||
}
|
||||
|
||||
fun isXray(): Boolean = (ANG_PACKAGE.startsWith("com.v2ray.ang"))
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.res.AssetManager
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
@@ -274,7 +273,8 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
return deleteServer.count()
|
||||
}
|
||||
|
||||
fun removeAllServer() {
|
||||
fun removeAllServer(): Int {
|
||||
val count =
|
||||
if (subscriptionId.isEmpty() && keywordFilter.isEmpty()) {
|
||||
MmkvManager.removeAllServer()
|
||||
} else {
|
||||
@@ -282,18 +282,22 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
for (item in serversCopy) {
|
||||
MmkvManager.removeServer(item.guid)
|
||||
}
|
||||
serversCache.toList().count()
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
fun removeInvalidServer() {
|
||||
fun removeInvalidServer(): Int {
|
||||
var count = 0
|
||||
if (subscriptionId.isEmpty() && keywordFilter.isEmpty()) {
|
||||
MmkvManager.removeInvalidServer("")
|
||||
count += MmkvManager.removeInvalidServer("")
|
||||
} else {
|
||||
val serversCopy = serversCache.toList()
|
||||
for (item in serversCopy) {
|
||||
MmkvManager.removeInvalidServer(item.guid)
|
||||
count += MmkvManager.removeInvalidServer(item.guid)
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
fun sortByTestResults() {
|
||||
|
||||
@@ -31,10 +31,10 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
|
||||
AppConfig.PREF_VPN_DNS,
|
||||
AppConfig.PREF_REMOTE_DNS,
|
||||
AppConfig.PREF_DOMESTIC_DNS,
|
||||
AppConfig.PREF_DNS_HOSTS,
|
||||
AppConfig.PREF_DELAY_TEST_URL,
|
||||
AppConfig.PREF_LOCAL_DNS_PORT,
|
||||
AppConfig.PREF_SOCKS_PORT,
|
||||
AppConfig.PREF_HTTP_PORT,
|
||||
AppConfig.PREF_LOGLEVEL,
|
||||
AppConfig.PREF_LANGUAGE,
|
||||
AppConfig.PREF_UI_MODE_NIGHT,
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
<string name="server_lab_encryption">التشفير</string>
|
||||
<string name="server_lab_flow">التدفق</string>
|
||||
<string name="server_lab_public_key" translatable="false">المفتاح العام</string>
|
||||
<string name="server_lab_preshared_key">PreSharedKey(optional)</string>
|
||||
<string name="server_lab_short_id" translatable="false">المعرّف القصير</string>
|
||||
<string name="server_lab_spider_x" translatable="false">SpiderX</string>
|
||||
<string name="server_lab_secret_key" translatable="false">المفتاح السري</string>
|
||||
@@ -179,6 +180,9 @@
|
||||
<string name="title_pref_domestic_dns">DNS المحلي (اختياري)</string>
|
||||
<string name="summary_pref_domestic_dns">DNS</string>
|
||||
|
||||
<string name="title_pref_dns_hosts">DNS hosts (Format: domain:address,…)</string>
|
||||
<string name="summary_pref_dns_hosts">domain:address,…</string>
|
||||
|
||||
<string name="title_pref_delay_test_url">True delay test url (http/https)</string>
|
||||
<string name="summary_pref_delay_test_url">Url</string>
|
||||
|
||||
@@ -189,11 +193,8 @@
|
||||
<string name="title_pref_allow_insecure">السماح غير الآمن</string>
|
||||
<string name="summary_pref_allow_insecure">عند TLS، الافتراضي هو السماح غير الآمن</string>
|
||||
|
||||
<string name="title_pref_socks_port">منفذ بروكسي SOCKS5</string>
|
||||
<string name="summary_pref_socks_port">منفذ بروكسي SOCKS5</string>
|
||||
|
||||
<string name="title_pref_http_port">منفذ بروكسي HTTP</string>
|
||||
<string name="summary_pref_http_port">منفذ بروكسي HTTP</string>
|
||||
<string name="title_pref_socks_port">منفذ بروكسي Local</string>
|
||||
<string name="summary_pref_socks_port">منفذ بروكسي Local</string>
|
||||
|
||||
<string name="title_pref_local_dns_port">منفذ DNS المحلي</string>
|
||||
<string name="summary_pref_local_dns_port">منفذ DNS المحلي</string>
|
||||
@@ -214,6 +215,7 @@
|
||||
<string name="title_privacy_policy">سياسة الخصوصية</string>
|
||||
<string name="title_about">حول\nترجمة م. ابراهيم قاسم</string>
|
||||
<string name="title_source_code">الكود المصدري</string>
|
||||
<string name="title_oss_license">Open Source licenses</string>
|
||||
<string name="title_tg_channel">قناة Telegram</string>
|
||||
<string name="title_configuration_backup">نسخ التكوين احتياطيًا</string>
|
||||
<string name="summary_configuration_backup">موقع التخزين: [%s]، سيتم مسح النسخة الاحتياطية بعد إلغاء تثبيت التطبيق أو مسح التخزين</string>
|
||||
@@ -260,6 +262,10 @@
|
||||
<string name="filter_config_all">جميع مجموعات الاشتراك</string>
|
||||
<string name="title_del_duplicate_config_count">حذف %d من الإعدادات المكررة</string>
|
||||
|
||||
<string name="title_del_config_count">Delete %d configurations</string>
|
||||
<string name="title_import_config_count">Import %d configurations</string>
|
||||
<string name="title_export_config_count">Export %d configurations</string>
|
||||
<string name="title_update_config_count">Update %d configurations</string>
|
||||
<string name="tasker_start_service">بدء الخدمة</string>
|
||||
<string name="tasker_setting_confirm">تأكيد</string>
|
||||
|
||||
@@ -279,6 +285,7 @@
|
||||
|
||||
<string name="connection_test_pending">التحقق من الاتصال</string>
|
||||
<string name="connection_test_testing">يجري الاختبار…</string>
|
||||
<string name="connection_test_testing_count">Testing %d configurations…</string>
|
||||
<string name="connection_test_available">نجاح: استغرق اتصال HTTP %dms</string>
|
||||
<string name="connection_test_error">فشل اكتشاف اتصال الإنترنت: %s</string>
|
||||
<string name="connection_test_fail">الإنترنت غير متاح</string>
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
<string name="server_lab_encryption">এনক্রিপশন</string>
|
||||
<string name="server_lab_flow">ফ্লো</string>
|
||||
<string name="server_lab_public_key" translatable="false">পাবলিক কী</string>
|
||||
<string name="server_lab_preshared_key">PreSharedKey(optional)</string>
|
||||
<string name="server_lab_short_id" translatable="false">শর্ট আইডি</string>
|
||||
<string name="server_lab_spider_x" translatable="false">SpiderX</string>
|
||||
<string name="server_lab_secret_key" translatable="false">সিক্রেট কী</string>
|
||||
@@ -179,6 +180,9 @@
|
||||
<string name="title_pref_domestic_dns">ঘরোয়া DNS (ঐচ্ছিক)</string>
|
||||
<string name="summary_pref_domestic_dns">DNS</string>
|
||||
|
||||
<string name="title_pref_dns_hosts">DNS hosts (Format: domain:address,…)</string>
|
||||
<string name="summary_pref_dns_hosts">domain:address,…</string>
|
||||
|
||||
<string name="title_pref_delay_test_url">সঠিক বিলম্ব পরীক্ষা ইউআরএল (http/https)</string>
|
||||
<string name="summary_pref_delay_test_url">ইউআরএল</string>
|
||||
|
||||
@@ -189,11 +193,8 @@
|
||||
<string name="title_pref_allow_insecure">allowInsecure</string>
|
||||
<string name="summary_pref_allow_insecure">যখন TLS, ডিফল্টভাবে allowInsecure</string>
|
||||
|
||||
<string name="title_pref_socks_port">SOCKS5 প্রক্সি পোর্ট</string>
|
||||
<string name="summary_pref_socks_port">SOCKS5 প্রক্সি পোর্ট</string>
|
||||
|
||||
<string name="title_pref_http_port">HTTP প্রক্সি পোর্ট</string>
|
||||
<string name="summary_pref_http_port">HTTP প্রক্সি পোর্ট</string>
|
||||
<string name="title_pref_socks_port">Local প্রক্সি পোর্ট</string>
|
||||
<string name="summary_pref_socks_port">Local প্রক্সি পোর্ট</string>
|
||||
|
||||
<string name="title_pref_local_dns_port">স্থানীয় DNS পোর্ট</string>
|
||||
<string name="summary_pref_local_dns_port">স্থানীয় DNS পোর্ট</string>
|
||||
@@ -214,6 +215,7 @@
|
||||
<string name="title_privacy_policy">গোপনীয়তা নীতি</string>
|
||||
<string name="title_about">সম্পর্কিত</string>
|
||||
<string name="title_source_code">সোর্স কোড</string>
|
||||
<string name="title_oss_license">Open Source licenses</string>
|
||||
<string name="title_tg_channel">টেলিগ্রাম চ্যানেল</string>
|
||||
<string name="title_configuration_backup">কনফিগারেশন ব্যাকআপ</string>
|
||||
<string name="summary_configuration_backup">স্টোরেজ অবস্থান: [%s], অ্যাপ আনইনস্টল বা স্টোরেজ ক্লিয়ার করার পরে ব্যাকআপ মুছে যাবে</string>
|
||||
@@ -259,6 +261,10 @@
|
||||
<string name="title_filter_config">কনফিগারেশন ফাইল ফিল্টার করুন</string>
|
||||
<string name="filter_config_all">সব সাবস্ক্রিপশন গ্রুপ</string>
|
||||
<string name="title_del_duplicate_config_count">%d ডুপ্লিকেট কনফিগারেশন মুছে ফেলুন</string>
|
||||
<string name="title_del_config_count">Delete %d configurations</string>
|
||||
<string name="title_import_config_count">Import %d configurations</string>
|
||||
<string name="title_export_config_count">Export %d configurations</string>
|
||||
<string name="title_update_config_count">Update %d configurations</string>
|
||||
<string name="tasker_start_service">সার্ভিস শুরু করুন</string>
|
||||
<string name="tasker_setting_confirm">নিশ্চিত করুন</string>
|
||||
|
||||
@@ -278,6 +284,7 @@
|
||||
|
||||
<string name="connection_test_pending">সংযোগ পরীক্ষা করুন</string>
|
||||
<string name="connection_test_testing">পরীক্ষা চলছে…</string>
|
||||
<string name="connection_test_testing_count">Testing %d configurations…</string>
|
||||
<string name="connection_test_available">সফল: HTTP সংযোগ নিয়েছে %dms</string>
|
||||
<string name="connection_test_error">ইন্টারনেট সংযোগ সনাক্ত করতে ব্যর্থ: %s</string>
|
||||
<string name="connection_test_fail">ইন্টারনেট উপলব্ধ নয়</string>
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
<string name="toast_permission_denied">گرؽڌن موجوز مومکن نؽڌ</string>
|
||||
<string name="toast_permission_denied_notification">گرؽڌن موجوز وارسۊوی مومکن نؽڌ</string>
|
||||
<string name="notification_action_more">سی گرؽڌن دۉسمندیا بیشتر کیلیک کوݩ</string>
|
||||
<string name="toast_services_start">ره وستن خدمات</string>
|
||||
<string name="toast_services_start">ر وستن خدمات</string>
|
||||
<string name="toast_services_stop">واڌاشتن خدمات</string>
|
||||
<string name="toast_services_success">ره وستن خدمات وا مووفقیت ٱنجوم وابی</string>
|
||||
<string name="toast_services_failure">ره وستن خدمات وا مووفقیت ٱنجوم نوابی</string>
|
||||
<string name="toast_services_success">ر وستن خدمات وا مووفقیت ٱنجوم وابی</string>
|
||||
<string name="toast_services_failure">ر وستن خدمات وا مووفقیت ٱنجوم نوابی</string>
|
||||
|
||||
<!--ServerActivity-->
|
||||
<string name="title_server">فایل کانفیگ</string>
|
||||
@@ -81,6 +81,7 @@
|
||||
<string name="server_lab_encryption">رزم نگاری</string>
|
||||
<string name="server_lab_flow">جریان</string>
|
||||
<string name="server_lab_public_key">کیلیت پوی وولاتی</string>
|
||||
<string name="server_lab_preshared_key">کیلیت رمز ناهاڌن ازاف (اختیاری)</string>
|
||||
<string name="server_lab_short_id">ShortId</string>
|
||||
<string name="server_lab_spider_x">SpiderX</string>
|
||||
<string name="server_lab_secret_key">کیلیت سیخومی</string>
|
||||
@@ -119,7 +120,7 @@
|
||||
<string name="server_lab_port_hop_interval">فاسله پورت گوم (سانیه)</string>
|
||||
<string name="server_lab_stream_pinsha256">pinSHA256</string>
|
||||
<string name="server_lab_xhttp_mode">هالت XHTTP</string>
|
||||
<string name="server_lab_xhttp_extra">XHTTP قلوه خام JSON، قالوو: { XHTTPObject }</string>
|
||||
<string name="server_lab_xhttp_extra">XHTTP Extra خام JSON، قالوو: { XHTTPObject }</string>
|
||||
|
||||
<!-- PerAppProxyActivity -->
|
||||
<string name="msg_dialog_progress">هون بار ونی بۊ</string>
|
||||
@@ -139,11 +140,11 @@
|
||||
<string name="title_vpn_settings">سامووا VPN</string>
|
||||
<string name="title_pref_per_app_proxy">پروکسی و ری برنومه</string>
|
||||
<string name="summary_pref_per_app_proxy">پوی وولاتی: برنومه واجۊری بیڌه پروکسی هڌ، منپیز موستقیم بؽ نشووه هڌ. هالت دور زیڌن: برنومه نشووک ناڌه موستقیمن منپیز هڌ، پروکسی نشووک زیڌه نؽڌ. گۊزینه پسند خوتکار برنومه پروکسی من نومگه</string>
|
||||
<string name="title_pref_is_booted">منپیز خوتکار مجال ره ونی</string>
|
||||
<string name="summary_pref_is_booted">مجال ره وندن، خوساخوس و سرور پسند بیڌه منپیز ابۊ که گاشڌ نا مووفق بۊ.</string>
|
||||
<string name="title_pref_is_booted">منپیز خوتکار مجال ر ونی</string>
|
||||
<string name="summary_pref_is_booted">مجال ر وندن، خوساخوس و سرور پسند بیڌه منپیز ابۊ که گاشڌ نا مووفق بۊ.</string>
|
||||
|
||||
<string name="title_mux_settings">سامووا Mux</string>
|
||||
<string name="title_pref_mux_enabled">ره وندن Mux</string>
|
||||
<string name="title_pref_mux_enabled">ر وندن Mux</string>
|
||||
<string name="summary_pref_mux_enabled">زل تر، ٱما گاشڌ منپیز زی قت بۊ بارت دؽوۉداری، TCP، UDP و QUIC ن ای لم سفارشی کۊنین.</string>
|
||||
<string name="title_pref_mux_concurency">منپیزا TCP (تلایه منجا 1-1024)</string>
|
||||
<string name="title_pref_mux_xudp_concurency">منپیزا XUDP (تلایه منجا 1-1024)</string>
|
||||
@@ -154,24 +155,24 @@
|
||||
<item>گوم زیڌن</item>
|
||||
</string-array>
|
||||
|
||||
<string name="title_pref_speed_enabled">ره وندن نشۉݩ داڌن سورعت</string>
|
||||
<string name="title_pref_speed_enabled">ر وندن نشۉݩ داڌن سورعت</string>
|
||||
<string name="summary_pref_speed_enabled">نشۉݩ داڌن سورعت هیم سکویی من وارسۊویا. نماڌ وارسۊوی و ری و کار گرؽڌن آلشت ابۊ.</string>
|
||||
|
||||
<string name="title_pref_sniffing_enabled">ره وندن Sniffing</string>
|
||||
<string name="title_pref_sniffing_enabled">ر وندن Sniffing</string>
|
||||
<string name="summary_pref_sniffing_enabled">دامنه sniff ن ز کتن امتهۉݩ کۊنین (پؽش فرز رۊشن)</string>
|
||||
<string name="title_pref_route_only_enabled">ره وندن routeOnly</string>
|
||||
<string name="title_pref_route_only_enabled">ر وندن routeOnly</string>
|
||||
<string name="summary_pref_route_only_enabled">ز نوم دامنه sniffed تینا سی تور جوستن استفاڌه کۊنین وو آدرس مورد نزرن و عونوان آدرس IP ووردارین.</string>
|
||||
|
||||
<string name="title_pref_local_dns_enabled">ره وندن DNS مهلی</string>
|
||||
<string name="title_pref_local_dns_enabled">ر وندن DNS مهلی</string>
|
||||
<string name="summary_pref_local_dns_enabled">DNS پردازشت وابیڌه و دس هسته ماژول DNS (پؽشنهاڌ ابۊ، ٱر نیاز هڌ ک جوستن تور وو ولات ٱسلین دور زنی)</string>
|
||||
|
||||
<string name="title_pref_fake_dns_enabled">ره وندن DNS جئلی</string>
|
||||
<string name="title_pref_fake_dns_enabled">ر وندن DNS جئلی</string>
|
||||
<string name="summary_pref_fake_dns_enabled">DNS مهلی آدرسا IP جئلی ن وورگنه (زل تر، ٱما گاشڌ من یقرد ز برنومیل کار نکونه)</string>
|
||||
|
||||
<string name="title_pref_prefer_ipv6">ترجی IPv6</string>
|
||||
<string name="summary_pref_prefer_ipv6">ترجی داڌن نشۊوی وو تورا IPv6</string>
|
||||
|
||||
<string name="title_pref_remote_dns">DNS ز ره دیر (اختیاری) (udp/tcp/https/quic) (اختیاری)</string>
|
||||
<string name="title_pref_remote_dns">DNS ز ر دیر (اختیاری) (udp/tcp/https/quic) (اختیاری)</string>
|
||||
<string name="summary_pref_remote_dns">DNS</string>
|
||||
|
||||
<string name="title_pref_vpn_dns">VPN DNS (تینا IPv4/v6)</string>
|
||||
@@ -179,21 +180,21 @@
|
||||
<string name="title_pref_domestic_dns">DNS منی (اختیاری)</string>
|
||||
<string name="summary_pref_domestic_dns">DNS</string>
|
||||
|
||||
<string name="title_pref_dns_hosts">DNS هاست موستقیم (قالوو: دامنه: آدرس،...)</string>
|
||||
<string name="summary_pref_dns_hosts">دامنه:آدرس،...</string>
|
||||
|
||||
<string name="title_pref_delay_test_url">آدرس اینترنتی آزمایش تئخیر واقعی (http/https)</string>
|
||||
<string name="summary_pref_delay_test_url">نشۊوی اینترنتی</string>
|
||||
|
||||
<string name="title_pref_proxy_sharing_enabled">هشتن منپیزا ز LAN</string>
|
||||
<string name="summary_pref_proxy_sharing_enabled">پوی دسگایل ترن وا آدرس IP ایسا، ز ره socks/http و پروکسی منپیز بۊن، تینا من شبکه قابل اعتماد فعال بۊ تا ز منپیز ؛یر موجاز جلو گری بۊ.</string>
|
||||
<string name="summary_pref_proxy_sharing_enabled">پوی دسگایل ترن وا آدرس IP ایسا، ز ر socks/http و پروکسی منپیز بۊن، تینا من شبکه قابل اعتماد فعال بۊ تا ز منپیز ؛یر موجاز جلو گری بۊ.</string>
|
||||
<string name="toast_warning_pref_proxysharing_short">منپیزا ز LAN ن موجار کۊنین، موتمعن بۊین ک من ی شبکه قابل ائتماڌ هڌین.</string>
|
||||
|
||||
<string name="title_pref_allow_insecure">اجازه نا ٱمن</string>
|
||||
<string name="summary_pref_allow_insecure">مجال و کار بردن TLS ب تۉر پؽش فرز، موجوز نا ٱمن فعال هڌ.</string>
|
||||
|
||||
<string name="title_pref_socks_port">پورت پروکسی SOCKS5</string>
|
||||
<string name="summary_pref_socks_port">پورت پروکسی SOCKS5</string>
|
||||
|
||||
<string name="title_pref_http_port">پورت پروکسی HTTP</string>
|
||||
<string name="summary_pref_http_port">پورت پروکسی HTTP</string>
|
||||
<string name="title_pref_socks_port">پورت پروکسی مهلی</string>
|
||||
<string name="summary_pref_socks_port">پورت پروکسی مهلی</string>
|
||||
|
||||
<string name="title_pref_local_dns_port">پورت DNS مهلی</string>
|
||||
<string name="summary_pref_local_dns_port">پورت DNS مهلی</string>
|
||||
@@ -201,8 +202,8 @@
|
||||
<string name="title_pref_confirm_remove">قوۊل کردن پاک کردن کانفیگ</string>
|
||||
<string name="summary_pref_confirm_remove">سی پاک وابیڌن فایل کانفیگ نیاز به قوۊل کردن دووارته ز سمت منتور هڌ</string>
|
||||
|
||||
<string name="title_pref_start_scan_immediate">زی اسکنن ره ون</string>
|
||||
<string name="summary_pref_start_scan_immediate">شؽواتگرن سی اسکن، زی مجال ره وندن بۊگۊشین، اندی ترین کودن اسکن کۊنین یا شؽواتی ن منه نوار ٱوزار پسند کۊنین.</string>
|
||||
<string name="title_pref_start_scan_immediate">زی اسکنن ر ون</string>
|
||||
<string name="summary_pref_start_scan_immediate">شؽواتگرن سی اسکن، زی مجال ر وندن بۊگۊشین، اندی ترین کودن اسکن کۊنین یا شؽواتی ن منه نوار ٱوزار پسند کۊنین.</string>
|
||||
|
||||
<string name="title_pref_append_http_proxy">پروکسی HTTP ن و VPN ازاف کۊنین</string>
|
||||
<string name="summary_pref_append_http_proxy">پروکسی HTTP ن موسقیمن ز (مۊرۊرگر/ی قرد ز برنومیل لادراری بیڌه)، بؽ استفاڌه ز دسگا NIC مجازی (Android 10+) استفاڌه ابۊ.</string>
|
||||
@@ -238,7 +239,7 @@
|
||||
<string name="title_logcat">داسووا</string>
|
||||
<string name="logcat_copy">لف گیری</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_duplicate_config">پاک کردن کانفیگا تکراری جرگه سکویی</string>
|
||||
<string name="title_del_invalid_config">پاک کردن کانفیگا نا موئتبر جرگه سکویی</string>
|
||||
@@ -261,7 +262,11 @@
|
||||
<string name="filter_config_all">پوی جرگیل</string>
|
||||
<string name="title_del_duplicate_config_count">پاک کردن %d کانفیگ تکراری</string>
|
||||
|
||||
<string name="tasker_start_service">ره وندن خدمات</string>
|
||||
<string name="title_del_config_count">پاک کردن %d کانفیگ</string>
|
||||
<string name="title_import_config_count">و من ٱووردن %d کانفیگ</string>
|
||||
<string name="title_export_config_count">و در کشیڌن %d کانفیگ</string>
|
||||
<string name="title_update_config_count">ورۊ کردن %d کانفیگ</string>
|
||||
<string name="tasker_start_service">ر وندن خدمات</string>
|
||||
<string name="tasker_setting_confirm">قوۊل</string>
|
||||
|
||||
<string name="routing_settings_domain_strategy">نشقه دامنه</string>
|
||||
@@ -288,6 +293,7 @@
|
||||
|
||||
<string name="connection_test_pending">منپیزن واجۊری کوݩ</string>
|
||||
<string name="connection_test_testing">هونی آزمایش ابۊ…</string>
|
||||
<string name="connection_test_testing_count">%d کانفیگ هونی آزمایش ابۊ...</string>
|
||||
<string name="connection_test_available">مووفق بی: منپیز HTTP %dms تۊل کشی</string>
|
||||
<string name="connection_test_error">منپیز و اینترنتن نجوست: %s</string>
|
||||
<string name="connection_test_fail">اینترنت من دسرس نؽ</string>
|
||||
@@ -301,7 +307,7 @@
|
||||
<string name="title_pref_fragment_packets">Fragment Packets</string>
|
||||
<string name="title_pref_fragment_length">Fragment Length (min-max)</string>
|
||||
<string name="title_pref_fragment_interval">Fragment Interval (min-max)</string>
|
||||
<string name="title_pref_fragment_enabled">فعال کردن Fragment</string>
|
||||
<string name="title_pref_fragment_enabled">ر وندن Fragment</string>
|
||||
|
||||
<string-array name="share_method">
|
||||
<item>QRcode</item>
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
<string name="menu_item_import_config_manually_vless">تایپ دستی[VLESS]</string>
|
||||
<string name="menu_item_import_config_manually_ss">تایپ دستی[SHADOWSOCKS]</string>
|
||||
<string name="menu_item_import_config_manually_socks">تایپ دستی[SOCKS]</string>
|
||||
<string name="menu_item_import_config_manually_http">Type manually[HTTP]</string>
|
||||
<string name="menu_item_import_config_manually_http">تایپ دستی[HTTP]</string>
|
||||
<string name="menu_item_import_config_manually_trojan">تایپ دستی[TROJAN]</string>
|
||||
<string name="menu_item_import_config_manually_wireguard">WIREGUARD]تایپ دستی</string>
|
||||
<string name="menu_item_import_config_manually_hysteria2">TYPE MANUALLY[HYSTERIA2]</string>
|
||||
<string name="menu_item_import_config_manually_wireguard">تایپ دستی[WIREGUARD]</string>
|
||||
<string name="menu_item_import_config_manually_hysteria2">تایپ دستی[HYSTERIA2]</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">کانفیگ سفارشی را به صورت محلی وارد کنید</string>
|
||||
@@ -115,7 +115,7 @@
|
||||
<string name="server_lab_port_hop_interval">فاصله پورت پرش (ثانیه)</string>
|
||||
<string name="server_lab_stream_pinsha256">PINSHA256</string>
|
||||
<string name="server_lab_xhttp_mode">حالت XHTTP</string>
|
||||
<string name="server_lab_xhttp_extra">جیسون خام XHTTP EXTRA، فرمت: { XHTTPObject }</string>
|
||||
<string name="server_lab_xhttp_extra">خام JSON XHTTP Extra، قالب: { XHTTPObject }</string>
|
||||
|
||||
<!-- PerAppProxyActivity -->
|
||||
<string name="title_user_asset_add_url">آدرس اینترنتی را اضافه کنید</string>
|
||||
@@ -178,21 +178,21 @@
|
||||
<string name="title_pref_domestic_dns">DNS داخلی (اختیاری)</string>
|
||||
<string name="summary_pref_domestic_dns">DNS</string>
|
||||
|
||||
<string name="title_pref_dns_hosts">DNS مستقیم هاست(فرمت: دامنه: آدرس،…)</string>
|
||||
<string name="summary_pref_dns_hosts">دامنه: آدرس، …</string>
|
||||
|
||||
<string name="title_pref_delay_test_url">آدرس اینترنتی آزمایش تاخیر واقعی کانفیگ ها (HTTP/HTTPS)</string>
|
||||
<string name="summary_pref_delay_test_url">URL</string>
|
||||
|
||||
<string name="title_pref_proxy_sharing_enabled">اجازه اتصالات از طریق LAN</string>
|
||||
<string name="summary_pref_proxy_sharing_enabled">دستگاه های دیگر میتوانند از طریق socks/http به پراکسی توسط نشانی آیپی شما متصل شوند، فقط در شبکه مورد اعتماد فعال میشوند تا از اتصال غیرمجاز جلوگیری کنند.</string>
|
||||
<string name="summary_pref_proxy_sharing_enabled">سایر دستگاهها میتوانند با آدرس آیپی شما از طریق پراکسی محلی به پروکسی متصل شوند، فقط در شبکه قابل اعتماد فعال شود تا از اتصال غیرمجاز جلوگیری شود.</string>
|
||||
<string name="toast_warning_pref_proxysharing_short">اتصالات از طریق LAN را مجاز کنید، مطمئن شوید که در یک شبکه قابل اعتماد هستید</string>
|
||||
|
||||
<string name="title_pref_allow_insecure">مجوز ناامن</string>
|
||||
<string name="title_pref_allow_insecure">اعطای مجوز ناامن</string>
|
||||
<string name="summary_pref_allow_insecure">هنگام استفاده از TLS، به طور پیش فرض مجوز ناامن فعال است.</string>
|
||||
|
||||
<string name="title_pref_socks_port">پورت پروکسی SOCKS5</string>
|
||||
<string name="summary_pref_socks_port">پورت پروکسی SOCKS5</string>
|
||||
|
||||
<string name="title_pref_http_port">پورت پروکسی HTTP</string>
|
||||
<string name="summary_pref_http_port">پورت پروکسی HTTP</string>
|
||||
<string name="title_pref_socks_port">پورت پروکسی محلی</string>
|
||||
<string name="summary_pref_socks_port">پورت پروکسی محلی</string>
|
||||
|
||||
<string name="title_pref_local_dns_port">پورت DNS محلی</string>
|
||||
<string name="summary_pref_local_dns_port">پورت DNS محلی</string>
|
||||
@@ -259,6 +259,10 @@
|
||||
<string name="filter_config_all">همه گروههای اشتراک</string>
|
||||
<string name="title_del_duplicate_config_count">حذف %d کانفیگ تکراری</string>
|
||||
|
||||
<string name="title_del_config_count">حذف %d کانفیگ</string>
|
||||
<string name="title_import_config_count">وارد کردن %d کانفیگ</string>
|
||||
<string name="title_export_config_count">صادر کردن %d کانفیگ</string>
|
||||
<string name="title_update_config_count">آپدیت کردن %d کانفیگ</string>
|
||||
<string name="tasker_start_service">شروع خدمات</string>
|
||||
<string name="tasker_setting_confirm">تایید</string>
|
||||
|
||||
@@ -286,6 +290,7 @@
|
||||
|
||||
<string name="connection_test_pending">اتصال را بررسی کنید</string>
|
||||
<string name="connection_test_testing">در حال آزمایش...</string>
|
||||
<string name="connection_test_testing_count">تست کردن %d کانفیگ…</string>
|
||||
<string name="connection_test_available">موفقیت: اتصال HTTP %dms طول کشید</string>
|
||||
<string name="connection_test_error">اتصال به اینترنت شناسایی نشد: %s</string>
|
||||
<string name="connection_test_fail">اینترنت در دسترس نیست</string>
|
||||
|
||||
@@ -179,24 +179,24 @@
|
||||
<string name="title_pref_domestic_dns">Внутренняя DNS (необязательно)</string>
|
||||
<string name="summary_pref_domestic_dns">DNS</string>
|
||||
|
||||
<string name="title_pref_dns_hosts">Узлы DNS (формат: домен:адрес,…)</string>
|
||||
<string name="summary_pref_dns_hosts">домен:адрес,…</string>
|
||||
|
||||
<string name="title_pref_delay_test_url">Сервис проверки времени отклика (HTTP/HTTPS)</string>
|
||||
<string name="summary_pref_delay_test_url">URL</string>
|
||||
|
||||
<string name="title_pref_proxy_sharing_enabled">Разрешать подключения из LAN</string>
|
||||
<string name="summary_pref_proxy_sharing_enabled">Другие устройства могут подключаться, используя ваш IP-адрес, чтобы использовать прокси по протоколам SOCKS/HTTP. Используйте только в доверенной сети, чтобы избежать несанкционированного подключения.</string>
|
||||
<string name="summary_pref_proxy_sharing_enabled">Другие устройства могут подключаться, используя ваш IP-адрес, чтобы использовать локальный прокси. Используйте только в доверенной сети, чтобы избежать несанкционированного подключения.</string>
|
||||
<string name="toast_warning_pref_proxysharing_short">Доступ из LAN разрешён, убедитесь, что вы находитесь в доверенной сети</string>
|
||||
|
||||
<string name="title_pref_allow_insecure">Разрешать небезопасные</string>
|
||||
<string name="summary_pref_allow_insecure">Для TLS по умолчанию разрешены небезопасные соединения</string>
|
||||
|
||||
<string name="title_pref_socks_port">Порт SOCKS5-прокси</string>
|
||||
<string name="summary_pref_socks_port">Порт SOCKS5-прокси</string>
|
||||
<string name="title_pref_socks_port">Порт локального прокси</string>
|
||||
<string name="summary_pref_socks_port">Порт локального прокси</string>
|
||||
|
||||
<string name="title_pref_http_port">Порт HTTP-прокси</string>
|
||||
<string name="summary_pref_http_port">Порт HTTP-прокси</string>
|
||||
|
||||
<string name="title_pref_local_dns_port">Локальный порт DNS</string>
|
||||
<string name="summary_pref_local_dns_port">Локальный порт DNS</string>
|
||||
<string name="title_pref_local_dns_port">Порт локальной DNS</string>
|
||||
<string name="summary_pref_local_dns_port">Порт локальной DNS</string>
|
||||
|
||||
<string name="title_pref_confirm_remove">Подтверждение удаления профиля</string>
|
||||
<string name="summary_pref_confirm_remove">Требовать двойное подтверждение удаления профиля</string>
|
||||
@@ -260,6 +260,10 @@
|
||||
<string name="title_filter_config">Фильтр групп</string>
|
||||
<string name="filter_config_all">Все группы</string>
|
||||
<string name="title_del_duplicate_config_count">Удалено дубликатов профилей: %d</string>
|
||||
<string name="title_del_config_count">Удалено профилей: %d</string>
|
||||
<string name="title_import_config_count">Импортировано профилей: %d</string>
|
||||
<string name="title_export_config_count">Экспортировано профилей: %d</string>
|
||||
<string name="title_update_config_count">Обновлено профилей: %d</string>
|
||||
|
||||
<string name="tasker_start_service">Запуск службы</string>
|
||||
<string name="tasker_setting_confirm">Подтвердить</string>
|
||||
@@ -288,6 +292,7 @@
|
||||
|
||||
<string name="connection_test_pending">Проверить подключение</string>
|
||||
<string name="connection_test_testing">Проверка…</string>
|
||||
<string name="connection_test_testing_count">Проверка профилей: %d</string>
|
||||
<string name="connection_test_available">Успешно: HTTP-соединение заняло %d мс</string>
|
||||
<string name="connection_test_error">Сбой проверки интернет-соединения: %s</string>
|
||||
<string name="connection_test_fail">Интернет недоступен</string>
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
<string name="server_lab_encryption">Mã hóa</string>
|
||||
<string name="server_lab_flow">Kiểm soát lưu lượng (Flow)</string>
|
||||
<string name="server_lab_public_key">PublicKey</string>
|
||||
<string name="server_lab_preshared_key">PreSharedKey(optional)</string>
|
||||
<string name="server_lab_short_id">ShortId</string>
|
||||
<string name="server_lab_spider_x">SpiderX</string>
|
||||
<string name="server_lab_secret_key">SecretKey</string>
|
||||
@@ -178,6 +179,9 @@
|
||||
<string name="title_pref_domestic_dns">DNS nội địa (Không bắt buộc)</string>
|
||||
<string name="summary_pref_domestic_dns">DNS</string>
|
||||
|
||||
<string name="title_pref_dns_hosts">DNS hosts (Format: domain:address,…)</string>
|
||||
<string name="summary_pref_dns_hosts">domain:address,…</string>
|
||||
|
||||
<string name="title_pref_delay_test_url">URL kiểm tra độ trễ thực (HTTP / HTTPS)</string>
|
||||
<string name="summary_pref_delay_test_url">URL</string>
|
||||
|
||||
@@ -188,11 +192,8 @@
|
||||
<string name="title_pref_allow_insecure">Bỏ qua xác minh chứng chỉ</string>
|
||||
<string name="summary_pref_allow_insecure">Khi nhập những cấu hình có bảo mật TLS, mặc định sẽ không xác minh chứng chỉ.</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="title_pref_http_port">Cổng Proxy HTTP</string>
|
||||
<string name="summary_pref_http_port">Cổng Proxy HTTP</string>
|
||||
<string name="title_pref_socks_port">Cổng Proxy Local</string>
|
||||
<string name="summary_pref_socks_port">Cổng Proxy Local</string>
|
||||
|
||||
<string name="title_pref_local_dns_port">Cổng Local DNS</string>
|
||||
<string name="summary_pref_local_dns_port">Cổng Local DNS</string>
|
||||
@@ -214,6 +215,7 @@
|
||||
<string name="title_privacy_policy">Chính sách bảo mật</string>
|
||||
<string name="title_about">Giới thiệu</string>
|
||||
<string name="title_source_code">Mã nguồn</string>
|
||||
<string name="title_oss_license">Open Source licenses</string>
|
||||
<string name="title_tg_channel">Kênh Telegram</string>
|
||||
<string name="title_configuration_backup">Sao lưu cấu hình</string>
|
||||
<string name="summary_configuration_backup">Nơi lưu trữ: [%s], bản backup sẽ được dọn dẹp sau khi xóa ứng dụng hoặc xóa bộ nhớ.</string>
|
||||
@@ -259,6 +261,10 @@
|
||||
<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">Xoá %d cấu hình trùng lặp</string>
|
||||
|
||||
<string name="title_del_config_count">Delete %d configurations</string>
|
||||
<string name="title_import_config_count">Import %d configurations</string>
|
||||
<string name="title_export_config_count">Export %d configurations</string>
|
||||
<string name="title_update_config_count">Update %d configurations</string>
|
||||
<string name="tasker_start_service">Khởi động v2rayNG</string>
|
||||
<string name="tasker_setting_confirm">Xác nhận</string>
|
||||
|
||||
@@ -278,6 +284,7 @@
|
||||
|
||||
<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_count">Testing %d configurations…</string>
|
||||
<string name="connection_test_available">Kiểm tra thành công: thời gian truy cập Google là %d ms</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>
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
<string name="server_lab_encryption">加密方式(encryption)</string>
|
||||
<string name="server_lab_flow">流控(flow)</string>
|
||||
<string name="server_lab_public_key">PublicKey</string>
|
||||
<string name="server_lab_preshared_key">PreSharedKey(optional)</string>
|
||||
<string name="server_lab_short_id">ShortId</string>
|
||||
<string name="server_lab_spider_x">SpiderX</string>
|
||||
<string name="server_lab_secret_key">SecretKey</string>
|
||||
@@ -175,6 +176,9 @@
|
||||
<string name="title_pref_domestic_dns">境内DNS (可选)</string>
|
||||
<string name="summary_pref_domestic_dns">DNS</string>
|
||||
|
||||
<string name="title_pref_dns_hosts">DNS hosts (格式: 域名:地址,…)</string>
|
||||
<string name="summary_pref_dns_hosts">domain:address,…</string>
|
||||
|
||||
<string name="title_pref_delay_test_url">真连接延迟测试网址 (http/https)</string>
|
||||
<string name="summary_pref_delay_test_url">Url</string>
|
||||
|
||||
@@ -185,11 +189,8 @@
|
||||
<string name="title_pref_allow_insecure">跳过证书验证(allowInsecure)</string>
|
||||
<string name="summary_pref_allow_insecure">传输层安全选tls时,默认跳过证书验证(allowInsecure)</string>
|
||||
|
||||
<string name="title_pref_socks_port">SOCKS5代理端口</string>
|
||||
<string name="summary_pref_socks_port">SOCKS5代理端口</string>
|
||||
|
||||
<string name="title_pref_http_port">HTTP代理端口</string>
|
||||
<string name="summary_pref_http_port">HTTP代理端口</string>
|
||||
<string name="title_pref_socks_port">本地代理端口</string>
|
||||
<string name="summary_pref_socks_port">本地代理端口</string>
|
||||
|
||||
<string name="title_pref_local_dns_port">本地DNS端口</string>
|
||||
<string name="summary_pref_local_dns_port">本地DNS端口</string>
|
||||
@@ -210,6 +211,7 @@
|
||||
<string name="title_privacy_policy">隐私权政策</string>
|
||||
<string name="title_about">关于</string>
|
||||
<string name="title_source_code">源代码</string>
|
||||
<string name="title_oss_license">Open Source licenses</string>
|
||||
<string name="title_tg_channel">Telegram 频道</string>
|
||||
<string name="title_configuration_backup">备份配置</string>
|
||||
<string name="summary_configuration_backup">存储位置: [%s], 卸载App或清除存储后备份将被清除</string>
|
||||
@@ -256,6 +258,10 @@
|
||||
<string name="filter_config_all">所有分组</string>
|
||||
<string name="title_del_duplicate_config_count">删除 %d 个重复配置</string>
|
||||
|
||||
<string name="title_del_config_count">删除 %d 个配置</string>
|
||||
<string name="title_import_config_count">导入 %d 个配置</string>
|
||||
<string name="title_export_config_count">导出 %d 个配置</string>
|
||||
<string name="title_update_config_count">更新 %d 个配置</string>
|
||||
<string name="tasker_start_service">启动服务</string>
|
||||
<string name="tasker_setting_confirm">确定</string>
|
||||
|
||||
@@ -275,6 +281,7 @@
|
||||
|
||||
<string name="connection_test_pending">"检查网络连接"</string>
|
||||
<string name="connection_test_testing">"测试中…"</string>
|
||||
<string name="connection_test_testing_count">测试 %d 个配置中…</string>
|
||||
<string name="connection_test_available">"连接成功:延时 %d 毫秒"</string>
|
||||
<string name="connection_test_error">"失败:%s"</string>
|
||||
<string name="connection_test_fail">"无互联网连接"</string>
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
<string name="server_lab_encryption">加密 (encryption)</string>
|
||||
<string name="server_lab_flow">流程 (flow)</string>
|
||||
<string name="server_lab_public_key">PublicKey</string>
|
||||
<string name="server_lab_preshared_key">PreSharedKey(optional)</string>
|
||||
<string name="server_lab_short_id">ShortId</string>
|
||||
<string name="server_lab_spider_x">SpiderX</string>
|
||||
<string name="server_lab_secret_key">SecretKey</string>
|
||||
@@ -174,8 +175,8 @@
|
||||
|
||||
<string name="title_pref_vpn_dns">VPN DNS (僅支援 IPv4/v6)</string>
|
||||
|
||||
<string name="title_pref_domestic_dns">國內 DNS (可選)</string>
|
||||
<string name="summary_pref_domestic_dns">DNS</string>
|
||||
<string name="title_pref_dns_hosts">DNS hosts (格式: 網域:位址,…)</string>
|
||||
<string name="summary_pref_dns_hosts">domain:address,…</string>
|
||||
|
||||
<string name="title_pref_delay_test_url">真連線延遲測試網址 (http/https)</string>
|
||||
<string name="summary_pref_delay_test_url">Url</string>
|
||||
@@ -187,11 +188,8 @@
|
||||
<string name="title_pref_allow_insecure">跳過憑證驗證 (allowInsecure)</string>
|
||||
<string name="summary_pref_allow_insecure">傳輸層安全選 tls 時,預設跳過憑證驗證 (allowInsecure)</string>
|
||||
|
||||
<string name="title_pref_socks_port">SOCKS5 Proxy 埠</string>
|
||||
<string name="summary_pref_socks_port">SOCKS5 Proxy 埠</string>
|
||||
|
||||
<string name="title_pref_http_port">HTTP Proxy 埠</string>
|
||||
<string name="summary_pref_http_port">HTTP Proxy 埠</string>
|
||||
<string name="title_pref_socks_port">本地 Proxy 埠</string>
|
||||
<string name="summary_pref_socks_port">本地 Proxy 埠</string>
|
||||
|
||||
<string name="title_pref_local_dns_port">本機 DNS 埠</string>
|
||||
<string name="summary_pref_local_dns_port">本機 DNS 埠</string>
|
||||
@@ -212,6 +210,7 @@
|
||||
<string name="title_privacy_policy">隱私權政策</string>
|
||||
<string name="title_about">關於</string>
|
||||
<string name="title_source_code">原始碼</string>
|
||||
<string name="title_oss_license">Open Source licenses</string>
|
||||
<string name="title_tg_channel">Telegram 頻道</string>
|
||||
<string name="title_configuration_backup">備份設定</string>
|
||||
<string name="summary_configuration_backup">儲存位置: [%s], 卸載App或清除儲存後備份將被清除</string>
|
||||
@@ -256,8 +255,12 @@
|
||||
<string name="title_sort_by_test_results">依偵測結果排序</string>
|
||||
<string name="title_filter_config">過濾設定</string>
|
||||
<string name="filter_config_all">所有分組</string>
|
||||
<string name="title_del_duplicate_config_count">Delete %d duplicate configurations</string>
|
||||
<string name="title_del_duplicate_config_count">删除 %d 个重复配置</string>
|
||||
|
||||
<string name="title_del_config_count">删除 %d 个配置</string>
|
||||
<string name="title_import_config_count">导入 %d 个配置</string>
|
||||
<string name="title_export_config_count">导出 %d 个配置</string>
|
||||
<string name="title_update_config_count">更新 %d 个配置</string>
|
||||
<string name="tasker_start_service">啟動服務</string>
|
||||
<string name="tasker_setting_confirm">確定</string>
|
||||
|
||||
@@ -277,6 +280,7 @@
|
||||
|
||||
<string name="connection_test_pending">"測試連線能力"</string>
|
||||
<string name="connection_test_testing">"測試中……"</string>
|
||||
<string name="connection_test_testing_count">測試 %d 个配置中…</string>
|
||||
<string name="connection_test_available">"成功:%d ms延遲"</string>
|
||||
<string name="connection_test_error">"測試網際網路連線失敗:%s"</string>
|
||||
<string name="connection_test_fail">"無法使用網際網路"</string>
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
<item>ws</item>
|
||||
<item>httpupgrade</item>
|
||||
<item>xhttp</item>
|
||||
<item>splithttp</item>
|
||||
<item>h2</item>
|
||||
<item>grpc</item>
|
||||
</string-array>
|
||||
@@ -210,5 +209,6 @@
|
||||
<item>auto</item>
|
||||
<item>packet-up</item>
|
||||
<item>stream-up</item>
|
||||
<item>stream-one</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -182,21 +182,21 @@
|
||||
<string name="title_pref_domestic_dns">Domestic DNS (Optional)</string>
|
||||
<string name="summary_pref_domestic_dns">DNS</string>
|
||||
|
||||
<string name="title_pref_dns_hosts">DNS hosts (Format: domain:address,…)</string>
|
||||
<string name="summary_pref_dns_hosts">domain:address,…</string>
|
||||
|
||||
<string name="title_pref_delay_test_url">True delay test url (http/https)</string>
|
||||
<string name="summary_pref_delay_test_url">Url</string>
|
||||
|
||||
<string name="title_pref_proxy_sharing_enabled">Allow connections from the LAN</string>
|
||||
<string name="summary_pref_proxy_sharing_enabled">Other devices can connect to proxy by your ip address through socks/http, Only enable in trusted network to avoid unauthorized connection</string>
|
||||
<string name="summary_pref_proxy_sharing_enabled">Other devices can connect to proxy by your ip address through local proxy, Only enable in trusted network to avoid unauthorized connection</string>
|
||||
<string name="toast_warning_pref_proxysharing_short">Allow connections from the LAN, Make sure you are in a trusted network</string>
|
||||
|
||||
<string name="title_pref_allow_insecure">allowInsecure</string>
|
||||
<string name="summary_pref_allow_insecure">When TLS, the default allowInsecure</string>
|
||||
|
||||
<string name="title_pref_socks_port">SOCKS5 proxy port</string>
|
||||
<string name="summary_pref_socks_port">SOCKS5 proxy port</string>
|
||||
|
||||
<string name="title_pref_http_port">HTTP proxy port</string>
|
||||
<string name="summary_pref_http_port">HTTP proxy port</string>
|
||||
<string name="title_pref_socks_port">Local proxy port</string>
|
||||
<string name="summary_pref_socks_port">Local proxy port</string>
|
||||
|
||||
<string name="title_pref_local_dns_port">Local DNS port</string>
|
||||
<string name="summary_pref_local_dns_port">Local DNS port</string>
|
||||
@@ -263,6 +263,10 @@
|
||||
<string name="title_filter_config">Filter configuration file</string>
|
||||
<string name="filter_config_all">All groups</string>
|
||||
<string name="title_del_duplicate_config_count">Delete %d duplicate configurations</string>
|
||||
<string name="title_del_config_count">Delete %d configurations</string>
|
||||
<string name="title_import_config_count">Import %d configurations</string>
|
||||
<string name="title_export_config_count">Export %d configurations</string>
|
||||
<string name="title_update_config_count">Update %d configurations</string>
|
||||
|
||||
<string name="tasker_start_service">Start Service</string>
|
||||
<string name="tasker_setting_confirm">Confirm</string>
|
||||
@@ -291,6 +295,7 @@
|
||||
|
||||
<string name="connection_test_pending">Check Connectivity</string>
|
||||
<string name="connection_test_testing">Testing…</string>
|
||||
<string name="connection_test_testing_count">Testing %d configurations…</string>
|
||||
<string name="connection_test_available">Success: HTTP connection took %dms</string>
|
||||
<string name="connection_test_error">Fail to detect internet connection: %s</string>
|
||||
<string name="connection_test_fail">Internet Unavailable</string>
|
||||
|
||||
@@ -180,12 +180,6 @@
|
||||
android:summary="10808"
|
||||
android:title="@string/title_pref_socks_port" />
|
||||
|
||||
<EditTextPreference
|
||||
android:inputType="number"
|
||||
android:key="pref_http_port"
|
||||
android:summary="10809"
|
||||
android:title="@string/title_pref_http_port" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="pref_remote_dns"
|
||||
android:summary="@string/summary_pref_remote_dns"
|
||||
@@ -196,6 +190,11 @@
|
||||
android:summary="@string/summary_pref_domestic_dns"
|
||||
android:title="@string/title_pref_domestic_dns" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="pref_dns_hosts"
|
||||
android:summary="@string/summary_pref_dns_hosts"
|
||||
android:title="@string/title_pref_dns_hosts" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="pref_delay_test_url"
|
||||
android:summary="@string/summary_pref_delay_test_url"
|
||||
|
||||
@@ -7,7 +7,7 @@ plugins {
|
||||
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath(libs.oss.licenses.plugin)
|
||||
classpath(libs.gradle.license.plugin)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. For more details, visit
|
||||
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
[versions]
|
||||
agp = "8.7.2"
|
||||
desugar_jdk_libs = "2.1.4"
|
||||
gradleLicensePlugin = "0.9.8"
|
||||
kotlin = "2.1.0"
|
||||
coreKtx = "1.15.0"
|
||||
junit = "4.13.2"
|
||||
@@ -9,16 +11,14 @@ appcompat = "1.7.0"
|
||||
material = "1.12.0"
|
||||
activity = "1.9.3"
|
||||
constraintlayout = "2.2.0"
|
||||
mmkvStatic = "1.3.9"
|
||||
mmkvStatic = "1.3.11"
|
||||
gson = "2.11.0"
|
||||
ossLicensesPlugin = "0.10.6"
|
||||
playServicesOssLicenses = "17.1.0"
|
||||
quickieFoss = "1.13.1"
|
||||
rxjava = "3.1.9"
|
||||
rxandroid = "3.0.2"
|
||||
rxpermissions = "0.12"
|
||||
toastcompat = "1.1.0"
|
||||
editorkit = "2.9.0"
|
||||
quickieBundled = "1.10.0"
|
||||
core = "3.5.3"
|
||||
workRuntimeKtx = "2.10.0"
|
||||
lifecycleViewmodelKtx = "2.8.7"
|
||||
@@ -29,6 +29,8 @@ preferenceKtx = "1.2.1"
|
||||
recyclerview = "1.3.2"
|
||||
[libraries]
|
||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
desugar_jdk_libs = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugar_jdk_libs" }
|
||||
gradle-license-plugin = { module = "com.jaredsburrows:gradle-license-plugin", version.ref = "gradleLicensePlugin" }
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
||||
@@ -38,8 +40,7 @@ androidx-activity = { group = "androidx.activity", name = "activity", version.re
|
||||
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
||||
mmkv-static = { module = "com.tencent:mmkv-static", version.ref = "mmkvStatic" }
|
||||
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
|
||||
oss-licenses-plugin = { module = "com.google.android.gms:oss-licenses-plugin", version.ref = "ossLicensesPlugin" }
|
||||
play-services-oss-licenses = { module = "com.google.android.gms:play-services-oss-licenses", version.ref = "playServicesOssLicenses" }
|
||||
quickie-foss = { module = "com.github.T8RIN.QuickieExtended:quickie-foss", version.ref = "quickieFoss" }
|
||||
rxjava = { module = "io.reactivex.rxjava3:rxjava", version.ref = "rxjava" }
|
||||
rxandroid = { module = "io.reactivex.rxjava3:rxandroid", version.ref = "rxandroid" }
|
||||
rxpermissions = { module = "com.github.tbruyelle:rxpermissions", version.ref = "rxpermissions" }
|
||||
@@ -47,7 +48,6 @@ toastcompat = { module = "me.drakeet.support:toastcompat", version.ref = "toastc
|
||||
editorkit = { module = "com.blacksquircle.ui:editorkit", version.ref = "editorkit" }
|
||||
language-base = { module = "com.blacksquircle.ui:language-base", version.ref = "editorkit" }
|
||||
language-json = { module = "com.blacksquircle.ui:language-json", version.ref = "editorkit" }
|
||||
quickie-bundled = { module = "io.github.g00fy2.quickie:quickie-bundled", version.ref = "quickieBundled" }
|
||||
core = { module = "com.google.zxing:core", version.ref = "core" }
|
||||
work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "workRuntimeKtx" }
|
||||
work-multiprocess = { module = "androidx.work:work-multiprocess", version.ref = "workRuntimeKtx" }
|
||||
|
||||
@@ -16,7 +16,6 @@ dependencyResolutionManagement {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
maven { url = uri("https://jitpack.io") }
|
||||
}
|
||||
}
|
||||
|
||||
27
fastlane/metadata/android/en-US/full_description.txt
Normal file
27
fastlane/metadata/android/en-US/full_description.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
<p>A V2Ray client for Android, support <a href="https://github.com/XTLS/Xray-core">Xray core</a> and <a href="https://github.com/v2fly/v2ray-core">v2fly core</a></p>
|
||||
|
||||
<h3>Telegram Channel</h3>
|
||||
|
||||
<p><a href="https://t.me/github_2dust">github_2dust</a></p>
|
||||
|
||||
<h3>Usage</h3>
|
||||
|
||||
<h4>Geoip and Geosite</h4>
|
||||
|
||||
<ul>
|
||||
<li>geoip.dat and geosite.dat files are in <code>Android/data/com.v2ray.ang/files/assets</code> (path may differ on some Android device)</li>
|
||||
<li>download feature will get enhanced version in this <a href="https://github.com/Loyalsoldier/v2ray-rules-dat">repo</a> (Note it need a working proxy)</li>
|
||||
<li>latest official <a href="https://github.com/v2fly/domain-list-community">domain list</a> and <a href="https://github.com/v2fly/geoip">ip list</a> can be imported manually</li>
|
||||
<li>possible to use third party dat file in the same folder, like <a href="https://guide.v2fly.org/routing/sitedata.html#%E5%A4%96%E7%BD%AE%E7%9A%84%E5%9F%9F%E5%90%8D%E6%96%87%E4%BB%B6">h2y</a></li>
|
||||
</ul>
|
||||
|
||||
<h3>More in our <a href="https://github.com/2dust/v2rayNG/wiki">wiki</a></h3>
|
||||
|
||||
<h3>Development guide</h3>
|
||||
|
||||
<p>Android project under V2rayNG folder can be compiled directly in Android Studio, or using Gradle wrapper. But the v2ray core inside the aar is (probably) outdated.
|
||||
The aar can be compiled from the Golang project <a href="https://github.com/2dust/AndroidLibV2rayLite">AndroidLibV2rayLite</a> or <a href="https://github.com/2dust/AndroidLibXrayLite">AndroidLibXrayLite</a>.
|
||||
For a quick start, read guide for <a href="https://github.com/golang/go/wiki/Mobile">Go Mobile</a> and <a href="https://tutorialedge.net/golang/makefiles-for-go-developers/">Makefiles for Go Developers</a></p>
|
||||
|
||||
<p>v2rayNG can run on Android Emulators. For WSA, VPN permission need to be granted via
|
||||
<code>appops set [package name] ACTIVATE_VPN allow</code></p>
|
||||
BIN
fastlane/metadata/android/en-US/images/icon.png
Normal file
BIN
fastlane/metadata/android/en-US/images/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
1
fastlane/metadata/android/en-US/short_description.txt
Normal file
1
fastlane/metadata/android/en-US/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
A V2Ray client for Android, support Xray core and v2fly core
|
||||
1
fastlane/metadata/android/en-US/title.txt
Normal file
1
fastlane/metadata/android/en-US/title.txt
Normal file
@@ -0,0 +1 @@
|
||||
v2rayNG
|
||||
Reference in New Issue
Block a user