Release 1.2.2 (#28)

* Fix version detection edge case

* Fix VrApi detection

* Delete empty icon file

* Remove leftover code

* Animate icon and label on patch switching

* Fix forced replace icon/label patch

* Rename patch

* Create Unity stub if UE4 smali is present only

* Remove unused VrApi after patching

* Add line breaks for appends

* Add OculusXRPlugin binary patch

and improve binary patching

* Mark frida cleanup patch as not recommended

* Change frida cleanup behavior

* Filter version with existing directories

* Show cover if selected

* Remove VrApi library patch

* Android XR metadata

* Huawei VR metadata

* More metadata

* Uses-library for Android XR

* Bump version

* Rename patch
This commit is contained in:
Mathew Tkachuk authored and GitHub committed 2025-12-21 22:18:18 +03:00
1 parent c50c431a7e
commit 474f7bf12a
20 files changed
+236 -82

No files matched your search

@@ -39,15 +39,15 @@
<string name="patch_copy_libraries">Copy overport libraries</string>
<string name="patch_copy_ovrplugin_vrapi">Copy OVRPlugin if VrApi is present</string>
<string name="patch_fix_min_android_sdk">Fix minimal Android SDK</string>
<string name="patch_generate_config">Generate ovrport config</string>
<string name="patch_generate_config">Generate overport config</string>
<string name="patch_remove_localized_names">Remove localized app names</string>
<string name="patch_clean_up_frida">Clean up Frida leftovers</string>
<string name="patch_clean_up_frida">Clean up Frida leftovers in smali</string>
<string name="patch_oculus_unity">Patch Oculus detection for Unity</string>
<string name="patch_oculus_unreal">Patch Oculus detection for Unreal</string>
<string name="patch_vr_metadata">Pico/YVR/Quest metadata</string>
<string name="patch_launcher_entry">Fix launcher icon entry</string>
<string name="patch_remove_uses_library">Remove uses-library</string>
<string name="patch_fix_unreal_crash">Fix Unreal Engine 4 crash</string>
<string name="patch_fix_unreal_crash">Fix UE4 crash with Unity stub</string>
<string name="patch_meta_xr_audio">Patch Meta XR Audio</string>
<string name="patch_mark_as_debuggable">Mark application as debuggable</string>
<string name="patch_mark_allow_backup">Mark application to allow backup</string>
@@ -56,4 +56,5 @@
<string name="patch_force_passthrough">Force enable passthrough</string>
<string name="patch_disable_space_warp">Disable application space warp if used</string>
<string name="patch_disable_controller_offset">Disable controller tracking offset</string>
<string name="patch_remove_vrapi">Remove VrApi library</string>
</resources>
@@ -46,7 +46,6 @@ fun AppContent(
}
var versionToUpdate by remember { mutableStateOf<GithubRelease?>(null) }
var showAboutDialog by remember { mutableStateOf(false) }
val urlHandler = LocalUriHandler.current
LaunchedEffect(Unit) {
@@ -95,18 +94,5 @@ fun AppContent(
navigationItems = listOf(patcherNavItem),
itemsEnabled = !viewModel.working && !viewModel.isApkLoaded()
)
if (showAboutDialog) {
AlertDialog(
onDismissRequest = { showAboutDialog = false },
title = { Text("overport") },
text = { Text("about overport") }, // TODO
confirmButton = {
TextButton(onClick = { showAboutDialog = false }) {
Text("Close")
}
},
)
}
}
}
@@ -31,9 +31,12 @@ fun ApplicationInfo(
applicationPackage: String? = "com.company.application",
applicationVersion: String? = "1.0.0",
applicationIcon: ImageBitmap? = null,
forceLocalInfo: Boolean = false,
useCover: Boolean = false,
) {
var iconIsLoading by rememberSaveable(applicationPackage) { mutableStateOf(true) }
var onlineIcon by rememberSaveable(applicationPackage) { mutableStateOf<ImageBitmap?>(null) }
var onlineCover by rememberSaveable(applicationPackage) { mutableStateOf<ImageBitmap?>(null) }
var onlineLabel by rememberSaveable(applicationPackage) { mutableStateOf<String?>(null) }
val scope = rememberCoroutineScope()
@@ -44,12 +47,18 @@ fun ApplicationInfo(
val info = applicationPackage?.let { getApplicationInfo(it) }
onlineLabel = info?.displayName
val image = info?.run {
val icon = info?.run {
val associated = images.associateBy { it.imageType }
associated["APP_IMG_ICON"] ?: associated["APP_IMG_COVER_SQUARE"]
}
onlineIcon = image?.uri?.let { Base64.getDecoder().decode(it) }?.decodeBitmap()
val cover = info?.run {
val associated = images.associateBy { it.imageType }
associated["APP_IMG_COVER_SQUARE"] ?: associated["APP_IMG_ICON"]
}
onlineIcon = icon?.uri?.let { Base64.getDecoder().decode(it) }?.decodeBitmap()
onlineCover = cover?.uri?.let { Base64.getDecoder().decode(it) }?.decodeBitmap()
}
iconIsLoading = false
}
@@ -61,14 +70,9 @@ fun ApplicationInfo(
) {
Box {
FadeVisibility(!iconIsLoading) {
onlineIcon?.let {
Image(
it,
contentDescription = null,
modifier = Modifier.size(48.dp).rounded(8.dp)
)
} ?: run {
if (applicationIcon == null) {
AnimatedContent((onlineCover.takeIf { useCover } ?: onlineIcon)
.takeIf { !forceLocalInfo } ?: applicationIcon) {
if (it == null) {
Icon(
Icons.Default.Widgets,
contentDescription = null,
@@ -76,7 +80,7 @@ fun ApplicationInfo(
)
} else {
Image(
applicationIcon,
it,
contentDescription = null,
modifier = Modifier.size(48.dp).rounded(8.dp)
)
@@ -91,7 +95,7 @@ fun ApplicationInfo(
modifier = Modifier.height(48.dp),
verticalArrangement = Arrangement.Center
) {
AnimatedContent(onlineLabel ?: applicationName) {
AnimatedContent(onlineLabel.takeIf { !forceLocalInfo } ?: applicationName) {
Text("$it ($applicationVersion)")
}
Text(
@@ -20,7 +20,7 @@ import overportapp.composeapp.generated.resources.*
@OptIn(ExperimentalLayoutApi::class)
@Composable
@Preview
fun ApplicationInfoCard(
fun ApplicationInfoContent(
applicationName: String? = "Application",
applicationPackage: String? = "",
applicationVersion: String? = "1.0.0",
@@ -28,6 +28,26 @@ fun ApplicationInfoCard(
onCancel: () -> Unit = {},
onConfirm: (Map<String, List<String>>) -> Unit = {}
) {
val enabledPatches = remember(applicationPackage) {
mutableStateMapOf(
*PatchStore.recommended().map { it.name to listOf<String>() }.toTypedArray()
)
}
var patchIconArgument by remember(applicationPackage) {
mutableStateOf("icon")
}
fun togglePatch(patch: Patch) {
val checked = enabledPatches.containsKey(patch.name)
if (checked) {
enabledPatches.remove(patch.name)
} else {
enabledPatches[patch.name] = listOf()
}
}
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
@@ -36,27 +56,15 @@ fun ApplicationInfoCard(
horizontalArrangement = Arrangement.SpaceBetween,
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
ApplicationInfo(applicationName, applicationPackage, applicationVersion, applicationIcon)
}
val enabledPatches = remember {
mutableStateMapOf(
*PatchStore.recommended().map { it.name to listOf<String>() }.toTypedArray()
ApplicationInfo(
applicationName,
applicationPackage,
applicationVersion,
applicationIcon,
!enabledPatches.containsKey(PATCH_REPLACE_ICON_LABEL.name),
patchIconArgument != "icon",
)
}
var patchIconArgument by remember {
mutableStateOf("icon")
}
fun togglePatch(patch: Patch) {
val checked = enabledPatches.containsKey(patch.name)
if (checked) {
enabledPatches.remove(patch.name)
} else {
enabledPatches[patch.name] = listOf()
}
}
Box(modifier = Modifier.weight(1f)) {
LazyColumn {
@@ -129,7 +137,9 @@ fun ApplicationInfoCard(
Button(
modifier = Modifier.weight(1f),
onClick = {
enabledPatches[PATCH_REPLACE_ICON_LABEL.name] = listOf(patchIconArgument)
if (enabledPatches.containsKey(PATCH_REPLACE_ICON_LABEL.name)) {
enabledPatches[PATCH_REPLACE_ICON_LABEL.name] = listOf(patchIconArgument)
}
onConfirm(enabledPatches)
}
) {
@@ -70,7 +70,7 @@ fun PatcherScreen(
}
FadeVisibility(isPatcherVisible) {
ApplicationInfoCard(
ApplicationInfoContent(
viewModel.currentAppName(),
viewModel.currentAppPackage(),
viewModel.currentAppVersion(),
@@ -24,6 +24,7 @@ object PatchLocalizer {
PATCH_META_XR_AUDIO to Res.string.patch_meta_xr_audio,
PATCH_MARK_AS_DEBUGGABLE to Res.string.patch_mark_as_debuggable,
PATCH_MARK_ALLOW_BACKUP to Res.string.patch_mark_allow_backup,
PATCH_REMOVE_VRAPI to Res.string.patch_remove_vrapi,
PATCH_REMOVE_UNREAL_FORCE_QUIT to Res.string.patch_remove_unreal_force_quit,
PATCH_FORCE_PASSTHROUGH to Res.string.patch_force_passthrough,
PATCH_DISABLE_SPACE_WARP to Res.string.patch_disable_space_warp,