Skip to content

Commit

Permalink
feat(network): socks5 proxy support (#530)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sadwhy authored Nov 19, 2024
1 parent a4bd367 commit ff33727
Show file tree
Hide file tree
Showing 11 changed files with 399 additions and 7 deletions.
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@
android:parentActivityName=".MainActivity" />
<activity
android:name=".settings.SettingsExtensionsActivity"
android:parentActivityName=".MainActivity" />
android:parentActivityName=".MainActivity"
android:windowSoftInputMode="adjustPan"/>
<activity
android:name=".settings.SettingsAddonActivity"
android:parentActivityName=".MainActivity" />
Expand Down
71 changes: 71 additions & 0 deletions app/src/main/java/ani/dantotsu/settings/ProxyDialogFragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package ani.dantotsu.settings

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import ani.dantotsu.BottomSheetDialogFragment
import ani.dantotsu.databinding.BottomSheetProxyBinding
import ani.dantotsu.snackString
import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.restartApp

class ProxyDialogFragment : BottomSheetDialogFragment() {
private var _binding: BottomSheetProxyBinding? = null
private val binding get() = _binding!!

private var proxyHost: String? = PrefManager.getVal<String>(PrefName.Socks5ProxyHost) ?: ""
private var proxyPort: String? = PrefManager.getVal<String>(PrefName.Socks5ProxyPort) ?: ""
private var proxyUsername: String? = PrefManager.getVal<String>(PrefName.Socks5ProxyUsername) ?: ""
private var proxyPassword: String? = PrefManager.getVal<String>(PrefName.Socks5ProxyPassword) ?: ""
private var authEnabled: Boolean = PrefManager.getVal<Boolean>(PrefName.ProxyAuthEnabled)
private val proxyEnabled: Boolean = PrefManager.getVal<Boolean>(PrefName.EnableSocks5Proxy)

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = BottomSheetProxyBinding.inflate(inflater, container, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

binding.proxyHost.setText(proxyHost)
binding.proxyPort.setText(proxyPort)
binding.proxyUsername.setText(proxyUsername)
binding.proxyPassword.setText(proxyPassword)
binding.proxyAuthentication.isChecked = authEnabled

binding.proxySave.setOnClickListener {
proxyHost = binding.proxyHost.text.toString() ?: ""
proxyPort = binding.proxyPort.text.toString() ?: ""
proxyUsername = binding.proxyUsername.text.toString() ?: ""
proxyPassword = binding.proxyPassword.text.toString() ?: ""

PrefManager.setVal(PrefName.Socks5ProxyHost, proxyHost)
PrefManager.setVal(PrefName.Socks5ProxyPort, proxyPort)
PrefManager.setVal(PrefName.Socks5ProxyUsername, proxyUsername)
PrefManager.setVal(PrefName.Socks5ProxyPassword, proxyPassword)

dismiss()
if (proxyEnabled) activity?.restartApp()
}

binding.proxyAuthentication.setOnCheckedChangeListener { _, isChecked ->
PrefManager.setVal(PrefName.ProxyAuthEnabled, isChecked)
binding.proxyUsername.isEnabled = isChecked
binding.proxyPassword.isEnabled = isChecked
binding.proxyUsernameLayout.isEnabled = isChecked
binding.proxyPasswordLayout.isEnabled = isChecked
}
}

override fun onDestroyView() {
_binding = null
super.onDestroyView()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ import ani.dantotsu.initActivity
import ani.dantotsu.media.MediaType
import ani.dantotsu.navBarHeight
import ani.dantotsu.parsers.ParserTestActivity
import ani.dantotsu.restartApp
import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.statusBarHeight
import ani.dantotsu.others.CustomBottomDialog
import ani.dantotsu.themes.ThemeManager
import ani.dantotsu.util.customAlertDialog
import eu.kanade.domain.base.BasePreferences
Expand Down Expand Up @@ -271,6 +273,26 @@ class SettingsExtensionsActivity : AppCompatActivity() {
}
),
Settings(
type = 2,
name = getString(R.string.proxy),
desc = getString(R.string.proxy_desc),
icon = R.drawable.swap_horizontal_circle_24,
isChecked = PrefManager.getVal(PrefName.EnableSocks5Proxy),
switch = { isChecked, _ ->
PrefManager.setVal(PrefName.EnableSocks5Proxy, isChecked)
restartApp()
}
),
Settings(
type = 1,
name = getString(R.string.proxy_setup),
desc = getString(R.string.proxy_setup_desc),
icon = R.drawable.lan_24,
onClick = {
ProxyDialogFragment().show(supportFragmentManager, "dialog")
}
),
Settings(
type = 2,
name = getString(R.string.force_legacy_installer),
desc = getString(R.string.force_legacy_installer_desc),
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/java/ani/dantotsu/settings/saving/Preferences.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
IncludeMangaList(Pref(Location.General, Boolean::class, true)),
AdultOnly(Pref(Location.General, Boolean::class, false)),
CommentsEnabled(Pref(Location.General, Int::class, 0)),
EnableSocks5Proxy(Pref(Location.General, Boolean::class, false)),
ProxyAuthEnabled(Pref(Location.General, Boolean::class, false)),

//User Interface
UseOLED(Pref(Location.UI, Boolean::class, false)),
Expand Down Expand Up @@ -197,6 +199,8 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
RefreshStatus(Pref(Location.Irrelevant, Boolean::class, false)),
rpcEnabled(Pref(Location.Irrelevant, Boolean::class, true)),

//testing

//Protected
DiscordToken(Pref(Location.Protected, String::class, "")),
DiscordId(Pref(Location.Protected, String::class, "")),
Expand All @@ -210,4 +214,8 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
AppPassword(Pref(Location.Protected, String::class, "")),
BiometricToken(Pref(Location.Protected, String::class, "")),
OverridePassword(Pref(Location.Protected, Boolean::class, false)),
Socks5ProxyHost(Pref(Location.Protected, String::class, "")),
Socks5ProxyPort(Pref(Location.Protected, String::class, "")),
Socks5ProxyUsername(Pref(Location.Protected, String::class, "")),
Socks5ProxyPassword(Pref(Location.Protected, String::class, "")),
}
48 changes: 42 additions & 6 deletions app/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,50 @@ import okhttp3.brotli.BrotliInterceptor
import okhttp3.logging.HttpLoggingInterceptor
import java.io.File
import java.util.concurrent.TimeUnit
import java.net.InetSocketAddress
import java.net.Proxy
import java.net.Authenticator
import java.net.PasswordAuthentication
import java.util.prefs.Preferences
import okhttp3.Credentials
import okhttp3.Response
import okhttp3.Route

class NetworkHelper(
context: Context
) {

init {
setupSocks5Proxy()
}

private fun setupSocks5Proxy() {
val proxyEnabled = PrefManager.getVal<Boolean>(PrefName.EnableSocks5Proxy)
if (proxyEnabled) {
val proxyHost = PrefManager.getVal<String>(PrefName.Socks5ProxyHost)
val proxyPort = PrefManager.getVal<String>(PrefName.Socks5ProxyPort)

System.setProperty("socksProxyHost", proxyHost)
System.setProperty("socksProxyPort", proxyPort)

if (PrefManager.getVal<Boolean>(PrefName.ProxyAuthEnabled)) {
val proxyUsername = PrefManager.getVal<String>(PrefName.Socks5ProxyUsername)
val proxyPassword = PrefManager.getVal<String>(PrefName.Socks5ProxyPassword)

Authenticator.setDefault(object : Authenticator() {
override fun getPasswordAuthentication(): PasswordAuthentication {
return PasswordAuthentication(proxyUsername, proxyPassword.toCharArray())
}
}
)
}
} else {
System.clearProperty("socksProxyHost")
System.clearProperty("socksProxyPort")
Authenticator.setDefault(null)
}
}

val cookieJar = AndroidCookieJar()

val client: OkHttpClient = run {
Expand All @@ -47,11 +86,9 @@ class NetworkHelper(
}
}


if (PrefManager.getVal<Boolean>(PrefName.VerboseLogging)) {
val httpLoggingInterceptor = HttpLoggingInterceptor(ConsoleLogger()).apply {
level = HttpLoggingInterceptor.Level.BASIC

}
builder.addNetworkInterceptor(httpLoggingInterceptor)
}
Expand All @@ -75,9 +112,8 @@ class NetworkHelper(
PREF_DOH_SHECAN -> builder.dohShecan()
PREF_DOH_LIBREDNS -> builder.dohLibreDNS()
}

builder.build()
}
builder.build()
}

val downloadClient = client.newBuilder().callTimeout(20, TimeUnit.MINUTES).build()

Expand All @@ -103,4 +139,4 @@ class NetworkHelper(
companion object {
fun defaultUserAgentProvider() = PrefManager.getVal<String>(PrefName.DefaultUserAgent)
}
}
}
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/lan_24.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M120,880L120,600L240,600L240,440L440,440L440,360L320,360L320,80L640,80L640,360L520,360L520,440L720,440L720,600L840,600L840,880L520,880L520,600L640,600L640,520L320,520L320,600L440,600L440,880L120,880ZM400,280L560,280L560,160L400,160L400,280ZM200,800L360,800L360,680L200,680L200,800ZM600,800L760,800L760,680L600,680L600,800ZM480,280L480,280L480,280L480,280ZM360,680L360,680L360,680L360,680ZM600,680L600,680L600,680L600,680Z"/>
</vector>
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/network_node_24.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M220,880Q162,880 121,839Q80,798 80,740Q80,682 121,641Q162,600 220,600Q238,600 255,604.5Q272,609 287,617L440,464L440,354Q396,341 368,304.5Q340,268 340,220Q340,162 381,121Q422,80 480,80Q538,80 579,121Q620,162 620,220Q620,268 592,304.5Q564,341 520,354L520,464L674,617Q689,609 705.5,604.5Q722,600 740,600Q798,600 839,641Q880,682 880,740Q880,798 839,839Q798,880 740,880Q682,880 641,839Q600,798 600,740Q600,722 604.5,705Q609,688 617,673L480,536L343,673Q351,688 355.5,705Q360,722 360,740Q360,798 319,839Q278,880 220,880ZM740,800Q765,800 782.5,782.5Q800,765 800,740Q800,715 782.5,697.5Q765,680 740,680Q715,680 697.5,697.5Q680,715 680,740Q680,765 697.5,782.5Q715,800 740,800ZM480,280Q505,280 522.5,262.5Q540,245 540,220Q540,195 522.5,177.5Q505,160 480,160Q455,160 437.5,177.5Q420,195 420,220Q420,245 437.5,262.5Q455,280 480,280ZM220,800Q245,800 262.5,782.5Q280,765 280,740Q280,715 262.5,697.5Q245,680 220,680Q195,680 177.5,697.5Q160,715 160,740Q160,765 177.5,782.5Q195,800 220,800Z"/>
</vector>
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/swap_horizontal_circle_24.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M360,720L416,664L354,600L520,600L520,520L354,520L416,456L360,400L200,560L360,720ZM600,560L760,400L600,240L544,296L606,360L440,360L440,440L606,440L544,504L600,560ZM480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880ZM480,800Q614,800 707,707Q800,614 800,480Q800,346 707,253Q614,160 480,160Q346,160 253,253Q160,346 160,480Q160,614 253,707Q346,800 480,800ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Z"/>
</vector>
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/vpn_key_24.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M280,720Q180,720 110,650Q40,580 40,480Q40,380 110,310Q180,240 280,240Q346,240 401,273Q456,306 488,360L920,360L920,600L840,600L840,720L600,720L600,600L488,600Q456,654 401,687Q346,720 280,720ZM280,640Q346,640 386,599.5Q426,559 434,520L680,520L680,640L760,640L760,520L840,520L840,440L434,440Q426,401 386,360.5Q346,320 280,320Q214,320 167,367Q120,414 120,480Q120,546 167,593Q214,640 280,640ZM280,560Q313,560 336.5,536.5Q360,513 360,480Q360,447 336.5,423.5Q313,400 280,400Q247,400 223.5,423.5Q200,447 200,480Q200,513 223.5,536.5Q247,560 280,560ZM280,480Q280,480 280,480Q280,480 280,480Q280,480 280,480Q280,480 280,480Q280,480 280,480Q280,480 280,480L280,480L280,480L280,480L280,480L280,480L280,480L280,480Q280,480 280,480Q280,480 280,480Z"/>
</vector>
Loading

0 comments on commit ff33727

Please sign in to comment.