Opt KPM module installation to support URL-encoded filenames and extract module IDs for dynamically constructed names.
This will fix the flashback issue due to path issue Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
This commit is contained in:
@@ -39,6 +39,8 @@ import androidx.core.content.edit
|
|||||||
import shirkneko.zako.sukisu.ui.theme.ThemeConfig
|
import shirkneko.zako.sukisu.ui.theme.ThemeConfig
|
||||||
import shirkneko.zako.sukisu.ui.component.rememberCustomDialog
|
import shirkneko.zako.sukisu.ui.component.rememberCustomDialog
|
||||||
import shirkneko.zako.sukisu.ui.component.ConfirmDialogHandle
|
import shirkneko.zako.sukisu.ui.component.ConfirmDialogHandle
|
||||||
|
import java.net.URLDecoder
|
||||||
|
import java.net.URLEncoder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KPM 管理界面
|
* KPM 管理界面
|
||||||
@@ -145,8 +147,6 @@ fun KpmScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val selectPatchLauncher = rememberLauncherForActivityResult(
|
val selectPatchLauncher = rememberLauncherForActivityResult(
|
||||||
contract = ActivityResultContracts.StartActivityForResult()
|
contract = ActivityResultContracts.StartActivityForResult()
|
||||||
) { result ->
|
) { result ->
|
||||||
@@ -156,7 +156,8 @@ fun KpmScreen(
|
|||||||
|
|
||||||
scope.launch {
|
scope.launch {
|
||||||
val fileName = uri.lastPathSegment ?: "unknown.kpm"
|
val fileName = uri.lastPathSegment ?: "unknown.kpm"
|
||||||
val tempFile = File(context.cacheDir, fileName)
|
val encodedFileName = URLEncoder.encode(fileName, "UTF-8")
|
||||||
|
val tempFile = File(context.cacheDir, encodedFileName)
|
||||||
|
|
||||||
context.contentResolver.openInputStream(uri)?.use { input ->
|
context.contentResolver.openInputStream(uri)?.use { input ->
|
||||||
tempFile.outputStream().use { output ->
|
tempFile.outputStream().use { output ->
|
||||||
@@ -281,10 +282,10 @@ fun KpmScreen(
|
|||||||
snackBarHost = snackBarHost,
|
snackBarHost = snackBarHost,
|
||||||
kpmUninstallSuccess = kpmUninstallSuccess,
|
kpmUninstallSuccess = kpmUninstallSuccess,
|
||||||
kpmUninstallFailed = kpmUninstallFailed,
|
kpmUninstallFailed = kpmUninstallFailed,
|
||||||
confirmDialog = confirmDialog,
|
|
||||||
FailedtoCheckModuleFile = FailedtoCheckModuleFile,
|
FailedtoCheckModuleFile = FailedtoCheckModuleFile,
|
||||||
uninstall = uninstall,
|
uninstall = uninstall,
|
||||||
cancel = cancel
|
cancel = cancel,
|
||||||
|
confirmDialog = confirmDialog
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -307,11 +308,21 @@ private suspend fun handleModuleInstall(
|
|||||||
kpmInstallSuccess: String,
|
kpmInstallSuccess: String,
|
||||||
kpmInstallFailed: String
|
kpmInstallFailed: String
|
||||||
) {
|
) {
|
||||||
val moduleName = tempFile.nameWithoutExtension
|
val moduleId = extractModuleId(tempFile.name)
|
||||||
|
if (moduleId == null) {
|
||||||
|
Log.e("KsuCli", "Failed to extract module ID from file: ${tempFile.name}")
|
||||||
|
snackBarHost.showSnackbar(
|
||||||
|
message = kpmInstallFailed,
|
||||||
|
duration = SnackbarDuration.Short
|
||||||
|
)
|
||||||
|
tempFile.delete()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val targetPath = "/data/adb/kpm/$moduleId.kpm"
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (isEmbed) {
|
if (isEmbed) {
|
||||||
val targetPath = "/data/adb/kpm/$moduleName.kpm"
|
|
||||||
Runtime.getRuntime().exec(arrayOf("su", "-c", "mkdir -p /data/adb/kpm")).waitFor()
|
Runtime.getRuntime().exec(arrayOf("su", "-c", "mkdir -p /data/adb/kpm")).waitFor()
|
||||||
Runtime.getRuntime().exec(arrayOf("su", "-c", "cp ${tempFile.absolutePath} $targetPath")).waitFor()
|
Runtime.getRuntime().exec(arrayOf("su", "-c", "cp ${tempFile.absolutePath} $targetPath")).waitFor()
|
||||||
}
|
}
|
||||||
@@ -340,6 +351,18 @@ private suspend fun handleModuleInstall(
|
|||||||
tempFile.delete()
|
tempFile.delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun extractModuleId(fileName: String): String? {
|
||||||
|
return try {
|
||||||
|
val decodedFileName = URLDecoder.decode(fileName, "UTF-8")
|
||||||
|
val pattern = "([^/]*?)\\.kpm$".toRegex()
|
||||||
|
val matchResult = pattern.find(decodedFileName)
|
||||||
|
matchResult?.groupValues?.get(1)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("KsuCli", "Failed to extract module ID: ${e.message}", e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun handleModuleUninstall(
|
private suspend fun handleModuleUninstall(
|
||||||
module: KpmViewModel.ModuleInfo,
|
module: KpmViewModel.ModuleInfo,
|
||||||
viewModel: KpmViewModel,
|
viewModel: KpmViewModel,
|
||||||
@@ -351,7 +374,7 @@ private suspend fun handleModuleUninstall(
|
|||||||
cancel: String,
|
cancel: String,
|
||||||
confirmDialog: ConfirmDialogHandle
|
confirmDialog: ConfirmDialogHandle
|
||||||
) {
|
) {
|
||||||
val moduleFileName = "primary:${module.id}.kpm"
|
val moduleFileName = "${module.id}.kpm"
|
||||||
val moduleFilePath = "/data/adb/kpm/$moduleFileName"
|
val moduleFilePath = "/data/adb/kpm/$moduleFileName"
|
||||||
|
|
||||||
val fileExists = try {
|
val fileExists = try {
|
||||||
|
|||||||
Reference in New Issue
Block a user