|
|
|
|
@ -13,9 +13,13 @@ namespace DepotDownloader
|
|
|
|
|
{
|
|
|
|
|
public class Credentials
|
|
|
|
|
{
|
|
|
|
|
public bool HasSessionToken { get; set; }
|
|
|
|
|
public ulong SessionToken { get; set; }
|
|
|
|
|
public byte[] Steam2Ticket { get; set; }
|
|
|
|
|
|
|
|
|
|
public bool IsValid
|
|
|
|
|
{
|
|
|
|
|
get { return SessionToken > 0 && Steam2Ticket != null; }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ReadOnlyCollection<SteamApps.LicenseListCallback.License> Licenses
|
|
|
|
|
@ -34,6 +38,8 @@ namespace DepotDownloader
|
|
|
|
|
SteamUser steamUser;
|
|
|
|
|
SteamApps steamApps;
|
|
|
|
|
|
|
|
|
|
CallbackManager callbacks;
|
|
|
|
|
|
|
|
|
|
bool bConnected;
|
|
|
|
|
bool bAborted;
|
|
|
|
|
DateTime connectTime;
|
|
|
|
|
@ -65,6 +71,13 @@ namespace DepotDownloader
|
|
|
|
|
this.steamUser = this.steamClient.GetHandler<SteamUser>();
|
|
|
|
|
this.steamApps = this.steamClient.GetHandler<SteamApps>();
|
|
|
|
|
|
|
|
|
|
this.callbacks = new CallbackManager(this.steamClient);
|
|
|
|
|
|
|
|
|
|
this.callbacks.Register(new Callback<SteamClient.ConnectedCallback>(ConnectedCallback));
|
|
|
|
|
this.callbacks.Register(new Callback<SteamUser.LoggedOnCallback>(LogOnCallback));
|
|
|
|
|
this.callbacks.Register(new Callback<SteamUser.SessionTokenCallback>(SessionTokenCallback));
|
|
|
|
|
this.callbacks.Register(new Callback<SteamApps.LicenseListCallback>(LicenseListCallback));
|
|
|
|
|
|
|
|
|
|
Console.Write( "Connecting to Steam3..." );
|
|
|
|
|
|
|
|
|
|
Connect();
|
|
|
|
|
@ -72,55 +85,106 @@ namespace DepotDownloader
|
|
|
|
|
|
|
|
|
|
public Credentials WaitForCredentials()
|
|
|
|
|
{
|
|
|
|
|
if (credentials.IsValid || bAborted)
|
|
|
|
|
return credentials;
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
HandleCallbacks();
|
|
|
|
|
WaitForCallbacks();
|
|
|
|
|
}
|
|
|
|
|
while (!bAborted && (credentials.SessionToken == 0 || credentials.Steam2Ticket == null));
|
|
|
|
|
while (!bAborted && !credentials.IsValid);
|
|
|
|
|
|
|
|
|
|
return credentials;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RequestAppInfo(uint appId)
|
|
|
|
|
{
|
|
|
|
|
if (bAborted || AppInfo.ContainsKey(appId))
|
|
|
|
|
if (AppInfo.ContainsKey(appId) || bAborted)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
steamApps.GetAppInfo( new uint[] { appId } );
|
|
|
|
|
Action<SteamApps.AppInfoCallback> cbMethod = appInfo =>
|
|
|
|
|
{
|
|
|
|
|
foreach (var app in appInfo.Apps)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Got AppInfo for {0}: {1}", app.AppID, app.Status);
|
|
|
|
|
AppInfo.Add(app.AppID, app);
|
|
|
|
|
|
|
|
|
|
KeyValue depots;
|
|
|
|
|
if (app.Sections.TryGetValue(EAppInfoSection.Depots, out depots))
|
|
|
|
|
{
|
|
|
|
|
if (depots[app.AppID.ToString()]["OverridesCDDB"].AsBoolean(false))
|
|
|
|
|
{
|
|
|
|
|
AppInfoOverridesCDR[app.AppID] = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using (JobCallback<SteamApps.AppInfoCallback> appInfoCallback = new JobCallback<SteamApps.AppInfoCallback>(steamApps.GetAppInfo(appId), cbMethod, callbacks))
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
HandleCallbacks();
|
|
|
|
|
WaitForCallbacks();
|
|
|
|
|
}
|
|
|
|
|
while (!appInfoCallback.Completed && !bAborted);
|
|
|
|
|
}
|
|
|
|
|
while (!bAborted && !AppInfo.ContainsKey(appId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RequestAppTicket(uint appId)
|
|
|
|
|
{
|
|
|
|
|
if (bAborted || AppTickets.ContainsKey(appId))
|
|
|
|
|
if (AppTickets.ContainsKey(appId) || bAborted)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
steamApps.GetAppOwnershipTicket(appId);
|
|
|
|
|
Action<SteamApps.AppOwnershipTicketCallback> cbMethod = appTicket =>
|
|
|
|
|
{
|
|
|
|
|
if (appTicket.Result != EResult.OK)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Unable to get appticket for {0}: {1}", appTicket.AppID, appTicket.Result);
|
|
|
|
|
Abort();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Got appticket for {0}!", appTicket.AppID);
|
|
|
|
|
AppTickets[appTicket.AppID] = appTicket.Ticket;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using (JobCallback<SteamApps.AppOwnershipTicketCallback> appTicketCallback = new JobCallback<SteamApps.AppOwnershipTicketCallback>(steamApps.GetAppOwnershipTicket(appId), cbMethod, callbacks))
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
HandleCallbacks();
|
|
|
|
|
WaitForCallbacks();
|
|
|
|
|
}
|
|
|
|
|
while (!appTicketCallback.Completed && !bAborted);
|
|
|
|
|
}
|
|
|
|
|
while (!bAborted && !AppTickets.ContainsKey(appId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RequestDepotKey(uint depotId)
|
|
|
|
|
{
|
|
|
|
|
if (bAborted || DepotKeys.ContainsKey(depotId))
|
|
|
|
|
if (DepotKeys.ContainsKey(depotId) || bAborted)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
steamApps.GetDepotDecryptionKey(depotId);
|
|
|
|
|
Action<SteamApps.DepotKeyCallback> cbMethod = depotKey =>
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Got depot key for {0} result: {1}", depotKey.DepotID, depotKey.Result);
|
|
|
|
|
|
|
|
|
|
if (depotKey.Result != EResult.OK)
|
|
|
|
|
{
|
|
|
|
|
Abort();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DepotKeys[depotKey.DepotID] = depotKey.DepotKey;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using (JobCallback<SteamApps.DepotKeyCallback> depotKeyCallback = new JobCallback<SteamApps.DepotKeyCallback>(steamApps.GetDepotDecryptionKey(depotId), cbMethod, callbacks))
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
HandleCallbacks();
|
|
|
|
|
WaitForCallbacks();
|
|
|
|
|
}
|
|
|
|
|
while (!depotKeyCallback.Completed && !bAborted);
|
|
|
|
|
}
|
|
|
|
|
while (!bAborted && !DepotKeys.ContainsKey(depotId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Connect()
|
|
|
|
|
@ -142,24 +206,23 @@ namespace DepotDownloader
|
|
|
|
|
bConnected = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HandleCallbacks()
|
|
|
|
|
{
|
|
|
|
|
while ( true )
|
|
|
|
|
|
|
|
|
|
private void WaitForCallbacks()
|
|
|
|
|
{
|
|
|
|
|
var callback = steamClient.WaitForCallback( true, TimeSpan.FromSeconds( 1 ) );
|
|
|
|
|
callbacks.RunWaitCallbacks( TimeSpan.FromSeconds(1) );
|
|
|
|
|
|
|
|
|
|
TimeSpan diff = DateTime.Now - connectTime;
|
|
|
|
|
|
|
|
|
|
if (diff > STEAM3_TIMEOUT && !bConnected)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Timeout connecting to Steam3.");
|
|
|
|
|
Abort();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( callback == null )
|
|
|
|
|
break;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( callback.IsType<SteamClient.ConnectedCallback>() )
|
|
|
|
|
private void ConnectedCallback(SteamClient.ConnectedCallback connected)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(" Done!");
|
|
|
|
|
bConnected = true;
|
|
|
|
|
@ -167,11 +230,10 @@ namespace DepotDownloader
|
|
|
|
|
|
|
|
|
|
Console.Write("Logging '{0}' into Steam3...", logonDetails.Username);
|
|
|
|
|
}
|
|
|
|
|
else if ( callback.IsType<SteamUser.LoggedOnCallback>() )
|
|
|
|
|
{
|
|
|
|
|
var msg = callback as SteamUser.LoggedOnCallback;
|
|
|
|
|
|
|
|
|
|
if ( msg.Result == EResult.AccountLogonDenied )
|
|
|
|
|
private void LogOnCallback(SteamUser.LoggedOnCallback loggedOn)
|
|
|
|
|
{
|
|
|
|
|
if (loggedOn.Result == EResult.AccountLogonDenied)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("This account is protected by Steam Guard. Please enter the authentication code sent to your email address.");
|
|
|
|
|
Console.Write("Auth Code: ");
|
|
|
|
|
@ -180,90 +242,47 @@ namespace DepotDownloader
|
|
|
|
|
|
|
|
|
|
Console.Write("Retrying Steam3 connection...");
|
|
|
|
|
Connect();
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else if ( msg.Result != EResult.OK )
|
|
|
|
|
else if (loggedOn.Result != EResult.OK)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine( "Unable to login to Steam3: {0}", msg.Result );
|
|
|
|
|
Console.WriteLine("Unable to login to Steam3: {0}", loggedOn.Result);
|
|
|
|
|
Abort();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Console.WriteLine(" Done!");
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Got Steam2 Ticket!");
|
|
|
|
|
credentials.Steam2Ticket = msg.Steam2Ticket;
|
|
|
|
|
credentials.Steam2Ticket = loggedOn.Steam2Ticket;
|
|
|
|
|
|
|
|
|
|
if (ContentDownloader.Config.CellID == 0)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine( "Using Steam3 suggest CellID: " + msg.CellID );
|
|
|
|
|
ContentDownloader.Config.CellID = (int)msg.CellID;
|
|
|
|
|
Console.WriteLine("Using Steam3 suggest CellID: " + loggedOn.CellID);
|
|
|
|
|
ContentDownloader.Config.CellID = (int)loggedOn.CellID;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (callback.IsType<SteamApps.AppOwnershipTicketCallback>())
|
|
|
|
|
{
|
|
|
|
|
var msg = callback as SteamApps.AppOwnershipTicketCallback;
|
|
|
|
|
|
|
|
|
|
if ( msg.Result != EResult.OK )
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine( "Unable to get appticket for {0}: {1}", msg.AppID, msg.Result );
|
|
|
|
|
Abort();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Console.WriteLine( "Got appticket for {0}!", msg.AppID );
|
|
|
|
|
AppTickets[msg.AppID] = msg.Ticket;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (callback.IsType<SteamUser.SessionTokenCallback>())
|
|
|
|
|
private void SessionTokenCallback(SteamUser.SessionTokenCallback sessionToken)
|
|
|
|
|
{
|
|
|
|
|
var msg = callback as SteamUser.SessionTokenCallback;
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Got session token!");
|
|
|
|
|
credentials.SessionToken = msg.SessionToken;
|
|
|
|
|
credentials.HasSessionToken = true;
|
|
|
|
|
}
|
|
|
|
|
else if (callback.IsType<SteamApps.LicenseListCallback>())
|
|
|
|
|
{
|
|
|
|
|
var msg = callback as SteamApps.LicenseListCallback;
|
|
|
|
|
|
|
|
|
|
if ( msg.Result != EResult.OK )
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine( "Unable to get license list: {0} ", msg.Result );
|
|
|
|
|
Abort();
|
|
|
|
|
break;
|
|
|
|
|
credentials.SessionToken = sessionToken.SessionToken;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Console.WriteLine( "Got {0} licenses for account!", msg.LicenseList.Count );
|
|
|
|
|
Licenses = msg.LicenseList;
|
|
|
|
|
}
|
|
|
|
|
else if (callback.IsType<SteamClient.JobCallback<SteamApps.AppInfoCallback>>())
|
|
|
|
|
private void LicenseListCallback(SteamApps.LicenseListCallback licenseList)
|
|
|
|
|
{
|
|
|
|
|
var msg = callback as SteamClient.JobCallback<SteamApps.AppInfoCallback>;
|
|
|
|
|
|
|
|
|
|
foreach (var app in msg.Callback.Apps)
|
|
|
|
|
if (licenseList.Result != EResult.OK)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Got AppInfo for {0}: {1}", app.AppID, app.Status);
|
|
|
|
|
AppInfo.Add(app.AppID, app);
|
|
|
|
|
Console.WriteLine("Unable to get license list: {0} ", licenseList.Result);
|
|
|
|
|
Abort();
|
|
|
|
|
|
|
|
|
|
KeyValue depots;
|
|
|
|
|
if ( app.Sections.TryGetValue( EAppInfoSection.Depots, out depots ) )
|
|
|
|
|
{
|
|
|
|
|
if ( depots[ app.AppID.ToString() ][ "OverridesCDDB" ].AsBoolean( false ) )
|
|
|
|
|
{
|
|
|
|
|
AppInfoOverridesCDR[ app.AppID ] = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else if (callback.IsType<SteamApps.DepotKeyCallback>())
|
|
|
|
|
{
|
|
|
|
|
var msg = callback as SteamApps.DepotKeyCallback;
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Got depot key for {0} result: {1}", msg.DepotID, msg.Result);
|
|
|
|
|
DepotKeys[msg.DepotID] = msg.DepotKey;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Console.WriteLine("Got {0} licenses for account!", licenseList.LicenseList.Count);
|
|
|
|
|
Licenses = licenseList.LicenseList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|