Skip to content

Commit 1db503e

Browse files
authored
Release 1.17.0
Release 1.17.0
2 parents b306116 + f28d02e commit 1db503e

79 files changed

Lines changed: 4579 additions & 2053 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,31 @@
11
# GameVault App Changelog
22

3+
## 1.17.0
4+
Recommended Gamevault Server Version: `v15.0.0`
5+
### Changes
6+
7+
- Replaced setup wizard with a new login window
8+
- Introduced multi-profile support: if no user profile is configured, the demo user is used by default
9+
- Login window now dynamically adapts to the server configuration
10+
- Upgraded all connections to use OAuth 2.0 authentication flow
11+
- Added support for login and registration via configured identity providers (SSO)
12+
- Implemented pending activation state in the login process
13+
- Added options for logout from this device and logout from all devices
14+
- Introduced support for multiple root directories, including selection during download
15+
- Improved image cache performance
16+
- Added support for additional request headers
17+
- New game settings: default parameters for Un/Installer
18+
- Cloud Saves: root path is now included in the generated config.yaml
19+
- Offline cache now auto-renews when outdated
20+
- Added visual indicator on the install game card when an update is available
21+
- Implemented skeleton loading animations in the community tab to better indicate loading states
22+
- Added "Go to Game" button after installation is complete
23+
- Pressing F5 in the Library now also refreshes the list of installed games
24+
- Build temporary offline cache if it does not exist, so that you can still see your installed games in offline mode even if you have deleted the offline cache or it is corrupted.
25+
- Copy button for own users API key in the user settings
26+
- Bug fix: extraction time remaining now displays correctly
27+
- Bug fix: Duplicate entries when typing in the library search
28+
329
## 1.16.1
430
Recommended Gamevault Server Version: `v14.1.0`
531
### Changes

gamevault/App.xaml.cs

Lines changed: 53 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -43,76 +43,65 @@ public static App Instance
4343
}
4444
}
4545
#endregion
46-
public static bool ShowToastMessage = true;
46+
public static bool HideToSystemTray = true;
4747
public static bool IsWindowsPackage = false;
4848

4949
public static CommandOptions? CommandLineOptions { get; internal set; } = null;
5050

5151
private NotifyIcon m_Icon;
5252
private JumpList jumpList;
5353

54-
private GameTimeTracker m_gameTimeTracker;
54+
5555

5656
protected override void OnStartup(StartupEventArgs e)
5757
{
5858
base.OnStartup(e);
5959
AnalyticsHelper.Instance.InitHeartBeat();
6060
AnalyticsHelper.Instance.RegisterGlobalEvents();
61-
AnalyticsHelper.Instance.SendCustomEvent(CustomAnalyticsEventKeys.APP_INITIALIZED, AnalyticsHelper.Instance.GetSysInfo());
61+
AnalyticsHelper.Instance.SendCustomEvent(CustomAnalyticsEventKeys.APP_INITIALIZED, AnalyticsHelper.Instance.GetSysInfo());
6262
}
6363

