Split DepotDownloader configuration file into account settings stored in IsolatedStorage, and depot installation data stored in the .DepotDownloader config directory alongside cached manifests

pull/74/head
Ryan Kistner 6 years ago
parent 2c46ee32ea
commit 436519d445

@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using ProtoBuf;
using System.IO;
using System.IO.Compression;
using System.IO.IsolatedStorage;
using System.Linq;
using SteamKit2;
using SteamKit2.Discovery;
namespace DepotDownloader
{
[ProtoContract]
class AccountSettingsStore
{
[ProtoMember(1, IsRequired=false)]
public Dictionary<string, byte[]> SentryData { get; private set; }
[ProtoMember(2, IsRequired = false)]
public System.Collections.Concurrent.ConcurrentDictionary<string, int> ContentServerPenalty { get; private set; }
[ProtoMember(3, IsRequired = false)]
public Dictionary<string, string> LoginKeys { get; private set; }
string FileName = null;
AccountSettingsStore()
{
SentryData = new Dictionary<string, byte[]>();
ContentServerPenalty = new System.Collections.Concurrent.ConcurrentDictionary<string, int>();
LoginKeys = new Dictionary<string, string>();
}
static bool Loaded
{
get { return Instance != null; }
}
public static AccountSettingsStore Instance = null;
static readonly IsolatedStorageFile IsolatedStorage = IsolatedStorageFile.GetUserStoreForAssembly();
public static void LoadFromFile(string filename)
{
if (Loaded)
throw new Exception("Config already loaded");
if (IsolatedStorage.FileExists(filename))
{
try
{
using (var fs = IsolatedStorage.OpenFile(filename, FileMode.Open, FileAccess.Read))
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Decompress))
{
Instance = ProtoBuf.Serializer.Deserialize<AccountSettingsStore>(ds);
}
}
catch (IOException ex)
{
Console.WriteLine("Failed to load account settings: {0}", ex.Message);
Instance = new AccountSettingsStore();
}
}
else
{
Instance = new AccountSettingsStore();
}
Instance.FileName = filename;
}
public static void Save()
{
if (!Loaded)
throw new Exception("Saved config before loading");
try
{
using (var fs = IsolatedStorage.OpenFile(Instance.FileName, FileMode.Open, FileAccess.Read))
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Compress))
{
ProtoBuf.Serializer.Serialize<AccountSettingsStore>(ds, Instance);
}
}
catch (IOException ex)
{
Console.WriteLine("Failed to save account settings: {0}", ex.Message);
}
}
}
}

@ -90,7 +90,7 @@ namespace DepotDownloader
var weightedCdnServers = servers.Select(x =>
{
int penalty = 0;
ConfigStore.TheConfig.ContentServerPenalty.TryGetValue(x.Host, out penalty);
AccountSettingsStore.Instance.ContentServerPenalty.TryGetValue(x.Host, out penalty);
return Tuple.Create(x, penalty);
}).OrderBy(x => x.Item2).ThenBy(x => x.Item1.WeightedLoad);
@ -174,8 +174,8 @@ namespace DepotDownloader
Console.WriteLine("Failed to connect to content server {0}: {1}", server, ex.Message);
int penalty = 0;
ConfigStore.TheConfig.ContentServerPenalty.TryGetValue(server.Host, out penalty);
ConfigStore.TheConfig.ContentServerPenalty[server.Host] = penalty + 1;
AccountSettingsStore.Instance.ContentServerPenalty.TryGetValue(server.Host, out penalty);
AccountSettingsStore.Instance.ContentServerPenalty[server.Host] = penalty + 1;
}
}

