diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
index 1279ce2..ed3b099 100644
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -39,15 +39,15 @@
Copy overport libraries
Copy OVRPlugin if VrApi is present
Fix minimal Android SDK
- Generate ovrport config
+ Generate overport config
Remove localized app names
- Clean up Frida leftovers
+ Clean up Frida leftovers in smali
Patch Oculus detection for Unity
Patch Oculus detection for Unreal
Pico/YVR/Quest metadata
Fix launcher icon entry
Remove uses-library
- Fix Unreal Engine 4 crash
+ Fix UE4 crash with Unity stub
Patch Meta XR Audio
Mark application as debuggable
Mark application to allow backup
@@ -56,4 +56,5 @@
Force enable passthrough
Disable application space warp if used
Disable controller tracking offset
+ Remove VrApi library
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/AppContent.kt b/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/AppContent.kt
index 9b82d53..8295047 100644
--- a/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/AppContent.kt
+++ b/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/AppContent.kt
@@ -46,7 +46,6 @@ fun AppContent(
}
var versionToUpdate by remember { mutableStateOf(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")
- }
- },
- )
- }
}
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/ApplicationInfo.kt b/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/ApplicationInfo.kt
index 70f42ff..48cb4b0 100644
--- a/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/ApplicationInfo.kt
+++ b/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/ApplicationInfo.kt
@@ -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(null) }
+ var onlineCover by rememberSaveable(applicationPackage) { mutableStateOf(null) }
var onlineLabel by rememberSaveable(applicationPackage) { mutableStateOf(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(
diff --git a/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/ApplicationInfoCard.kt b/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/ApplicationInfoContent.kt
similarity index 81%
rename from composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/ApplicationInfoCard.kt
rename to composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/ApplicationInfoContent.kt
index e581a03..18ee753 100644
--- a/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/ApplicationInfoCard.kt
+++ b/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/ApplicationInfoContent.kt
@@ -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>) -> Unit = {}
) {
+ val enabledPatches = remember(applicationPackage) {
+ mutableStateMapOf(
+ *PatchStore.recommended().map { it.name to listOf() }.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() }.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)
}
) {
diff --git a/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/PatcherScreen.kt b/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/PatcherScreen.kt
index 46efca2..4d916c0 100644
--- a/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/PatcherScreen.kt
+++ b/composeApp/src/commonMain/kotlin/moe/crx/overport/app/composables/PatcherScreen.kt
@@ -70,7 +70,7 @@ fun PatcherScreen(
}
FadeVisibility(isPatcherVisible) {
- ApplicationInfoCard(
+ ApplicationInfoContent(
viewModel.currentAppName(),
viewModel.currentAppPackage(),
viewModel.currentAppVersion(),
diff --git a/composeApp/src/commonMain/kotlin/moe/crx/overport/app/util/PatchLocalizer.kt b/composeApp/src/commonMain/kotlin/moe/crx/overport/app/util/PatchLocalizer.kt
index a71c14b..5566c33 100644
--- a/composeApp/src/commonMain/kotlin/moe/crx/overport/app/util/PatchLocalizer.kt
+++ b/composeApp/src/commonMain/kotlin/moe/crx/overport/app/util/PatchLocalizer.kt
@@ -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,
diff --git a/gradle.properties b/gradle.properties
index 492bfae..7b34f53 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -7,4 +7,4 @@ org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8
android.nonTransitiveRClass=true
android.useAndroidX=true
#Application
-appVersion=1.2.1
\ No newline at end of file
+appVersion=1.2.2
\ No newline at end of file
diff --git a/overportcli/build.gradle.kts b/overportcli/build.gradle.kts
index 5718164..190d29e 100644
--- a/overportcli/build.gradle.kts
+++ b/overportcli/build.gradle.kts
@@ -8,7 +8,7 @@ plugins {
}
group = "moe.crx"
-version = "1.2.1"
+version = "1.2.2"
dependencies {
implementation(libs.android.tools.build)
diff --git a/overportcli/src/main/java/moe/crx/overport/patches/CleanUpFridaPatch.kt b/overportcli/src/main/java/moe/crx/overport/patches/CleanUpFridaPatch.kt
index d8bfbb1..fc4a803 100644
--- a/overportcli/src/main/java/moe/crx/overport/patches/CleanUpFridaPatch.kt
+++ b/overportcli/src/main/java/moe/crx/overport/patches/CleanUpFridaPatch.kt
@@ -6,16 +6,6 @@ import moe.crx.overport.utils.named
import moe.crx.overport.utils.takeNodesEach
val PATCH_CLEAN_UP_FRIDA = Patch("patch_clean_up_frida") {
- selectLibrary("libfrda.so") {
- file.delete()
- }
- selectLibrary("libfrda.config.so") {
- file.delete()
- }
- selectLibrary("libscript.so") {
- file.delete()
- }
-
selectManifestJson {
takeNodesEach({ named("manifest") }) {
takeNodesEach({ named("application") }) {
diff --git a/overportcli/src/main/java/moe/crx/overport/patches/CopyOVRPluginVrApiPatch.kt b/overportcli/src/main/java/moe/crx/overport/patches/CopyOVRPluginVrApiPatch.kt
index a178e3e..da5ce93 100644
--- a/overportcli/src/main/java/moe/crx/overport/patches/CopyOVRPluginVrApiPatch.kt
+++ b/overportcli/src/main/java/moe/crx/overport/patches/CopyOVRPluginVrApiPatch.kt
@@ -9,8 +9,8 @@ val PATCH_COPY_OVRPLUGIN_VRAPI = Patch("patch_copy_ovrplugin_vrapi") {
val arch = getLibraries().resolve("lib/${archDirectory.name}")
if (arch.exists()) {
- val hasVrApi = arch.listFiles().find { it.name.lowercase() == "libvrapi.so" } != null
- if (hasVrApi) {
+ val vrApi = archDirectory.listFiles().find { it.name.lowercase() == "libvrapi.so" }
+ if (vrApi != null) {
arch.listFiles().filter { it.name == "libOVRPlugin.so" }.forEach { library ->
library.copyTo(File(archDirectory, library.name), true)
}
diff --git a/overportcli/src/main/java/moe/crx/overport/patches/FixUnrealCrashPatch.kt b/overportcli/src/main/java/moe/crx/overport/patches/FixUnrealCrashPatch.kt
index b9ad178..1885fbe 100644
--- a/overportcli/src/main/java/moe/crx/overport/patches/FixUnrealCrashPatch.kt
+++ b/overportcli/src/main/java/moe/crx/overport/patches/FixUnrealCrashPatch.kt
@@ -3,18 +3,18 @@ package moe.crx.overport.patches
import moe.crx.overport.patching.Patch
val PATCH_FIX_UNREAL_CRASH = Patch("patch_fix_unreal_crash") {
- createSmali("com/unity3d/player/UnityPlayer") {
- if (readText().isBlank()) {
- append(".class public Lcom/unity3d/player/UnityPlayer;")
- append(".super Ljava/lang/Object;")
- append(".field public static currentActivity:Landroid/app/Activity;")
- }
- }
-
selectSmali("com/epicgames/ue4/GameActivity") {
replace(
"sput-object (\\w+), Lcom\\/epicgames\\/ue4\\/GameActivity;->\\w+:Lcom\\/epicgames\\/ue4\\/GameActivity;",
"$0\nsput-object $1, Lcom/unity3d/player/UnityPlayer;->currentActivity:Landroid/app/Activity;"
)
+
+ createSmali("com/unity3d/player/UnityPlayer") {
+ if (readText().isBlank()) {
+ appendLine(".class public Lcom/unity3d/player/UnityPlayer;")
+ appendLine(".super Ljava/lang/Object;")
+ appendLine(".field public static currentActivity:Landroid/app/Activity;")
+ }
+ }
}
}
\ No newline at end of file
diff --git a/overportcli/src/main/java/moe/crx/overport/patches/LauncherEntryPatch.kt b/overportcli/src/main/java/moe/crx/overport/patches/LauncherEntryPatch.kt
index 892d9f7..49c1d5c 100644
--- a/overportcli/src/main/java/moe/crx/overport/patches/LauncherEntryPatch.kt
+++ b/overportcli/src/main/java/moe/crx/overport/patches/LauncherEntryPatch.kt
@@ -45,6 +45,7 @@ val PATCH_LAUNCHER_ENTRY = Patch("patch_launcher_entry") {
.put(createCategory("android.intent.category.LAUNCHER"))
.put(createCategory("com.oculus.intent.category.VR"))
.put(createCategory("com.yvr.intent.category.VR"))
+ .put(createCategory("org.khronos.openxr.intent.category.IMMERSIVE_HMD"))
}
}
}
diff --git a/overportcli/src/main/java/moe/crx/overport/patches/OculusUnityPatch.kt b/overportcli/src/main/java/moe/crx/overport/patches/OculusUnityPatch.kt
index 1616581..24d9f89 100644
--- a/overportcli/src/main/java/moe/crx/overport/patches/OculusUnityPatch.kt
+++ b/overportcli/src/main/java/moe/crx/overport/patches/OculusUnityPatch.kt
@@ -8,4 +8,15 @@ val PATCH_OCULUS_UNITY = Patch("patch_oculus_unity") {
"(getIsOnOculusHardware\\(\\)Z.*?)return (\\w+)", "$1\nconst/4 $2, 0x1\nreturn $2"
)
}
+
+ selectLibrary("libOculusXRPlugin.so") {
+ replaceHex(
+ "1F 1C 00 72 ?? ?? ?? ?? E9 07 9F 1A C0 00 80 52 20 00 A0 72 ?? ?? ?? ??",
+ "1F 1C 00 72 ?? ?? ?? ?? 29 00 80 52 C0 00 80 52 20 00 A0 72 ?? ?? ?? ??"
+ )
+ replaceHex(
+ "00 28 18 BF 01 20 ?? ?? 08 70 06 20 C0 F2 01 00",
+ "01 20 00 BF 00 BF ?? ?? 08 70 06 20 C0 F2 01 00"
+ )
+ }
}
\ No newline at end of file
diff --git a/overportcli/src/main/java/moe/crx/overport/patches/RemoveUsesLibraryPatch.kt b/overportcli/src/main/java/moe/crx/overport/patches/RemoveUsesLibraryPatch.kt
index 7787e6b..d473b4b 100644
--- a/overportcli/src/main/java/moe/crx/overport/patches/RemoveUsesLibraryPatch.kt
+++ b/overportcli/src/main/java/moe/crx/overport/patches/RemoveUsesLibraryPatch.kt
@@ -1,6 +1,7 @@
package moe.crx.overport.patches
import moe.crx.overport.patching.Patch
+import moe.crx.overport.utils.nameAttribute
import moe.crx.overport.utils.named
import moe.crx.overport.utils.takeNodesEach
@@ -8,8 +9,12 @@ val PATCH_REMOVE_USES_LIBRARY = Patch("patch_remove_uses_library") {
selectManifestJson {
takeNodesEach({ named("manifest") }) {
takeNodesEach({ named("application") }) {
- takeNodesEach({ named("uses-library") }) { null }
- takeNodesEach({ named("uses-native-library") }) { null }
+ takeNodesEach({ named("uses-library") }) {
+ if (nameAttribute() != "libopenxr.google.so") null else this
+ }
+ takeNodesEach({ named("uses-native-library") }) {
+ if (nameAttribute() != "libopenxr.google.so") null else this
+ }
}
}
}
diff --git a/overportcli/src/main/java/moe/crx/overport/patches/RemoveVrApiPatch.kt b/overportcli/src/main/java/moe/crx/overport/patches/RemoveVrApiPatch.kt
new file mode 100644
index 0000000..b155803
--- /dev/null
+++ b/overportcli/src/main/java/moe/crx/overport/patches/RemoveVrApiPatch.kt
@@ -0,0 +1,16 @@
+package moe.crx.overport.patches
+
+import moe.crx.overport.patching.Patch
+
+val PATCH_REMOVE_VRAPI = Patch("patch_remove_vrapi", false) {
+ selectWorkspace {
+ file.resolve("root/lib").listFiles()?.forEach { archDirectory ->
+ val arch = getLibraries().resolve("lib/${archDirectory.name}")
+
+ if (arch.exists()) {
+ val vrApi = archDirectory.listFiles().find { it.name.lowercase() == "libvrapi.so" }
+ vrApi?.delete()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/overportcli/src/main/java/moe/crx/overport/patches/ReplaceIconLabelPatch.kt b/overportcli/src/main/java/moe/crx/overport/patches/ReplaceIconLabelPatch.kt
index 107880a..9e0e79a 100644
--- a/overportcli/src/main/java/moe/crx/overport/patches/ReplaceIconLabelPatch.kt
+++ b/overportcli/src/main/java/moe/crx/overport/patches/ReplaceIconLabelPatch.kt
@@ -55,6 +55,12 @@ val PATCH_REPLACE_ICON_LABEL = Patch("patch_replace_icon_label") { arguments ->
}
}
+ if (!iconDownloaded) {
+ selectFile("root/res/drawable/custom_icon_ovrp.png") {
+ delete()
+ }
+ }
+
if (iconDownloaded) {
selectPackageBlock {
getOrCreate("", "drawable", "custom_icon_ovrp").apply {
diff --git a/overportcli/src/main/java/moe/crx/overport/patches/VRMetadataPatch.kt b/overportcli/src/main/java/moe/crx/overport/patches/VRMetadataPatch.kt
index 972cf97..8aa97b8 100644
--- a/overportcli/src/main/java/moe/crx/overport/patches/VRMetadataPatch.kt
+++ b/overportcli/src/main/java/moe/crx/overport/patches/VRMetadataPatch.kt
@@ -22,10 +22,100 @@ fun createMetadata(name: String, value: String): JSONObject {
)
}
+fun createMetadataFloat(name: String, value: Float): JSONObject {
+ return JSONObject().put("node_type", "element").put("name", "meta-data").put(
+ "attributes", JSONArray().put(
+ JSONObject().put("name", "name").put("id", 16842755)
+ .put("uri", "http://schemas.android.com/apk/res/android").put("prefix", "android")
+ .put("value_type", "STRING").put("data", name)
+ ).put(
+ JSONObject().put("name", "value").put("id", 16842788)
+ .put("uri", "http://schemas.android.com/apk/res/android").put("prefix", "android")
+ .put("value_type", "FLOAT").put("data", value)
+ )
+ )
+}
+
+fun createUsesFeature(name: String, required: Boolean): JSONObject {
+ return JSONObject().put("node_type", "element").put("name", "uses-feature").put(
+ "attributes", JSONArray().put(
+ JSONObject().put("name", "name").put("id", 16842755)
+ .put("uri", "http://schemas.android.com/apk/res/android").put("prefix", "android")
+ .put("value_type", "STRING").put("data", name)
+ ).put(
+ JSONObject().put("name", "required").put("id", 16843406)
+ .put("uri", "http://schemas.android.com/apk/res/android").put("prefix", "android")
+ .put("value_type", "BOOLEAN").put("data", required)
+ )
+ )
+}
+
+fun createUsesLibrary(name: String, required: Boolean): JSONObject {
+ return JSONObject().put("node_type", "element").put("name", "uses-library").put(
+ "attributes", JSONArray().put(
+ JSONObject().put("name", "name").put("id", 16842755)
+ .put("uri", "http://schemas.android.com/apk/res/android").put("prefix", "android")
+ .put("value_type", "STRING").put("data", name)
+ ).put(
+ JSONObject().put("name", "required").put("id", 16843406)
+ .put("uri", "http://schemas.android.com/apk/res/android").put("prefix", "android")
+ .put("value_type", "BOOLEAN").put("data", required)
+ )
+ )
+}
+
+fun createUsesPermission(name: String): JSONObject {
+ return JSONObject().put("node_type", "element").put("name", "uses-permission").put(
+ "attributes", JSONArray().put(
+ JSONObject().put("name", "name").put("id", 16842755)
+ .put("uri", "http://schemas.android.com/apk/res/android").put("prefix", "android")
+ .put("value_type", "STRING").put("data", name)
+ )
+ )
+}
+
+fun createProperty(key: String, value: String): JSONObject {
+ return JSONObject().put("node_type", "element").put("name", "property").put(
+ "attributes", JSONArray().put(
+ JSONObject().put("name", "name").put("id", 16842755)
+ .put("uri", "http://schemas.android.com/apk/res/android").put("prefix", "android")
+ .put("value_type", "STRING").put("data", key)
+ ).put(
+ JSONObject().put("name", "value").put("id", 16842788)
+ .put("uri", "http://schemas.android.com/apk/res/android").put("prefix", "android")
+ .put("value_type", "STRING").put("data", value)
+ )
+ )
+}
+
val PATCH_VR_METADATA = Patch("patch_vr_metadata") {
selectManifestJson {
takeNodesEach({ named("manifest") }) {
takeNodesEach({ named("application") }) {
+ takeNodesEach({ named("activity") }) {
+ takeNodes {
+ this?.put(
+ createProperty(
+ "android.window.PROPERTY_XR_ACTIVITY_START_MODE",
+ "XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED"
+ )
+ )?.put(
+ createProperty(
+ "android.window.PROPERTY_XR_BOUNDARY_TYPE_RECOMMENDED",
+ "XR_BOUNDARY_TYPE_LARGE"
+ )
+ )
+ }
+ }
+ takeNodes {
+ this?.put(createUsesFeature("android.software.xr.api.openxr", true))
+ this?.put(createUsesFeature("android.software.xr.api.spatial", true))
+ this?.put(createUsesLibrary("libopenxr.google.so", false))
+ this?.put(createUsesFeature("android.software.xr.input.controller", false))
+ ?.put(createUsesPermission("org.khronos.openxr.permission.OPENXR"))
+ ?.put(createUsesPermission("org.khronos.openxr.permission.OPENXR_SYSTEM"))
+ ?.put(createUsesPermission("com.huawei.android.permission.VR"))
+ }
takeNodesEach({ named("meta-data") }) {
if (nameAttribute() == "com.oculus.supportedDevices") null else this
}
@@ -33,6 +123,14 @@ val PATCH_VR_METADATA = Patch("patch_vr_metadata") {
this?.put(createMetadata("pvr.app.type", "vr"))
?.put(createMetadata("com.yvr.intent.category.VR", "vr_only"))
?.put(createMetadata("com.oculus.supportedDevices", "all"))
+ ?.put(createMetadata("com.huawei.android.vr.application.mode", "vr_only"))
+ ?.put(createMetadata("com.huawei.android.vr.application.type", "game"))
+ ?.put(createMetadata("com.huawei.vr.application.freeDegree", "3dof|6dof"))
+ ?.put(createMetadataFloat("android.max_aspect", 2.1f))
+ ?.put(createMetadata("minWaveSDKVersion", "1"))
+ ?.put(createMetadata("com.htc.vr.content.NumController", "1,2"))
+ ?.put(createMetadata("com.htc.vr.content.NumDoFController", "3,6DoF"))
+ ?.put(createMetadata("com.htc.vr.content.NumDoFHmd", "3,6DoF"))
}
}
}
diff --git a/overportcli/src/main/java/moe/crx/overport/patching/FileTransformer.kt b/overportcli/src/main/java/moe/crx/overport/patching/FileTransformer.kt
index 2f14506..f9adbb4 100644
--- a/overportcli/src/main/java/moe/crx/overport/patching/FileTransformer.kt
+++ b/overportcli/src/main/java/moe/crx/overport/patching/FileTransformer.kt
@@ -8,6 +8,10 @@ class FileTransformer(val file: File) {
file.writeText(Regex(input, RegexOption.DOT_MATCHES_ALL).replace(file.readText(), output))
}
+ fun delete(): Boolean {
+ return file.deleteRecursively()
+ }
+
fun readText(): String {
return file.readText()
}
@@ -16,6 +20,11 @@ class FileTransformer(val file: File) {
file.appendText(line)
}
+ fun appendLine(line: String) {
+ append(line)
+ append("\n")
+ }
+
fun readJson(): JSONObject? {
return runCatching { JSONObject(file.readText()) }.getOrNull()
}
@@ -35,6 +44,10 @@ class FileTransformer(val file: File) {
fun replaceHex(input: String, output: String) {
val bytes = file.readBytes()
val inputBytes = input.split(' ')
+ val outputBytes = output.split(' ')
+ var startIndex = -1
+
+ check(inputBytes.size == outputBytes.size)
for (i in 0..