Skip to content

Commit 63c0a39

Browse files
committed
Added manual savegame up/download buttons to gameview
1 parent 7b7f9f4 commit 63c0a39

File tree

8 files changed

+114
-45
lines changed

8 files changed

+114
-45
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Recommended Gamevault Server Version: `v14.0.0`
55
### Changes
66

77
- Cloud Saves (+)
8+
- Bug fix: Youtube url not loading in gameview
89
- Bug fix: Game window sometimes started in the background when launched via gamevault uri
910

1011
## 1.14.0

gamevault/Helper/Integrations/SaveGameHelper.cs

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,17 @@ internal SaveGameHelper()
5252
{
5353
zipHelper = new SevenZipHelper();
5454
}
55-
internal async Task RestoreBackup(int gameId)
55+
internal async Task<bool> RestoreBackup(int gameId, string installationDir)
5656
{
5757
if (!LoginManager.Instance.IsLoggedIn() || !SettingsViewModel.Instance.CloudSaves || !SettingsViewModel.Instance.License.IsActive())
58-
return;
58+
return false;
5959

6060
using (HttpClient client = new HttpClient())
6161
{
6262
try
6363
{
6464
client.Timeout = TimeSpan.FromSeconds(15);
65-
string deviceId = GetDeviceId();
65+
string installationId = GetGameInstallationId(installationDir);
6666
string[] auth = WebHelper.GetCredentials();
6767
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{auth[0]}:{auth[1]}")));
6868
client.DefaultRequestHeaders.Add("User-Agent", $"GameVault/{SettingsViewModel.Instance.Version}");
@@ -71,7 +71,7 @@ internal async Task RestoreBackup(int gameId)
7171
{
7272
response.EnsureSuccessStatusCode();
7373
string fileName = response.Content.Headers.ContentDisposition.FileName.Split('_')[1].Split('.')[0];
74-
if (fileName != deviceId)
74+
if (fileName != installationId)
7575
{
7676
string tempFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
7777
Directory.CreateDirectory(tempFolder);
@@ -96,6 +96,7 @@ internal async Task RestoreBackup(int gameId)
9696
process.WaitForExit();
9797
ProcessShepherd.Instance.RemoveProcess(process);
9898
Directory.Delete(tempFolder, true);
99+
return true;
99100
}
100101
}
101102
}
@@ -112,16 +113,18 @@ internal async Task RestoreBackup(int gameId)
112113
}
113114
}
114115
}
116+
return false;
115117
}
116-
private string GetDeviceId()
118+
private string GetGameInstallationId(string installationDir)
117119
{
118-
string deviceId = Preferences.Get(AppConfigKey.DeviceId, AppFilePath.UserFile);
119-
if (string.IsNullOrWhiteSpace(deviceId))
120+
string metadataFile = Path.Combine(installationDir, "gamevault-exec");
121+
string installationId = Preferences.Get(AppConfigKey.InstallationId, metadataFile);
122+
if (string.IsNullOrWhiteSpace(installationId))
120123
{
121-
deviceId = Guid.NewGuid().ToString();
122-
Preferences.Set(AppConfigKey.DeviceId, deviceId, AppFilePath.UserFile);
124+
installationId = Guid.NewGuid().ToString();
125+
Preferences.Set(AppConfigKey.InstallationId, installationId, metadataFile);
123126
}
124-
return deviceId;
127+
return installationId;
125128
}
126129
internal async Task BackupSaveGamesFromIds(List<int> gameIds)
127130
{
@@ -135,7 +138,16 @@ internal async Task BackupSaveGamesFromIds(List<int> gameIds)
135138
}
136139
try
137140
{
138-
await BackupSaveGame(removedId);
141+
MainWindowViewModel.Instance.AppBarText = "Uploading Savegame to the Server...";
142+
bool success = await BackupSaveGame(removedId);
143+
if (success)
144+
{
145+
MainWindowViewModel.Instance.AppBarText = "Successfully synchronized the cloud saves";
146+
}
147+
else
148+
{
149+
MainWindowViewModel.Instance.AppBarText = "Failed to upload your Savegame to the Server";
150+
}
139151
}
140152
catch (Exception ex)
141153
{
@@ -149,36 +161,31 @@ internal async Task BackupSaveGamesFromIds(List<int> gameIds)
149161
// Remove IDs that are no longer in the new list
150162
runningGameIds = runningGameIds.Intersect(gameIds).ToList();
151163
}
152-
internal async Task BackupSaveGame(int gameId)
164+
internal async Task<bool> BackupSaveGame(int gameId)
153165
{
154166
if (!SettingsViewModel.Instance.License.IsActive())
155-
return;
167+
return false;
156168

157-
string gameMetadataTitle = FindGameTitleFromInstalledGames(gameId);
158-
if (gameMetadataTitle != "")
169+
var installedGame = InstallViewModel.Instance?.InstalledGames?.FirstOrDefault(g => g.Key?.ID == gameId);
170+
string gameMetadataTitle = installedGame?.Key?.Metadata?.Title ?? "";
171+
string installationDir = installedGame?.Value ?? "";
172+
if (gameMetadataTitle != "" && installationDir != "")
159173
{
160174
string title = await SearchForLudusaviGameTitle(gameMetadataTitle);
161175
string tempFolder = await CreateBackup(title);
162176
string archive = Path.Combine(tempFolder, "backup.zip");
163177
if (Directory.GetFiles(tempFolder, "mapping.yaml", SearchOption.AllDirectories).Length == 0)
164178
{
165179
Directory.Delete(tempFolder, true);
166-
return;
180+
return false;
167181
}
168182
await zipHelper.PackArchive(tempFolder, archive);
169183

170-
bool success = await UploadSavegame(archive, gameId);
184+
bool success = await UploadSavegame(archive, gameId, installationDir);
171185
Directory.Delete(tempFolder, true);
172-
if (!success)
173-
{
174-
MainWindowViewModel.Instance.AppBarText = "Failed to sync your savegame to the cloud.";
175-
}
186+
return success;
176187
}
177-
}
178-
private string FindGameTitleFromInstalledGames(int gameId)
179-
{
180-
string gameMetadataTitle = InstallViewModel.Instance?.InstalledGames?.FirstOrDefault(g => g.Key?.ID == gameId).Key?.Metadata?.Title ?? "";
181-
return gameMetadataTitle;
188+
return false;
182189
}
183190
internal async Task<string> SearchForLudusaviGameTitle(string title)
184191
{
@@ -232,14 +239,14 @@ private async Task<string> CreateBackup(string lunusaviTitle)
232239
return tempFolder;
233240
});
234241
}
235-
private async Task<bool> UploadSavegame(string saveFilePath, int gameId)
242+
private async Task<bool> UploadSavegame(string saveFilePath, int gameId, string installationDir)
236243
{
237244
try
238245
{
239-
string devideId = GetDeviceId();
246+
string installationId = GetGameInstallationId(installationDir);
240247
using (MemoryStream memoryStream = await FileToMemoryStreamAsync(saveFilePath))
241248
{
242-
await WebHelper.UploadFileAsync(@$"{SettingsViewModel.Instance.ServerUrl}/api/savefiles/user/{LoginManager.Instance.GetCurrentUser()!.ID}/game/{gameId}", memoryStream, "x.zip", new KeyValuePair<string, string>("X-Device-Id", devideId));
249+
await WebHelper.UploadFileAsync(@$"{SettingsViewModel.Instance.ServerUrl}/api/savefiles/user/{LoginManager.Instance.GetCurrentUser()!.ID}/game/{gameId}", memoryStream, "x.zip", new KeyValuePair<string, string>("X-Installation-Id", installationId));
243250
}
244251
}
245252
catch

gamevault/Models/AppInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public enum AppConfigKey
4949
DevModeEnabled,
5050
DevTargetPhalcodeTestBackend,
5151
//
52-
DeviceId
52+
InstallationId
5353
}
5454
public static class AppFilePath
5555
{

gamevault/Resources/Assets/Icons.xaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@
147147
<Geometry x:Key="IconCloudSave">
148148
m10.325 14.125l-1.4-1.4q-.3-.3-.7-.3t-.7.3t-.3.713t.3.712L9.65 16.3q.3.3.7.3t.7-.3l4.225-4.225q.3-.3.3-.725t-.3-.725t-.725-.3t-.725.3zM6.5 20q-2.275 0-3.887-1.575T1 14.575q0-1.95 1.175-3.475T5.25 9.15q.625-2.3 2.5-3.725T12 4q2.925 0 4.963 2.038T19 11q1.725.2 2.863 1.488T23 15.5q0 1.875-1.312 3.188T18.5 20z
149149
</Geometry>
150+
<Geometry x:Key="IconCloudSaveUpload">
151+
M4.25 14q.15.575.363 1.1t.487 1q.225.375.175.8t-.325.7t-.688.263t-.637-.363q-.525-.8-.888-1.65t-.562-1.8q-.1-.4.163-.725T3.025 13t.763.275t.462.725m.85-6.1q-.275.475-.487 1T4.25 10q-.125.45-.462.725T3.025 11t-.687-.3t-.163-.7q.2-.975.575-1.875t.9-1.65q.225-.325.625-.337t.675.262t.325.7t-.175.8m2.775 10.95q.5.3 1.025.525t1.075.375q.425.125.7.45t.275.75t-.3.675t-.7.175q-.925-.2-1.787-.55T6.5 20.375q-.35-.225-.387-.638t.237-.712q.3-.3.725-.35t.8.175m2.15-14.6q-.55.15-1.062.363t-1.013.512q-.4.225-.837.188t-.738-.338t-.275-.7t.375-.625q.825-.525 1.713-.887t1.837-.563q.375-.075.675.175t.3.675t-.275.75t-.7.45m6.05 14.625q.375-.225.813-.187t.737.337t.275.713t-.375.612q-.8.525-1.7.888t-1.85.562q-.4.075-.712-.175t-.313-.675t.288-.75t.712-.45q.575-.15 1.1-.362t1.025-.513m-2.1-14.625q-.425-.125-.7-.45T13 3.05t.3-.675t.675-.175q.95.2 1.85.563t1.7.887q.35.225.375.625t-.25.7q-.3.3-.725.35T16.1 5.15q-.525-.3-1.05-.525t-1.075-.375m5.775 9.725q.125-.425.463-.7t.762-.275t.687.325t.163.725q-.2.95-.587 1.825T20.35 17.5q-.225.325-.625.35t-.675-.25t-.325-.712t.175-.813q.275-.5.488-1.012t.362-1.088M18.9 7.9q-.225-.375-.175-.8t.325-.7t.675-.25t.625.35q.55.8.925 1.675T21.85 10q.075.4-.188.7t-.687.3t-.763-.275T19.75 10q-.15-.575-.362-1.1t-.488-1M11.975 17q-.425 0-.712-.288T10.975 16v-5.125l-1.875 1.9q-.3.3-.712.3t-.713-.3t-.312-.712t.287-.713l3.625-3.65q.275-.275.7-.275t.7.275l3.575 3.575q.3.3.313.725t-.288.725t-.725.3t-.725-.3l-1.85-1.85V16q0 .425-.287.713t-.713.287
152+
</Geometry>
150153
<Geometry x:Key="IconGameViewMaximize">
151154
M4 3.5a.5.5 0 0 0-.5.5v1.614a.75.75 0 0 1-1.5 0V4a2 2 0 0 1 2-2h1.614a.75.75 0 0 1 0 1.5zm5.636-.75a.75.75 0 0 1 .75-.75H12a2 2 0 0 1 2 2v1.614a.75.75 0 0 1-1.5 0V4a.5.5 0 0 0-.5-.5h-1.614a.75.75 0 0 1-.75-.75M2.75 9.636a.75.75 0 0 1 .75.75V12a.5.5 0 0 0 .5.5h1.614a.75.75 0 0 1 0 1.5H4a2 2 0 0 1-2-2v-1.614a.75.75 0 0 1 .75-.75m10.5 0a.75.75 0 0 1 .75.75V12a2 2 0 0 1-2 2h-1.614a.75.75 0 1 1 0-1.5H12a.5.5 0 0 0 .5-.5v-1.614a.75.75 0 0 1 .75-.75
152155
</Geometry>

gamevault/UserControls/GameViewUserControl.xaml

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -347,24 +347,47 @@
347347
</Style.Triggers>
348348
</Style>
349349
</StackPanel.Style>
350-
<Button Style="{StaticResource ButtonWrapper}" Click="ManualBackupSaveGame_Click" Cursor="Hand">
350+
<Path Data="{StaticResource IconCloudSave}" Fill="{DynamicResource MahApps.Brushes.ThemeForeground}"/>
351+
<TextBlock FontWeight="Bold" Margin="5,4,150,0">
352+
<Hyperlink TextDecorations="None" NavigateUri="http://gamevau.lt/docs/gamevault-plus/cloud-saves" RequestNavigate="Website_Navigate">
353+
<Hyperlink.Inlines>
354+
<Run Text="Cloud Saves"/>
355+
</Hyperlink.Inlines>
356+
</Hyperlink>
357+
</TextBlock>
358+
<Button Style="{StaticResource ButtonWrapper}" Cursor="Hand" Click="RestoreCloudSaves_Click">
351359
<Button.ToolTip>
352-
<TextBlock Text="{Binding CloudSaveMatchTitle,StringFormat='{}Sync manually for {0}'}"/>
360+
<TextBlock Text="{Binding CloudSaveMatchTitle,StringFormat='{}Download Savefiles for {0}'}"/>
353361
</Button.ToolTip>
354362
<Grid Style="{StaticResource HoverEffect}" Background="#02000000">
355-
<Path Data="{StaticResource IconCloudSave}" Fill="{DynamicResource MahApps.Brushes.ThemeForeground}"/>
363+
<Path Data="{StaticResource IconCloudSaveUpload}" Fill="{DynamicResource MahApps.Brushes.ThemeForeground}" RenderTransformOrigin="0.5,0.5" Margin="0,-1,0,-1">
364+
<Path.RenderTransform>
365+
<TransformGroup>
366+
<ScaleTransform ScaleX="0.8" ScaleY="0.8"/>
367+
<RotateTransform Angle="180"/>
368+
</TransformGroup>
369+
</Path.RenderTransform>
370+
</Path>
371+
<Grid.RenderTransform>
372+
<ScaleTransform/>
373+
</Grid.RenderTransform>
374+
</Grid>
375+
</Button>
376+
<Button Style="{StaticResource ButtonWrapper}" Cursor="Hand" Click="BackupCloudSaves_Click">
377+
<Button.ToolTip>
378+
<TextBlock Text="{Binding CloudSaveMatchTitle,StringFormat='{}Upload Savefiles for {0}'}"/>
379+
</Button.ToolTip>
380+
<Grid Style="{StaticResource HoverEffect}" Background="#02000000">
381+
<Path Data="{StaticResource IconCloudSaveUpload}" Fill="{DynamicResource MahApps.Brushes.ThemeForeground}" RenderTransformOrigin="0.4,0.2" Margin="0,-1,0,-1">
382+
<Path.RenderTransform>
383+
<ScaleTransform ScaleX="0.8" ScaleY="0.8"/>
384+
</Path.RenderTransform>
385+
</Path>
356386
<Grid.RenderTransform>
357387
<ScaleTransform/>
358388
</Grid.RenderTransform>
359389
</Grid>
360390
</Button>
361-
<TextBlock FontWeight="Bold" Margin="5,4,0,0">
362-
<Hyperlink TextDecorations="None" NavigateUri="http://gamevau.lt/docs/gamevault-plus/cloud-saves" RequestNavigate="Website_Navigate">
363-
<Hyperlink.Inlines>
364-
<Run Text="Cloud Saves"/>
365-
</Hyperlink.Inlines>
366-
</Hyperlink>
367-
</TextBlock>
368391
</StackPanel>
369392
<StackPanel Margin="0,4,0,0" Background="Transparent" Height="68">
370393
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,0">

gamevault/UserControls/GameViewUserControl.xaml.cs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ private void Share_Click(object sender, RoutedEventArgs e)
380380
}
381381
catch { }
382382
}
383-
private async void ManualBackupSaveGame_Click(object sender, RoutedEventArgs e)
383+
private async void BackupCloudSaves_Click(object sender, RoutedEventArgs e)
384384
{
385385
try
386386
{
@@ -392,15 +392,47 @@ private async void ManualBackupSaveGame_Click(object sender, RoutedEventArgs e)
392392
}
393393
MainWindowViewModel.Instance.AppBarText = "Uploading Savegame to the Server...";
394394
((FrameworkElement)sender).IsEnabled = false;
395-
await SaveGameHelper.Instance.BackupSaveGame(ViewModel!.Game!.ID);
396-
MainWindowViewModel.Instance.AppBarText = "Successfully synchronized the cloud saves";
395+
bool success = await SaveGameHelper.Instance.BackupSaveGame(ViewModel!.Game!.ID);
396+
if (success)
397+
{
398+
MainWindowViewModel.Instance.AppBarText = "Successfully synchronized the cloud saves";
399+
}
400+
else
401+
{
402+
MainWindowViewModel.Instance.AppBarText = "Failed to upload your Savegame to the Server";
403+
}
397404
}
398405
catch
399406
{
400407
MainWindowViewModel.Instance.AppBarText = "Failed to Upload your Savegame to the Server";
401408
}
402409
((FrameworkElement)sender).IsEnabled = true;
403410
}
411+
private async void RestoreCloudSaves_Click(object sender, RoutedEventArgs e)
412+
{
413+
try
414+
{
415+
if (!SettingsViewModel.Instance.License.IsActive())
416+
{
417+
MainWindowViewModel.Instance.SetActiveControl(MainControl.Settings);
418+
MainWindowViewModel.Instance.Settings.SetTabIndex(4);
419+
return;
420+
}
421+
MainWindowViewModel.Instance.AppBarText = $"Syncing cloud save...";
422+
((FrameworkElement)sender).IsEnabled = false;
423+
string installationDir = InstallViewModel.Instance.InstalledGames.First(g => g.Key.ID == ViewModel!.Game!.ID).Value;
424+
bool success = await SaveGameHelper.Instance.RestoreBackup(ViewModel!.Game!.ID, installationDir);
425+
if (success)
426+
{
427+
MainWindowViewModel.Instance.AppBarText = "Successfully synchronized the cloud save";
428+
}
429+
}
430+
catch
431+
{
432+
MainWindowViewModel.Instance.AppBarText = "Failed to restore the Savegame";
433+
}
434+
((FrameworkElement)sender).IsEnabled = true;
435+
}
404436
#region Markdown
405437
private void OpenHyperlink(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
406438
{

gamevault/UserControls/InstallUserControl.xaml.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,12 @@ private async void Play_Click(object sender, RoutedEventArgs e)
297297

298298
public static async Task PlayGame(int gameId)
299299
{
300-
await SaveGameHelper.Instance.RestoreBackup(gameId);
300+
301301
string path = "";
302302
KeyValuePair<Game, string> result = InstallViewModel.Instance.InstalledGames.Where(g => g.Key.ID == gameId).FirstOrDefault();
303+
MainWindowViewModel.Instance.AppBarText = $"Syncing cloud save...";
304+
await SaveGameHelper.Instance.RestoreBackup(gameId, result.Value);
305+
303306
if (!result.Equals(default(KeyValuePair<Game, string>)))
304307
{
305308
path = result.Value;

gamevault/ViewModels/SettingsViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ public string Version
379379
{
380380
get
381381
{
382-
return Assembly.GetExecutingAssembly().GetName().Version.ToString();// + " EA";
382+
return Assembly.GetExecutingAssembly().GetName().Version.ToString() + " EA";
383383
}
384384
}
385385
//DevMode

0 commit comments

Comments
 (0)