Skip to content

Commit ba68079

Browse files
Merge pull request #136 from hdgamer1404Jonas/main
Add Support for Custom Splash screens
2 parents 6bf3d73 + bbc43e3 commit ba68079

File tree

4 files changed

+69
-9
lines changed

4 files changed

+69
-9
lines changed

QuestPatcher.Core/Models/PatchingOptions.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,16 @@ public bool HandTracking
2424
public bool Microphone { get; set; }
2525

2626
public bool OpenXR { get; set; }
27-
27+
2828
public bool FlatScreenSupport { get; set; }
2929

3030
public HandTrackingVersion HandTrackingType { get; set; }
3131

3232
public ModLoader ModLoader { get; set; } = ModLoader.QuestLoader;
3333

34+
/// <summary>
35+
/// Path to a PNG file containing a custom splash screen.
36+
/// </summary>
37+
public string? CustomSplashPath { get; set; } = null;
3438
}
3539
}

QuestPatcher.Core/Patching/PatchingManager.cs

+27-7
Original file line numberDiff line numberDiff line change
@@ -201,24 +201,28 @@ private async Task PatchManifest(ApkZip apk)
201201
"org.khronos.openxr.permission.OPENXR_SYSTEM",
202202
});
203203

204-
AxmlElement providerElement = new("provider") {
205-
Attributes = {new("authorities", AndroidNamespaceUri, AuthoritiesAttributeResourceId, "org.khronos.openxr.runtime_broker;org.khronos.openxr.system_runtime_broker")},
204+
AxmlElement providerElement = new("provider")
205+
{
206+
Attributes = { new("authorities", AndroidNamespaceUri, AuthoritiesAttributeResourceId, "org.khronos.openxr.runtime_broker;org.khronos.openxr.system_runtime_broker") },
206207
};
207-
AxmlElement runtimeIntent = new("intent") {
208+
AxmlElement runtimeIntent = new("intent")
209+
{
208210
Children = {
209211
new("action") {
210212
Attributes = {new("name", AndroidNamespaceUri, NameAttributeResourceId, "org.khronos.openxr.OpenXRRuntimeService")},
211213
},
212214
},
213215
};
214-
AxmlElement layerIntent = new("intent") {
216+
AxmlElement layerIntent = new("intent")
217+
{
215218
Children = {
216219
new("action") {
217220
Attributes = {new("name", AndroidNamespaceUri, NameAttributeResourceId, "org.khronos.openxr.OpenXRApiLayerService")},
218221
},
219222
},
220223
};
221-
manifest.Children.Add(new("queries") {
224+
manifest.Children.Add(new("queries")
225+
{
222226
Children = {
223227
providerElement,
224228
runtimeIntent,
@@ -475,6 +479,21 @@ private async Task ModifyApk(string mainPath, string? modloaderPath, string? uni
475479
await AddFlatscreenSupport(apk, ovrPlatformSdkPath!);
476480
}
477481

482+
if (_config.PatchingOptions.CustomSplashPath != null)
483+
{
484+
Log.Information("Checking if Splash screen file exists");
485+
if (File.Exists(_config.PatchingOptions.CustomSplashPath))
486+
{
487+
apk.RemoveFile("assets/vr_splash.png");
488+
await AddFileToApk(_config.PatchingOptions.CustomSplashPath, "assets/vr_splash.png", apk, true);
489+
Log.Information("Replaced Splash with custom Image");
490+
}
491+
else
492+
{
493+
Log.Warning("Could not add custom splash screen: file did not exist.");
494+
}
495+
}
496+
478497
Log.Information("Patching manifest . . .");
479498
await PatchManifest(apk);
480499

@@ -495,8 +514,9 @@ private async Task ModifyApk(string mainPath, string? modloaderPath, string? uni
495514
/// <param name="filePath">The path to the file to copy into the APK</param>
496515
/// <param name="apkFilePath">The name of the file in the APK to create</param>
497516
/// <param name="apk">The apk to copy the file into</param>
517+
/// <param name="useStore">If enabled, compression is disabled and the STORE compression method is used.</param>
498518
/// <exception cref="PatchingException">If the file already exists in the APK, if configured to throw.</exception>
499-
private async Task AddFileToApk(string filePath, string apkFilePath, ApkZip apk)
519+
private async Task AddFileToApk(string filePath, string apkFilePath, ApkZip apk, bool useStore = false)
500520
{
501521
using var fileStream = File.OpenRead(filePath);
502522
if (apk.ContainsFile(apkFilePath))
@@ -511,7 +531,7 @@ private async Task AddFileToApk(string filePath, string apkFilePath, ApkZip apk)
511531
fileStream.Position = 0;
512532
}
513533

514-
await apk.AddFileAsync(apkFilePath, fileStream, PatchingCompression);
534+
await apk.AddFileAsync(apkFilePath, fileStream, useStore ? null : PatchingCompression);
515535
}
516536

517537
/// <summary>

QuestPatcher/ViewModels/PatchingViewModel.cs

+24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
2+
using System.Linq;
23
using Avalonia.Controls;
4+
using Avalonia.Platform.Storage;
35
using QuestPatcher.Core;
46
using QuestPatcher.Core.Models;
57
using QuestPatcher.Core.Patching;
@@ -17,6 +19,8 @@ public class PatchingViewModel : ViewModelBase
1719

1820
public string PatchingStageText { get; private set; } = "";
1921

22+
public string? CustomSplashPath => Config.PatchingOptions.CustomSplashPath;
23+
2024
public Config Config { get; }
2125

2226
public OperationLocker Locker { get; }
@@ -104,6 +108,26 @@ public async void StartPatching()
104108
}
105109
}
106110

111+
public async void SelectSplashPath()
112+
{
113+
try
114+
{
115+
var files = await _mainWindow.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
116+
{
117+
FileTypeFilter = new[]
118+
{
119+
FilePickerFileTypes.ImagePng
120+
}
121+
});
122+
Config.PatchingOptions.CustomSplashPath = files.FirstOrDefault()?.Path.LocalPath;
123+
this.RaisePropertyChanged(nameof(CustomSplashPath));
124+
}
125+
catch (Exception ex)
126+
{
127+
Log.Error(ex, "Failed to select splash screen path");
128+
}
129+
}
130+
107131
/// <summary>
108132
/// Updates the patching stage text in the view
109133
/// </summary>

QuestPatcher/Views/PatchingView.axaml

+13-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<Panel>
1313
<DockPanel IsVisible="{Binding !IsPatchingInProgress}">
1414
<StackPanel Margin="20" Orientation="Vertical" DockPanel.Dock="Top">
15-
<ToggleButton IsChecked="{Binding Config.ShowPatchingOptions}" VerticalAlignment="Top" HorizontalAlignment="Right">Customise Permissions</ToggleButton>
15+
<ToggleButton IsChecked="{Binding Config.ShowPatchingOptions}" VerticalAlignment="Top" HorizontalAlignment="Right">Patching Options</ToggleButton>
1616
<ScrollViewer Margin="0 15 0 0" IsVisible="{Binding Config.ShowPatchingOptions}" HorizontalScrollBarVisibility="Auto" VerticalAlignment="Top" Background="{DynamicResource PatchingOptionsBackground}">
1717
<StackPanel Orientation="Horizontal" Spacing="25" Margin="10">
1818
<ToggleSwitch IsChecked="{Binding Config.PatchingOptions.ExternalFiles}" IsEnabled="False">Allow External Files</ToggleSwitch>
@@ -32,6 +32,18 @@
3232
</StackPanel>
3333
</StackPanel>
3434
</ScrollViewer>
35+
<Panel Margin="0 10 0 0" Background="{DynamicResource PatchingOptionsBackground}">
36+
<StackPanel Orientation="Vertical" Spacing="10" IsVisible="{Binding Config.ShowPatchingOptions}" Margin="10">
37+
<StackPanel Orientation="Horizontal" Spacing="5">
38+
<TextBlock>Custom Splash Screen:</TextBlock>
39+
</StackPanel>
40+
<StackPanel Orientation="Horizontal" Spacing="5">
41+
<Button Command="{Binding SelectSplashPath}">Browse</Button>
42+
<TextBlock Text="{Binding CustomSplashPath}" IsVisible="{Binding CustomSplashPath, Converter={x:Static ObjectConverters.IsNotNull}}>" VerticalAlignment="Center"/>
43+
<TextBlock Text="None Selected" IsVisible="{Binding CustomSplashPath, Converter={x:Static ObjectConverters.IsNull}}>" VerticalAlignment="Center" />
44+
</StackPanel>
45+
</StackPanel>
46+
</Panel>
3547
</StackPanel>
3648

3749
<StackPanel HorizontalAlignment="Center" Orientation="Vertical" VerticalAlignment="Center" Spacing="20">

0 commit comments

Comments
 (0)