diff --git a/LANCommander.Launcher/UI/Components/LibraryItemContextMenu.razor b/LANCommander.Launcher/UI/Components/LibraryItemContextMenu.razor index 439a9ba6..8e4cae61 100644 --- a/LANCommander.Launcher/UI/Components/LibraryItemContextMenu.razor +++ b/LANCommander.Launcher/UI/Components/LibraryItemContextMenu.razor @@ -192,12 +192,11 @@ else { Title = $"File Conflicts", Maximizable = false, - DefaultMaximized = false, + DefaultMaximized = true, Closable = true, Draggable = true, Centered = true, - OkText = "Replace", - Footer = null, + OkText = "Replace Selected", }; var modalRef = ModalService.CreateModal(modalOptions, Model.DataItem as Game); diff --git a/LANCommander.Launcher/UI/Components/ValidateFilesDialog.razor b/LANCommander.Launcher/UI/Components/ValidateFilesDialog.razor index cb863fde..918ee9db 100644 --- a/LANCommander.Launcher/UI/Components/ValidateFilesDialog.razor +++ b/LANCommander.Launcher/UI/Components/ValidateFilesDialog.razor @@ -5,13 +5,34 @@ @inject SDK.Client Client @inject IMessageService MessageService - +
+ + + @context.LocalFileInfo?.CreationTime + + + @context.LocalFileInfo?.LastWriteTime + + + @if (context.LocalFileInfo?.Length > 0) + { + @ByteSizeLib.ByteSize.FromBytes(context.LocalFileInfo.Length) + } + + + @if (context.Length > 0) + { + @ByteSizeLib.ByteSize.FromBytes(context.Length) + } +
@code { - IEnumerable Conflicts = new List(); - IEnumerable Selected = new List(); + IEnumerable Conflicts = new List(); + IEnumerable Selected = new List(); + + bool Loading = true; protected override async Task OnInitializedAsync() { @@ -26,12 +47,22 @@ async Task LoadData() { Conflicts = await Client.Games.ValidateFilesAsync(Options.InstallDirectory, Options.Id); + + Loading = false; } public override async Task OnFeedbackOkAsync(ModalClosingEventArgs args) { + Loading = true; + StateHasChanged(); + await Task.Yield(); + await Client.Games.DownloadFilesAsync(Options.InstallDirectory, Options.Id, Selected.Select(e => e.FullName)); + Loading = false; + StateHasChanged(); + await Task.Yield(); + await base.CloseFeedbackAsync(); } } diff --git a/LANCommander.SDK/Models/ArchiveEntry.cs b/LANCommander.SDK/Models/ArchiveEntry.cs index 794f37fc..007e62ac 100644 --- a/LANCommander.SDK/Models/ArchiveEntry.cs +++ b/LANCommander.SDK/Models/ArchiveEntry.cs @@ -3,4 +3,5 @@ public class ArchiveEntry public string FullName { get; set; } public string Name { get; set; } public uint Crc32 { get; set; } + public long Length { get; set; } } \ No newline at end of file diff --git a/LANCommander.SDK/Models/ArchiveValidationConflict.cs b/LANCommander.SDK/Models/ArchiveValidationConflict.cs new file mode 100644 index 00000000..09d3fbcf --- /dev/null +++ b/LANCommander.SDK/Models/ArchiveValidationConflict.cs @@ -0,0 +1,13 @@ +using System.IO; + +namespace LANCommander.SDK.Models +{ + public class ArchiveValidationConflict + { + public string FullName { get; set; } + public string Name { get; set; } + public uint Crc32 { get; set; } + public long Length { get; set; } + public FileInfo LocalFileInfo { get; set; } + } +} diff --git a/LANCommander.SDK/Services/GameService.cs b/LANCommander.SDK/Services/GameService.cs index ec591981..18d221e8 100644 --- a/LANCommander.SDK/Services/GameService.cs +++ b/LANCommander.SDK/Services/GameService.cs @@ -1025,20 +1025,33 @@ namespace LANCommander.SDK.Services /// The game's install directory /// The game's ID /// List of file conflicts - public async Task> ValidateFilesAsync(string installDirectory, Guid gameId) + public async Task> ValidateFilesAsync(string installDirectory, Guid gameId) { var manifest = await ManifestHelper.ReadAsync(installDirectory, gameId); - var archive = await Client.GetRequestAsync($"/api/Archives/Contents/{gameId}/{manifest.Version}"); - var entries = await Client.GetRequestAsync>($"/api/Archives/{archive.Id}"); + var entries = await Client.GetRequestAsync>($"/api/Archives/Contents/{gameId}/{manifest.Version}"); - var conflictedEntries = new List(); + var conflictedEntries = new List(); + + var savePathEntries = manifest.SavePaths?.SelectMany(p => Client.Saves.GetFileSavePathEntries(p, installDirectory)) ?? new List(); foreach (var entry in entries) { + if (savePathEntries.Any(e => e.ArchivePath.Equals(entry.FullName, StringComparison.OrdinalIgnoreCase))) + continue; + + if (entry.FullName.EndsWith('/')) + continue; + var localFile = Path.Combine(installDirectory, entry.FullName.Replace('/', Path.DirectorySeparatorChar)); if (!Path.Exists(localFile)) - conflictedEntries.Add(entry); + conflictedEntries.Add(new ArchiveValidationConflict + { + Name = entry.Name, + FullName = entry.FullName, + Crc32 = entry.Crc32, + Length = entry.Length, + }); else { uint crc = 0; @@ -1062,7 +1075,13 @@ namespace LANCommander.SDK.Services } if (crc == 0 || crc != entry.Crc32) - conflictedEntries.Add(entry); + conflictedEntries.Add(new ArchiveValidationConflict + { + Name = entry.Name, + FullName = entry.FullName, + Crc32 = entry.Crc32, + LocalFileInfo = new FileInfo(localFile) + }); } } @@ -1096,7 +1115,6 @@ namespace LANCommander.SDK.Services { Overwrite = true, PreserveFileTime = true, - PreserveAttributes = true, }); } else // Skip to next entry diff --git a/LANCommander.Server/Controllers/Api/ArchivesController.cs b/LANCommander.Server/Controllers/Api/ArchivesController.cs index 11b9ba2a..22776c5e 100644 --- a/LANCommander.Server/Controllers/Api/ArchivesController.cs +++ b/LANCommander.Server/Controllers/Api/ArchivesController.cs @@ -110,7 +110,8 @@ namespace LANCommander.Server.Controllers.Api { FullName = entry.FullName, Name = entry.Name, - Crc32 = entry.Crc32 + Crc32 = entry.Crc32, + Length = entry.Length, }); } }