Refactored DepotDownloader to use CallbackManager

pull/8/head
azuisleet 14 years ago
parent 6c00c19300
commit 5bc21f183a

@ -294,7 +294,7 @@ namespace DepotDownloader
steam3Credentials = steam3.WaitForCredentials(); steam3Credentials = steam3.WaitForCredentials();
if (!steam3Credentials.HasSessionToken) if (!steam3Credentials.IsValid)
{ {
Console.WriteLine("Unable to get steam3 credentials."); Console.WriteLine("Unable to get steam3 credentials.");
return; return;
@ -311,7 +311,7 @@ namespace DepotDownloader
private static ContentServerClient.Credentials GetSteam2Credentials(uint appId) private static ContentServerClient.Credentials GetSteam2Credentials(uint appId)
{ {
if (steam3 == null || !steam3Credentials.HasSessionToken) if (steam3 == null || !steam3Credentials.IsValid)
{ {
return null; return null;
} }
@ -443,7 +443,7 @@ namespace DepotDownloader
List<IPEndPoint> serverList = steam3.steamClient.GetServersOfType(EServerType.CS); List<IPEndPoint> serverList = steam3.steamClient.GetServersOfType(EServerType.CS);
List<CDNClient.ClientEndPoint> cdnServers = null; List<CDNClient.ClientEndPoint> cdnServers = null;
int tries = 0, counterDeferred = 0, counterCDN = 0; int tries = 0, counterDeferred = 0;
for(int i = 0; ; i++ ) for(int i = 0; ; i++ )
{ {
@ -452,9 +452,8 @@ namespace DepotDownloader
cdnServers = CDNClient.FetchServerList(new CDNClient.ClientEndPoint(endpoint.Address.ToString(), endpoint.Port), Config.CellID); cdnServers = CDNClient.FetchServerList(new CDNClient.ClientEndPoint(endpoint.Address.ToString(), endpoint.Port), Config.CellID);
if (cdnServers == null) counterDeferred++; if (cdnServers == null) counterDeferred++;
else if (cdnServers.Count == 0) counterCDN++;
if (cdnServers != null && cdnServers.Count > 0) if (cdnServers != null && cdnServers.Count((ep) => { return ep.Type == "CS"; }) > 0)
break; break;
if (((i+1) % serverList.Count) == 0) if (((i+1) % serverList.Count) == 0)
@ -465,9 +464,8 @@ namespace DepotDownloader
return; return;
} }
Console.Write("\nSearching for content servers... (deferred: {0}, CDN: {1})", counterDeferred, counterCDN); Console.Write("\nSearching for content servers... (deferred: {0})", counterDeferred);
counterDeferred = 0; counterDeferred = 0;
counterCDN = 0;
Thread.Sleep(1000); Thread.Sleep(1000);
} }
} }
@ -481,11 +479,13 @@ namespace DepotDownloader
Console.WriteLine(" Done!"); Console.WriteLine(" Done!");
Console.Write("Downloading depot manifest..."); Console.Write("Downloading depot manifest...");
List<CDNClient.ClientEndPoint> cdnEndpoints = cdnServers.Where((ep) => { return ep.Type == "CDN"; }).ToList();
List<CDNClient.ClientEndPoint> csEndpoints = cdnServers.Where((ep) => { return ep.Type == "CS"; }).ToList();
CDNClient cdnClient = null; CDNClient cdnClient = null;
foreach (var server in cdnServers) foreach (var server in csEndpoints)
{ {
CDNClient client = new CDNClient(cdnServers[0], steam3.AppTickets[(uint)depotId]); CDNClient client = new CDNClient(server, steam3.AppTickets[(uint)depotId]);
if (client.Connect()) if (client.Connect())
{ {

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

Loading…
Cancel
Save