Compare commits

..

3 commits

Author SHA1 Message Date
13a076ad79 brbrbr patapim 2026-01-01 05:11:23 +05:00
3dc9c8c279 split installation info to parts 2026-01-01 05:11:05 +05:00
c29658e7e4 add storage functionality and appdata model 2026-01-01 05:10:44 +05:00
11 changed files with 550 additions and 236 deletions

View file

@ -0,0 +1,9 @@
using MetaforceInstaller.Core.Models;
namespace MetaforceInstaller.Core.Intefaces;
public interface IStorageService
{
AppData Load();
void Save(AppData data);
}

View file

@ -0,0 +1,6 @@
namespace MetaforceInstaller.Core.Models;
public class AppData
{
public List<InstallationData> Installations { get; set; } = new();
}

View file

@ -0,0 +1,10 @@
namespace MetaforceInstaller.Core.Models;
public class InstallationData
{
public Guid Id { get; set; } = Guid.NewGuid();
public string Title { get; set; }
public string AndroidPackagePath { get; set; }
public string WindowsServerPackagePath { get; set; }
public string WindowsAdminPackagePath { get; set; }
}

View file

@ -0,0 +1,12 @@
namespace MetaforceInstaller.Core.Models;
public record InstallationParts
{
public bool OculusClientExists { get; init; }
public bool PicoClientExists { get; init; }
public bool AndroidAdminExists { get; init; }
public bool AndroidContentExists { get; init; }
public bool WindowsContentExists { get; init; }
public bool WindowsAdminExists { get; init; }
public bool WindowsServerExists { get; init; }
}

View file

@ -0,0 +1,36 @@
using System.Text.Json;
using MetaforceInstaller.Core.Intefaces;
using MetaforceInstaller.Core.Models;
namespace MetaforceInstaller.Core.Services;
public class StorageService : IStorageService
{
private readonly string _storagePath;
public StorageService()
{
var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
var appDirectory = Path.Combine(appData, "MetaforceInstaller");
Directory.CreateDirectory(appDirectory);
_storagePath = Path.Combine(appDirectory, "installations.json");
}
public AppData Load()
{
if (!File.Exists(_storagePath))
return new AppData();
var json = File.ReadAllText(_storagePath);
return JsonSerializer.Deserialize<AppData>(json) ?? new AppData();
}
public void Save(AppData data)
{
var json = JsonSerializer.Serialize(data, new JsonSerializerOptions
{
WriteIndented = true
});
File.WriteAllText(_storagePath, json);
}
}

View file

