Skip to content

Commit

Permalink
Release 1.10.1
Browse files Browse the repository at this point in the history
Release 1.10.1
  • Loading branch information
Yelo420 authored May 27, 2024
2 parents 2bb8fc1 + f67f18e commit c5a6da4
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 125 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# GameVault App Changelog

## 1.10.1.0
Recommended Gamevault Server Version: `v12.1.1`
### Changes

- Total size of all files is now displayed on the download cards
- An empty release year is no longer displayed in the gameview
- Bug fix: The escape key sometimes did not work in the game settings
- Bug fix: Game settings recache button did nothing
- Bug fix: Rare crash when starting the app if at least one non-extracted game is downloaded.
- Bug fix: Crash on download game - restart app - extract game
- Bug fix: Download UI sometimes did not display the status correctly when the game was installed

## 1.10.0.0
Recommended Gamevault Server Version: `v12.1.0`
### Changes
Expand Down
123 changes: 25 additions & 98 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,115 +1,42 @@
# gamevault-app
![logo](https://gamevau.lt/img/logo-text-and-image-sbs.png)
[You can find the official Website/Documentation here](https://gamevau.lt)
[![logo](https://gamevau.lt/img/logo-text-and-image-sbs.png)](https://gamevau.lt)

## Library Technical Decision Matrix
# GameVault Application

> This is probably irrelevant to you if you are not a developer.
> GameVault internally needs to behave different in each of the following scenarios.
## Introduction

<details>
<summary>Scenario 1: No paths exist</summary>

| Path | State |
| :------------- |:-------------:|
| ``D:/GameVault/Downloads/(74) Assassin's Creed Unity/`` | ``empty or non-existent`` |
| ``D:/GameVault/Installations/(74) Assassin's Creed Unity/`` | ``empty or non-existent`` |

**When does this happen**

- The Game was not even downloaded yet.
- The Game was deleted.

**What needs to be done**

- Don't show the game in download or library tab (obviously).

---

</details>

<details>
<summary>Scenario 2: Download Path exists</summary>
**What is GameVault?**
GameVault is an innovative gaming platform providing a self-hosted, source-available alternative to popular gaming platforms. It lets you and your friends enjoy DRM-free games stored on your file server in an organized way. Think of it as a self-hosted Steam. The project you are looking at right now is the client application.

| Path | State |
| :------------- |:-------------:|
| ``D:/GameVault/Downloads/(74) Assassin's Creed Unity/`` | ``contains the (partial) game.zip`` |
| ``D:/GameVault/Installations/(74) Assassin's Creed Unity/`` | ``empty or non-existent`` |

**When does this happen**

- The Game is still downloading.
- The Game was freshly downloaded but not installed.
- The Game was installed sometime ago but then deleted but the download was never cleared (unlikely)

**What needs to be done**

- Identify the game using the id
- Show the Game as "Downloaded" in the Downloaded Tab
- Show the Game in the library but grey out the play button, inform the user that they **need to install** the game into the folder `D:/GameVault/Installations/(74) Assassin's Creed Unity/` to play and track it using gamevault.
- Change Download button to play button in Library View -> Game Details, link it to the Installations -> Game entry with greyed out play button.

---

</details>

<details>
<summary>Scenario 3: Both paths exist</summary>
**Learn More & Get Started**
[You can learn more about the project and find useful guides and information on the official Website.](https://gamevau.lt)

| Path | State |
| :------------- |:-------------:|
| ``D:/GameVault/Downloads/(74) Assassin's Creed Unity/`` | ``contains the game.zip`` |
| ``D:/GameVault/Installations/(74) Assassin's Creed Unity/`` | ``contains game files (.exe)`` |

**When does this happen**
## Support 🤝

- The Game has been freshly installed and User has not deleted the download yet
- User forgot to delete download files or wants to keep it for offline/archival purposes.
We're working hard in our free time to provide you, your friends, and families with the best self-hosted gaming experience.
It would mean a lot to us if you could support us developers by [getting GameVault+](https://gamevau.lt/gamevault-plus).

**What needs to be done**

- Identify the game using the id
- Make the game playable in Installations tab
- Offer User to clear the download folder using "Clear All" button, now that the game is installed to save some space.
- Change Download button to play button in Library View -> Game Details, link it to the Installations -> Game entry.
- Cracktime Daemon monitors Game Folder for running exes

---

</details>

<details>
<summary>Scenario 4: Installations Path exists</summary>

| Path | State |
| :------------- |:-------------:|
| ``D:/GameVault/Downloads/(74) Assassin's Creed Unity/`` | ``empty or non-existent`` |
| ``D:/GameVault/Installations/(74) Assassin's Creed Unity/`` | ``contains game files (.exe)`` |
Alternatively, you can support us by donating us some spare dollars on any of these platforms:

**When does this happen**
- [Ko-Fi](https://ko-fi.com/phalcode)
- [Liberapay](https://liberapay.com/Phalcode)
- [GitHub Sponsors](https://github.com/sponsors/Phalcode)
- [PayPal](https://paypal.me/phalcode)

- The Game has been installed and the Download deleted.
**TIP FOR DONATORS:**
If you connect your Discord account to Ko-Fi, you'll automatically receive the "@Supporters" role and permanently stand out in our Discord members list. If you donate through a different platform and want to obtain the role, simply send us a message with your receipt as proof that you're truly a Supporter. 🌟

**What needs to be done**
## License 📜

- Identify the game using the id
- Make the game playable in Installations tab
- Offer User to clear the download folder using "Clear All" button, now that the game is installed to save some space.
- Change Download button to play button in Library View -> Game Details, link it to the Installations -> Game entry.
- Cracktime Daemon monitors Game Folder for running exes
**[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)**

---
This work is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-nc-sa/4.0/).

</details>
This project is not and never was open-source. [Click here to learn why.](https://gamevau.lt/blog/2023/07/13/)

### License
[![CC BY-NC-SA 4.0][cc-by-nc-sa-shield]][cc-by-nc-sa]
## Legal Disclaimer ⚖️

This work is licensed under a
[Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License][cc-by-nc-sa].
GameVault manages DRM-free games and is solely a tool to address this need. We are not responsible for the content or files users store or share.

[![CC BY-NC-SA 4.0][cc-by-nc-sa-image]][cc-by-nc-sa]
When we say DRM-free games, we only mean games obtained legally. While GameVault can theoretically be used with illegally obtained games, we do not endorse or support piracy.

[cc-by-nc-sa]: http://creativecommons.org/licenses/by-nc-sa/4.0/
[cc-by-nc-sa-image]: https://licensebuttons.net/l/by-nc-sa/4.0/88x31.png
[cc-by-nc-sa-shield]: https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey.svg
Users must be aware of and comply with copyright laws in their respective jurisdictions. We encourage responsible and legal use of GameVault. Unlawful use is strictly improper and unauthorized.
2 changes: 1 addition & 1 deletion gamevault/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
[assembly: AssemblyVersion("1.10.0.0")]
[assembly: AssemblyVersion("1.10.1.0")]
[assembly: AssemblyCopyright("© Phalcode™. All Rights Reserved.")]
#if DEBUG
[assembly: XmlnsDefinition("debug-mode", "Namespace")]
Expand Down
34 changes: 23 additions & 11 deletions gamevault/UserControls/GameDownloadUserControl.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,29 @@
<local:CacheImage HorizontalAlignment="Left" VerticalAlignment="Top" MaxWidth="52" Margin="2,2,120,2" ImageCacheType="BoxArt" Data="{Binding Path=Game}" CornerRadius="2" Cursor="Hand" MouseLeftButtonUp="GameImage_MouseLeftButtonUp"/>

<TextBlock HorizontalAlignment="Left" VerticalAlignment="Top" Margin="56,2,0,0" Text="{Binding Path=Game.Title}" MaxWidth="106" FontSize="6" FontWeight="Bold"/>

<Grid Style="{DynamicResource HoverEffect}" VerticalAlignment="Top" HorizontalAlignment="Right" Background="Transparent" Cursor="Hand" Width="8" Height="9" Margin="0,2,2,0" RenderTransformOrigin="0.5,0.5" MouseLeftButtonUp="DeleteFile_MouseLeftButtonUp">
<Path Data="{StaticResource IconTrash}" Fill="IndianRed" Margin="0,0,-13,-13">
<Path.RenderTransform>
<ScaleTransform ScaleX="0.35" ScaleY="0.35"/>
</Path.RenderTransform>
</Path>
<Grid.RenderTransform>
<ScaleTransform/>
</Grid.RenderTransform>
</Grid>
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Right">
<Grid Style="{DynamicResource HoverEffect}" Background="Transparent" Cursor="Hand" HorizontalAlignment="Right" Width="8" Height="9" Margin="0,2,2,0" RenderTransformOrigin="0.5,0.5" MouseLeftButtonUp="DeleteFile_MouseLeftButtonUp">
<Path Data="{StaticResource IconTrash}" Fill="IndianRed" Margin="0,0,-13,-13">
<Path.RenderTransform>
<ScaleTransform ScaleX="0.35" ScaleY="0.35"/>
</Path.RenderTransform>
</Path>
<Grid.RenderTransform>
<ScaleTransform/>
</Grid.RenderTransform>
</Grid>
<TextBlock Text="{Binding TotalDataSize,Converter={StaticResource sizeConv}}" FontSize="2" HorizontalAlignment="Center" Margin="0,0,1.3,0" Foreground="{DynamicResource MahApps.Brushes.ThemeForeground}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding TotalDataSize}" Value="0">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
<Grid Style="{DynamicResource HoverEffect}" VerticalAlignment="Top" HorizontalAlignment="Right" Background="Transparent" Cursor="Hand" Width="8" Height="9" Margin="0,2,12,0" RenderTransformOrigin="0.5,0.5" MouseLeftButtonUp="OpenDirectory_MouseLeftButtonUp">
<Path Data="{StaticResource IconGameSettingsFolder}" Fill="{DynamicResource MahApps.Brushes.ThemeForeground}" Margin="0,0,-14,-13">
<Path.RenderTransform>
Expand Down
63 changes: 53 additions & 10 deletions gamevault/UserControls/GameDownloadUserControl.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System.IO;
using System.Linq;
using System.Net.Http.Headers;
using System.Runtime;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
Expand Down Expand Up @@ -56,6 +57,7 @@ public GameDownloadUserControl(Game game, bool download)
}
else
{
UpdateDataSizeUI();
if (File.Exists($"{m_DownloadPath}\\Extract\\gamevault-metadata") && Preferences.Get(AppConfigKey.ExtractionFinished, $"{m_DownloadPath}\\Extract\\gamevault-metadata") == "1")
{
ViewModel.State = "Extracted";
Expand All @@ -76,12 +78,30 @@ public GameDownloadUserControl(Game game, bool download)
}
}
}
private bool TryRecreatePausedUI()
private void UpdateDataSizeUI()
{
string resumeData = Preferences.Get(AppConfigKey.DownloadProgress, $"{m_DownloadPath}\\gamevault-metadata");
if (!string.IsNullOrEmpty(resumeData))
Task.Run(() =>
{
try
{
double size = 0;
foreach (FileInfo file in new DirectoryInfo(m_DownloadPath).GetFiles("*", SearchOption.AllDirectories))
{
file.Refresh();
size += file.Length;
}
ViewModel.TotalDataSize = size;
}
catch { }
});

}
private bool TryRecreatePausedUI()
{
try
{
string resumeData = Preferences.Get(AppConfigKey.DownloadProgress, $"{m_DownloadPath}\\gamevault-metadata");
if (!string.IsNullOrEmpty(resumeData))
{
string[] resumeDataToProcess = resumeData.Split(";");
var resumePos = long.Parse(resumeDataToProcess[0]);
Expand All @@ -93,8 +113,9 @@ private bool TryRecreatePausedUI()
ViewModel.State = "Download Paused";
return true;
}
catch { }
}
catch { }

return false;
}
public bool IsDownloading()
Expand Down Expand Up @@ -168,7 +189,7 @@ private async Task DownloadGame(bool tryResume = false)
await CacheHelper.CreateOfflineCacheAsync(ViewModel.Game);
}
catch (Exception ex)
{
{
IsDownloadActive = false;
client.Dispose();
ViewModel.State = $"Error: '{ex.Message}'";
Expand Down Expand Up @@ -269,6 +290,7 @@ private void DownloadProgress(long totalFileSize, long currentBytesDownloaded, l

private void DownloadCompleted()
{
UpdateDataSizeUI();
ViewModel.DownloadUIVisibility = System.Windows.Visibility.Hidden;
client.Dispose();
IsDownloadActive = false;
Expand All @@ -286,6 +308,7 @@ private void DownloadCompleted()
Directory.CreateDirectory(ViewModel.InstallPath);
}
MainWindowViewModel.Instance.Library.GetGameInstalls().AddSystemFileWatcher(ViewModel.InstallPath);
ToastMessageHelper.CreateToastMessage("Notification", $"Download of {ViewModel.Game.Title} Complete");
if (SettingsViewModel.Instance.AutoExtract)
{
App.Current.Dispatcher.Invoke((Action)async delegate
Expand All @@ -296,7 +319,6 @@ private void DownloadCompleted()
uiBtnExtract.IsEnabled = true;
});
}
ToastMessageHelper.CreateToastMessage("Notification", $"Download of {ViewModel.Game.Title} Complete");
}

private void CancelDownload_Click(object sender, RoutedEventArgs e)
Expand Down Expand Up @@ -391,9 +413,13 @@ private void GameImage_MouseLeftButtonUp(object sender, System.Windows.Input.Mou

private void ExtractionProgress(object sender, SevenZipProgressEventArgs e)
{
long totalBytesDownloaded = (Convert.ToInt64(ViewModel.Game.Size) / 100) * e.PercentageDone;
ViewModel.ExtractionInfo = $"{$"{FormatBytesHumanReadable(totalBytesDownloaded, (DateTime.Now - startTime).TotalSeconds, 1000)}/s"} - {FormatBytesHumanReadable(totalBytesDownloaded)} of {FormatBytesHumanReadable(Convert.ToInt64(ViewModel.Game.Size))} | Time left: {CalculateTimeLeft(Convert.ToInt64(ViewModel.Game.Size), totalBytesDownloaded, (DateTime.Now - startTime).TotalMilliseconds)}";
ViewModel.GameExtractionProgress = e.PercentageDone;
try
{
ViewModel.GameExtractionProgress = e.PercentageDone;
long totalBytesDownloaded = (Convert.ToInt64(ViewModel.Game.Size) / 100) * e.PercentageDone;
ViewModel.ExtractionInfo = $"{$"{FormatBytesHumanReadable(totalBytesDownloaded, (DateTime.Now - startTime).TotalSeconds, 1000)}/s"} - {FormatBytesHumanReadable(totalBytesDownloaded)} of {FormatBytesHumanReadable(Convert.ToInt64(ViewModel.Game.Size))} | Time left: {CalculateTimeLeft(Convert.ToInt64(ViewModel.Game.Size), totalBytesDownloaded, (DateTime.Now - startTime).TotalMilliseconds)}";
}
catch { }
}
private async void Extract_Click(object sender, RoutedEventArgs e)
{
Expand All @@ -418,7 +444,7 @@ private async Task Extract()
ViewModel.ExtractionUIVisibility = System.Windows.Visibility.Hidden;
ViewModel.State = "Extracting...";
ViewModel.ExtractionUIVisibility = System.Windows.Visibility.Visible;

downloadSpeedCalc = new DownloadSpeedCalculator();//Reuse download speed calculator as extraction speed calculator and set new instance to reset it
sevenZipHelper.Process += ExtractionProgress;
startTime = DateTime.Now;
int result;
Expand Down Expand Up @@ -458,6 +484,7 @@ private async Task Extract()
ViewModel.InstallationStepperProgress = 1;
ViewModel.ExtractionUIVisibility = System.Windows.Visibility.Hidden;
ToastMessageHelper.CreateToastMessage("Notification", $"Extraction of {ViewModel.Game.Title} Complete");
UpdateDataSizeUI();
}
else
{
Expand Down Expand Up @@ -530,6 +557,15 @@ private async void Install_Click(object sender, RoutedEventArgs e)
{
((FrameworkElement)sender).IsEnabled = false;
uiBtnExtract.IsEnabled = false;
try
{
if (!Directory.Exists(ViewModel.InstallPath))//make sure install path exists with file watcher attached
{
Directory.CreateDirectory(ViewModel.InstallPath);
}
MainWindowViewModel.Instance.Library.GetGameInstalls().AddSystemFileWatcher(ViewModel.InstallPath);
}
catch { }
if (ViewModel.Game.Type == GameType.WINDOWS_PORTABLE || ViewModel.Game.Type == GameType.LINUX_PORTABLE)
{
bool error = false;
Expand Down Expand Up @@ -564,6 +600,7 @@ await Task.Run(async () =>
{
MainWindowViewModel.Instance.AppBarText = $"Successfully installed '{ViewModel.Game.Title}'";
ViewModel.InstallationStepperProgress = 2;
ViewModel.State = "Installed";
}
}
else if (ViewModel.Game.Type == GameType.WINDOWS_SETUP)
Expand Down Expand Up @@ -594,6 +631,12 @@ await Task.Run(async () =>
if (setupProcess != null)
{
await setupProcess.WaitForExitAsync();
ViewModel.InstallationStepperProgress = 2;
if (InstallViewModel.Instance.InstalledGames.Any(g => g.Key.ID == ViewModel.Game.ID))
{
ViewModel.InstallationStepperProgress = 2;
ViewModel.State = "Installed";
}
}
}
else
Expand Down
2 changes: 1 addition & 1 deletion gamevault/UserControls/GameSettingsUserControl.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@
</StackPanel>
<TextBlock Text="Recache Game" FontSize="15" FontWeight="Bold" TextDecorations="Underline" Margin="0,20,0,0"/>
<TextBlock Text="When pressed, this Button will re-fetch all data for the mapped RAWG Game from RAWG.IO and cache it on the Server." FontSize="15" Margin="0,5,0,0"/>
<local:IconButton Text="Recache Game" FontSize="15" Icon="{DynamicResource IconReload}" IconMargin="0,0,5,2" HorizontalAlignment="Left" Margin="0,5,0,0" Width="140" Height="33" MouseLeftButtonUp="Recache_Click"/>
<local:IconButton Text="Recache Game" FontSize="15" Icon="{DynamicResource IconReload}" IconMargin="0,0,5,2" HorizontalAlignment="Left" Margin="0,5,0,0" Width="140" Height="33" Click="Recache_Click"/>

<TextBlock Text="Remap Game" FontSize="15" FontWeight="Bold" TextDecorations="Underline" Margin="0,20,0,0"/>
<TextBlock Text="Is the currently mapped Game incorrect or missing? Manually search the RAWG API and re-map your Game here." FontSize="15" Margin="0,5,0,0"/>
Expand Down
Loading

0 comments on commit c5a6da4

Please sign in to comment.