Add local SOCKS username/password support

This commit is contained in:
2dust committed 2026-04-13 20:17:30 +08:00
1 parent de91fb27db
commit e54e713db7
15 files changed
+98 -6

No files matched your search

@@ -58,6 +58,8 @@ 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_SOCKS_USERNAME = "pref_socks_username"
const val PREF_SOCKS_PASSWORD = "pref_socks_password"
const val PREF_REMOTE_DNS = "pref_remote_dns"
const val PREF_DOMESTIC_DNS = "pref_domestic_dns"
const val PREF_DNS_HOSTS = "pref_dns_hosts"
@@ -44,10 +44,16 @@ data class V2rayConfig(
var auth: String? = null,
var udp: Boolean? = null,
var userLevel: Int? = null,
var accounts: List<SocksAccountBean>? = null,
var name: String? = null,
@SerializedName("MTU")
var mtu: Int? = null
)
) {
data class SocksAccountBean(
var user: String = "",
var pass: String = ""
)
}
data class SniffingBean(
var enabled: Boolean,
@@ -276,6 +276,14 @@ object SettingsManager {
return Utils.parseInt(MmkvManager.decodeSettingsString(AppConfig.PREF_SOCKS_PORT), AppConfig.PORT_SOCKS.toInt())
}
fun getSocksUsername(): String? {
return MmkvManager.decodeSettingsString(AppConfig.PREF_SOCKS_USERNAME)?.trim()?.takeIf { it.isNotEmpty() }
}
fun getSocksPassword(): String? {
return MmkvManager.decodeSettingsString(AppConfig.PREF_SOCKS_PASSWORD)?.trim()?.takeIf { it.isNotEmpty() }
}
/**
* Get the HTTP port.
* @return The HTTP port.
@@ -373,12 +373,29 @@ object V2rayConfigManager {
private fun getInbounds(v2rayConfig: V2rayConfig): Boolean {
try {
val socksPort = SettingsManager.getSocksPort()
val socksUsername = SettingsManager.getSocksUsername()
val socksPassword = SettingsManager.getSocksPassword()
val inbound1 = v2rayConfig.inbounds[0]
if (inbound1.settings == null) {
inbound1.settings = V2rayConfig.InboundBean.InSettingsBean()
}
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_PROXY_SHARING) != true) {
inbound1.listen = AppConfig.LOOPBACK
}
inbound1.port = socksPort
if (socksUsername != null && socksPassword != null) {
inbound1.settings?.auth = "password"
inbound1.settings?.accounts = listOf(
V2rayConfig.InboundBean.InSettingsBean.SocksAccountBean(
user = socksUsername,
pass = socksPassword
)
)
} else {
inbound1.settings?.auth = "noauth"
inbound1.settings?.accounts = null
}
val fakedns = MmkvManager.decodeSettingsBool(AppConfig.PREF_FAKE_DNS_ENABLED) == true
val sniffAllTlsAndHttp =
MmkvManager.decodeSettingsBool(AppConfig.PREF_SNIFFING_ENABLED, true) != false
@@ -57,7 +57,11 @@ class TProxyService(
private fun buildConfig(): String {
val socksPort = SettingsManager.getSocksPort()
val socksUsername = SettingsManager.getSocksUsername()
val socksPassword = SettingsManager.getSocksPassword()
val vpnConfig = SettingsManager.getCurrentVpnInterfaceAddressConfig()
val escapedSocksUsername = socksUsername?.replace("'", "''")
val escapedSocksPassword = socksPassword?.replace("'", "''")
return buildString {
appendLine("tunnel:")
appendLine(" mtu: ${SettingsManager.getVpnMtu()}")
@@ -71,6 +75,10 @@ class TProxyService(
appendLine(" port: ${socksPort}")
appendLine(" address: ${AppConfig.LOOPBACK}")
appendLine(" udp: 'udp'")
if (escapedSocksUsername != null && escapedSocksPassword != null) {
appendLine(" username: '${escapedSocksUsername}'")
appendLine(" password: '${escapedSocksPassword}'")
}
// Read-write timeout settings
val timeoutSetting = MmkvManager.decodeSettingsString(AppConfig.PREF_HEV_TUNNEL_RW_TIMEOUT) ?: AppConfig.HEVTUN_RW_TIMEOUT
@@ -118,9 +118,17 @@ class SettingsActivity : BaseActivity() {
fun updateSummary(pref: androidx.preference.Preference) {
when (pref) {
is EditTextPreference -> {
pref.summary = pref.text.orEmpty()
if (pref.key == AppConfig.PREF_SOCKS_PASSWORD) {
pref.summary = if (pref.text.isNullOrEmpty()) "" else "******"
} else {
pref.summary = pref.text.orEmpty()
}
pref.setOnPreferenceChangeListener { p, newValue ->
p.summary = (newValue as? String).orEmpty()
if (p.key == AppConfig.PREF_SOCKS_PASSWORD) {
p.summary = if ((newValue as? String).isNullOrEmpty()) "" else "******"
} else {
p.summary = (newValue as? String).orEmpty()
}
true
}
}
@@ -219,6 +219,10 @@
<string name="title_pref_socks_port">منفذ بروكسي Local</string>
<string name="summary_pref_socks_port">منفذ بروكسي Local</string>
<string name="title_pref_socks_username">Local proxy username (optional)</string>
<string name="summary_pref_socks_username">Username</string>
<string name="title_pref_socks_password">Local proxy password (optional)</string>
<string name="summary_pref_socks_password">Password</string>
<string name="title_pref_local_dns_port">منفذ DNS المحلي</string>
<string name="summary_pref_local_dns_port">منفذ DNS المحلي</string>
@@ -219,6 +219,10 @@
<string name="title_pref_socks_port">Local প্রক্সি পোর্ট</string>
<string name="summary_pref_socks_port">Local প্রক্সি পোর্ট</string>
<string name="title_pref_socks_username">Local proxy username (optional)</string>
<string name="summary_pref_socks_username">Username</string>
<string name="title_pref_socks_password">Local proxy password (optional)</string>
<string name="summary_pref_socks_password">Password</string>
<string name="title_pref_local_dns_port">স্থানীয় DNS পোর্ট</string>
<string name="summary_pref_local_dns_port">স্থানীয় DNS পোর্ট</string>
@@ -217,6 +217,10 @@
<string name="title_pref_socks_port">پورت پروکسی محلی</string>
<string name="summary_pref_socks_port">پورت پروکسی محلی</string>
<string name="title_pref_socks_username">Local proxy username (optional)</string>
<string name="summary_pref_socks_username">Username</string>
<string name="title_pref_socks_password">Local proxy password (optional)</string>
<string name="summary_pref_socks_password">Password</string>
<string name="title_pref_local_dns_port">پورت DNS محلی</string>
<string name="summary_pref_local_dns_port">پورت DNS محلی</string>
@@ -218,6 +218,10 @@
<string name="title_pref_socks_port">Порт локального прокси</string>
<string name="summary_pref_socks_port">Порт локального прокси</string>
<string name="title_pref_socks_username">Имя пользователя локального прокси (опционально)</string>
<string name="summary_pref_socks_username">Имя пользователя</string>
<string name="title_pref_socks_password">Пароль локального прокси (опционально)</string>
<string name="summary_pref_socks_password">Пароль</string>
<string name="title_pref_local_dns_port">Порт локальной DNS</string>
<string name="summary_pref_local_dns_port">Порт локальной DNS</string>
@@ -219,6 +219,10 @@
<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_socks_username">Tên người dùng Proxy Local (Không bắt buộc)</string>
<string name="summary_pref_socks_username">Tên người dùng</string>
<string name="title_pref_socks_password">Mật khẩu Proxy Local (Không bắt buộc)</string>
<string name="summary_pref_socks_password">Mật khẩu</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,10 +214,14 @@
<string name="title_pref_allow_insecure">跳过证书验证 (allowInsecure)</string>
<string name="summary_pref_allow_insecure">传输层安全选 tls 时,默认跳过证书验证 (allowInsecure)</string>
<string name="title_pref_socks_port">本地代理端口</string>
<string name="summary_pref_socks_port">本地代理端口</string>
<string name="title_pref_socks_port">本地代理端口</string>
<string name="summary_pref_socks_port">本地代理端口</string>
<string name="title_pref_socks_username">本地代理用户名 (可选)</string>
<string name="summary_pref_socks_username">用户名</string>
<string name="title_pref_socks_password">本地代理密码 (可选)</string>
<string name="summary_pref_socks_password">密码</string>
<string name="title_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>
@@ -217,6 +217,10 @@
<string name="title_pref_socks_port">本地代理埠</string>
<string name="summary_pref_socks_port">本地代理埠</string>
<string name="title_pref_socks_username">本地代理使用者名稱 (選擇)</string>
<string name="summary_pref_socks_username">使用者名稱</string>
<string name="title_pref_socks_password">本地代理密碼 (選擇)</string>
<string name="summary_pref_socks_password">密碼</string>
<string name="title_pref_local_dns_port">本機 DNS 埠</string>
<string name="summary_pref_local_dns_port">本機 DNS 埠</string>
@@ -222,6 +222,10 @@
<string name="title_pref_socks_port">Local proxy port</string>
<string name="summary_pref_socks_port">Local proxy port</string>
<string name="title_pref_socks_username">Local proxy username (optional)</string>
<string name="summary_pref_socks_username">Username</string>
<string name="title_pref_socks_password">Local proxy password (optional)</string>
<string name="summary_pref_socks_password">Password</string>
<string name="title_pref_local_dns_port">Local DNS port</string>
<string name="summary_pref_local_dns_port">Local DNS port</string>
@@ -157,6 +157,17 @@
android:summary="10808"
android:title="@string/title_pref_socks_port" />
<EditTextPreference
android:key="pref_socks_username"
android:summary="@string/summary_pref_socks_username"
android:title="@string/title_pref_socks_username" />
<EditTextPreference
android:inputType="textPassword"
android:key="pref_socks_password"
android:summary="@string/summary_pref_socks_password"
android:title="@string/title_pref_socks_password" />
<EditTextPreference
android:key="pref_remote_dns"
android:summary="@string/summary_pref_remote_dns"