@ -0,0 +1,89 @@
using System.IO.Compression;
using MetaforceInstaller.Core.Models;
namespace MetaforceInstaller.Core.Services;
public class ZipScrapper
{
public static InstallationParts PeekFiles(ZipArchive archive)
{
return new InstallationParts
{
AndroidContentExists = DoesAndroidContentExists(archive),
OculusClientExists = DoesOculusClientExists(archive),
PicoClientExists = DoesPicoClientExists(archive),
AndroidAdminExists = DoesAndroidAdminExists(archive),
WindowsAdminExists = DoesPcAdminExists(archive),
WindowsContentExists = DoesWindowsContentExists(archive),
WindowsServerExists = DoesServerExists(archive),
};
// Console.WriteLine($"Contents of {archive}:");
// Console.WriteLine("----------------------------------");
//
// foreach (ZipArchiveEntry entry in archive.Entries)
// {
// // You can access properties like entry.Name, entry.FullName, entry.Length (uncompressed size), entry.CompressedLength
// Console.WriteLine($"Entry: {entry.FullName}");
// Console.WriteLine($" Uncompressed Size: {entry.Length} bytes");
// Console.WriteLine($" Compressed Size: {entry.CompressedLength} bytes");
// Console.WriteLine("----------------------------------");
// }
}
public static string ExtractZip(ZipArchive archive, string outputPath)
{
archive.ExtractToDirectory(outputPath);
return outputPath;
}
private static bool DoesPicoClientExists(ZipArchive archive)
{
return archive.Entries
.Any(entry => entry.Name.Contains("MetaforcePico")
&& entry.Name.EndsWith(".apk"));
}
private static bool DoesOculusClientExists(ZipArchive archive)
{
return archive.Entries
.Any(entry => entry.Name.Contains("MetaforceOculus")
&& entry.Name.EndsWith(".apk"));
}
private static bool DoesAndroidAdminExists(ZipArchive archive)
{
return archive.Entries
.Any(entry => entry.Name.Contains("MetaforceAdmin")
&& entry.Name.EndsWith(".apk"));
}
private static bool DoesAndroidContentExists(ZipArchive archive)
{
return archive.Entries
.Any(entry => entry.Name.Contains("Content_Android")
&& entry.Name.EndsWith(".zip"));
}
private static bool DoesWindowsContentExists(ZipArchive archive)
{
return archive.Entries
.Any(entry => entry.Name.Contains("Content_StandaloneWindows")
&& entry.Name.EndsWith(".zip"));
}
private static bool DoesPcAdminExists(ZipArchive archive)
{
return archive.Entries
.Any(entry => entry.FullName.Contains("MetaforceAdminPC")
&& entry.Name.EndsWith(".exe") && !entry.Name.Contains("UnityCrashHandler") &&
!entry.Name.Contains("crashpad_handler"));
}
private static bool DoesServerExists(ZipArchive archive)
{
return archive.Entries
.Any(entry => entry.FullName.Contains("MetaforceServer")
&& entry.Name.EndsWith(".exe") && !entry.Name.Contains("UnityCrashHandler") &&
!entry.Name.Contains("crashpad_handler"));
}
}

View file

@ -10,11 +10,11 @@
<ResourceDictionary> <ResourceDictionary>
<ResourceDictionary.ThemeDictionaries> <ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light"> <ResourceDictionary x:Key="Light">
<SvgImage x:Key="Logo" Source="/Images/logo_red.svg"/> <SvgImage x:Key="Logo" Source="/Images/logo_red.svg" />
</ResourceDictionary> </ResourceDictionary>
<ResourceDictionary x:Key="Dark"> <ResourceDictionary x:Key="Dark">
<SvgImage x:Key="Logo" Source="/Images/logo_red.svg"/> <SvgImage x:Key="Logo" Source="/Images/logo_red.svg" />
</ResourceDictionary> </ResourceDictionary>
</ResourceDictionary.ThemeDictionaries> </ResourceDictionary.ThemeDictionaries>
</ResourceDictionary> </ResourceDictionary>
@ -22,49 +22,44 @@
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="96" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Main Content Area --> <Image Grid.Row="0"
<Grid Grid.Row="0" Margin="8"> Margin="20"
<Grid.ColumnDefinitions> VerticalAlignment="Center"
<ColumnDefinition Width="3*" /> <!-- 30% --> Source="{DynamicResource Logo}"
<ColumnDefinition Width="7*" /> <!-- 70% --> HorizontalAlignment="Left">
</Grid.ColumnDefinitions> </Image>
<!-- Left Panel - Buttons --> <Button Grid.Row="0" Name="NewInstallationButton" Margin="20" VerticalAlignment="Center"
<StackPanel Grid.Column="0" Margin="20" Spacing="15"> HorizontalAlignment="Right">
<Button Name="ChooseApkButton" Content="Choose .apk" + Add new installation
HorizontalAlignment="Stretch" /> </Button>
<Button Name="ChooseContentButton" Content="Choose .zip" <ScrollViewer Grid.Row="1">
HorizontalAlignment="Stretch" /> <StackPanel Margin="10">
<Expander Header="Item 1" Margin="0,5" HorizontalAlignment="Stretch">
<TextBlock Text="Content for item 1" Margin="10" />
</Expander>
<Button Name="InstallButton" Content="Install" <Expander Header="Item 2" Margin="0,5" HorizontalAlignment="Stretch">
HorizontalAlignment="Stretch" /> <TextBlock Text="Content for item 2" Margin="10" />
</Expander>
<Expander Header="Item 3" Margin="0,5" HorizontalAlignment="Stretch">
<TextBlock Text="Content for item 3" Margin="10" />
</Expander>
<Expander Header="Item 4" Margin="0,5" HorizontalAlignment="Stretch">
<TextBlock Text="Content for item 4" Margin="10" />
</Expander>
<Expander Header="Item 5" Margin="0,5" HorizontalAlignment="Stretch">
<TextBlock Text="Content for item 5" Margin="10" />
</Expander>
</StackPanel> </StackPanel>
</ScrollViewer>
<Image Grid.Column="0"
Margin="20"
VerticalAlignment="Bottom"
Source="{DynamicResource Logo}"
HorizontalAlignment="Center">
</Image>
<!-- Right Panel - Logs -->
<TextBox Grid.Column="1" Name="LogsTextBox"
IsReadOnly="True"
AcceptsReturn="True"
TextWrapping="Wrap"
FontFamily="Consolas,Courier New,monospace"
Focusable="False"
Margin="4,0,0,0" />
</Grid>
<!-- Progress Bar at Bottom -->
<ProgressBar Grid.Row="1" Name="InstallProgressBar"
Height="20" Minimum="0" Maximum="100" Value="0"
Margin="8" />
</Grid> </Grid>
</Window> </Window>

