Skip to content

Commit

Permalink
chore: Merge branch dev to main (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ushie authored Jan 16, 2025
2 parents bac3f5a + 211c754 commit ddeec82
Show file tree
Hide file tree
Showing 22 changed files with 171 additions and 136 deletions.
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
# [1.1.0-dev.3](https://github.com/revenge-mod/revenge-manager/compare/v1.1.0-dev.2...v1.1.0-dev.3) (2025-01-16)


### Features

* Cleanup about page and remove previous team members ([39ee2c6](https://github.com/revenge-mod/revenge-manager/commit/39ee2c654c62b63045d918cf7ffddcee55f6614f))

# [1.1.0-dev.2](https://github.com/revenge-mod/revenge-manager/compare/v1.1.0-dev.1...v1.1.0-dev.2) (2025-01-16)


### Bug Fixes

* Display correct group status in between steps ([706a547](https://github.com/revenge-mod/revenge-manager/commit/706a547f65e9e72f13cf56a8e0102db6617b4b9a))


### Features

* Implement automatic mirror switching and fix handling of stalled downloads ([#14](https://github.com/revenge-mod/revenge-manager/issues/14)) ([9921793](https://github.com/revenge-mod/revenge-manager/commit/992179349641e96fc383650767b196557767ea22))

# [1.1.0-dev.1](https://github.com/revenge-mod/revenge-manager/compare/v1.0.1-dev.1...v1.1.0-dev.1) (2025-01-16)


### Features

* Temporarily use DEFAULT if SHIZUKU permissions are not granted ([#15](https://github.com/revenge-mod/revenge-manager/issues/15)) ([f784bf6](https://github.com/revenge-mod/revenge-manager/commit/f784bf622d764c2c9e43d0ab20ef3b7c83de13c1))

## [1.0.1-dev.1](https://github.com/revenge-mod/revenge-manager/compare/v1.0.0...v1.0.1-dev.1) (2024-11-24)


### Bug Fixes

* Switch to JingMatrix/LSPatch to fix patching on Android 15 ([#10](https://github.com/revenge-mod/revenge-manager/issues/10)) ([343a91d](https://github.com/revenge-mod/revenge-manager/commit/343a91d83c3e394c3cd6e396de5d4a33a5ae3dbe))

# 1.0.0 (2024-10-20)


Expand Down
Binary file modified app/libs/lspatch.aar
Binary file not shown.
Binary file modified app/src/main/assets/lspatch/so/arm64-v8a/liblspatch.so
Binary file not shown.
Binary file modified app/src/main/assets/lspatch/so/armeabi-v7a/liblspatch.so
Binary file not shown.
Binary file modified app/src/main/assets/lspatch/so/x86/liblspatch.so
Binary file not shown.
Binary file modified app/src/main/assets/lspatch/so/x86_64/liblspatch.so
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class DownloadManager(
.setAllowedOverRoaming(true)
.let(downloadManager::enqueue)

var lastProgressTime = System.currentTimeMillis()

// Repeatedly request download state until it is finished
while (true) {
try {
Expand Down Expand Up @@ -90,8 +92,16 @@ class DownloadManager(

cursor.use {
when (status) {
DownloadManager.STATUS_PENDING, DownloadManager.STATUS_PAUSED ->
DownloadManager.STATUS_PENDING, DownloadManager.STATUS_PAUSED -> {
val currentTime = System.currentTimeMillis()
val elapsedTime = currentTime - lastProgressTime

if (elapsedTime >= 5000L) {
return DownloadResult.Error(debugReason = "Download timeout")
}

onProgressUpdate(null)
}

DownloadManager.STATUS_RUNNING ->
onProgressUpdate(getDownloadProgress(cursor))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class DownloadBaseStep(

override val nameRes = R.string.step_dl_base

override val url: String = "$baseUrl/tracker/download/$version/base"
override val downloadMirrorUrlPath: String = "/tracker/download/$version/base"
override val destination = dir.resolve("base-$version.apk")
override val workingCopy = workingDir.resolve("base-$version.apk")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class DownloadLangStep(

override val nameRes = R.string.step_dl_lang

override val url: String = "$baseUrl/tracker/download/$version/config.en"
override val downloadMirrorUrlPath: String = "/tracker/download/$version/config.en"
override val destination = dir.resolve("config.en-$version.apk")
override val workingCopy = workingDir.resolve("config.en-$version.apk")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class DownloadLibsStep(

override val nameRes = R.string.step_dl_lib

override val url: String = "$baseUrl/tracker/download/$version/config.$arch"
override val downloadMirrorUrlPath: String = "/tracker/download/$version/config.$arch"
override val destination = dir.resolve("config.$arch-$version.apk")
override val workingCopy = workingDir.resolve("config.$arch-$version.apk")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class DownloadModStep(

override val nameRes = R.string.step_dl_mod

override val url: String = "https://github.com/revenge-mod/revenge-xposed/releases/latest/download/app-release.apk"
override val downloadFullUrl: String = "https://github.com/revenge-mod/revenge-xposed/releases/latest/download/app-release.apk"
override val destination = preferenceManager.moduleLocation
override val workingCopy = workingDir.resolve("xposed.apk")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class DownloadResourcesStep(

override val nameRes = R.string.step_dl_res

override val url: String = "$baseUrl/tracker/download/$version/config.xxhdpi"
override val downloadMirrorUrlPath: String = "/tracker/download/$version/config.xxhdpi"
override val destination = dir.resolve("config.xxhdpi-$version.apk")
override val workingCopy = workingDir.resolve("config.xxhdpi-$version.apk")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.compose.runtime.setValue
import app.revenge.manager.R
import app.revenge.manager.domain.manager.DownloadManager
import app.revenge.manager.domain.manager.DownloadResult
import app.revenge.manager.domain.manager.Mirror
import app.revenge.manager.domain.manager.PreferenceManager
import app.revenge.manager.installer.step.Step
import app.revenge.manager.installer.step.StepGroup
Expand All @@ -26,18 +27,22 @@ import kotlin.math.roundToInt
* Files are downloaded to [destination] then copied to [workingCopy] for safe patching
*/
@Stable
abstract class DownloadStep: Step() {
abstract class DownloadStep : Step() {

protected val preferenceManager: PreferenceManager by inject()
protected val baseUrl = preferenceManager.mirror.baseUrl

private val downloadManager: DownloadManager by inject()
private val context: Context by inject()

/**
* Url of the desired file to download
*/
abstract val url: String
open val downloadFullUrl: String? = null

/**
* Mirror url path of the desired file to download
*/
open val downloadMirrorUrlPath: String? = null

/**
* Where to download the file to
Expand All @@ -54,6 +59,36 @@ abstract class DownloadStep: Step() {
var cached by mutableStateOf(false)
private set

suspend fun download(downloadUrl: String, destination: File, runner: StepRunner): Boolean {
val fileName = destination.name
var lastProgress: Float? = null

val result = downloadManager.download(downloadUrl, destination) { newProgress ->
progress = newProgress

if (newProgress != lastProgress && newProgress != null) {
lastProgress = newProgress
runner.logger.d("$fileName download progress: ${(newProgress * 100f).roundToInt()}%")
}
}

when (result) {
is DownloadResult.Success -> {
return true
}

is DownloadResult.Error -> {
runner.logger.e("Current mirror ${preferenceManager.mirror.name} failed: ${result.debugReason}")
return false
}

is DownloadResult.Cancelled -> {
status = StepStatus.UNSUCCESSFUL
throw CancellationException("$fileName download cancelled")
}
}
}

/**
* Verifies that a file was properly downloaded
*/
Expand Down Expand Up @@ -86,46 +121,48 @@ abstract class DownloadStep: Step() {
}

runner.logger.i("$fileName was not properly cached, downloading now")
var lastProgress: Float? = null
val result = downloadManager.download(url, destination) { newProgress ->
progress = newProgress
if (newProgress != lastProgress && newProgress != null) {
lastProgress = newProgress
runner.logger.d("$fileName download progress: ${(lastProgress!! * 100f).roundToInt()}%")
}

var downloadUrl = if (downloadMirrorUrlPath != null) {
preferenceManager.mirror.baseUrl + downloadMirrorUrlPath
} else {
downloadFullUrl
}

when (result) {
is DownloadResult.Success -> {
try {
runner.logger.i("Verifying downloaded file")
verify()
runner.logger.i("$fileName downloaded successfully")
} catch (t: Throwable) {
mainThread {
context.showToast(R.string.msg_download_verify_failed)
}

throw t
var successfulDownload = download(downloadUrl!!, destination, runner)

// If the current mirror fails, try other mirrors
if (!successfulDownload && downloadMirrorUrlPath != null) {
for (mirror in Mirror.entries - preferenceManager.mirror) {
downloadUrl = mirror.baseUrl + downloadMirrorUrlPath

if (download(downloadUrl, destination, runner)) {
preferenceManager.mirror = mirror
successfulDownload = true
break
}
runner.logger.i("Moving $fileName to working directory")
destination.copyTo(workingCopy, true)
}
}

is DownloadResult.Error -> {
mainThread {
context.showToast(R.string.msg_download_failed)
runner.downloadErrored = true
}

throw Error("Failed to download: ${result.debugReason}")
if (!successfulDownload) {
mainThread {
context.showToast(R.string.msg_download_failed)
runner.downloadErrored = true
}
throw Error("Failed to download $fileName from all mirrors.")
}

is DownloadResult.Cancelled -> {
status = StepStatus.UNSUCCESSFUL
throw CancellationException("$fileName download cancelled")
try {
runner.logger.i("Verifying downloaded file")
verify()
runner.logger.i("$fileName downloaded successfully")
} catch (t: Throwable) {
mainThread {
context.showToast(R.string.msg_download_verify_failed)
}
throw t
}
}

runner.logger.i("Moving $fileName to working directory")
destination.copyTo(workingCopy, true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import app.revenge.manager.domain.manager.PreferenceManager
import app.revenge.manager.installer.Installer
import app.revenge.manager.installer.session.SessionInstaller
import app.revenge.manager.installer.shizuku.ShizukuInstaller
import app.revenge.manager.installer.shizuku.ShizukuPermissions
import app.revenge.manager.installer.step.Step
import app.revenge.manager.installer.step.StepGroup
import app.revenge.manager.installer.step.StepRunner
import app.revenge.manager.utils.isMiui
import app.revenge.manager.utils.showToast
import org.koin.core.component.inject
import java.io.File

Expand Down Expand Up @@ -38,7 +40,15 @@ class InstallStep(
?.takeIf { it.isNotEmpty() }
?: throw Error("Missing APKs from LSPatch step; failure likely")

val installer: Installer = when (preferences.installMethod) {
val installMethod = if (preferences.installMethod == InstallMethod.SHIZUKU && !ShizukuPermissions.waitShizukuPermissions()) {
// Temporarily use DEFAULT if SHIZUKU permissions are not granted
context.showToast(R.string.msg_shizuku_denied)
InstallMethod.DEFAULT
} else {
preferences.installMethod
}

val installer: Installer = when (installMethod) {
InstallMethod.DEFAULT -> SessionInstaller(context)
InstallMethod.SHIZUKU -> ShizukuInstaller(context)
}
Expand Down
22 changes: 2 additions & 20 deletions app/src/main/java/app/revenge/manager/ui/activity/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,15 @@ import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.core.app.ActivityCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.lifecycleScope
import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.transitions.SlideTransition
import app.revenge.manager.domain.manager.InstallMethod
import app.revenge.manager.domain.manager.PreferenceManager
import app.revenge.manager.installer.shizuku.ShizukuPermissions
import app.revenge.manager.ui.screen.home.HomeScreen
import app.revenge.manager.ui.screen.installer.InstallerScreen
import app.revenge.manager.ui.theme.RevengeManagerTheme
import app.revenge.manager.utils.DiscordVersion
import app.revenge.manager.utils.Intents
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.transitions.SlideTransition

class MainActivity : ComponentActivity() {

private val preferences: PreferenceManager by inject()

override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen()
enableEdgeToEdge()
Expand All @@ -40,14 +31,6 @@ class MainActivity : ComponentActivity() {
)
}

if (preferences.installMethod == InstallMethod.SHIZUKU) {
lifecycleScope.launch {
if (!ShizukuPermissions.waitShizukuPermissions()) {
preferences.installMethod = InstallMethod.DEFAULT
}
}
}

val screen = if (intent.action == Intents.Actions.INSTALL && version != null) {
InstallerScreen(DiscordVersion.fromVersionCode(version)!!)
} else {
Expand All @@ -62,5 +45,4 @@ class MainActivity : ComponentActivity() {
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -141,17 +141,16 @@ class AboutScreen : Screen {
}
}

Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly,
modifier = Modifier
.fillMaxWidth()
.padding(top = 16.dp, bottom = 20.dp)
) {
UserEntry("oSumAtrIX", "Developer", "osumatrix")
UserEntry("Palm", "Lead developer", "palmdevs", isLarge = true)
UserEntry("Gabriel.W.J.", "Developer", "Gabe-W-J")
}
// Row(
// verticalAlignment = Alignment.CenterVertically,
// horizontalArrangement = Arrangement.SpaceEvenly,
// modifier = Modifier
// .fillMaxWidth()
// .padding(top = 16.dp, bottom = 20.dp)
// ) {
// UserEntry("oSumAtrIX", "Developer", "osumatrix", isLarge = true)
// UserEntry("Palm", "Lead developer", "palmdevs", isLarge = true)
// }

Text(
text = stringResource(R.string.label_team),
Expand Down Expand Up @@ -241,11 +240,6 @@ class AboutScreen : Screen {
uriHandler.openUri("https://github.com/rushiiMachine")
}
)
Divider(
thickness = 0.5.dp,
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f),
modifier = Modifier.padding(horizontal = 16.dp)
)
ListItem(
text = "Xinto",
subtext = "Developer of the preference manager",
Expand All @@ -267,11 +261,11 @@ class AboutScreen : Screen {
// text = stringResource(R.string.label_translate),
// onClick = { uriHandler.openUri("https://crowdin.com/project/vendetta-manager") }
// )
Divider(
thickness = 0.5.dp,
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f),
modifier = Modifier.padding(horizontal = 16.dp)
)
// Divider(
// thickness = 0.5.dp,
// color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f),
// modifier = Modifier.padding(horizontal = 16.dp)
// )
ListItem(
text = stringResource(R.string.title_os_libraries),
onClick = { navigator.push(LibrariesScreen()) }
Expand Down
Loading

0 comments on commit ddeec82

Please sign in to comment.