@ -1,70 +0,0 @@
using System;
using System.Collections.Generic;
using ProtoBuf;
using System.IO;
using System.IO.Compression;
namespace DepotDownloader
{
[ProtoContract]
class ConfigStore
{
[ProtoMember(1)]
public Dictionary<uint, ulong> LastManifests { get; private set; }
[ProtoMember(3, IsRequired=false)]
public Dictionary<string, byte[]> SentryData { get; private set; }
[ProtoMember(4, IsRequired = false)]
public System.Collections.Concurrent.ConcurrentDictionary<string, int> ContentServerPenalty { get; private set; }
[ProtoMember(5, IsRequired = false)]
public Dictionary<string, string> LoginKeys { get; private set; }
string FileName = null;
ConfigStore()
{
LastManifests = new Dictionary<uint, ulong>();
SentryData = new Dictionary<string, byte[]>();
ContentServerPenalty = new System.Collections.Concurrent.ConcurrentDictionary<string, int>();
LoginKeys = new Dictionary<string, string>();
}
static bool Loaded
{
get { return TheConfig != null; }
}
public static ConfigStore TheConfig = null;
public static void LoadFromFile(string filename)
{
if (Loaded)
throw new Exception("Config already loaded");
if (File.Exists(filename))
{
using (FileStream fs = File.Open(filename, FileMode.Open))
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Decompress))
TheConfig = ProtoBuf.Serializer.Deserialize<ConfigStore>(ds);
}
else
{
TheConfig = new ConfigStore();
}
TheConfig.FileName = filename;
}
public static void Save()
{
if (!Loaded)
throw new Exception("Saved config before loading");
using (FileStream fs = File.Open(TheConfig.FileName, FileMode.Create))
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Compress))
ProtoBuf.Serializer.Serialize<ConfigStore>(ds, TheConfig);
}
}
}

@ -339,7 +339,7 @@ namespace DepotDownloader
if ( username != null && Config.RememberPassword )
{
_ = ConfigStore.TheConfig.LoginKeys.TryGetValue( username, out loginKey );
_ = AccountSettingsStore.Instance.LoginKeys.TryGetValue( username, out loginKey );
}
steam3 = new Steam3Session(
@ -395,6 +395,16 @@ namespace DepotDownloader
public static async Task DownloadAppAsync( uint appId, uint depotId, ulong manifestId, string branch, string os, bool isUgc )
{
// Load our configuration data containing the depots currently installed
string configPath = ContentDownloader.Config.InstallDirectory;
if (string.IsNullOrWhiteSpace(configPath))
{
configPath = DEFAULT_DOWNLOAD_DIR;
}
Directory.CreateDirectory(Path.Combine(configPath, CONFIG_DIR));
DepotConfigStore.LoadFromFile(Path.Combine(configPath, CONFIG_DIR, "depot.config"));
if ( steam3 != null )
steam3.RequestAppInfo( appId );
@ -574,11 +584,11 @@ namespace DepotDownloader
string configDir = Path.Combine( depot.installDir, CONFIG_DIR );
ulong lastManifestId = INVALID_MANIFEST_ID;
ConfigStore.TheConfig.LastManifests.TryGetValue( depot.id, out lastManifestId );
DepotConfigStore.Instance.InstalledManifestIDs.TryGetValue( depot.id, out lastManifestId );
// In case we have an early exit, this will force equiv of verifyall next run.
ConfigStore.TheConfig.LastManifests[ depot.id ] = INVALID_MANIFEST_ID;
ConfigStore.Save();
DepotConfigStore.Instance.InstalledManifestIDs[ depot.id ] = INVALID_MANIFEST_ID;
DepotConfigStore.Save();
if ( lastManifestId != INVALID_MANIFEST_ID )
{
@ -971,8 +981,8 @@ namespace DepotDownloader
await Task.WhenAll( tasks ).ConfigureAwait( false );
ConfigStore.TheConfig.LastManifests[ depot.id ] = depot.manifestId;
ConfigStore.Save();
DepotConfigStore.Instance.InstalledManifestIDs[ depot.id ] = depot.manifestId;
DepotConfigStore.Save();
Console.WriteLine( "Depot {0} - Downloaded {1} bytes ({2} bytes uncompressed)", depot.id, DepotBytesCompressed, DepotBytesUncompressed );
}

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using ProtoBuf;
using System.IO;
using System.IO.Compression;
namespace DepotDownloader
{
[ProtoContract]
class DepotConfigStore
{
[ProtoMember(1)]
public Dictionary<uint, ulong> InstalledManifestIDs { get; private set; }
string FileName = null;
DepotConfigStore()
{
InstalledManifestIDs = new Dictionary<uint, ulong>();
}
static bool Loaded
{
get { return Instance != null; }
}
public static DepotConfigStore Instance = null;
public static void LoadFromFile(string filename)
{
if (Loaded)
throw new Exception("Config already loaded");
if (File.Exists(filename))
{
using (FileStream fs = File.Open(filename, FileMode.Open))
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Decompress))
Instance = ProtoBuf.Serializer.Deserialize<DepotConfigStore>(ds);
}
else
{
Instance = new DepotConfigStore();
}
Instance.FileName = filename;
}
public static void Save()
{
if (!Loaded)
throw new Exception("Saved config before loading");
using (FileStream fs = File.Open(Instance.FileName, FileMode.Create))
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Compress))
ProtoBuf.Serializer.Serialize<DepotConfigStore>(ds, Instance);
}
}
}