View file

@ -26,205 +26,211 @@ public partial class MainWindow : Window
public MainWindow() public MainWindow()
{ {
InitializeComponent(); InitializeComponent();
NewInstallationButton.Click += OnNewInstalltionClick;
LogMessage("MetaforceInstaller by slavagm"); // LogMessage("MetaforceInstaller by slavagm");
//
_adbService = new AdbService(); // _adbService = new AdbService();
_adbService.ProgressChanged += OnAdbProgressChanged; // _adbService.ProgressChanged += OnAdbProgressChanged;
_adbService.StatusChanged += OnAdbStatusChanged; // _adbService.StatusChanged += OnAdbStatusChanged;
//
CheckAndEnableInstallButton(); // CheckAndEnableInstallButton();
//
ChooseApkButton.Click += OnChooseApkClicked; // ChooseApkButton.Click += OnChooseApkClicked;
ChooseContentButton.Click += OnChooseContentClicked; // ChooseContentButton.Click += OnChooseContentClicked;
InstallButton.Click += OnInstallClicked; // InstallButton.Click += OnInstallClicked;
} }
private void OnAdbProgressChanged(object? sender, ProgressInfo e) public async void OnNewInstalltionClick(object? sender, RoutedEventArgs e)
{ {
Dispatcher.UIThread.InvokeAsync(() => var newInstallationDialog = new NewInstallationDialog();
{ await newInstallationDialog.ShowDialog<NewInstallationDialog>(this);
if (e.PercentageComplete != _lastUpdatedProgress &&
e.PercentageComplete % PROGRESS_UPDATE_STEP == 0)
{
InstallProgressBar.Value = e.PercentageComplete;
_lastUpdatedProgress = e.PercentageComplete;
}
if (e.PercentageComplete != _lastLoggedProgress &&
e.PercentageComplete % PROGRESS_LOG_STEP == 0 || e.PercentageComplete == 100)
{
LogMessage(
e.TotalBytes > 0
? $"Прогресс: {e.PercentageComplete}% ({FormatBytes(e.BytesTransferred)} / {FormatBytes(e.TotalBytes)})"
: $"Прогресс: {e.PercentageComplete}%");
_lastLoggedProgress = e.PercentageComplete;
}
});
} }
private void OnProgressReport(ProgressInfo progressInfo) // private void OnAdbProgressChanged(object? sender, ProgressInfo e)
{ // {
Dispatcher.UIThread.InvokeAsync(() => // Dispatcher.UIThread.InvokeAsync(() =>
{ // {
if (progressInfo.PercentageComplete != _lastUpdatedProgress && // if (e.PercentageComplete != _lastUpdatedProgress &&
progressInfo.PercentageComplete % PROGRESS_UPDATE_STEP == 0) // e.PercentageComplete % PROGRESS_UPDATE_STEP == 0)
{ // {
InstallProgressBar.Value = progressInfo.PercentageComplete; // InstallProgressBar.Value = e.PercentageComplete;
_lastUpdatedProgress = progressInfo.PercentageComplete; // _lastUpdatedProgress = e.PercentageComplete;
} // }
//
// if (e.PercentageComplete != _lastLoggedProgress &&
if (progressInfo.PercentageComplete != _lastLoggedProgress && // e.PercentageComplete % PROGRESS_LOG_STEP == 0 || e.PercentageComplete == 100)
(progressInfo.PercentageComplete % PROGRESS_LOG_STEP == 0 || progressInfo.PercentageComplete == 100)) // {
{ // LogMessage(
LogMessage( // e.TotalBytes > 0
progressInfo.TotalBytes > 0 // ? $"Прогресс: {e.PercentageComplete}% ({FormatBytes(e.BytesTransferred)} / {FormatBytes(e.TotalBytes)})"
? $"Прогресс: {progressInfo.PercentageComplete}% ({FormatBytes(progressInfo.BytesTransferred)} / {FormatBytes(progressInfo.TotalBytes)})" // : $"Прогресс: {e.PercentageComplete}%");
: $"Прогресс: {progressInfo.PercentageComplete}%"); //
// _lastLoggedProgress = e.PercentageComplete;
_lastLoggedProgress = progressInfo.PercentageComplete; // }
} // });
}); // }
} //
// private void OnProgressReport(ProgressInfo progressInfo)
private void OnAdbStatusChanged(object? sender, string e) // {
{ // Dispatcher.UIThread.InvokeAsync(() =>
Dispatcher.UIThread.InvokeAsync(() => // {
{ // if (progressInfo.PercentageComplete != _lastUpdatedProgress &&
InstallProgressBar.Value = 0; // progressInfo.PercentageComplete % PROGRESS_UPDATE_STEP == 0)
_lastLoggedProgress = -1; // {
_lastUpdatedProgress = -1; // InstallProgressBar.Value = progressInfo.PercentageComplete;
LogMessage(e); // _lastUpdatedProgress = progressInfo.PercentageComplete;
}); // }
} //
//
private string FormatBytes(long bytes) // if (progressInfo.PercentageComplete != _lastLoggedProgress &&
{ // (progressInfo.PercentageComplete % PROGRESS_LOG_STEP == 0 || progressInfo.PercentageComplete == 100))
string[] suffixes = ["B", "KB", "MB", "GB", "TB"]; // {
var counter = 0; // LogMessage(
double number = bytes; // progressInfo.TotalBytes > 0
// ? $"Прогресс: {progressInfo.PercentageComplete}% ({FormatBytes(progressInfo.BytesTransferred)} / {FormatBytes(progressInfo.TotalBytes)})"
while (Math.Round(number / 1024) >= 1) // : $"Прогресс: {progressInfo.PercentageComplete}%");
{ //
number /= 1024; // _lastLoggedProgress = progressInfo.PercentageComplete;
counter++; // }
} // });
// }
return $"{number:N1} {suffixes[counter]}"; //
} // private void OnAdbStatusChanged(object? sender, string e)
// {
// Dispatcher.UIThread.InvokeAsync(() =>
private async void CheckAndEnableInstallButton() // {
{ // InstallProgressBar.Value = 0;
InstallButton.IsEnabled = !string.IsNullOrEmpty(_apkPath) && !string.IsNullOrEmpty(_zipPath); // _lastLoggedProgress = -1;
} // _lastUpdatedProgress = -1;
// LogMessage(e);
private async void OnChooseApkClicked(object? sender, RoutedEventArgs e) // });
{ // }
var topLevel = GetTopLevel(this); //
var files = await topLevel!.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions // private string FormatBytes(long bytes)
{ // {
Title = "Выберите APK файл", // string[] suffixes = ["B", "KB", "MB", "GB", "TB"];
AllowMultiple = false, // var counter = 0;
FileTypeFilter = new[] // double number = bytes;
{ //
new FilePickerFileType("APK Files") // while (Math.Round(number / 1024) >= 1)
{ // {
Patterns = new[] { "*.apk" } // number /= 1024;
} // counter++;
} // }
}); //
// return $"{number:N1} {suffixes[counter]}";
if (files.Count >= 1) // }
{ //
_apkPath = files[0].Path.LocalPath; //
LogMessage($"APK выбран: {Path.GetFileName(_apkPath)}"); // private async void CheckAndEnableInstallButton()
} // {
// InstallButton.IsEnabled = !string.IsNullOrEmpty(_apkPath) && !string.IsNullOrEmpty(_zipPath);
CheckAndEnableInstallButton(); // }
} //
// private async void OnChooseApkClicked(object? sender, RoutedEventArgs e)
private async void OnChooseContentClicked(object? sender, RoutedEventArgs e) // {
{ // var topLevel = GetTopLevel(this);
var topLevel = GetTopLevel(this); // var files = await topLevel!.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
var files = await topLevel!.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions // {
{ // Title = "Выберите APK файл",
Title = "Выберите архив с контентом", // AllowMultiple = false,
AllowMultiple = false, // FileTypeFilter = new[]
FileTypeFilter = new[] // {
{ // new FilePickerFileType("APK Files")
new FilePickerFileType("ZIP Files") // {
{ // Patterns = new[] { "*.apk" }
Patterns = new[] { "*.zip" } // }
} // }
} // });
}); //
// if (files.Count >= 1)
if (files.Count >= 1) // {
{ // _apkPath = files[0].Path.LocalPath;
_zipPath = files[0].Path.LocalPath; // LogMessage($"APK выбран: {Path.GetFileName(_apkPath)}");
LogMessage($"Контент выбран: {Path.GetFileName(_zipPath)}"); // }
} //
// CheckAndEnableInstallButton();
CheckAndEnableInstallButton(); // }
} //
// private async void OnChooseContentClicked(object? sender, RoutedEventArgs e)
private async void OnInstallClicked(object? sender, RoutedEventArgs e) // {
{ // var topLevel = GetTopLevel(this);
if (string.IsNullOrEmpty(_apkPath) || string.IsNullOrEmpty(_zipPath)) // var files = await topLevel!.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{ // {
LogMessage("Ошибка: Выберите APK файл и папку с контентом"); // Title = "Выберите архив с контентом",
return; // AllowMultiple = false,
} // FileTypeFilter = new[]
// {
_adbService.RefreshDeviceData(); // new FilePickerFileType("ZIP Files")
// {
InstallButton.IsEnabled = false; // Patterns = new[] { "*.zip" }
InstallProgressBar.Value = 0; // }
// }
try // });
{ //
LogMessage("Начинаем установку..."); // if (files.Count >= 1)
// {
var deviceInfo = _adbService.GetDeviceInfo(); // _zipPath = files[0].Path.LocalPath;
LogMessage($"Найдено устройство: {deviceInfo.SerialNumber}"); // LogMessage($"Контент выбран: {Path.GetFileName(_zipPath)}");
LogMessage($"Состояние: {deviceInfo.State}"); // }
LogMessage($"Модель: {deviceInfo.Model} - {deviceInfo.Name}"); //
// CheckAndEnableInstallButton();
var progress = new Progress<ProgressInfo>(OnProgressReport); // }
//
await _adbService.InstallApkAsync(_apkPath, progress); // private async void OnInstallClicked(object? sender, RoutedEventArgs e)
// {
var apkInfo = ApkScrapper.GetApkInfo(_apkPath); // if (string.IsNullOrEmpty(_apkPath) || string.IsNullOrEmpty(_zipPath))
LogMessage($"Ставим {apkInfo.PackageName} версии {apkInfo.VersionName}"); // {
var zipName = Path.GetFileName(_zipPath); // LogMessage("Ошибка: Выберите APK файл и папку с контентом");
var outputPath = // return;
@$"/storage/emulated/0/Android/data/{apkInfo.PackageName}/files/{zipName}"; // }
LogMessage($"Начинаем копирование контента в {outputPath}"); //
// _adbService.RefreshDeviceData();
await _adbService.CopyFileAsync(_zipPath, outputPath, progress); //
// InstallButton.IsEnabled = false;
LogMessage("Установка завершена успешно!"); // InstallProgressBar.Value = 0;
} //
catch (Exception ex) // try
{ // {
LogMessage($"Ошибка установки: {ex.Message}"); // LogMessage("Начинаем установку...");
} //
finally // var deviceInfo = _adbService.GetDeviceInfo();
{ // LogMessage($"Найдено устройство: {deviceInfo.SerialNumber}");
InstallButton.IsEnabled = true; // LogMessage($"Состояние: {deviceInfo.State}");
InstallProgressBar.Value = 0; // LogMessage($"Модель: {deviceInfo.Model} - {deviceInfo.Name}");
} //
} // var progress = new Progress<ProgressInfo>(OnProgressReport);
//
private void LogMessage(string message) // await _adbService.InstallApkAsync(_apkPath, progress);
{ //
var timestamp = DateTime.Now.ToString("HH:mm:ss"); // var apkInfo = ApkScrapper.GetApkInfo(_apkPath);
LogsTextBox.Text += $"[{timestamp}] {message}\n"; // LogMessage($"Ставим {apkInfo.PackageName} версии {apkInfo.VersionName}");
// var zipName = Path.GetFileName(_zipPath);
var scrollViewer = LogsTextBox.FindAncestorOfType<ScrollViewer>(); // var outputPath =
scrollViewer?.ScrollToEnd(); // @$"/storage/emulated/0/Android/data/{apkInfo.PackageName}/files/{zipName}";
} // LogMessage($"Начинаем копирование контента в {outputPath}");
//
// await _adbService.CopyFileAsync(_zipPath, outputPath, progress);
//
// LogMessage("Установка завершена успешно!");
// }
// catch (Exception ex)
// {
// LogMessage($"Ошибка установки: {ex.Message}");
// }
// finally
// {
// InstallButton.IsEnabled = true;
// InstallProgressBar.Value = 0;
// }
// }
//
// private void LogMessage(string message)
// {
// var timestamp = DateTime.Now.ToString("HH:mm:ss");
// LogsTextBox.Text += $"[{timestamp}] {message}\n";
//
// var scrollViewer = LogsTextBox.FindAncestorOfType<ScrollViewer>();
// scrollViewer?.ScrollToEnd();
// }
} }

