some refactoring

This commit is contained in:
Вячеслав 2026-01-01 22:58:33 +05:00
parent 89c3dcb424
commit bbf905495c
8 changed files with 160 additions and 106 deletions

View file

@ -5,4 +5,5 @@ public class InstallationData
public Guid Id { get; set; } = Guid.NewGuid();
public required string Title { get; set; }
public required InstallationParts Parts { get; set; }
public DateTime InstalledAt { get; set; } = DateTime.Now;
}

View file

@ -9,18 +9,4 @@ public class InstallationParts
public string? WindowsContentPath { get; init; }
public string? WindowsAdminPath { get; init; }
public string? WindowsServerPath { get; init; }
public InstallationParts ExtendPaths(string prefixPath)
{
return new InstallationParts
{
OculusClientPath = OculusClientPath is null ? null : Path.Combine(prefixPath, OculusClientPath),
PicoClientPath = PicoClientPath is null ? null : Path.Combine(prefixPath, PicoClientPath),
AndroidAdminPath = AndroidAdminPath is null ? null : Path.Combine(prefixPath, AndroidAdminPath),
AndroidContentPath = AndroidContentPath is null ? null : Path.Combine(prefixPath, AndroidContentPath),
WindowsContentPath = WindowsContentPath is null ? null : Path.Combine(prefixPath, WindowsContentPath),
WindowsAdminPath = WindowsAdminPath is null ? null : Path.Combine(prefixPath, WindowsAdminPath),
WindowsServerPath = WindowsServerPath is null ? null : Path.Combine(prefixPath, WindowsServerPath)
};
}
}

View file