6464
private async void Application_Startup(object sender, StartupEventArgs e)
6565
{
6666
Application.Current.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(AppDispatcherUnhandledException);
67-
#if DEBUG
68-
AppFilePath.InitDebugPaths();
69-
CreateDirectories();
70-
RestoreTheme();
71-
await CacheHelper.OptimizeCache();
72-
#else
67+
7368
try
7469
{
75-
CreateDirectories();
76-
RestoreTheme();
77-
UpdateWindow updateWindow = new UpdateWindow();
78-
updateWindow.ShowDialog();
70+
LoginWindow loginWindow = new LoginWindow();
71+
bool? result = loginWindow.ShowDialog();
72+
if (result == null || result == false)
73+
Shutdown();
74+
loginWindow = null;
75+
#if WINDOWS
76+
InitNotifyIcon();
77+
InitJumpList();
78+
#endif
7979
}
8080
catch (Exception ex)
8181
{
8282
LogUnhandledException(ex);
83-
//m_StoreHelper.NoInternetException();
8483
}
85-
#endif
86-
await LoginManager.Instance.StartupLogin();
87-
await LoginManager.Instance.PhalcodeLogin(true);
88-
89-
AnalyticsHelper.Instance.SendCustomEvent(CustomAnalyticsEventKeys.USER_SETTINGS, AnalyticsHelper.Instance.PrepareSettingsForAnalytics());
9084

91-
m_gameTimeTracker = new GameTimeTracker();
92-
await m_gameTimeTracker.Start();
85+
//AnalyticsHelper.Instance.SendCustomEvent(CustomAnalyticsEventKeys.USER_SETTINGS, AnalyticsHelper.Instance.PrepareSettingsForAnalytics());
9386

94-
bool startMinimizedByPreferences = false;
95-
bool startMinimizedByCLI = false;
87+
// bool startMinimizedByPreferences = false;
88+
// bool startMinimizedByCLI = false;
9689

97-
if ((CommandLineOptions?.Minimized).HasValue)
98-
startMinimizedByCLI = CommandLineOptions!.Minimized!.Value;
99-
else if (SettingsViewModel.Instance.BackgroundStart)
100-
startMinimizedByPreferences = true;
90+
// if ((CommandLineOptions?.Minimized).HasValue)
91+
// startMinimizedByCLI = CommandLineOptions!.Minimized!.Value;
92+
// else if (SettingsViewModel.Instance.BackgroundStart)
93+
// startMinimizedByPreferences = true;
10194

102-
if (!startMinimizedByPreferences && MainWindow == null)
103-
{
104-
MainWindow = new MainWindow();
105-
MainWindow.Show();
106-
}
107-
if (startMinimizedByCLI && MainWindow != null)
108-
{
109-
MainWindow.Hide();
110-
}
111-
#if WINDOWS
112-
InitNotifyIcon();
113-
InitJumpList();
114-
#endif
115-
// After the app is created and most things are instantiated, handle any special command line stuff
95+
// if (!startMinimizedByPreferences && MainWindow == null)
96+
// {
97+
// MainWindow = new MainWindow();
98+
// MainWindow.Show();
99+
// }
100+
// if (startMinimizedByCLI && MainWindow != null)
101+
// {
102+
// MainWindow.Hide();
103+
// }
104+
// // After the app is created and most things are instantiated, handle any special command line stuff
116105
if (PipeServiceHandler.Instance != null)
117106
{
118107
// Strictly speaking we should hold up all commands until we have a confirmed login & setup is complete, but for now we'll assume that auto-login has worked
@@ -136,10 +125,10 @@ public void LogUnhandledException(Exception e)
136125
Application.Current.DispatcherUnhandledException -= new DispatcherUnhandledExceptionEventHandler(AppDispatcherUnhandledException);
137126
string errorMessage = $"MESSAGE:\n{e.Message}\nINNER_EXCEPTION:{(e.InnerException != null ? "" + e.InnerException.Message : null)}";
138127
string errorStackTrace = $"STACK_TRACE:\n{(e.StackTrace != null ? "" + e.StackTrace : null)}";
139-
string errorLogPath = $"{AppFilePath.ErrorLog}\\GameVault_ErrorLog_{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.txt";
128+
string errorLogPath = $"{ProfileManager.ErrorLogDir}\\GameVault_ErrorLog_{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.txt";
140129
if (!File.Exists(errorLogPath))
141130
{
142-
Directory.CreateDirectory(AppFilePath.ErrorLog);
131+
Directory.CreateDirectory(ProfileManager.ErrorLogDir);
143132
File.Create(errorLogPath).Close();
144133
}
145134
File.WriteAllText(errorLogPath, errorMessage + "\n" + errorStackTrace);
@@ -189,6 +178,7 @@ public void SetJumpListGames()
189178
{
190179
try
191180
{
181+
jumpList.JumpItems.RemoveRange(5, jumpList.JumpItems.Count - 5);// Remove all previous games. Now we add the current game list
192182
var lastGames = InstallViewModel.Instance.InstalledGames.Take(5).ToArray();
193183
foreach (var game in lastGames)
194184
{
@@ -210,31 +200,22 @@ public void SetJumpListGames()
210200
}
211201
catch { }
212202
}
213-
private void RestoreTheme()
203+
public void ResetJumpListGames()
214204
{
215205
try
216206
{
217-
string currentThemeString = Preferences.Get(AppConfigKey.Theme, AppFilePath.UserFile, true);
218-
if (currentThemeString != string.Empty)
219-
{
220-
ThemeItem currentTheme = JsonSerializer.Deserialize<ThemeItem>(currentThemeString)!;
221-
222-
if (App.Current.Resources.MergedDictionaries[0].Source.OriginalString != currentTheme.Path)
223-
{
224-
App.Current.Resources.MergedDictionaries[0] = new ResourceDictionary() { Source = new Uri(currentTheme.Path) };
225-
}
226-
}
207+
jumpList.JumpItems.RemoveRange(5, jumpList.JumpItems.Count - 5);
208+
jumpList.Apply();
227209
}
228210
catch { }
229211
}
230212
private void NotifyIcon_DoubleClick(Object sender, EventArgs e)
231213
{
232-
if (MainWindow == null)
233-
{
234-
MainWindow = new MainWindow();
235-
MainWindow.Show();
236-
}
237-
else if (MainWindow.IsVisible == false)
214+
215+
if (MainWindow == null || MainWindow.GetType() != typeof(MainWindow))
216+
return;
217+
218+
if (MainWindow.IsVisible == false)
238219
{
239220
MainWindow.Show();
240221
}
@@ -244,6 +225,16 @@ private void NotifyIcon_DoubleClick(Object sender, EventArgs e)
244225
}
245226
}
246227

228+
public void SetTheme(string themeUri)
229+
{
230+
App.Current.Resources.MergedDictionaries[0] = new ResourceDictionary() { Source = new Uri(themeUri) };
231+
App.Current.Resources.MergedDictionaries[1] = new ResourceDictionary() { Source = new Uri("pack://application:,,,/gamevault;component/Resources/Assets/Base.xaml") };
232+
}
233+
public void ResetToDefaultTheme()
234+
{
235+
App.Current.Resources.MergedDictionaries[0] = new ResourceDictionary() { Source = new Uri("pack://application:,,,/gamevault;component/Resources/Assets/Themes/ThemeDefaultDark.xaml") };
236+
App.Current.Resources.MergedDictionaries[1] = new ResourceDictionary() { Source = new Uri("pack://application:,,,/gamevault;component/Resources/Assets/Base.xaml") };
237+
}
247238
private async void NotifyIcon_Exit_Click(Object sender, EventArgs e)
248239
{
249240
await ExitApp();
@@ -283,7 +274,7 @@ private void Navigate_Tab_Click(Object sender, EventArgs e)
283274

284275
private void ShutdownApp()
285276
{
286-
ShowToastMessage = false;
277+
HideToSystemTray = false;
287278
ProcessShepherd.Instance.KillAllChildProcesses();
288279
if (m_Icon != null)
289280
{
@@ -292,31 +283,13 @@ private void ShutdownApp()
292283
}
293284
Shutdown();
294285
}
295-
private void CreateDirectories()
296-
{
297-
if (!Directory.Exists(AppFilePath.ImageCache))
298-
{
299-
Directory.CreateDirectory(AppFilePath.ImageCache);
300-
}
301-
if (!Directory.Exists(AppFilePath.ConfigDir))
302-
{
303-
Directory.CreateDirectory(AppFilePath.ConfigDir);
304-
}
305-
if (!Directory.Exists(AppFilePath.ThemesLoadDir))
306-
{
307-
Directory.CreateDirectory(AppFilePath.ThemesLoadDir);
308-
}
309-
if (!Directory.Exists(AppFilePath.CloudSaveConfigDir))
310-
{
311-
Directory.CreateDirectory(AppFilePath.CloudSaveConfigDir);
312-
}
313-
}
314286
public bool IsWindowActiveAndControlInFocus(MainControl control)
315287
{
316288
if (Current.MainWindow == null)
317289
return false;
318290

319291
return Current.MainWindow.IsActive && MainWindowViewModel.Instance.ActiveControlIndex == (int)control;
320292
}
293+
321294
}
322295
}

gamevault/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//(used if a resource is not found in the page,
1212
// app, or any theme specific resource dictionaries)
1313
)]
14-
[assembly: AssemblyVersion("1.16.1.0")]
14+
[assembly: AssemblyVersion("1.17.0.0")]
1515
[assembly: AssemblyCopyright("© Phalcode™. All Rights Reserved.")]
1616
#if DEBUG
1717
[assembly: XmlnsDefinition("debug-mode", "Namespace")]
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Globalization;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using System.Windows.Data;
8+
9+
namespace gamevault.Converter
10+
{
11+
class BoolToVisibilityConverter : IValueConverter
12+
{
13+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
14+
{
15+
return (bool)value ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
16+
}
17+
18+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
19+
{
20+
return null;
21+
}
22+
}
23+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using gamevault.Models;
2+
using gamevault.ViewModels;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Globalization;
6+
using System.IO;
7+
using System.Linq;
8+
using System.Text;
9+
using System.Threading.Tasks;
10+
using System.Windows.Data;
11+
12+
namespace gamevault.Converter
13+
{
14+
internal class GameUpdateAvailableConverter : IValueConverter
15+
{
16+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
17+
{
18+
try
19+
{
20+
Game game = (Game)value;
21+
KeyValuePair<Game, string> result = InstallViewModel.Instance.InstalledGames.Where(g => g.Key.ID == game.ID).FirstOrDefault();
22+
string execFile = Path.Combine(result.Value, "gamevault-exec");
23+
string installedVersion = Preferences.Get(AppConfigKey.InstalledGameVersion, execFile);
24+
if(string.IsNullOrWhiteSpace(installedVersion))
25+
{
26+
Preferences.Set(AppConfigKey.InstalledGameVersion, game.Version, execFile);
27+
}
28+
else if (installedVersion != game.Version)
29+
{
30+
return true;
31+
}
32+
}
33+
catch { }
34+
return false;
35+
}
36+
37+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
38+
{
39+
return null;
40+
}
41+
}
42+
}

gamevault/Converter/ShowMappedTitleConverter.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using gamevault.Models;
1+
using gamevault.Helper;
2+
using gamevault.Models;
23
using System;
34
using System.Collections.Generic;
45
using System.Globalization;
@@ -14,7 +15,7 @@ public class ShowMappedTitleConverter : IValueConverter
1415
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
1516
{
1617

17-
bool showMappedTitle = Preferences.Get(AppConfigKey.ShowMappedTitle, AppFilePath.UserFile) == "1";
18+
bool showMappedTitle = Preferences.Get(AppConfigKey.ShowMappedTitle,LoginManager.Instance.GetUserProfile().UserConfigFile) == "1";
1819
if (showMappedTitle && value is Game game && !string.IsNullOrWhiteSpace(game?.Metadata?.Title))
1920
{
2021
return true;

0 commit comments

Comments
 (0)