Skip to content

Commit a4c8d51

Browse files
committed
Add version selection
1 parent 0f7ad01 commit a4c8d51

10 files changed

Lines changed: 173 additions & 32 deletions

File tree

QuestAppVersionSwitcher/AndroidDevice.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using ComputerUtils.Android.VarUtils;
1+
using Android.OS;
2+
using ComputerUtils.Android.VarUtils;
23

34
namespace QuestAppVersionSwitcher
45
{
@@ -24,5 +25,16 @@ public string totalSpaceString
2425
return SizeConverter.ByteSizeToString(totalSpace);
2526
}
2627
}
28+
29+
public static AndroidDevice GetCurrent()
30+
{
31+
return new AndroidDevice()
32+
{
33+
sdkVersion = (int)Build.VERSION.SdkInt,
34+
device = Build.Device,
35+
freeSpace = Environment.ExternalStorageDirectory.UsableSpace,
36+
totalSpace = Environment.ExternalStorageDirectory.TotalSpace,
37+
};
38+
}
2739
}
2840
}

QuestAppVersionSwitcher/Assets/html/flows/beat_saber_modding.html

Lines changed: 118 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<body>
1010
<div class="content" id="checking">
1111
<h1>Checking your current Beat Saber install</h1>
12-
<h3>Please wait a bit. This may take 3 minute</h3>
12+
<h3>Please wait a bit. This may take 3 minutes</h3>
1313
<div class="loaderContainer center">
1414
<div class="loaderBarRight"></div>
1515
<div class="loaderBarLeft"></div>
@@ -169,6 +169,45 @@ <h1>QAVS can currently not manage mods for Quest 3!</h1>
169169
<br>You can ask for help in the #quest-help channel at discord.gg/beatsabermods (Discord Server).
170170
</p>
171171
</div>
172+
<div class="content hidden" id="sl2">
173+
<h1>QAVS can currently not patch Beat Saber for you!</h1>
174+
<p>
175+
QAVS cannot patch Beat Saber. For that you will have to use QuestPatcher on your PC with Scotland2 selected.
176+
<br>
177+
After patching Beat Saber you can come back to QAVS to install and manage mods.
178+
<br>
179+
You can ask for help in the #quest-help channel at discord.gg/beatsabermods (Discord Server).
180+
181+
<br>
182+
<br>
183+
<button onclick="location.reload()">I installed Beat Saber. Please check my game again.</button>
184+
</p>
185+
</div>
186+
<div class="content hidden" id="notInstalled">
187+
<h1>Beat Saber is not installed</h1>
188+
<p>
189+
You must install Beat Saber from the store in order to mod it. Please come back after modding Beat Saber
190+
</p>
191+
<br>
192+
<br>
193+
<button onclick="location.reload()">I patched using QuestPatcher. Please check my game again.</button>
194+
</div>
195+
<div class="content hidden" id="selectVersion">
196+
<h1>Select a version</h1>
197+
<p>
198+
First you'll need to select one of the recommended game version you want to mod. If you're not sure which to choose just press <code>Next</code>
199+
</p>
200+
<br>
201+
<select id="gameVersions">
202+
203+
</select>
204+
<br>
205+
<button onclick="VersionSelected()">Next</button>
206+
<br>
207+
<br>
208+
<br>
209+
<button style="font-size: 0.7rem" onclick="SelectVersion(true)">Show all versions (not recommended></button>
210+
</div>
172211
<div style="position: fixed; bottom: 10px; left: 10px;">
173212
<button id="showSupportButton" onclick="ShowSupport()">Help</button>
174213
<div id="helpSection" style="display: none;" class="box">
@@ -207,6 +246,11 @@ <h2>Upload logs</h2>
207246
var tab = params.get('tab');
208247
var checkdowngrade = params.get('checkdowngrade');
209248
var startDownload = params.get('startdownload');
249+
var versionSpecified = false
250+
if(params.get("version")) {
251+
selectedVersion = params.get("version")
252+
versionSpecified = true
253+
}
210254
const start = ""
211255
const squareLoader = `
212256
<div class="loaderContainer center">
@@ -220,8 +264,37 @@ <h2>Upload logs</h2>
220264
<div class="loaderSquare"></div>
221265
</div>`
222266

267+
function VersionSelected() {
268+
selectedVersion = document.getElementById("gameVersions").value
269+
versionSpecified = true
270+
FirstOpen()
271+
}
272+
273+
function SelectVersion(showAll = false) {
274+
fetch("https://raw.githubusercontent.com/ComputerElite/QuestAppVersionSwitcher/main/Assets/downgrade.json").then(res => res.json().then(downgrade => {
275+
UpdateSupportedBeatSaberVersions().then(() => {
276+
if(SupportedBeatSaberVersions.length < 0) {
277+
OpenTab("offline")
278+
return
279+
}
280+
versions = downgrade.recommendedVersions
281+
if(!versions.includes(SupportedBeatSaberVersions[0])) versions.unshift(SupportedBeatSaberVersions[0])
282+
if(showAll) versions = SupportedBeatSaberVersions
283+
284+
var html = ""
285+
for(const v of versions) {
286+
html += `<option value="${v}">${SupportedBeatSaberVersions[0] == v ? `${v} (latest)` : v}</option>`
287+
}
288+
document.getElementById("gameVersions").innerHTML = html
289+
OpenTab("selectVersion")
290+
})
291+
})).catch(err => {
292+
console.log(err)
293+
OpenTab("offline")
294+
})
295+
}
296+
223297
function InitialStuff() {
224-
225298
if(tab) {
226299
if(tab == "afterrestore") {
227300
fetch(start + "/api/android/device").then(res => res.json().then(j => {
@@ -313,6 +386,7 @@ <h2>Upload logs</h2>
313386
function ModSettings() {
314387
location = start + `/?tab=patching`
315388
}
389+
var patchExtras = ""
316390
function ModDowngradedGame() {
317391
patchExtras = `?package=${lastDownloadProgress.packageName}&backup=${lastDownloadProgress.backupName}`
318392
OpenTab("modgame")
@@ -409,7 +483,7 @@ <h2>Upload logs</h2>
409483
return
410484
}
411485
fetch(start + "/api/cleardownloads", {method: "POST"})
412-
location = start + `/?download=true&version=${SupportedBeatSaberVersions[0]}&noaccesscheck=true&game=2448060205267927&afterdownload=${encodeURIComponent(start + `/flows/beat_saber_modding?tab=download&startdownload=true`)}`
486+
location = start + `/?download=true&version=${selectedVersion}&noaccesscheck=true&game=2448060205267927&afterdownload=${encodeURIComponent(start + `/flows/beat_saber_modding?tab=download&startdownload=true`)}`
413487
}
414488

415489
function CheckDowngrade() {
@@ -418,12 +492,12 @@ <h2>Upload logs</h2>
418492
el.innerText = moddedStatus.isInstalled ? moddedStatus.version : "Not installed"
419493
}
420494
for(const el of document.getElementsByClassName("supportedBsVersion")) {
421-
el.innerText = SupportedBeatSaberVersions[0]
495+
el.innerText = selectedVersion
422496
}
423497
// Check if the latest version is already downloaded by getting backup list of Beat Saber, then checking
424498
fetch(start + "/api/backups?package=com.beatgames.beatsaber").then(res => res.json().then(j => {
425499
for(const b of j.backups) {
426-
if(b.gameVersion == SupportedBeatSaberVersions[0] && b.isDownloadedFromOculus) {
500+
if(b.gameVersion == selectedVersion && b.isDownloadedFromOculus) {
427501
// Game version is already downloaded. Show mod game button
428502
console.log("Found backup for latest modable version, showing mod game button")
429503
// emulate finished download
@@ -447,7 +521,9 @@ <h2>Upload logs</h2>
447521
currentSha = json.msg
448522
console.log(currentSha)
449523
fetch("https://raw.githubusercontent.com/ComputerElite/APKDowngrader/main/versions.json").then(res => res.json().then(patches => {
450-
patches = patches.versions.filter(x => x.SSHA256 == currentSha && x.TV == SupportedBeatSaberVersions[0])
524+
patches = patches.versions.filter(x => x.SSHA256 == currentSha && x.TV == selectedVersion)
525+
console.log("Apk sha is " + currentSha)
526+
console.log()
451527
if (patches.length <= 0) {
452528
// No patches found
453529
OpenTab("patcheserror")
@@ -549,7 +625,7 @@ <h2>Upload logs</h2>
549625
handTrackingVersion: 0, // Default
550626
externalStorage: true,
551627
openXR: true,
552-
modloader: moddedStatus.recommendedModloader // QuestLoader = 0, Scotland2 = 1
628+
modloader: modloader // QuestLoader = 0, Scotland2 = 1
553629
}
554630
document.getElementById("modgamebutton").style.display = "none"
555631
patchInProgressContainer.style.display = "block"
@@ -601,30 +677,52 @@ <h2>Upload logs</h2>
601677
function UpdateModGamePage() {
602678
document.getElementById("modgamebsversion").innerText = moddedStatus.version;
603679
}
680+
681+
var selectedVersion = ""
682+
var modloader = 0
604683

605684
function FirstOpen() {
606685
// Not logged in
686+
OpenTab("checking")
687+
if(!selectedVersion) {
688+
// let user select the version they want to use
689+
SelectVersion()
690+
return
691+
}
607692
UpdateModdedStatus().then(() => {
608693
if(!moddedStatus.isInstalled) {
609694
// Downgrade
610-
OpenTab(diffDowngradeEnabled ? "downgradeLoginDiff" : "downgrade")
611-
CheckDowngrade()
695+
if(diffDowngradeEnabled) {
696+
OpenTab("notInstalled")
697+
} else {
698+
OpenTab("downgrade")
699+
CheckDowngrade()
700+
}
612701
} else {
613702
UpdateSupportedBeatSaberVersions().then(() => {
703+
if(selectedVersion == "" && SupportedBeatSaberVersions.length > 0) {
704+
selectedVersion = SupportedBeatSaberVersions[0]
705+
}
614706
if(SupportedBeatSaberVersions.length <= 0) {
615707
// OH NO; USER IS OFFLINE
616708
OpenTab("offline")
617-
} else if(SupportedBeatSaberVersions[0] == moddedStatus.version) {
709+
} else if(selectedVersion == moddedStatus.version) {
618710
// Continue with modding
619-
620-
if(moddedStatus.isPatched) {
621-
// Already modded
622-
OpenTab("alreadymodded")
623-
} else {
624-
// Not modded
625-
OpenTabIfSAFAccess("modgame")
626-
UpdateModGamePage()
627-
}
711+
fetch(`${start}/api/patching/recommendmodloader?package=com.beatgames.beatsaber&version=${selectedVersion}`).then(res => res.json().then(j => {
712+
modloader = j.modloader
713+
if(moddedStatus.isPatched) {
714+
// Already modded
715+
OpenTab("alreadymodded")
716+
} else {
717+
// Not modded
718+
if(modloader == 1 && moddedStatus.device.sdkVersion >= 32) {
719+
OpenTab("sl2")
720+
} else {
721+
OpenTabIfSAFAccess("modgame")
722+
UpdateModGamePage()
723+
}
724+
}
725+
}))
628726
} else {
629727
// Downgrade
630728
CheckDowngrade()
@@ -639,6 +737,7 @@ <h2>Upload logs</h2>
639737

640738
function UpdateSupportedBeatSaberVersions() {
641739
return new Promise((resolve, reject) => {
740+
SupportedBeatSaberVersions = []
642741
fetch("https://computerelite.github.io/tools/Beat_Saber/coreMods.json").then(res => res.json().then(j => {
643742
for(const [key, value] of Object.entries(j)) {
644743
SupportedBeatSaberVersions.push(key);

QuestAppVersionSwitcher/Assets/html/index.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,14 @@ <h2>Downloads</h2>
358358
</label>
359359
Use Diff downgrading (disable means use default)
360360
</label>
361+
<br>
362+
<label class="option">
363+
<label class="switch normal">
364+
<input id="installModsQ3" type="checkbox">
365+
<span class="slider round"></span>
366+
</label>
367+
Install mods anyway on Q3 (not recommended as it most likely won't work)
368+
</label>
361369
<div class="buttonContainer">
362370
<div class="button" id="checkUpdate">Check for QuestAppVersionSwitcher updates</div>
363371
<div class="buttonLabel">Checks if updates for QuestAppVersionSwitcher exist</div>

QuestAppVersionSwitcher/Assets/html/script.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,14 +331,20 @@ fetch("/api/android/device").then(res => res.json().then(res => {
331331
}))
332332

333333
function UpdateInstalledModsQuest3Hint() {
334-
var isOnQuest3 = device == "eureka" && modloader == 0 // only hide mods stuff on QuestLoader
334+
var isOnQuest3 = device == "eureka" && modloader == 0 && !localStorage.installModsQ3 // only hide mods stuff on QuestLoader
335335
for(const e of document.getElementsByClassName("quest3hide")) {
336336
e.style.display = isOnQuest3 ? "none" : "block"
337337
}
338338
for(const e of document.getElementsByClassName("quest3show")) {
339339
e.style.display = isOnQuest3 ? "block" : "none"
340340
}
341341
}
342+
document.getElementById("installModsQ3").checked = localStorage.installModsQ3 == "true"
343+
344+
document.getElementById("installModsQ3").onchange = () => {
345+
localStorage.installModsQ3 = document.getElementById("installModsQ3").checked
346+
UpdateInstalledModsQuest3Hint()
347+
}
342348

343349
function LaunchApp() {
344350
fetch("/api/android/launch", {

QuestAppVersionSwitcher/ClientModels.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class PatchingStatus
1212
public string version { get; set; } = "";
1313
public string copyOf { get; set; } = "";
1414
public string versionCode { get; set; } = "";
15+
public AndroidDevice device { get; set; } = new AndroidDevice();
1516
public ModLoader recommendedModloader { get; set; } = ModLoader.QuestLoader;
1617
public string package { get; set; } = "";
1718
public ModdedJson moddedJson { get; set; } = null;

QuestAppVersionSwitcher/FolderPermission.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,6 @@ public static void DeleteDirectoryContent(string dir)
268268

269269
public static bool NeedsSAF()
270270
{
271-
//return false;
272271
return Build.VERSION.SdkInt > BuildVersionCodes.Q;
273272
}
274273

QuestAppVersionSwitcher/PatchingManager.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using System.Net;
1414
using System.Text;
1515
using System.Text.Json;
16+
using Android.OS;
1617
using JetBrains.Annotations;
1718
using QuestAppVersionSwitcher.Mods;
1819
using QuestPatcher.QMod;
@@ -412,6 +413,7 @@ public static PatchingStatus GetPatchingStatus(ApkZip apk, string packageId = ""
412413
manifestStream.Dispose();
413414
status.package = packageId;
414415
status.recommendedModloader = GetRecommendedModloader(status);
416+
status.device = AndroidDevice.GetCurrent();
415417
return status;
416418
}
417419

@@ -459,6 +461,7 @@ public static PatchingStatus GetPatchingStatus(ZipArchive apk, string packageId
459461
status.moddedJson = GetModdedJson(apk);
460462
status.package = packageId;
461463
status.recommendedModloader = GetRecommendedModloader(status);
464+
status.device = AndroidDevice.GetCurrent();
462465
manifestStream.Close();
463466
manifestStream.Dispose();
464467
return status;

QuestAppVersionSwitcher/Properties/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.15.18" package="com.ComputerElite.questappversionswitcher" android:installLocation="preferExternal" android:versionCode="139">
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.15.19" package="com.ComputerElite.questappversionswitcher" android:installLocation="preferExternal" android:versionCode="140">
33
<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="32" />
44
<uses-permission android:name="oculus.permission.handtracking" />
55
<uses-permission android:name="com.oculus.permission.HAND_TRACKING" />

QuestAppVersionSwitcher/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@
2222
// Minor Version
2323
// Build Number
2424
// Revision
25-
[assembly: AssemblyVersion("1.15.18.0")]
26-
[assembly: AssemblyFileVersion("1.15.18.0")]
25+
[assembly: AssemblyVersion("1.15.19.0")]
26+
[assembly: AssemblyFileVersion("1.15.19.0")]

QuestAppVersionSwitcher/WebServer.cs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
using Newtonsoft.Json;
4141
using OculusGraphQLApiLib.GraphQL;
4242
using QuestAppVersionSwitcher.DiffDowngrading;
43+
using QuestPatcher.QMod;
4344
using QuestPatcher.Zip;
4445
using DownloadStatus = QuestAppVersionSwitcher.ClientModels.DownloadStatus;
4546
using Environment = Android.OS.Environment;
@@ -283,6 +284,24 @@ public void Start()
283284
request.SendString(JsonSerializer.Serialize(CoreService.coreVars.patchingPermissions), "application/json");
284285
return true;
285286
});
287+
server.AddRoute("GET", "/api/patching/recommendmodloader", request =>
288+
{
289+
string package = request.queryString.Get("package");
290+
if (package == null)
291+
{
292+
request.SendString(ModLoaderResponse.GetResponse("No package specified", ModLoader.QuestLoader, false), "application/json", 400);
293+
return true;
294+
}
295+
string version = request.queryString.Get("version");
296+
if (version == null)
297+
{
298+
request.SendString(ModLoaderResponse.GetResponse("No version specified", ModLoader.QuestLoader, false), "application/json", 400);
299+
return true;
300+
}
301+
ModLoader recommended = PatchingManager.GetRecommendedModloader(new PatchingStatus {version = version, package = package});
302+
request.SendString(JsonSerializer.Serialize(ModLoaderResponse.GetResponse(recommended.ToString(), recommended, true)), "application/json");
303+
return true;
304+
});
286305
server.AddRoute("POST", "/api/patching/patchoptions", request =>
287306
{
288307
CoreService.coreVars.patchingPermissions = JsonSerializer.Deserialize<PatchingPermissions>(request.bodyString);
@@ -560,13 +579,7 @@ public void Start()
560579
});
561580
server.AddRoute("GET", "/api/android/device", serverRequest =>
562581
{
563-
serverRequest.SendString(JsonSerializer.Serialize(new AndroidDevice()
564-
{
565-
sdkVersion = (int)Build.VERSION.SdkInt,
566-
device = Build.Device,
567-
freeSpace = Environment.ExternalStorageDirectory.UsableSpace,
568-
totalSpace = Environment.ExternalStorageDirectory.TotalSpace,
569-
}), "application/json");
582+
serverRequest.SendString(JsonSerializer.Serialize(AndroidDevice.GetCurrent()), "application/json");
570583
return true;
571584
});
572585
server.AddRoute("POST", "/api/android/launch", serverRequest =>

0 commit comments

Comments
 (0)