@ -9,42 +9,46 @@ public class ZipScrapper
{
return new InstallationParts
{
AndroidContentPath = DoesAndroidContentExists(archive),
OculusClientPath = DoesOculusClientExists(archive),
PicoClientPath = DoesPicoClientExists(archive),
AndroidAdminPath = DoesAndroidAdminExists(archive),
WindowsAdminPath = DoesPcAdminExists(archive),
WindowsContentPath = DoesWindowsContentExists(archive),
WindowsServerPath = DoesServerExists(archive),
AndroidContentPath = FindAndroidContent(archive),
OculusClientPath = FindOculusClient(archive),
PicoClientPath = FindPicoClient(archive),
AndroidAdminPath = FindAndroidAdmin(archive),
WindowsAdminPath = FindPcAdmin(archive),
WindowsContentPath = FindWindowsContent(archive),
WindowsServerPath = FindServer(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, IProgress<double>? progress = null)
/// <summary>
/// Extracts ZIP archive to a unique folder based on installation GUID
/// </summary>
/// <param name="archive">ZIP archive to extract</param>
/// <param name="baseOutputPath">Base storage path</param>
/// <param name="installationGuid">Unique GUID for this installation</param>
/// <param name="progress">Progress reporter</param>
/// <returns>Full path to the extracted folder</returns>
public static string ExtractZip(
ZipArchive archive,
string baseOutputPath,
Guid installationGuid,
IProgress<double>? progress = null)
{
// Create unique folder for this installation
var installationFolder = Path.Combine(baseOutputPath, installationGuid.ToString());
Directory.CreateDirectory(installationFolder);
var entries = archive.Entries.Where(e => !string.IsNullOrEmpty(e.Name)).ToList();
var totalEntries = entries.Count;
var processedEntries = 0;
foreach (var entry in entries)
{
var destinationPath = Path.Combine(outputPath, entry.FullName);
var destinationPath = Path.Combine(installationFolder, entry.FullName);
var destinationDir = Path.GetDirectoryName(destinationPath);
if (!string.IsNullOrEmpty(destinationDir))
{
Directory.CreateDirectory(destinationDir);
Console.WriteLine($"Extracting {entry.FullName} to {destinationPath}");
}
entry.ExtractToFile(destinationPath, overwrite: true);
@ -53,66 +57,104 @@ public class ZipScrapper
progress?.Report((double)processedEntries / totalEntries * 100);
}
return outputPath;
return installationFolder;
}
private static string? DoesPicoClientExists(ZipArchive archive)
/// <summary>
/// Updates InstallationParts paths to reflect the actual extracted location
/// </summary>
public static InstallationParts UpdatePathsAfterExtraction(
InstallationParts parts,
string extractedFolderPath)
{
var entry = archive.Entries.FirstOrDefault(entry =>
entry.Name.Contains("MetaforcePico")
&& entry.Name.EndsWith(".apk"));
return new InstallationParts
{
AndroidContentPath = UpdatePath(parts.AndroidContentPath, extractedFolderPath),
OculusClientPath = UpdatePath(parts.OculusClientPath, extractedFolderPath),
PicoClientPath = UpdatePath(parts.PicoClientPath, extractedFolderPath),
AndroidAdminPath = UpdatePath(parts.AndroidAdminPath, extractedFolderPath),
WindowsAdminPath = UpdatePath(parts.WindowsAdminPath, extractedFolderPath),
WindowsContentPath = UpdatePath(parts.WindowsContentPath, extractedFolderPath),
WindowsServerPath = UpdatePath(parts.WindowsServerPath, extractedFolderPath),
};
}
private static string? UpdatePath(string? relativePath, string basePath)
{
if (string.IsNullOrEmpty(relativePath))
return null;
return Path.Combine(basePath, relativePath);
}
private static string? FindPicoClient(ZipArchive archive)
{
return FindEntry(archive,
name: "MetaforcePico",
extension: ".apk");
}
private static string? FindOculusClient(ZipArchive archive)
{
return FindEntry(archive,
name: "MetaforceOculus",
extension: ".apk");
}
private static string? FindAndroidAdmin(ZipArchive archive)
{
return FindEntry(archive,
name: "MetaforceAdmin",
extension: ".apk");
}
private static string? FindAndroidContent(ZipArchive archive)
{
return FindEntry(archive,
name: "Content_Android",
extension: ".zip");
}
private static string? FindWindowsContent(ZipArchive archive)
{
return FindEntry(archive,
name: "Content_StandaloneWindows",
extension: ".zip");
}
private static string? FindPcAdmin(ZipArchive archive)
{
return FindExecutable(archive, "MetaforceAdminPC");
}
private static string? FindServer(ZipArchive archive)
{
return FindExecutable(archive, "MetaforceServer");
}
/// <summary>
/// Finds an entry in archive by name and extension
/// </summary>
private static string? FindEntry(ZipArchive archive, string name, string extension)
{
var entry = archive.Entries.FirstOrDefault(e =>
e.Name.Contains(name, StringComparison.OrdinalIgnoreCase) &&
e.Name.EndsWith(extension, StringComparison.OrdinalIgnoreCase));
return entry?.FullName;
}
private static string? DoesOculusClientExists(ZipArchive archive)
/// <summary>
/// Finds an executable in archive, excluding crash handlers
/// </summary>
private static string? FindExecutable(ZipArchive archive, string containsName)
{
var entry = archive.Entries.FirstOrDefault(entry =>
entry.Name.Contains("MetaforceOculus")
&& entry.Name.EndsWith(".apk"));
return entry?.FullName;
}
private static string? DoesAndroidAdminExists(ZipArchive archive)
{
var entry = archive.Entries.FirstOrDefault(entry =>
entry.Name.Contains("MetaforceAdmin")
&& entry.Name.EndsWith(".apk"));
return entry?.FullName;
}
private static string? DoesAndroidContentExists(ZipArchive archive)
{
var entry = archive.Entries.FirstOrDefault(entry =>
entry.Name.Contains("Content_Android")
&& entry.Name.EndsWith(".zip"));
return entry?.FullName;
}
private static string? DoesWindowsContentExists(ZipArchive archive)
{
var entry = archive.Entries.FirstOrDefault(entry =>
entry.Name.Contains("Content_StandaloneWindows")
&& entry.Name.EndsWith(".zip"));
return entry?.FullName;
}
private static string? DoesPcAdminExists(ZipArchive archive)
{
var entry = archive.Entries.FirstOrDefault(entry =>
entry.FullName.Contains("MetaforceAdminPC") &&
entry.Name.EndsWith(".exe")
&& !entry.Name.Contains("UnityCrashHandler") &&
!entry.Name.Contains("crashpad_handler"));
return entry?.FullName;
}
private static string? DoesServerExists(ZipArchive archive)
{
var entry = archive.Entries.FirstOrDefault(entry =>
entry.FullName.Contains("MetaforceServer") &&
entry.Name.EndsWith(".exe")
&& !entry.Name.Contains("UnityCrashHandler") &&
!entry.Name.Contains("crashpad_handler"));
var entry = archive.Entries.FirstOrDefault(e =>
e.FullName.Contains(containsName, StringComparison.OrdinalIgnoreCase) &&
e.Name.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) &&
!e.Name.Contains("UnityCrashHandler", StringComparison.OrdinalIgnoreCase) &&
!e.Name.Contains("crashpad_handler", StringComparison.OrdinalIgnoreCase));
return entry?.FullName;
}
}