2020-06-19 15:48:14 +00:00
|
|
|
package com.vanced.manager.utils
|
|
|
|
|
2021-01-15 17:26:27 +00:00
|
|
|
import android.content.ActivityNotFoundException
|
2020-06-19 15:48:14 +00:00
|
|
|
import android.content.Context
|
2020-07-04 15:06:01 +00:00
|
|
|
import android.content.Intent
|
2020-07-10 19:09:51 +00:00
|
|
|
import android.util.Log
|
2021-01-15 17:26:27 +00:00
|
|
|
import android.widget.Toast
|
2020-12-11 19:22:43 +00:00
|
|
|
import androidx.browser.customtabs.CustomTabColorSchemeParams
|
2020-06-28 16:39:14 +00:00
|
|
|
import androidx.browser.customtabs.CustomTabsIntent
|
|
|
|
import androidx.core.content.ContextCompat
|
2020-11-05 16:35:49 +00:00
|
|
|
import androidx.core.net.toUri
|
2020-12-16 13:21:45 +00:00
|
|
|
import androidx.lifecycle.MutableLiveData
|
2020-11-15 17:04:23 +00:00
|
|
|
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
|
2020-11-05 18:26:27 +00:00
|
|
|
import com.beust.klaxon.JsonArray
|
|
|
|
import com.beust.klaxon.JsonObject
|
2020-07-12 18:05:03 +00:00
|
|
|
import com.vanced.manager.R
|
2020-11-10 18:16:29 +00:00
|
|
|
import com.vanced.manager.utils.AppUtils.generateChecksum
|
2021-02-03 18:24:28 +00:00
|
|
|
import com.vanced.manager.utils.AppUtils.log
|
2020-11-05 18:26:27 +00:00
|
|
|
import kotlinx.coroutines.Dispatchers
|
2020-11-15 00:26:07 +00:00
|
|
|
import kotlinx.coroutines.withContext
|
2020-11-10 18:16:29 +00:00
|
|
|
import java.io.File
|
2021-01-27 16:58:18 +00:00
|
|
|
import java.io.IOException
|
|
|
|
import java.net.HttpURLConnection
|
|
|
|
import java.net.SocketTimeoutException
|
|
|
|
import java.net.URL
|
2020-11-05 18:26:27 +00:00
|
|
|
import java.util.*
|
2020-06-19 15:48:14 +00:00
|
|
|
|
2021-01-16 17:00:38 +00:00
|
|
|
private const val TAG = "VMNetTools"
|
2020-07-12 18:05:03 +00:00
|
|
|
|
2021-01-16 17:00:38 +00:00
|
|
|
val vanced = MutableLiveData<JsonObject?>()
|
|
|
|
val music = MutableLiveData<JsonObject?>()
|
|
|
|
val microg = MutableLiveData<JsonObject?>()
|
|
|
|
val manager = MutableLiveData<JsonObject?>()
|
2020-06-28 16:39:14 +00:00
|
|
|
|
2021-10-08 11:58:07 +00:00
|
|
|
val vancedVersions = MutableLiveData<JsonArray<String>?>()
|
|
|
|
val musicVersions = MutableLiveData<JsonArray<String>?>()
|
2020-11-05 18:26:27 +00:00
|
|
|
|
2021-01-16 17:00:38 +00:00
|
|
|
val isFetching = MutableLiveData<Boolean>()
|
2020-12-19 08:35:07 +00:00
|
|
|
|
2021-01-25 16:54:19 +00:00
|
|
|
var isMicrogBroken: Boolean = false
|
|
|
|
|
|
|
|
var baseInstallUrl = ""
|
2020-11-05 18:26:27 +00:00
|
|
|
|
2021-01-16 17:00:38 +00:00
|
|
|
fun openUrl(url: String, color: Int, context: Context) {
|
|
|
|
try {
|
2021-04-19 15:57:14 +00:00
|
|
|
val customTabPrefs =
|
|
|
|
getDefaultSharedPreferences(context).getBoolean("use_custom_tabs", true)
|
2021-01-16 17:00:38 +00:00
|
|
|
if (customTabPrefs) {
|
|
|
|
val builder = CustomTabsIntent.Builder()
|
2021-04-19 15:57:14 +00:00
|
|
|
val params = CustomTabColorSchemeParams.Builder()
|
|
|
|
.setToolbarColor(ContextCompat.getColor(context, color))
|
2021-01-16 17:00:38 +00:00
|
|
|
builder.setDefaultColorSchemeParams(params.build())
|
|
|
|
val customTabsIntent = builder.build()
|
|
|
|
customTabsIntent.intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
|
|
customTabsIntent.launchUrl(context, url.toUri())
|
|
|
|
} else
|
2021-04-19 15:57:14 +00:00
|
|
|
context.startActivity(
|
|
|
|
Intent(
|
|
|
|
Intent.ACTION_VIEW,
|
|
|
|
url.toUri()
|
|
|
|
).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
|
|
)
|
2020-11-05 18:26:27 +00:00
|
|
|
|
2021-01-16 17:00:38 +00:00
|
|
|
} catch (e: ActivityNotFoundException) {
|
|
|
|
Toast.makeText(context, R.string.error, Toast.LENGTH_SHORT).show()
|
2021-02-05 09:07:05 +00:00
|
|
|
} catch (e: SecurityException) {
|
|
|
|
Toast.makeText(context, R.string.error, Toast.LENGTH_SHORT).show()
|
2020-06-28 16:39:14 +00:00
|
|
|
}
|
2021-01-16 17:00:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fun getFileNameFromUrl(url: String) = url.substring(url.lastIndexOf('/') + 1, url.length)
|
|
|
|
|
2021-01-27 16:58:18 +00:00
|
|
|
//TODO: Use a better connection method that doesn't cause inappropriate blocks
|
|
|
|
@Suppress("BlockingMethodInNonBlockingContext")
|
2021-01-16 17:00:38 +00:00
|
|
|
suspend fun loadJson(context: Context) = withContext(Dispatchers.IO) {
|
|
|
|
isFetching.postValue(true)
|
2021-01-24 18:12:06 +00:00
|
|
|
val installUrl = context.defPrefs.installUrl
|
2021-01-25 16:54:19 +00:00
|
|
|
if (baseInstallUrl == "" && installUrl != null) {
|
|
|
|
baseInstallUrl = installUrl
|
|
|
|
}
|
|
|
|
|
2021-01-27 16:58:18 +00:00
|
|
|
try {
|
|
|
|
val latestbaseUrl = "$baseInstallUrl/latest.json"
|
|
|
|
val connection = URL(latestbaseUrl).openConnection() as HttpURLConnection
|
|
|
|
connection.apply {
|
|
|
|
connectTimeout = 5000
|
|
|
|
readTimeout = 5000
|
|
|
|
connect()
|
|
|
|
}
|
|
|
|
if (connection.responseCode != 200) {
|
2021-02-03 18:24:28 +00:00
|
|
|
log(TAG, latestbaseUrl + ": " + connection.responseCode.toString())
|
2021-01-27 16:58:18 +00:00
|
|
|
baseInstallUrl = "https://mirror.codebucket.de/vanced/api/v1"
|
2021-01-25 16:54:19 +00:00
|
|
|
}
|
2021-01-27 16:58:18 +00:00
|
|
|
} catch (e: IOException) {
|
|
|
|
baseInstallUrl = "https://mirror.codebucket.de/vanced/api/v1"
|
|
|
|
} catch (e: SocketTimeoutException) {
|
2021-02-03 18:24:28 +00:00
|
|
|
log(TAG, "connection timed out")
|
2021-01-27 16:58:18 +00:00
|
|
|
baseInstallUrl = "https://mirror.codebucket.de/vanced/api/v1"
|
2021-01-25 16:54:19 +00:00
|
|
|
}
|
|
|
|
|
2021-02-03 18:24:28 +00:00
|
|
|
log(TAG, "Fetching using URL: $baseInstallUrl")
|
2021-01-27 16:58:18 +00:00
|
|
|
|
2021-01-16 17:00:38 +00:00
|
|
|
val calendar = Calendar.getInstance()
|
|
|
|
val hour = calendar.get(Calendar.HOUR_OF_DAY)
|
|
|
|
val minute = calendar.get(Calendar.MINUTE)
|
|
|
|
val second = calendar.get(Calendar.SECOND)
|
|
|
|
val fetchTime = "fetchTime=$hour$minute$second"
|
2021-01-27 16:58:18 +00:00
|
|
|
|
2021-01-25 16:54:19 +00:00
|
|
|
val latest = getJson("$baseInstallUrl/latest.json?$fetchTime")
|
|
|
|
val versions = getJson("$baseInstallUrl/versions.json?$fetchTime")
|
|
|
|
isMicrogBroken = latest?.boolean("is_microg_broken") ?: false
|
2021-01-16 17:00:38 +00:00
|
|
|
vanced.postValue(latest?.obj("vanced"))
|
2021-04-19 15:57:14 +00:00
|
|
|
vancedVersions.postValue(versions?.array("vanced"))
|
2021-01-16 17:00:38 +00:00
|
|
|
music.postValue(latest?.obj("music"))
|
|
|
|
musicVersions.postValue(versions?.array("music"))
|
|
|
|
microg.postValue(latest?.obj("microg"))
|
|
|
|
manager.postValue(latest?.obj("manager"))
|
|
|
|
isFetching.postValue(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
private suspend fun getJsonString(file: String, obj: String, context: Context): String {
|
|
|
|
return try {
|
2021-01-25 16:54:19 +00:00
|
|
|
getJson("$baseInstallUrl/$file")?.string(obj) ?: context.getString(R.string.unavailable)
|
2021-01-16 17:00:38 +00:00
|
|
|
} catch (e: Exception) {
|
|
|
|
Log.e(TAG, "Error: ", e)
|
|
|
|
context.getString(R.string.unavailable)
|
2020-07-01 17:52:56 +00:00
|
|
|
}
|
2021-01-16 17:00:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
suspend fun getSha256(hashUrl: String, obj: String, context: Context): String {
|
|
|
|
return getJsonString(hashUrl, obj, context)
|
|
|
|
}
|
|
|
|
|
|
|
|
fun checkSHA256(sha256: String, updateFile: File): Boolean {
|
|
|
|
return try {
|
|
|
|
val dataBuffer = updateFile.readBytes()
|
|
|
|
// Generate the checksum
|
|
|
|
val sum = generateChecksum(dataBuffer)
|
|
|
|
|
|
|
|
sum.equals(sha256, ignoreCase = true)
|
|
|
|
} catch (e: Exception) {
|
|
|
|
e.printStackTrace()
|
|
|
|
false
|
2020-11-10 18:16:29 +00:00
|
|
|
}
|
2021-01-16 17:00:38 +00:00
|
|
|
}
|
2020-11-10 18:16:29 +00:00
|
|
|
|
2021-04-19 15:50:56 +00:00
|
|
|
const val baseUrl = "https://api.vancedapp.com/api/v1"
|