View file

@ -0,0 +1,24 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="200" d:DesignHeight="400"
x:Class="MetaforceInstaller.UI.NewInstallationDialog"
Title="MetaforceInstaller">
<StackPanel Margin="24" Spacing="12">
<Label FontSize="36">Add new installation</Label>
<TextBox />
<Button Name="ChooseZip">Choose .zip with installation</Button>
<CheckBox Name="ServerCheckBox">Install server</CheckBox>
<CheckBox Name="PcAdminCheckBox">Install admin</CheckBox>
<CheckBox Name="AndroidAdminCheckbox">Save android admin</CheckBox>
<CheckBox Name="VrClientCheckbox">Save VR client</CheckBox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom" Spacing="8">
<Button Name="InstallButton">Install</Button>
<Button Name="CancelButton">Cancel</Button>
</StackPanel>
</StackPanel>
</Window>

View file

@ -0,0 +1,118 @@
using System.IO.Compression;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using MetaforceInstaller.Core.Models;
using MetaforceInstaller.Core.Services;
namespace MetaforceInstaller.UI;
public partial class NewInstallationDialog : Window
{
private string? _zipPath;
private InstallationParts? _installationParts;
public NewInstallationDialog()
{
InitializeComponent();
RefreshCheckboxes();
CancelButton.Click += OnCancelClick;
ChooseZip.Click += OnChooseZipClick;
InstallButton.IsEnabled = false;
InstallButton.Click += OnInstallClick;
}
private async void RefreshCheckboxes()
{
var serverCheckbox = ServerCheckBox;
var pcAdminCheckbox = PcAdminCheckBox;
var androidAdminCheckbox = AndroidAdminCheckbox;
var vrClientCheckbox = VrClientCheckbox;
serverCheckbox.Content = TextDefaults.InstallServer;
serverCheckbox.IsEnabled = true;
pcAdminCheckbox.Content = TextDefaults.InstallAdmin;
pcAdminCheckbox.IsEnabled = true;
androidAdminCheckbox.Content = TextDefaults.SaveAndroidAdmin;
androidAdminCheckbox.IsEnabled = true;
vrClientCheckbox.Content = TextDefaults.SaveVRClient;
vrClientCheckbox.IsEnabled = true;
}
private async void OnChooseZipClick(object? sender, RoutedEventArgs e)
{
var topLevel = GetTopLevel(this);
var files = await topLevel!.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = "Выберите архив с контентом",
AllowMultiple = false,
FileTypeFilter =
[
new FilePickerFileType("ZIP Files")
{
Patterns = ["*.zip"]
}
]
});
if (files.Count >= 1)
{
_zipPath = files[0].Path.LocalPath;
using var archive = ZipFile.OpenRead(_zipPath);
_installationParts = ZipScrapper.PeekFiles(archive);
UpdateCheckboxes();
archive.Dispose();
}
}
private async void OnInstallClick(object? sender, RoutedEventArgs e)
{
using var archive = ZipFile.OpenRead(_zipPath);
}
private void UpdateCheckboxes()
{
RefreshCheckboxes();
var serverCheckbox = ServerCheckBox;
var pcAdminCheckbox = PcAdminCheckBox;
var androidAdminCheckbox = AndroidAdminCheckbox;
var vrClientCheckbox = VrClientCheckbox;
if (!_installationParts.WindowsServerExists)
{
serverCheckbox.IsEnabled = false;
serverCheckbox.Content += "\nCouldn't find directory with server";
}
if (!_installationParts.WindowsAdminExists)
{
pcAdminCheckbox.IsEnabled = false;
pcAdminCheckbox.Content += "\nCouldn't find directory with PC admin";
}
if (!_installationParts.WindowsContentExists)
{
pcAdminCheckbox.IsEnabled = false;
pcAdminCheckbox.Content += "\nCouldn't find windows content";
}
if (!_installationParts.AndroidContentExists)
{
vrClientCheckbox.IsEnabled = false;
vrClientCheckbox.Content += "\nCouldn't find android content";
androidAdminCheckbox.IsEnabled = false;
androidAdminCheckbox.Content += "\nCouldn't find android content";
}
if (!_installationParts.PicoClientExists && !_installationParts.OculusClientExists)
{
vrClientCheckbox.IsEnabled = false;
vrClientCheckbox.Content += "\nCouldn't find any VR clients";
}
}
private void OnCancelClick(object? sender, RoutedEventArgs e)
{
Close();
}
}

View file

@ -0,0 +1,9 @@
namespace MetaforceInstaller.UI;
public static class TextDefaults
{
public static readonly string InstallServer = "Install Server";
public static readonly string InstallAdmin = "Install Admin";
public static readonly string SaveAndroidAdmin = "Save Android admin";
public static readonly string SaveVRClient = "Save VR client";
}