[feat] Smart Server Selection
This commit is contained in:
@@ -3,6 +3,8 @@ package com.acitelight.aether.service
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
|
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import okhttp3.CertificatePinner
|
import okhttp3.CertificatePinner
|
||||||
import okhttp3.HttpUrl
|
import okhttp3.HttpUrl
|
||||||
@@ -12,6 +14,9 @@ import okhttp3.OkHttpClient
|
|||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
import retrofit2.converter.gson.GsonConverterFactory
|
import retrofit2.converter.gson.GsonConverterFactory
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.net.HttpURLConnection
|
||||||
|
import java.net.InetAddress
|
||||||
|
import java.net.URL
|
||||||
import java.security.KeyStore
|
import java.security.KeyStore
|
||||||
import java.security.cert.Certificate
|
import java.security.cert.Certificate
|
||||||
import java.security.cert.CertificateFactory
|
import java.security.cert.CertificateFactory
|
||||||
@@ -88,19 +93,43 @@ object ApiClient {
|
|||||||
|
|
||||||
var api: ApiInterface? = null
|
var api: ApiInterface? = null
|
||||||
|
|
||||||
fun apply(url: String, crt: String)
|
suspend fun apply(urls: String, crt: String): String? {
|
||||||
{
|
try {
|
||||||
try{
|
val urlList = urls.split(";").map { it.trim() }
|
||||||
domain = url.toHttpUrlOrNull()?.host !!
|
|
||||||
|
var selectedUrl: String? = null
|
||||||
|
for (url in urlList) {
|
||||||
|
val host = url.toHttpUrlOrNull()?.host
|
||||||
|
if (host != null && pingHost(host)) {
|
||||||
|
selectedUrl = url
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedUrl == null) {
|
||||||
|
throw Exception("No reachable URL found")
|
||||||
|
}
|
||||||
|
|
||||||
|
domain = selectedUrl.toHttpUrlOrNull()?.host ?: ""
|
||||||
cert = crt
|
cert = crt
|
||||||
base = url
|
base = selectedUrl
|
||||||
api = createRetrofit().create(ApiInterface::class.java)
|
api = createRetrofit().create(ApiInterface::class.java)
|
||||||
}catch (e: Exception)
|
return base
|
||||||
{
|
} catch (e: Exception) {
|
||||||
api = null
|
api = null
|
||||||
base = ""
|
base = ""
|
||||||
domain = ""
|
domain = ""
|
||||||
cert = ""
|
cert = ""
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun pingHost(host: String): Boolean = withContext(Dispatchers.IO) {
|
||||||
|
return@withContext try {
|
||||||
|
val address = InetAddress.getByName(host)
|
||||||
|
address.isReachable(200)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.acitelight.aether.viewModel
|
package com.acitelight.aether.viewModel
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -86,7 +87,7 @@ class HomeScreenViewModel(application: Application) : AndroidViewModel(applicati
|
|||||||
if(u=="" || p=="" || ur=="" || c=="") return@launch
|
if(u=="" || p=="" || ur=="" || c=="") return@launch
|
||||||
|
|
||||||
try{
|
try{
|
||||||
ApiClient.apply(ur, c)
|
val usedUrl = ApiClient.apply(ur, c)
|
||||||
|
|
||||||
if (MediaManager.token == "null")
|
if (MediaManager.token == "null")
|
||||||
MediaManager.token = AuthManager.fetchToken(
|
MediaManager.token = AuthManager.fetchToken(
|
||||||
|
|||||||
@@ -76,14 +76,14 @@ class MeScreenViewModel(application: Application) : AndroidViewModel(application
|
|||||||
if (u == "" || c == "" || p == "" || us == "") return@launch
|
if (u == "" || c == "" || p == "" || us == "") return@launch
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ApiClient.apply(u, c)
|
val usedUrl = ApiClient.apply(u, c)
|
||||||
MediaManager.token = AuthManager.fetchToken(
|
MediaManager.token = AuthManager.fetchToken(
|
||||||
us,
|
us,
|
||||||
p
|
p
|
||||||
)!!
|
)!!
|
||||||
|
|
||||||
Global.loggedIn = true
|
Global.loggedIn = true
|
||||||
Toast.makeText(context, "Server Updated", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "Server Updated, Used Url: $usedUrl", Toast.LENGTH_SHORT).show()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
print(e.message)
|
print(e.message)
|
||||||
Toast.makeText(context, "Invalid Account or Server Information", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "Invalid Account or Server Information", Toast.LENGTH_SHORT).show()
|
||||||
|
|||||||
Reference in New Issue
Block a user