Skip to content

Commit 61a2ba6

Browse files
committed
feat: Add download remote game feature
1 parent fb20d70 commit 61a2ba6

5 files changed

Lines changed: 59 additions & 6 deletions

File tree

VNGod/Network/WebDAVClient.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.IO;
44
using System.Linq;
55
using System.Net;
6+
using System.Net.Http;
67
using System.Threading.Tasks;
78
using System.Windows.Navigation;
89
using VNGod.Properties;

VNGod/Utils/CompressHelper.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,14 @@ await Task.Run(() =>
6868
});
6969
}
7070
// Split a large zip file into smaller parts
71-
public static async Task CompressSplitZipFileAsync(string zipFilePath, string folderPath, IProgress<StagedProgressInfo> progress,int partSize=200)
71+
public static async Task CompressSplitZipFileAsync(string zipFilePath, string folderPath, IProgress<StagedProgressInfo> progress,int partSize=100)
7272
{
7373
string sevenZipPath = Settings.Default.SevenZipPath;
7474
ProcessStartInfo processStartInfo = new()
7575
{
7676
FileName = sevenZipPath,
77-
Arguments = $"a -bsp1 -bb1 -v{partSize}m \"{zipFilePath}\" \"{folderPath}\"",
77+
// Compress, and ignore .vngod files, split into parts
78+
Arguments = $"a -bsp1 -bb1 -x!*\\.vngod -v{partSize}m \"{zipFilePath}\" \"{folderPath}\"",
7879
UseShellExecute = false,
7980
RedirectStandardOutput = true,
8081
RedirectStandardError = true,
@@ -105,13 +106,13 @@ public static async Task CompressSplitZipFileAsync(string zipFilePath, string fo
105106
compressionProcesses.Remove(process);
106107
}
107108
// Extract split zip files
108-
public static async Task ExtractSplitZipsAsync(string zipFilePath, string extractPath, IProgress<StagedProgressInfo> progress)
109+
public static async Task DecompressSplitZipsAsync(string zipFilePath, string extractPath, IProgress<StagedProgressInfo> progress)
109110
{
110111
string sevenZipPath = Settings.Default.SevenZipPath;
111112
ProcessStartInfo processStartInfo = new()
112113
{
113114
FileName = sevenZipPath,
114-
Arguments = $"x -bsp1 -bb1 \"{zipFilePath}\" -o\"{extractPath}\"",
115+
Arguments = $"x -bsp1 -bb1 \"{zipFilePath}\" -o\"{extractPath}\" -y",
115116
UseShellExecute = false,
116117
RedirectStandardOutput = true,
117118
RedirectStandardError = true,

VNGod/Utils/WebDAVHelper.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,22 +134,25 @@ public static async Task<bool> UploadGameAsync(Repo repo, Game game, IProgress<S
134134
{
135135
try
136136
{
137+
// Do preparation work in a temporary directory
137138
string tmpPath = Path.Combine(FileHelper.tmpPath, game.DirectoryName);
138139
if (Directory.Exists(tmpPath))
139140
Directory.Delete(tmpPath, true);
140141
if (!await WebDAVClient.DeleteRemoteAsync($"{game.DirectoryName}/game"))
141142
Logger.Warn("Failed to delete remote game folder before upload. It may not exist.");
142143
Directory.CreateDirectory(tmpPath);
144+
// Compress game folder into split zip files
143145
await CompressHelper.CompressSplitZipFileAsync(Path.Combine(tmpPath, "game"), Path.Combine(repo.LocalPath, game.DirectoryName), progress);
144146
progress.Report(new StagedProgressInfo { StagePercentage = 0, StageName = "Preparing upload..." });
145147
string[] files = Directory.GetFiles(tmpPath);
146-
148+
// Upload each split zip file
147149
for (int i = 0; i < files.Length; i++)
148150
{
149151
if (await WebDAVClient.UploadFileAsync(files[i], $"{game.DirectoryName}/game/{Path.GetFileName(files[i])}") == false)
150152
throw new Exception($"Error uploading " + files[i]);
151153
progress.Report(new StagedProgressInfo { StagePercentage = (double)(i + 1) / files.Length * 100, StageName = "Uploading files..." });
152154
}
155+
Directory.Delete(tmpPath, true);
153156
progress.Report(new StagedProgressInfo { StagePercentage = 100, StageName = "Upload complete" });
154157
return true;
155158
}
@@ -159,6 +162,34 @@ public static async Task<bool> UploadGameAsync(Repo repo, Game game, IProgress<S
159162
return false;
160163
}
161164
}
165+
public static async Task<bool> DownloadGameAsync(Repo repo, Game game, IProgress<StagedProgressInfo> progress)
166+
{
167+
try
168+
{
169+
string tmpPath = Path.Combine(FileHelper.tmpPath, game.DirectoryName);
170+
if (Directory.Exists(tmpPath))
171+
Directory.Delete(tmpPath, true);
172+
Directory.CreateDirectory(tmpPath);
173+
List<string> remoteFiles = new();
174+
await WebDAVClient.ListRemoteAsync($"{game.DirectoryName}/game", remoteFiles);
175+
for (int i = 0; i < remoteFiles.Count; i++)
176+
{
177+
if (await WebDAVClient.DownloadFileAsync(remoteFiles[i], Path.Combine(tmpPath, Path.GetFileName(remoteFiles[i]))) == false)
178+
throw new Exception($"Error downloading " + remoteFiles[i]);
179+
progress.Report(new StagedProgressInfo { StagePercentage = (double)(i + 1) / remoteFiles.Count * 100, StageName = "Downloading files..." });
180+
}
181+
progress.Report(new StagedProgressInfo { StagePercentage = 100, StageName = "Decompressing files..." });
182+
await CompressHelper.DecompressSplitZipsAsync(Path.Combine(tmpPath, "game.7z.001"),repo.LocalPath, progress);
183+
Directory.Delete(tmpPath,true);
184+
progress.Report(new StagedProgressInfo { StagePercentage = 100, StageName = "Download complete" });
185+
return true;
186+
}
187+
catch (Exception ex)
188+
{
189+
Logger.Error($"Error when downloading and decompressing game: {ex.Message}", ex);
190+
return false;
191+
}
192+
}
162193
public static async Task<Repo> GetRemoteGamesAsync()
163194
{
164195
Repo games = new() { LocalPath = "WebDAV" };

VNGod/View/GameStorageWindow.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
</ListBox>
4343
<StackPanel Grid.Column="1" Grid.Row="1" VerticalAlignment="Center">
4444
<Button x:Name="uploadButton" Margin="20" Click="UploadButton_Click" IsEnabled="{DynamicResource WindowStatus.IsBusy}">Upload</Button>
45-
<Button x:Name="downloadButton" Margin="20" IsEnabled="{DynamicResource WindowStatus.IsBusy}">Download</Button>
45+
<Button x:Name="downloadButton" Margin="20" IsEnabled="{DynamicResource WindowStatus.IsBusy}" Click="DownloadButton_Click">Download</Button>
4646
<Button x:Name="deleteLocalButton" Margin="20" IsEnabled="{DynamicResource WindowStatus.IsBusy}">Delete Local</Button>
4747
<Button x:Name="deleteRemoteButton" Margin="20" IsEnabled="{DynamicResource WindowStatus.IsBusy}">Delete Remote</Button>
4848
<TextBlock x:Name="statusText" HorizontalAlignment="Center" Margin="20" Text="Status"/>

VNGod/View/GameStorageWindow.xaml.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,25 @@ private async void UploadButton_Click(object sender, RoutedEventArgs e)
5353
GetStatus().IsBusy = false;
5454
}
5555

56+
private async void DownloadButton_Click(object sender, RoutedEventArgs e)
57+
{
58+
if(remoteGameList.SelectedIndex < 0) return;
59+
GetStatus().IsBusy = true;
60+
var progress = new Progress<StagedProgressInfo>(value =>
61+
{
62+
workProgress.Value = value.StagePercentage;
63+
statusText.Text = value.StageName;
64+
});
65+
if(await WebDAVHelper.DownloadGameAsync(GetLoaclGames(), remoteGameList.SelectedItem as Game ?? throw new Exception("Error getting selected remote game"), progress))
66+
{
67+
Growl.Success("Successfully downloaded and extracted!");
68+
}
69+
else
70+
{
71+
Growl.Error("Failed to download, see log for more detail.");
72+
}
73+
GetStatus().IsBusy = false;
74+
}
5675
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
5776
{
5877
e.Cancel = true;
@@ -73,5 +92,6 @@ private async void Window_IsVisibleChanged(object sender, DependencyPropertyChan
7392
remoteGameList.ItemsSource = await WebDAVHelper.GetRemoteGamesAsync();
7493
}
7594
}
95+
7696
}
7797
}

0 commit comments

Comments
 (0)