@ -23,7 +23,7 @@ namespace DepotDownloader
DebugLog.Enabled = false;
ConfigStore.LoadFromFile( Path.Combine( Directory.GetCurrentDirectory(), "DepotDownloader.config" ) );
AccountSettingsStore.LoadFromFile( "account.config" );
#region Common Options
@ -191,7 +191,7 @@ namespace DepotDownloader
static bool InitializeSteam( string username, string password )
{
if ( username != null && password == null && ( !ContentDownloader.Config.RememberPassword || !ConfigStore.TheConfig.LoginKeys.ContainsKey( username ) ) )
if ( username != null && password == null && ( !ContentDownloader.Config.RememberPassword || !AccountSettingsStore.Instance.LoginKeys.ContainsKey( username ) ) )
{
do
{

@ -105,16 +105,16 @@ namespace DepotDownloader
if ( authenticatedUser )
{
FileInfo fi = new FileInfo( String.Format( "{0}.sentryFile", logonDetails.Username ) );
if ( ConfigStore.TheConfig.SentryData != null && ConfigStore.TheConfig.SentryData.ContainsKey( logonDetails.Username ) )
if ( AccountSettingsStore.Instance.SentryData != null && AccountSettingsStore.Instance.SentryData.ContainsKey( logonDetails.Username ) )
{
logonDetails.SentryFileHash = Util.SHAHash( ConfigStore.TheConfig.SentryData[ logonDetails.Username ] );
logonDetails.SentryFileHash = Util.SHAHash( AccountSettingsStore.Instance.SentryData[ logonDetails.Username ] );
}
else if ( fi.Exists && fi.Length > 0 )
{
var sentryData = File.ReadAllBytes( fi.FullName );
logonDetails.SentryFileHash = Util.SHAHash( sentryData );
ConfigStore.TheConfig.SentryData[ logonDetails.Username ] = sentryData;
ConfigStore.Save();
AccountSettingsStore.Instance.SentryData[ logonDetails.Username ] = sentryData;
AccountSettingsStore.Save();
}
}
@ -454,7 +454,7 @@ namespace DepotDownloader
DateTime now = new DateTime();
if ( now >= waitUntil ) break;
if ( ConfigStore.TheConfig.LoginKeys.ContainsKey( logonDetails.Username ) ) break;
if ( AccountSettingsStore.Instance.LoginKeys.ContainsKey( logonDetails.Username ) ) break;
callbacks.RunWaitAllCallbacks( TimeSpan.FromMilliseconds( 100 ) );
}
@ -544,8 +544,8 @@ namespace DepotDownloader
}
else if ( isLoginKey )
{
ConfigStore.TheConfig.LoginKeys.Remove( logonDetails.Username );
ConfigStore.Save();
AccountSettingsStore.Instance.LoginKeys.Remove( logonDetails.Username );
AccountSettingsStore.Save();
logonDetails.LoginKey = null;
@ -623,8 +623,8 @@ namespace DepotDownloader
byte[] hash = Util.SHAHash( machineAuth.Data );
Console.WriteLine( "Got Machine Auth: {0} {1} {2} {3}", machineAuth.FileName, machineAuth.Offset, machineAuth.BytesToWrite, machineAuth.Data.Length, hash );
ConfigStore.TheConfig.SentryData[ logonDetails.Username ] = machineAuth.Data;
ConfigStore.Save();
AccountSettingsStore.Instance.SentryData[ logonDetails.Username ] = machineAuth.Data;
AccountSettingsStore.Save();
var authResponse = new SteamUser.MachineAuthDetails
{
@ -651,8 +651,8 @@ namespace DepotDownloader
{
Console.WriteLine( "Accepted new login key for account {0}", logonDetails.Username );
ConfigStore.TheConfig.LoginKeys[ logonDetails.Username ] = loginKey.LoginKey;
ConfigStore.Save();
AccountSettingsStore.Instance.LoginKeys[ logonDetails.Username ] = loginKey.LoginKey;
AccountSettingsStore.Save();
steamUser.AcceptNewLoginKey( loginKey );
}

Loading…
Cancel
Save