Convert SteamCMD VDF to JSON to prepare for compatibility with web API
This commit is contained in:
parent
a198b7f9e5
commit
eb8c75d249
8 changed files with 172 additions and 118 deletions
|
@ -154,6 +154,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Gameloop.Vdf" Version="0.6.2" />
|
||||
<PackageReference Include="Gameloop.Vdf.JsonConverter" Version="0.2.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="System.ServiceModel.Primitives" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -201,10 +201,10 @@ internal sealed partial class SelectForm : CustomForm
|
|||
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
AppData appData = await SteamStore.QueryStoreAPI(appId);
|
||||
StoreAppData storeAppData = await SteamStore.QueryStoreAPI(appId);
|
||||
_ = Interlocked.Decrement(ref steamGamesToCheck);
|
||||
VProperty appInfo = await SteamCMD.GetAppInfo(appId, branch, buildId);
|
||||
if (appData is null && appInfo is null)
|
||||
CmdAppData cmdAppData = await SteamCMD.GetAppInfo(appId, branch, buildId);
|
||||
if (storeAppData is null && cmdAppData is null)
|
||||
{
|
||||
RemoveFromRemainingGames(name);
|
||||
return;
|
||||
|
@ -213,13 +213,13 @@ internal sealed partial class SelectForm : CustomForm
|
|||
if (Program.Canceled)
|
||||
return;
|
||||
ConcurrentDictionary<SelectionDLC, byte> dlc = new();
|
||||
List<Task> dlcTasks = new();
|
||||
HashSet<string> dlcIds = new();
|
||||
if (appData is not null)
|
||||
foreach (string dlcId in await SteamStore.ParseDlcAppIds(appData))
|
||||
List<Task> dlcTasks = [];
|
||||
HashSet<string> dlcIds = [];
|
||||
if (storeAppData is not null)
|
||||
foreach (string dlcId in await SteamStore.ParseDlcAppIds(storeAppData))
|
||||
_ = dlcIds.Add(dlcId);
|
||||
if (appInfo is not null)
|
||||
foreach (string dlcId in await SteamCMD.ParseDlcAppIds(appInfo))
|
||||
if (cmdAppData is not null)
|
||||
foreach (string dlcId in await SteamCMD.ParseDlcAppIds(cmdAppData))
|
||||
_ = dlcIds.Add(dlcId);
|
||||
if (dlcIds.Count > 0)
|
||||
foreach (string dlcAppId in dlcIds)
|
||||
|
@ -240,31 +240,27 @@ internal sealed partial class SelectForm : CustomForm
|
|||
string dlcName = null;
|
||||
string dlcIcon = null;
|
||||
bool onSteamStore = false;
|
||||
AppData dlcAppData = await SteamStore.QueryStoreAPI(dlcAppId, true);
|
||||
if (dlcAppData is not null)
|
||||
StoreAppData dlcStoreAppData = await SteamStore.QueryStoreAPI(dlcAppId, true);
|
||||
if (dlcStoreAppData is not null)
|
||||
{
|
||||
dlcName = dlcAppData.Name;
|
||||
dlcIcon = dlcAppData.HeaderImage;
|
||||
dlcName = dlcStoreAppData.Name;
|
||||
dlcIcon = dlcStoreAppData.HeaderImage;
|
||||
onSteamStore = true;
|
||||
fullGameAppId = dlcAppData.FullGame?.AppId;
|
||||
fullGameAppId = dlcStoreAppData.FullGame?.AppId;
|
||||
}
|
||||
else
|
||||
{
|
||||
VProperty dlcAppInfo = await SteamCMD.GetAppInfo(dlcAppId);
|
||||
if (dlcAppInfo is not null)
|
||||
CmdAppData dlcCmdAppData = await SteamCMD.GetAppInfo(dlcAppId);
|
||||
if (dlcCmdAppData is not null)
|
||||
{
|
||||
dlcName = dlcAppInfo.Value.GetChild("common")?.GetChild("name")?.ToString();
|
||||
string dlcIconStaticId = dlcAppInfo.Value.GetChild("common")?.GetChild("icon")
|
||||
?.ToString();
|
||||
dlcIconStaticId ??= dlcAppInfo.Value.GetChild("common")?.GetChild("logo_small")
|
||||
?.ToString();
|
||||
dlcIconStaticId ??= dlcAppInfo.Value.GetChild("common")?.GetChild("logo")
|
||||
?.ToString();
|
||||
dlcName = dlcCmdAppData.Common?.Name;
|
||||
string dlcIconStaticId = dlcCmdAppData.Common?.Icon;
|
||||
dlcIconStaticId ??= dlcCmdAppData.Common?.LogoSmall;
|
||||
dlcIconStaticId ??= dlcCmdAppData.Common?.Logo;
|
||||
if (dlcIconStaticId is not null)
|
||||
dlcIcon = IconGrabber.SteamAppImagesPath +
|
||||
@$"\{dlcAppId}\{dlcIconStaticId}.jpg";
|
||||
fullGameAppId = dlcAppInfo.Value.GetChild("common")?.GetChild("parent")
|
||||
?.ToString();
|
||||
fullGameAppId = dlcCmdAppData.Common?.Parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,26 +269,23 @@ internal sealed partial class SelectForm : CustomForm
|
|||
string fullGameName = null;
|
||||
string fullGameIcon = null;
|
||||
bool fullGameOnSteamStore = false;
|
||||
AppData fullGameAppData = await SteamStore.QueryStoreAPI(fullGameAppId, true);
|
||||
if (fullGameAppData is not null)
|
||||
StoreAppData fullGameStoreAppData =
|
||||
await SteamStore.QueryStoreAPI(fullGameAppId, true);
|
||||
if (fullGameStoreAppData is not null)
|
||||
{
|
||||
fullGameName = fullGameAppData.Name;
|
||||
fullGameIcon = fullGameAppData.HeaderImage;
|
||||
fullGameName = fullGameStoreAppData.Name;
|
||||
fullGameIcon = fullGameStoreAppData.HeaderImage;
|
||||
fullGameOnSteamStore = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
VProperty fullGameAppInfo = await SteamCMD.GetAppInfo(fullGameAppId);
|
||||
CmdAppData fullGameAppInfo = await SteamCMD.GetAppInfo(fullGameAppId);
|
||||
if (fullGameAppInfo is not null)
|
||||
{
|
||||
fullGameName = fullGameAppInfo.Value.GetChild("common")?.GetChild("name")
|
||||
?.ToString();
|
||||
string fullGameIconStaticId = fullGameAppInfo.Value.GetChild("common")
|
||||
?.GetChild("icon")?.ToString();
|
||||
fullGameIconStaticId ??= fullGameAppInfo.Value.GetChild("common")
|
||||
?.GetChild("logo_small")?.ToString();
|
||||
fullGameIconStaticId ??= fullGameAppInfo.Value.GetChild("common")
|
||||
?.GetChild("logo")?.ToString();
|
||||
fullGameName = fullGameAppInfo.Common?.Name;
|
||||
string fullGameIconStaticId = fullGameAppInfo.Common?.Icon;
|
||||
fullGameIconStaticId ??= fullGameAppInfo.Common?.LogoSmall;
|
||||
fullGameIconStaticId ??= fullGameAppInfo.Common?.Logo;
|
||||
if (fullGameIconStaticId is not null)
|
||||
dlcIcon = IconGrabber.SteamAppImagesPath +
|
||||
@$"\{fullGameAppId}\{fullGameIconStaticId}.jpg";
|
||||
|
@ -345,17 +338,15 @@ internal sealed partial class SelectForm : CustomForm
|
|||
return;
|
||||
}
|
||||
|
||||
Selection selection = Selection.GetOrCreate(Platform.Steam, appId, appData?.Name ?? name,
|
||||
Selection selection = Selection.GetOrCreate(Platform.Steam, appId, storeAppData?.Name ?? name,
|
||||
gameDirectory, dllDirectories,
|
||||
await gameDirectory.GetExecutableDirectories(true));
|
||||
selection.Product = "https://store.steampowered.com/app/" + appId;
|
||||
selection.Icon = IconGrabber.SteamAppImagesPath +
|
||||
@$"\{appId}\{appInfo?.Value.GetChild("common")?.GetChild("icon")}.jpg";
|
||||
selection.SubIcon = appData?.HeaderImage ?? IconGrabber.SteamAppImagesPath
|
||||
+ @$"\{appId}\{appInfo?.Value.GetChild("common")?.GetChild("clienticon")}.ico";
|
||||
selection.Publisher = appData?.Publishers[0] ??
|
||||
appInfo?.Value.GetChild("extended")?.GetChild("publisher")?.ToString();
|
||||
selection.Website = appData?.Website;
|
||||
selection.Icon = IconGrabber.SteamAppImagesPath + @$"\{appId}\{cmdAppData?.Common?.Icon}.jpg";
|
||||
selection.SubIcon = storeAppData?.HeaderImage ?? IconGrabber.SteamAppImagesPath
|
||||
+ @$"\{appId}\{cmdAppData?.Common?.ClientIcon}.ico";
|
||||
selection.Publisher = storeAppData?.Publishers[0] ?? cmdAppData?.Extended?.Publisher;
|
||||
selection.Website = storeAppData?.Website;
|
||||
if (Program.Canceled)
|
||||
return;
|
||||
Invoke(delegate
|
||||
|
|
53
CreamInstaller/Platforms/Steam/CmdAppDetails.cs
Normal file
53
CreamInstaller/Platforms/Steam/CmdAppDetails.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace CreamInstaller.Platforms.Steam;
|
||||
|
||||
public class CmdAppCommon
|
||||
{
|
||||
[JsonProperty(PropertyName = "type")] public string Type { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "name")] public string Name { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "icon")] public string Icon { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "clienticon")]
|
||||
public string ClientIcon { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "logo_small")]
|
||||
public string LogoSmall { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "logo")] public string Logo { set; get; }
|
||||
|
||||
[JsonProperty(PropertyName = "parent")]
|
||||
public string Parent { set; get; }
|
||||
}
|
||||
|
||||
public class CmdAppExtended
|
||||
{
|
||||
[JsonProperty(PropertyName = "listofdlc")]
|
||||
public string Dlc { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "publisher")]
|
||||
public string Publisher { get; set; }
|
||||
}
|
||||
|
||||
public class CmdAppData
|
||||
{
|
||||
[JsonProperty(PropertyName = "common")]
|
||||
public CmdAppCommon Common { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "depots")]
|
||||
public Dictionary<string, dynamic> Depots { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "extended")]
|
||||
public CmdAppExtended Extended { get; set; }
|
||||
}
|
||||
|
||||
public class CmdAppDetails
|
||||
{
|
||||
[JsonProperty(PropertyName = "status")]
|
||||
public string Status { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "data")] public Dictionary<string, CmdAppData> Data { get; set; }
|
||||
}
|
|
@ -10,6 +10,7 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using CreamInstaller.Resources;
|
||||
using CreamInstaller.Utility;
|
||||
using Gameloop.Vdf.JsonConverter;
|
||||
using Gameloop.Vdf.Linq;
|
||||
#if DEBUG
|
||||
using CreamInstaller.Forms;
|
||||
|
@ -17,7 +18,7 @@ using CreamInstaller.Forms;
|
|||
|
||||
namespace CreamInstaller.Platforms.Steam;
|
||||
|
||||
internal static class SteamCMD
|
||||
internal static partial class SteamCMD
|
||||
{
|
||||
private const int ProcessLimit = 20;
|
||||
|
||||
|
@ -32,10 +33,6 @@ internal static class SteamCMD
|
|||
private static readonly string DllPath = DirectoryPath + @"\steamclient.dll";
|
||||
|
||||
private static readonly string AppCachePath = DirectoryPath + @"\appcache";
|
||||
private static readonly string ConfigPath = DirectoryPath + @"\config";
|
||||
private static readonly string DumpsPath = DirectoryPath + @"\dumps";
|
||||
private static readonly string LogsPath = DirectoryPath + @"\logs";
|
||||
private static readonly string SteamAppsPath = DirectoryPath + @"\steamapps";
|
||||
|
||||
private static string DirectoryPath => ProgramData.DirectoryPath;
|
||||
internal static string AppInfoPath => ProgramData.AppInfoPath;
|
||||
|
@ -179,22 +176,7 @@ internal static class SteamCMD
|
|||
await Kill();
|
||||
try
|
||||
{
|
||||
if (ConfigPath.DirectoryExists())
|
||||
foreach (string file in ConfigPath.EnumerateDirectory("*.tmp"))
|
||||
file.DeleteFile();
|
||||
foreach (string file in DirectoryPath.EnumerateDirectory("*.old"))
|
||||
file.DeleteFile();
|
||||
foreach (string file in DirectoryPath.EnumerateDirectory("*.delete"))
|
||||
file.DeleteFile();
|
||||
foreach (string file in DirectoryPath.EnumerateDirectory("*.crash"))
|
||||
file.DeleteFile();
|
||||
foreach (string file in DirectoryPath.EnumerateDirectory("*.ntfs_transaction_failed"))
|
||||
file.DeleteFile();
|
||||
AppCachePath
|
||||
.DeleteDirectory(); // this is definitely needed, so SteamCMD gets the latest information for us
|
||||
DumpsPath.DeleteDirectory();
|
||||
LogsPath.DeleteDirectory();
|
||||
SteamAppsPath.DeleteDirectory(); // this is just a useless folder created from +app_update 4
|
||||
AppCachePath.DeleteDirectory();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -202,7 +184,7 @@ internal static class SteamCMD
|
|||
}
|
||||
});
|
||||
|
||||
internal static async Task<VProperty> GetAppInfo(string appId, string branch = "public", int buildId = 0)
|
||||
internal static async Task<CmdAppData> GetAppInfo(string appId, string branch = "public", int buildId = 0)
|
||||
{
|
||||
int attempts = 0;
|
||||
while (!Program.Canceled)
|
||||
|
@ -254,18 +236,49 @@ internal static class SteamCMD
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!appInfo.Value.Children().Any())
|
||||
return appInfo;
|
||||
VToken type = appInfo.Value.GetChild("common")?.GetChild("type");
|
||||
if (type is not null && type.ToString() != "Game")
|
||||
return appInfo;
|
||||
string buildid = appInfo.Value.GetChild("depots")?.GetChild("branches")?.GetChild(branch)
|
||||
?.GetChild("buildid")?.ToString();
|
||||
CmdAppData appData;
|
||||
try
|
||||
{
|
||||
if (appInfo.ToJson().Value.ToObject<CmdAppData>() is not { } cmdAppData)
|
||||
{
|
||||
appUpdateFile.DeleteFile();
|
||||
#if DEBUG
|
||||
DebugForm.Current.Log(
|
||||
"SteamCMD query failed on attempt #" + attempts + " for " + appId + " (" + branch +
|
||||
"): VDF-JSON conversion failed",
|
||||
LogTextBox.Warning);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
appData = cmdAppData;
|
||||
}
|
||||
catch
|
||||
#if DEBUG
|
||||
(Exception e)
|
||||
#endif
|
||||
{
|
||||
appUpdateFile.DeleteFile();
|
||||
#if DEBUG
|
||||
DebugForm.Current.Log(
|
||||
"SteamCMD query failed on attempt #" + attempts + " for " + appId + " (" + branch +
|
||||
"): VDF-JSON conversion failed (" + e.Message + ")",
|
||||
LogTextBox.Warning);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
string type = appData.Common?.Type;
|
||||
if (type is not null && type != "Game")
|
||||
return appData;
|
||||
if (appData.Depots is null || !appData.Depots.TryGetValue("branches", out dynamic appBranch))
|
||||
return appData;
|
||||
string buildid = appBranch?[branch]?.buildid;
|
||||
if (buildid is null && type is not null)
|
||||
return appInfo;
|
||||
return appData;
|
||||
if (type is not null && (!int.TryParse(buildid, out int gamebuildId) || gamebuildId >= buildId))
|
||||
return appInfo;
|
||||
HashSet<string> dlcAppIds = await ParseDlcAppIds(appInfo);
|
||||
return appData;
|
||||
HashSet<string> dlcAppIds = await ParseDlcAppIds(appData);
|
||||
foreach (string dlcAppUpdateFile in dlcAppIds.Select(id => $@"{AppInfoPath}\{id}.vdf"))
|
||||
dlcAppUpdateFile.DeleteFile();
|
||||
appUpdateFile.DeleteFile();
|
||||
|
@ -279,30 +292,27 @@ internal static class SteamCMD
|
|||
return null;
|
||||
}
|
||||
|
||||
internal static async Task<HashSet<string>> ParseDlcAppIds(VProperty appInfo)
|
||||
internal static async Task<HashSet<string>> ParseDlcAppIds(CmdAppData appData)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
HashSet<string> dlcIds = [];
|
||||
if (Program.Canceled || appInfo is null)
|
||||
if (Program.Canceled || appData is null)
|
||||
return dlcIds;
|
||||
VToken extended = appInfo.Value.GetChild("extended");
|
||||
if (extended is not null)
|
||||
foreach (VToken vToken in extended.Where(p => p is VProperty { Key: "listofdlc" }))
|
||||
{
|
||||
VProperty property = (VProperty)vToken;
|
||||
foreach (string id in property.Value.ToString().Split(","))
|
||||
if (int.TryParse(id, out int appId) && appId > 0)
|
||||
_ = dlcIds.Add("" + appId);
|
||||
}
|
||||
|
||||
VToken depots = appInfo.Value.GetChild("depots");
|
||||
CmdAppExtended extended = appData.Extended;
|
||||
if (extended?.Dlc != null)
|
||||
foreach (string id in extended.Dlc.Split(","))
|
||||
if (int.TryParse(id, out int appId) && appId > 0)
|
||||
_ = dlcIds.Add("" + appId);
|
||||
|
||||
Dictionary<string, dynamic> depots = appData.Depots;
|
||||
if (depots is null)
|
||||
return dlcIds;
|
||||
foreach (VToken vToken in depots.Where(
|
||||
p => p is VProperty property && int.TryParse(property.Key, out int _)))
|
||||
|
||||
foreach ((_, dynamic depot) in depots.Where(p => int.TryParse(p.Key, out _)))
|
||||
{
|
||||
VProperty property = (VProperty)vToken;
|
||||
if (int.TryParse(property.Value.GetChild("dlcappid")?.ToString(), out int appId) && appId > 0)
|
||||
string dlcAppId = depot.dlcappid;
|
||||
if (dlcAppId is not null && int.TryParse(dlcAppId, out int appId) && appId > 0)
|
||||
_ = dlcIds.Add("" + appId);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,20 +18,20 @@ internal static class SteamStore
|
|||
private const int CooldownGame = 600;
|
||||
private const int CooldownDlc = 1200;
|
||||
|
||||
internal static async Task<HashSet<string>> ParseDlcAppIds(AppData appData)
|
||||
internal static async Task<HashSet<string>> ParseDlcAppIds(StoreAppData storeAppData)
|
||||
=> await Task.Run(() =>
|
||||
{
|
||||
HashSet<string> dlcIds = new();
|
||||
if (appData.DLC is null)
|
||||
if (storeAppData.DLC is null)
|
||||
return dlcIds;
|
||||
foreach (string dlcId in from appId in appData.DLC
|
||||
foreach (string dlcId in from appId in storeAppData.DLC
|
||||
where appId > 0
|
||||
select appId.ToString(CultureInfo.InvariantCulture))
|
||||
_ = dlcIds.Add(dlcId);
|
||||
return dlcIds;
|
||||
});
|
||||
|
||||
internal static async Task<AppData> QueryStoreAPI(string appId, bool isDlc = false, int attempts = 0)
|
||||
internal static async Task<StoreAppData> QueryStoreAPI(string appId, bool isDlc = false, int attempts = 0)
|
||||
{
|
||||
while (!Program.Canceled)
|
||||
{
|
||||
|
@ -50,11 +50,12 @@ internal static class SteamStore
|
|||
foreach (KeyValuePair<string, JToken> app in apps)
|
||||
try
|
||||
{
|
||||
AppDetails appDetails = JsonConvert.DeserializeObject<AppDetails>(app.Value.ToString());
|
||||
if (appDetails is not null)
|
||||
StoreAppDetails storeAppDetails =
|
||||
JsonConvert.DeserializeObject<StoreAppDetails>(app.Value.ToString());
|
||||
if (storeAppDetails is not null)
|
||||
{
|
||||
AppData data = appDetails.Data;
|
||||
if (!appDetails.Success)
|
||||
StoreAppData data = storeAppDetails.Data;
|
||||
if (!storeAppDetails.Success)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugForm.Current.Log(
|
||||
|
@ -123,21 +124,19 @@ internal static class SteamStore
|
|||
+ ": Response deserialization null");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if DEBUG
|
||||
else
|
||||
DebugForm.Current.Log(
|
||||
"Steam store query failed on attempt #" + attempts + " for " + appId + (isDlc ? " (DLC)" : "") +
|
||||
": Response null",
|
||||
LogTextBox.Warning);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (cachedExists)
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<AppData>(cacheFile.ReadFile());
|
||||
return JsonConvert.DeserializeObject<StoreAppData>(cacheFile.ReadFile());
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
@ -3,14 +3,14 @@ using Newtonsoft.Json;
|
|||
|
||||
namespace CreamInstaller.Platforms.Steam;
|
||||
|
||||
public class AppFullGame
|
||||
public class StoreAppFullGame
|
||||
{
|
||||
[JsonProperty(PropertyName = "appid")] public string AppId { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "name")] public string Name { get; set; }
|
||||
}
|
||||
|
||||
public class AppData
|
||||
public class StoreAppData
|
||||
{
|
||||
[JsonProperty(PropertyName = "type")] public string Type { get; set; }
|
||||
|
||||
|
@ -20,7 +20,7 @@ public class AppData
|
|||
public int SteamAppId { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "fullgame")]
|
||||
public AppFullGame FullGame { get; set; }
|
||||
public StoreAppFullGame FullGame { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "dlc")] public List<int> DLC { get; set; }
|
||||
|
||||
|
@ -40,10 +40,10 @@ public class AppData
|
|||
public List<int> Packages { get; set; }
|
||||
}
|
||||
|
||||
public class AppDetails
|
||||
public class StoreAppDetails
|
||||
{
|
||||
[JsonProperty(PropertyName = "success")]
|
||||
public bool Success { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "data")] public AppData Data { get; set; }
|
||||
[JsonProperty(PropertyName = "data")] public StoreAppData Data { get; set; }
|
||||
}
|
|
@ -111,7 +111,7 @@ internal static class ProgramData
|
|||
// ignored
|
||||
}
|
||||
|
||||
return Enumerable.Empty<(Platform platform, string id)>();
|
||||
return [];
|
||||
}
|
||||
|
||||
internal static void WriteProgramChoices(IEnumerable<(Platform platform, string id)> choices)
|
||||
|
@ -144,7 +144,7 @@ internal static class ProgramData
|
|||
// ignored
|
||||
}
|
||||
|
||||
return Enumerable.Empty<(Platform platform, string gameId, string dlcId)>();
|
||||
return [];
|
||||
}
|
||||
|
||||
internal static void WriteDlcChoices(List<(Platform platform, string gameId, string dlcId)> choices)
|
||||
|
@ -177,7 +177,7 @@ internal static class ProgramData
|
|||
// ignored
|
||||
}
|
||||
|
||||
return Enumerable.Empty<(Platform platform, string id, string proxy, bool enabled)>();
|
||||
return [];
|
||||
}
|
||||
|
||||
internal static void WriteProxyChoices(
|
||||
|
|
|
@ -75,7 +75,7 @@ internal static class SafeIO
|
|||
Form form = null)
|
||||
{
|
||||
if (!directoryPath.DirectoryExists())
|
||||
return Enumerable.Empty<string>();
|
||||
return [];
|
||||
while (!Program.Canceled)
|
||||
try
|
||||
{
|
||||
|
@ -92,7 +92,7 @@ internal static class SafeIO
|
|||
break;
|
||||
}
|
||||
|
||||
return Enumerable.Empty<string>();
|
||||
return [];
|
||||
}
|
||||
|
||||
internal static IEnumerable<string> EnumerateSubdirectories(this string directoryPath, string directoryPattern,
|
||||
|
@ -100,7 +100,7 @@ internal static class SafeIO
|
|||
bool crucial = false, Form form = null)
|
||||
{
|
||||
if (!directoryPath.DirectoryExists())
|
||||
return Enumerable.Empty<string>();
|
||||
return [];
|
||||
while (!Program.Canceled)
|
||||
try
|
||||
{
|
||||
|
@ -117,7 +117,7 @@ internal static class SafeIO
|
|||
break;
|
||||
}
|
||||
|
||||
return Enumerable.Empty<string>();
|
||||
return [];
|
||||
}
|
||||
|
||||
internal static bool FileExists(this string filePath) => File.Exists(filePath);
|
||||
|
|
Loading…
Reference in a new issue