mirror of
https://github.com/ovrport/app.git
synced 2026-10-26 19:19:56 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c7cb335c8 | ||
|
|
3b1d59224a | ||
|
|
5028a0e8f0 | ||
|
|
c790854772 |
No files matched your search
@@ -40,7 +40,7 @@ If you have any issues regarding game compatibility, please, enable verbose logg
|
|||||||
|
|
||||||
# About legality
|
# About legality
|
||||||
|
|
||||||
Think of this app like an emulator: you need to legally own the game files to use it.
|
Think of this app like an emulator: you need to legally obtain the game files to use it.
|
||||||
|
|
||||||
Obviously, to get a Quest game running on a different headset, the app has to strip away some entitlement checks.
|
Obviously, to get a Quest game running on a different headset, the app has to strip away some entitlement checks.
|
||||||
However, the game still won't launch on a Quest unless you’ve actually bought it.
|
However, the game still won't launch on a Quest unless you’ve actually bought it.
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ kotlin {
|
|||||||
desktopMain.dependencies {
|
desktopMain.dependencies {
|
||||||
implementation(compose.desktop.currentOs)
|
implementation(compose.desktop.currentOs)
|
||||||
implementation(libs.kotlinx.coroutines.swing)
|
implementation(libs.kotlinx.coroutines.swing)
|
||||||
|
implementation(libs.com.formdev.flatlaf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-28
@@ -15,7 +15,6 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.graphics.ImageBitmap
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import moe.crx.overport.app.decodeBitmap
|
import moe.crx.overport.app.decodeBitmap
|
||||||
import moe.crx.overport.app.util.ModifierUtil.rounded
|
import moe.crx.overport.app.util.ModifierUtil.rounded
|
||||||
@@ -25,43 +24,53 @@ import overportapp.composeapp.generated.resources.Res
|
|||||||
import overportapp.composeapp.generated.resources.unknown_package
|
import overportapp.composeapp.generated.resources.unknown_package
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
val iconCache = mutableMapOf<String, ImageBitmap?>()
|
||||||
|
val coverCache = mutableMapOf<String, ImageBitmap?>()
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ApplicationInfo(
|
fun ApplicationInfo(
|
||||||
applicationName: String? = "Application",
|
applicationName: String,
|
||||||
applicationPackage: String? = "com.company.application",
|
applicationPackage: String,
|
||||||
applicationVersion: String? = "1.0.0",
|
applicationVersion: String,
|
||||||
applicationIcon: ImageBitmap? = null,
|
applicationIcon: ImageBitmap? = null,
|
||||||
forceLocalInfo: Boolean = false,
|
forceLocalInfo: Boolean = false,
|
||||||
useCover: Boolean = false,
|
useCover: Boolean = false,
|
||||||
) {
|
) {
|
||||||
var iconIsLoading by rememberSaveable(applicationPackage) { mutableStateOf(true) }
|
var iconIsLoading by remember(applicationPackage) { mutableStateOf(true) }
|
||||||
var onlineIcon by rememberSaveable(applicationPackage) { mutableStateOf<ImageBitmap?>(null) }
|
var onlineIcon by remember(applicationPackage) { mutableStateOf(iconCache[applicationPackage]) }
|
||||||
var onlineCover by rememberSaveable(applicationPackage) { mutableStateOf<ImageBitmap?>(null) }
|
var onlineCover by remember(applicationPackage) { mutableStateOf(coverCache[applicationPackage]) }
|
||||||
|
|
||||||
var onlineLabel by rememberSaveable(applicationPackage) { mutableStateOf<String?>(null) }
|
var onlineLabel by rememberSaveable(applicationPackage) { mutableStateOf<String?>(null) }
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
|
|
||||||
LaunchedEffect(applicationPackage) {
|
LaunchedEffect(applicationPackage) {
|
||||||
scope.launch {
|
withContext(Dispatchers.IO) {
|
||||||
withContext(Dispatchers.IO) {
|
if (iconCache.containsKey(applicationPackage)) {
|
||||||
runCatching {
|
return@withContext
|
||||||
val info = applicationPackage?.let { getApplicationInfo(it) }
|
|
||||||
onlineLabel = info?.displayName
|
|
||||||
|
|
||||||
val icon = info?.run {
|
|
||||||
val associated = images.associateBy { it.imageType }
|
|
||||||
associated["APP_IMG_ICON"] ?: associated["APP_IMG_COVER_SQUARE"]
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val info = getApplicationInfo(applicationPackage)
|
||||||
|
onlineLabel = info?.displayName
|
||||||
|
|
||||||
|
val icon = info?.run {
|
||||||
|
val associated = images.associateBy { it.imageType }
|
||||||
|
associated["APP_IMG_ICON"] ?: associated["APP_IMG_COVER_SQUARE"]
|
||||||
|
}
|
||||||
|
|
||||||
|
val cover = info?.run {
|
||||||
|
val associated = images.associateBy { it.imageType }
|
||||||
|
associated["APP_IMG_COVER_SQUARE"] ?: associated["APP_IMG_ICON"]
|
||||||
|
}
|
||||||
|
|
||||||
|
val iconBitmap = icon?.uri?.let { Base64.getDecoder().decode(it) }?.decodeBitmap()
|
||||||
|
val coverBitmap = cover?.uri?.let { Base64.getDecoder().decode(it) }?.decodeBitmap()
|
||||||
|
|
||||||
|
iconCache[applicationPackage] = iconBitmap
|
||||||
|
coverCache[applicationPackage] = coverBitmap
|
||||||
|
|
||||||
|
onlineIcon = iconBitmap
|
||||||
|
onlineCover = coverBitmap
|
||||||
|
|
||||||
|
iconIsLoading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -21,9 +21,9 @@ import overportapp.composeapp.generated.resources.*
|
|||||||
@Composable
|
@Composable
|
||||||
@Preview
|
@Preview
|
||||||
fun ApplicationInfoContent(
|
fun ApplicationInfoContent(
|
||||||
applicationName: String? = "Application",
|
applicationName: String,
|
||||||
applicationPackage: String? = "",
|
applicationPackage: String,
|
||||||
applicationVersion: String? = "1.0.0",
|
applicationVersion: String,
|
||||||
applicationIcon: ImageBitmap? = null,
|
applicationIcon: ImageBitmap? = null,
|
||||||
onCancel: () -> Unit = {},
|
onCancel: () -> Unit = {},
|
||||||
onConfirm: (Map<String, List<String>>) -> Unit = {}
|
onConfirm: (Map<String, List<String>>) -> Unit = {}
|
||||||
|
|||||||
+19
-22
@@ -35,30 +35,26 @@ fun PatcherScreen(
|
|||||||
val isPatcherVisible = !viewModel.working && viewModel.isApkLoaded()
|
val isPatcherVisible = !viewModel.working && viewModel.isApkLoaded()
|
||||||
|
|
||||||
LaunchedEffect(openFlow) {
|
LaunchedEffect(openFlow) {
|
||||||
scope.launch {
|
openFlow.collect {
|
||||||
openFlow.collect {
|
inputFile = it
|
||||||
inputFile = it
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(saveFlow) {
|
LaunchedEffect(saveFlow) {
|
||||||
scope.launch {
|
saveFlow.collect { stream ->
|
||||||
saveFlow.collect { stream ->
|
val outputStream = stream ?: return@collect
|
||||||
val outputStream = stream ?: return@collect
|
try {
|
||||||
try {
|
viewModel.process(patches)
|
||||||
viewModel.process(patches)
|
viewModel.export(outputStream)
|
||||||
viewModel.export(outputStream)
|
scope.launch {
|
||||||
scope.launch {
|
snackbarHostState.showSnackbar(getString(Res.string.apk_file_exported))
|
||||||
snackbarHostState.showSnackbar(getString(Res.string.apk_file_exported))
|
|
||||||
}
|
|
||||||
} catch (ex: Throwable) {
|
|
||||||
ex.printStackTrace()
|
|
||||||
errorMessage = getString(Res.string.unknown_error) to ex.stackTraceToString()
|
|
||||||
} finally {
|
|
||||||
viewModel.cancel()
|
|
||||||
outputStream.close()
|
|
||||||
}
|
}
|
||||||
|
} catch (ex: Throwable) {
|
||||||
|
ex.printStackTrace()
|
||||||
|
errorMessage = getString(Res.string.unknown_error) to ex.stackTraceToString()
|
||||||
|
} finally {
|
||||||
|
viewModel.cancel()
|
||||||
|
//outputStream.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,9 +67,9 @@ fun PatcherScreen(
|
|||||||
|
|
||||||
FadeVisibility(isPatcherVisible) {
|
FadeVisibility(isPatcherVisible) {
|
||||||
ApplicationInfoContent(
|
ApplicationInfoContent(
|
||||||
viewModel.currentAppName(),
|
viewModel.currentAppName() ?: "",
|
||||||
viewModel.currentAppPackage(),
|
viewModel.currentAppPackage() ?: "",
|
||||||
viewModel.currentAppVersion(),
|
viewModel.currentAppVersion() ?: "",
|
||||||
viewModel.currentAppIcon(),
|
viewModel.currentAppIcon(),
|
||||||
onCancel = {
|
onCancel = {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
@@ -105,6 +101,7 @@ fun PatcherScreen(
|
|||||||
errorMessage =
|
errorMessage =
|
||||||
getString(Res.string.cant_checkout_title) to getString(Res.string.cant_checkout_message)
|
getString(Res.string.cant_checkout_title) to getString(Res.string.cant_checkout_message)
|
||||||
} catch (ex: Throwable) {
|
} catch (ex: Throwable) {
|
||||||
|
ex.printStackTrace()
|
||||||
viewModel.cancel()
|
viewModel.cancel()
|
||||||
errorMessage = getString(Res.string.unknown_error) to ex.stackTraceToString()
|
errorMessage = getString(Res.string.unknown_error) to ex.stackTraceToString()
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
+2
-4
@@ -27,10 +27,8 @@ fun VersionManagerSheet(viewModel: MainViewModel, onSelected: (String) -> Unit,
|
|||||||
var available by remember { mutableStateOf<List<OverportRelease>?>(null) }
|
var available by remember { mutableStateOf<List<OverportRelease>?>(null) }
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
scope.launch {
|
withContext(Dispatchers.IO) {
|
||||||
withContext(Dispatchers.IO) {
|
available = viewModel.versionManager.available()
|
||||||
available = viewModel.versionManager.available()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import androidx.compose.ui.draganddrop.awtTransferable
|
|||||||
import androidx.compose.ui.window.Window
|
import androidx.compose.ui.window.Window
|
||||||
import androidx.compose.ui.window.application
|
import androidx.compose.ui.window.application
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import com.formdev.flatlaf.util.SystemFileChooser
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import moe.crx.overport.app.composables.AppContent
|
import moe.crx.overport.app.composables.AppContent
|
||||||
@@ -24,7 +25,6 @@ import org.jetbrains.compose.resources.stringResource
|
|||||||
import overportapp.composeapp.generated.resources.Res
|
import overportapp.composeapp.generated.resources.Res
|
||||||
import overportapp.composeapp.generated.resources.select_a_file
|
import overportapp.composeapp.generated.resources.select_a_file
|
||||||
import overportapp.composeapp.generated.resources.window_icon
|
import overportapp.composeapp.generated.resources.window_icon
|
||||||
import java.awt.FileDialog
|
|
||||||
import java.awt.Frame
|
import java.awt.Frame
|
||||||
import java.awt.datatransfer.DataFlavor
|
import java.awt.datatransfer.DataFlavor
|
||||||
import java.io.*
|
import java.io.*
|
||||||
@@ -97,23 +97,26 @@ fun main(args: Array<String>) = application {
|
|||||||
AppContent(
|
AppContent(
|
||||||
viewModel = viewModel,
|
viewModel = viewModel,
|
||||||
openFile = {
|
openFile = {
|
||||||
val fileDialog = FileDialog(Frame(), selectFileString, FileDialog.LOAD).apply {
|
val fileDialog = SystemFileChooser(selectFileString).apply {
|
||||||
directory = lastOpenedDirectory
|
currentDirectory = File(lastOpenedDirectory)
|
||||||
isVisible = true
|
selectedFile = null
|
||||||
}
|
}
|
||||||
|
|
||||||
val file = fileDialog.file?.let { File(fileDialog.directory).resolve(it) }
|
val file = if (fileDialog.showOpenDialog(Frame()) != SystemFileChooser.APPROVE_OPTION) null else {
|
||||||
|
fileDialog.selectedFile
|
||||||
|
}
|
||||||
|
|
||||||
openFile(file)
|
openFile(file)
|
||||||
},
|
},
|
||||||
saveFile = { name ->
|
saveFile = { name ->
|
||||||
val fileDialog = FileDialog(Frame(), selectFileString, FileDialog.SAVE).apply {
|
val fileDialog = SystemFileChooser(selectFileString).apply {
|
||||||
directory = lastOpenedDirectory
|
currentDirectory = File(lastOpenedDirectory)
|
||||||
file = name
|
selectedFile = File(lastOpenedDirectory, name)
|
||||||
isVisible = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val file = fileDialog.file?.let { File(fileDialog.directory).resolve(it) }
|
val file = if (fileDialog.showSaveDialog(Frame()) != SystemFileChooser.APPROVE_OPTION) null else {
|
||||||
|
fileDialog.selectedFile
|
||||||
|
}
|
||||||
|
|
||||||
scope.launch {
|
scope.launch {
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
|
|||||||
+1
-1
@@ -7,4 +7,4 @@ org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8
|
|||||||
android.nonTransitiveRClass=true
|
android.nonTransitiveRClass=true
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
#Application
|
#Application
|
||||||
appVersion=1.2.2
|
appVersion=1.2.3
|
||||||
@@ -13,8 +13,11 @@ bcpkix = "1.83"
|
|||||||
kotlinx-serialization = "1.9.0"
|
kotlinx-serialization = "1.9.0"
|
||||||
lifecycle-viewmodel-compose = "2.9.6"
|
lifecycle-viewmodel-compose = "2.9.6"
|
||||||
compose-hot-reload = "1.0.0"
|
compose-hot-reload = "1.0.0"
|
||||||
|
flatlaf = "3.7.2"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
|
com-formdev-flatlaf = { group = "com.formdev", name = "flatlaf", version.ref = "flatlaf" }
|
||||||
|
|
||||||
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidx-activityCompose" }
|
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidx-activityCompose" }
|
||||||
|
|
||||||
androidx-lifecycle-viewmodel = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel", version.ref = "androidx-lifecycle" }
|
androidx-lifecycle-viewmodel = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel", version.ref = "androidx-lifecycle" }
|
||||||
@@ -24,8 +27,8 @@ androidx-lifecycle-viewmodel-compose = { group = "org.jetbrains.androidx.lifecyc
|
|||||||
|
|
||||||
android-tools-build = { group = "com.android.tools.build", name = "apksig", version.ref = "apksig" }
|
android-tools-build = { group = "com.android.tools.build", name = "apksig", version.ref = "apksig" }
|
||||||
bouncycastle-pkix = { group = "org.bouncycastle", name = "bcpkix-jdk18on", version.ref = "bcpkix" }
|
bouncycastle-pkix = { group = "org.bouncycastle", name = "bcpkix-jdk18on", version.ref = "bcpkix" }
|
||||||
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name ="kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
|
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
|
||||||
kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name ="kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
|
kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
androidApplication = { id = "com.android.application", version.ref = "agp" }
|
androidApplication = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "moe.crx"
|
group = "moe.crx"
|
||||||
version = "1.2.2"
|
version = "1.2.3"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(libs.android.tools.build)
|
implementation(libs.android.tools.build)
|
||||||
|
|||||||
Binary file not shown.
@@ -31,7 +31,7 @@ fun createMetadataFloat(name: String, value: Float): JSONObject {
|
|||||||
).put(
|
).put(
|
||||||
JSONObject().put("name", "value").put("id", 16842788)
|
JSONObject().put("name", "value").put("id", 16842788)
|
||||||
.put("uri", "http://schemas.android.com/apk/res/android").put("prefix", "android")
|
.put("uri", "http://schemas.android.com/apk/res/android").put("prefix", "android")
|
||||||
.put("value_type", "FLOAT").put("data", value)
|
.put("value_type", "FLOAT").put("data", value.toRawBits())
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -91,6 +91,22 @@ fun createProperty(key: String, value: String): JSONObject {
|
|||||||
val PATCH_VR_METADATA = Patch("patch_vr_metadata") {
|
val PATCH_VR_METADATA = Patch("patch_vr_metadata") {
|
||||||
selectManifestJson {
|
selectManifestJson {
|
||||||
takeNodesEach({ named("manifest") }) {
|
takeNodesEach({ named("manifest") }) {
|
||||||
|
takeNodes {
|
||||||
|
this?.put(createUsesFeature("android.software.xr.api.openxr", true))
|
||||||
|
?.put(createUsesFeature("android.software.xr.api.spatial", true))
|
||||||
|
?.put(createUsesFeature("android.software.xr.input.controller", false))
|
||||||
|
?.put(createUsesFeature("android.hardware.xr.input.hand_tracking", false))
|
||||||
|
?.put(createUsesFeature("android.hardware.xr.input.eye_tracking", false))
|
||||||
|
?.put(createUsesPermission("org.khronos.openxr.permission.OPENXR"))
|
||||||
|
?.put(createUsesPermission("org.khronos.openxr.permission.OPENXR_SYSTEM"))
|
||||||
|
?.put(createUsesPermission("com.huawei.android.permission.VR"))
|
||||||
|
?.put(createUsesPermission("android.permission.EYE_TRACKING_COARSE"))
|
||||||
|
?.put(createUsesPermission("android.permission.EYE_TRACKING_FINE"))
|
||||||
|
?.put(createUsesPermission("android.permission.FACE_TRACKING"))
|
||||||
|
?.put(createUsesPermission("android.permission.HAND_TRACKING"))
|
||||||
|
?.put(createUsesPermission("android.permission.SCENE_UNDERSTANDING_COARSE"))
|
||||||
|
?.put(createUsesPermission("android.permission.SCENE_UNDERSTANDING_FINE"))
|
||||||
|
}
|
||||||
takeNodesEach({ named("application") }) {
|
takeNodesEach({ named("application") }) {
|
||||||
takeNodesEach({ named("activity") }) {
|
takeNodesEach({ named("activity") }) {
|
||||||
takeNodes {
|
takeNodes {
|
||||||
@@ -107,15 +123,6 @@ val PATCH_VR_METADATA = Patch("patch_vr_metadata") {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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") }) {
|
takeNodesEach({ named("meta-data") }) {
|
||||||
if (nameAttribute() == "com.oculus.supportedDevices") null else this
|
if (nameAttribute() == "com.oculus.supportedDevices") null else this
|
||||||
}
|
}
|
||||||
@@ -131,6 +138,7 @@ val PATCH_VR_METADATA = Patch("patch_vr_metadata") {
|
|||||||
?.put(createMetadata("com.htc.vr.content.NumController", "1,2"))
|
?.put(createMetadata("com.htc.vr.content.NumController", "1,2"))
|
||||||
?.put(createMetadata("com.htc.vr.content.NumDoFController", "3,6DoF"))
|
?.put(createMetadata("com.htc.vr.content.NumDoFController", "3,6DoF"))
|
||||||
?.put(createMetadata("com.htc.vr.content.NumDoFHmd", "3,6DoF"))
|
?.put(createMetadata("com.htc.vr.content.NumDoFHmd", "3,6DoF"))
|
||||||
|
?.put(createUsesLibrary("libopenxr.google.so", false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class VersionManager(val workingDirectory: File) {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val json = Json { ignoreUnknownKeys = true }
|
val json = Json { ignoreUnknownKeys = true }
|
||||||
const val VERSION = "1.2.2"
|
const val VERSION = "1.2.3"
|
||||||
|
|
||||||
private fun isVersionLower(left: String, right: String): Boolean {
|
private fun isVersionLower(left: String, right: String): Boolean {
|
||||||
val (lY, lM, lD) = left.substringBeforeLast('-').split('.').map { it.toInt() }
|
val (lY, lM, lD) = left.substringBeforeLast('-').split('.').map { it.toInt() }
|
||||||
|
|||||||
Reference in new issue
Block a user