diff --git a/DepotDownloader/CDRManager.cs b/DepotDownloader/CDRManager.cs deleted file mode 100644 index e2e844d2..00000000 --- a/DepotDownloader/CDRManager.cs +++ /dev/null @@ -1,454 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Security.Cryptography; -using SteamKit2; -using SteamKit2.Blob; -using ProtoBuf; -using System.IO.Compression; - -// TODO: make these properties tofix this -#pragma warning disable 649 - -namespace DepotDownloader -{ - [ProtoContract] - class CDR - { - [BlobField(1)] - [ProtoMember(1)] - public List Apps; - - [BlobField(2)] - [ProtoMember(2)] - public List Subs; - } - - [ProtoContract] - class App - { - [BlobField(2)] - [ProtoMember(1)] - public string Name; - - [BlobField(1)] - [ProtoMember(2)] - public int AppID; - - [BlobField(11)] - [ProtoMember(3)] - public int CurrentVersion; - - [BlobField(10)] - [ProtoMember(4)] - public List Versions; - - [BlobField(12)] - [ProtoMember(5)] - public List FileSystems; - - [BlobField(14)] - [ProtoMember(6)] - public Dictionary UserDefined; - - [BlobField(16)] - [ProtoMember(7)] - public int BetaVersion; - } - - [ProtoContract] - class Sub - { - [BlobField(1)] - [ProtoMember(1)] - public int SubID; - - [BlobField(6)] - [ProtoMember(2)] - public List AppIDs; - } - - [ProtoContract] - class AppVersion - { - [BlobField(2)] - [ProtoMember(1)] - public uint VersionID; - - [BlobField(5)] - [ProtoMember(2)] - public string DepotEncryptionKey; - - [BlobField(6)] - [ProtoMember(3)] - public bool IsEncryptionKeyAvailable; - } - - [ProtoContract] - class FileSystem - { - [BlobField(1)] - [ProtoMember(1)] - public int AppID; - - [BlobField(2)] - [ProtoMember(2)] - public string Name; - - [BlobField(4)] - [ProtoMember(3)] - public string Platform; - } - - static class CDRManager - { - const string CDR_FILENAME = "cdr.proto"; - - static CDR cdrObj; - - public static void Update() - { - Console.Write( "Updating CDR..." ); - - var hasCachedCDR = File.Exists(CDR_FILENAME); - - if (DateTime.Now > ConfigCache.Instance.CDRCacheTime || !hasCachedCDR) - { - byte[] cdrHash = hasCachedCDR ? ConfigCache.Instance.CDRHash : null; - - foreach (var configServer in ServerCache.ConfigServers) - { - try - { - ConfigServerClient csClient = new ConfigServerClient(); - csClient.Connect(configServer); - - byte[] tempCdr = csClient.GetContentDescriptionRecord(cdrHash); - - if (tempCdr == null) - continue; - - if (tempCdr.Length == 0) - break; - - using (MemoryStream ms = new MemoryStream(tempCdr)) - using (BlobReader reader = BlobReader.CreateFrom(ms)) - cdrObj = (CDR)BlobTypedReader.Deserialize(reader, typeof(CDR)); - - using (FileStream fs = File.Open(CDR_FILENAME, FileMode.Create)) - using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Compress)) - ProtoBuf.Serializer.Serialize(ds, cdrObj); - - ConfigCache.Instance.CDRHash = SHAHash(tempCdr); - ConfigCache.Instance.CDRCacheTime = DateTime.Now.AddMinutes(30); - ConfigCache.Instance.Save(ConfigCache.CONFIG_FILENAME); - break; - } - catch (Exception e) - { - Console.WriteLine("Warning: Unable to download CDR from config server {0}: {1}", configServer, e.Message); - } - } - - if(cdrObj != null) - { - Console.WriteLine(" Done!"); - return; - } - else if (!File.Exists(CDR_FILENAME)) - { - Console.WriteLine("Error: Unable to download CDR!"); - return; - } - } - - using (FileStream fs = File.Open(CDR_FILENAME, FileMode.Open)) - using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Decompress)) - cdrObj = ProtoBuf.Serializer.Deserialize(ds); - - Console.WriteLine(" Done!"); - } - - static App GetAppBlob( int appID ) - { - return cdrObj.Apps.Find( app => app.AppID == appID ); - } - - static Sub GetSubBlob( int subID ) - { - return cdrObj.Subs.Find( sub => sub.SubID == subID ); - } - - public static string GetDepotName( int depotId ) - { - // Match hardcoded names from hldsupdatetool for certain HL1 depots - if ( depotId == 1 ) - return "Half-Life Base Content"; - else if ( depotId == 4 ) - return "Linux Server Engine"; - else if ( depotId == 5 ) - return "Win32 Server Engine"; - - App app = GetAppBlob( depotId ); - - if ( app == null ) - { - return null; - } - - return app.Name; - } - - public static int GetLatestDepotVersion( int depotId, bool beta ) - { - App app = GetAppBlob( depotId ); - - if ( app == null ) - { - return -1; - } - - if ( beta && app.BetaVersion > app.CurrentVersion ) - return app.BetaVersion; - - return app.CurrentVersion; - } - - public static byte[] GetDepotEncryptionKey( int depotId, int version ) - { - App app = GetAppBlob( depotId ); - - if ( app == null ) - { - return null; - } - - foreach ( AppVersion ver in app.Versions ) - { - if ( ver.VersionID == version ) - { - if ( ver.IsEncryptionKeyAvailable ) - return DecodeHexString( ver.DepotEncryptionKey ); - break; - } - } - - return null; - } - - static byte[] DecodeHexString( string hex ) - { - if ( hex == null ) - return null; - - int chars = hex.Length; - byte[] bytes = new byte[ chars / 2 ]; - - for ( int i = 0 ; i < chars ; i += 2 ) - bytes[ i / 2 ] = Convert.ToByte( hex.Substring( i, 2 ), 16 ); - - return bytes; - } - - public static List GetDepotIDsForApp( int appId, bool allPlatforms ) - { - List depotIDs = new List(); - - App appInfoBlob = GetAppBlob( appId ); - - if ( appInfoBlob == null ) - { - return null; - } - - PlatformID platform = Environment.OSVersion.Platform; - string platformStr = ""; - - if ( platform == PlatformID.Win32NT ) - platformStr = "windows"; - else if ( Util.IsMacOSX() ) - platformStr = "macos"; - - if (appInfoBlob.FileSystems == null) - return depotIDs; - - foreach ( var blobField in appInfoBlob.FileSystems ) - { - string depotPlatform = blobField.Platform; - - if ( depotPlatform == null || - depotPlatform.Contains( platformStr ) || - allPlatforms ) - { - depotIDs.Add( blobField.AppID ); - } - } - - return depotIDs; - } - - public static List GetDepotIDsForGameserver( string gameName, bool allPlatforms ) - { - List appIDs = new List(); - - App serverAppInfoBlob = GetAppBlob( 4 ); - - PlatformID platform = Environment.OSVersion.Platform; - bool goldSrc = false; - - if ( gameName.Equals( "valve", StringComparison.OrdinalIgnoreCase ) ) - goldSrc = true; - else - { - string platformSuffix = ""; - int gameLen = gameName.Length; - - if (platform == PlatformID.Win32NT) - platformSuffix = "-win32"; - else if (platform == PlatformID.Unix && !Util.IsMacOSX()) - platformSuffix = "-linux"; - - foreach (var blobField in serverAppInfoBlob.FileSystems) - { - string mountName = blobField.Name; - - if (String.Compare(mountName, 0, gameName, 0, gameLen, true) == 0) - { - string suffix = mountName.Substring(gameLen); - - if (suffix == "" || - suffix == platformSuffix || - allPlatforms && (suffix == "-win32" || suffix == "-linux")) - { - if ( blobField.AppID < 200 ) - goldSrc = true; - - appIDs.Add( blobField.AppID ); - } - } - } - - } - - // For HL1 server installs, this is hardcoded in hldsupdatetool - if ( goldSrc ) - { - // Win32 or Linux Server Engine - if ( allPlatforms ) - { - appIDs.Add( 4 ); - appIDs.Add( 5 ); - } - else if ( platform == PlatformID.Win32NT ) - appIDs.Add( 5 ); - else if ( platform == PlatformID.Unix && !Util.IsMacOSX() ) - appIDs.Add( 4 ); - - // Half-Life Base Content - appIDs.Add( 1 ); - } - - return appIDs; - } - - public static string GetDedicatedServerFolder( int depotId ) - { - App app = GetAppBlob( depotId ); - - if (app == null || app.UserDefined == null ) - return null; - - foreach ( var entry in app.UserDefined ) - { - if ( entry.Key.Equals( "dedicatedserverfolder", StringComparison.OrdinalIgnoreCase ) ) - { - return entry.Value; - } - } - - return null; - } - - public static void ListGameServers() - { - App serverAppInfoBlob = GetAppBlob( 4 ); - - List sourceGames = new List(); - List hl1Games = new List(); - List thirdPartyGames = new List(); - - // Hardcoded in hldsupdatetool - hl1Games.Add( "valve" ); - - foreach ( var blobField in serverAppInfoBlob.FileSystems ) - { - int id = blobField.AppID; - string name = blobField.Name; - - int suffixPos = name.LastIndexOf( "-win32" ); - - if ( suffixPos == -1 ) - suffixPos = name.LastIndexOf( "-linux" ); - - if ( suffixPos > 0 ) - name = name.Remove( suffixPos ); - - // These numbers come from hldsupdatetool - if ( id < 1000 ) - { - if ( id < 200 ) - { - if ( !hl1Games.Contains( name ) ) - hl1Games.Add( name ); - } - else - { - if ( !sourceGames.Contains( name ) ) - sourceGames.Add( name ); - } - } - else - { - if ( !thirdPartyGames.Contains( name ) ) - thirdPartyGames.Add( name ); - } - } - - sourceGames.Sort( StringComparer.Ordinal ); - hl1Games.Sort( StringComparer.Ordinal ); - thirdPartyGames.Sort( StringComparer.Ordinal ); - - Console.WriteLine( "** 'game' options for Source DS install:\n" ); - foreach ( string game in sourceGames ) - Console.WriteLine( "\t\"{0}\"", game ); - - Console.WriteLine( "\n** 'game' options for HL1 DS install:\n"); - foreach ( string game in hl1Games ) - Console.WriteLine( "\t\"{0}\"", game ); - - Console.WriteLine( "\n** 'game' options for Third-Party game servers:\n" ); - foreach ( string game in thirdPartyGames ) - Console.WriteLine( "\t\"{0}\"", game ); - } - - public static bool SubHasDepot( int subId, int depotId ) - { - Sub sub = GetSubBlob( subId ); - - if ( sub == null ) - return false; - - return sub.AppIDs.Contains( depotId ); - } - - static byte[] SHAHash( byte[] data ) - { - using ( SHA1Managed sha = new SHA1Managed() ) - { - byte[] output = sha.ComputeHash( data ); - - return output; - } - } - } -} diff --git a/DepotDownloader/ConfigCache.cs b/DepotDownloader/ConfigCache.cs deleted file mode 100644 index 7f73235f..00000000 --- a/DepotDownloader/ConfigCache.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using ProtoBuf; -using System.IO; -using System.IO.Compression; -using System.Net; - -namespace DepotDownloader -{ - [ProtoContract] - class ConfigCache - { - public const string CONFIG_FILENAME = "config.proto"; - public static ConfigCache Instance = Load(CONFIG_FILENAME); - - [ProtoContract] - class IPEndpointSurrogate - { - [ProtoMember(1)] - private byte[] address; - [ProtoMember(2)] - private int port; - - public IPEndpointSurrogate() - { - } - - public IPEndpointSurrogate(byte[] address, int port) - { - this.address = address; - this.port = port; - } - - public static implicit operator IPEndPoint(IPEndpointSurrogate ip) - { - if (ip == null || ip.address == null) - return null; - - return new IPEndPoint(new IPAddress(ip.address), ip.port); - } - - public static implicit operator IPEndpointSurrogate(IPEndPoint ip) - { - if (ip == null) - return null; - - return new IPEndpointSurrogate(ip.Address.GetAddressBytes(), ip.Port); - } - } - - [ProtoMember(1)] - public byte[] CDRHash { get; set; } - [ProtoMember(2)] - public DateTime CDRCacheTime { get; set; } - - [ProtoMember(3)] - public ServerList ConfigServers { get; set; } - [ProtoMember(4)] - public ServerList CSDSServers { get; set; } - [ProtoMember(5)] - public DateTime ServerCacheTime { get; set; } - - public static ConfigCache Load(string filename) - { - ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(IPEndPoint), true).SetSurrogate(typeof(IPEndpointSurrogate)); - - if(!File.Exists(filename)) - return new ConfigCache(); - - try - { - using (FileStream fs = File.Open(filename, FileMode.Open)) - using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Decompress)) - return ProtoBuf.Serializer.Deserialize(ds); - } - catch (IOException) - { - File.Delete(filename); - } - catch (Exception e) - { - Console.WriteLine("Unable to load config cache: {0}", e.Message); - } - - return new ConfigCache(); - } - - public void Save(string filename) - { - try - { - using (FileStream fs = File.Open(filename, FileMode.Create)) - using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Compress)) - ProtoBuf.Serializer.Serialize(ds, this); - } - catch (IOException) - { - } - } - } -} diff --git a/DepotDownloader/ContentDownloader.cs b/DepotDownloader/ContentDownloader.cs index 4f447235..2c3b1d8a 100644 --- a/DepotDownloader/ContentDownloader.cs +++ b/DepotDownloader/ContentDownloader.cs @@ -24,45 +24,16 @@ namespace DepotDownloader private static Steam3Session steam3; private static Steam3Session.Credentials steam3Credentials; - private static IPEndPoint lastSteam2ContentServer; - - private abstract class IDepotDownloadInfo - { - public int id { get; protected set; } - public string installDir { get; protected set; } - public string contentName { get; protected set; } - - public abstract DownloadSource GetDownloadType(); - } - - private sealed class DepotDownloadInfo2 : IDepotDownloadInfo + private sealed class DepotDownloadInfo { - public int version { get; private set; } - - public IPEndPoint[] contentServers = null; - public Steam2Manifest manifest = null; - public List NodesToDownload = new List(); - public byte[] cryptKey = null; - - public override DownloadSource GetDownloadType() { return DownloadSource.Steam2; } - - public DepotDownloadInfo2(int id, int version, string installDir, string contentName) - { - this.id = id; - this.version = version; - this.installDir = installDir; - this.contentName = contentName; - } - } + public int id { get; private set; } + public string installDir { get; private set; } + public string contentName { get; private set; } - private sealed class DepotDownloadInfo3 : IDepotDownloadInfo - { public ulong manifestId { get; private set; } public byte[] depotKey; - public override DownloadSource GetDownloadType() { return DownloadSource.Steam3; } - - public DepotDownloadInfo3(int depotid, ulong manifestId, string installDir, string contentName) + public DepotDownloadInfo(int depotid, ulong manifestId, string installDir, string contentName) { this.id = depotid; this.manifestId = manifestId; @@ -71,7 +42,7 @@ namespace DepotDownloader } } - static bool CreateDirectories( int depotId, uint depotVersion, DownloadSource source, out string installDir ) + static bool CreateDirectories( int depotId, uint depotVersion, out string installDir ) { installDir = null; try @@ -91,16 +62,6 @@ namespace DepotDownloader Directory.CreateDirectory(ContentDownloader.Config.InstallDirectory); installDir = ContentDownloader.Config.InstallDirectory; - - if (source == DownloadSource.Steam2) - { - string serverFolder = CDRManager.GetDedicatedServerFolder(depotId); - if (serverFolder != null && serverFolder != "") - { - installDir = Path.Combine(ContentDownloader.Config.InstallDirectory, serverFolder); - Directory.CreateDirectory(installDir); - } - } } } catch @@ -111,63 +72,6 @@ namespace DepotDownloader return true; } - static string[] GetExcludeList( ContentServerClient.StorageSession session, Steam2Manifest manifest ) - { - string[] excludeList = null; - - for ( int x = 0 ; x < manifest.Nodes.Count ; ++x ) - { - var dirEntry = manifest.Nodes[ x ]; - if ( dirEntry.Name == "exclude.lst" && - dirEntry.FullName.StartsWith( "reslists" + Path.DirectorySeparatorChar ) && - ( dirEntry.Attributes & Steam2Manifest.Node.Attribs.EncryptedFile ) == 0 ) - { - string excludeFile = Encoding.UTF8.GetString( session.DownloadFile( dirEntry ) ); - if ( Environment.OSVersion.Platform == PlatformID.Win32NT ) - excludeFile = excludeFile.Replace( '/', Path.DirectorySeparatorChar ); - else - excludeFile = excludeFile.Replace( '\\', Path.DirectorySeparatorChar ); - excludeList = excludeFile.Split( new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries ); - break; - } - } - - return excludeList; - } - - static bool IsFileExcluded( string file, string[] excludeList ) - { - if ( excludeList == null || file.Length < 1 ) - return false; - - foreach ( string e in excludeList ) - { - int wildPos = e.IndexOf( "*" ); - - if ( wildPos == -1 ) - { - if ( file.StartsWith( e ) ) - return true; - continue; - } - - if ( wildPos == 0 ) - { - if ( e.Length == 1 || file.EndsWith( e.Substring( 1 ) ) ) - return true; - continue; - } - - string start = e.Substring( 0, wildPos ); - string end = e.Substring( wildPos + 1, e.Length - wildPos - 1 ); - - if ( file.StartsWith( start ) && file.EndsWith( end ) ) - return true; - } - - return false; - } - static bool TestIsFileIncluded(string filename) { if (!Config.UsingFileList) @@ -193,7 +97,7 @@ namespace DepotDownloader static bool AccountHasAccess( int depotId, bool appId=false ) { if ( steam3 == null || (steam3.Licenses == null && steam3.steamUser.SteamID.AccountType != EAccountType.AnonUser) ) - return CDRManager.SubHasDepot( 0, depotId ); + return false; IEnumerable licenseQuery; if ( steam3.steamUser.SteamID.AccountType == EAccountType.AnonUser ) @@ -221,47 +125,11 @@ namespace DepotDownloader return true; } } - - if ( CDRManager.SubHasDepot( ( int )license, depotId ) ) - return true; } return false; } - static bool AppIsSteam3(int appId) - { - if (steam3 == null || steam3.AppInfoOverridesCDR == null) - { - return false; - } - - steam3.RequestAppInfo((uint)appId); - - bool app_override; - if(!steam3.AppInfoOverridesCDR.TryGetValue((uint)appId, out app_override)) - return false; - - KeyValue depots = GetSteam3AppSection(appId, EAppInfoSection.Depots); - foreach (KeyValue depotChild in depots.Children) - { - if (depotChild == null) - return false; - - int id; - if (!int.TryParse(depotChild.Name, out id)) - continue; - - var nodes = depotChild["manifests"].Children; - var nodes_encrypted = depotChild["encryptedmanifests"].Children; - - if (nodes.Count == 0 && nodes_encrypted.Count == 0) - return false; - } - - return true; - } - internal static KeyValue GetSteam3AppSection( int appId, EAppInfoSection section ) { if (steam3 == null || steam3.AppInfo == null) @@ -300,30 +168,6 @@ namespace DepotDownloader return section_kv; } - enum DownloadSource - { - Steam2, - Steam3 - } - - static DownloadSource GetAppDownloadSource(int appId) - { - if (appId == -1 || !AppIsSteam3(appId)) - return DownloadSource.Steam2; - - KeyValue config = GetSteam3AppSection(appId, EAppInfoSection.Config); - int contenttype = config["contenttype"].AsInteger(0); - - // EContentDownloadSourceType? - if (contenttype != 3) - { - Console.WriteLine("Warning: App {0} does not advertise contenttype as steam3, but has steam3 depots", appId); - } - - return DownloadSource.Steam3; - } - - static uint GetSteam3AppChangeNumber(int appId) { if (steam3 == null || steam3.AppInfo == null) @@ -342,7 +186,7 @@ namespace DepotDownloader static uint GetSteam3AppBuildNumber(int appId, string branch) { - if (appId == -1 || !AppIsSteam3(appId)) + if (appId == -1) return 0; @@ -363,7 +207,7 @@ namespace DepotDownloader static ulong GetSteam3DepotManifest(int depotId, int appId, string branch) { - if (appId == -1 || !AppIsSteam3(appId)) + if (appId == -1) return 0; KeyValue depots = GetSteam3AppSection(appId, EAppInfoSection.Depots); @@ -416,11 +260,7 @@ namespace DepotDownloader static string GetAppOrDepotName(int depotId, int appId) { - if (appId == -1 || !AppIsSteam3(appId)) - { - return CDRManager.GetDepotName(depotId); - } - else if (depotId == -1) + if (depotId == -1) { KeyValue info = GetSteam3AppSection(appId, EAppInfoSection.Common); @@ -474,22 +314,7 @@ namespace DepotDownloader steam3.Disconnect(); } - private static ContentServerClient.Credentials GetSteam2Credentials(uint appId) - { - if (steam3 == null || !steam3Credentials.IsValid) - { - return null; - } - - return new ContentServerClient.Credentials() - { - Steam2Ticket = steam3Credentials.Steam2Ticket, - AppTicket = steam3.AppTickets[appId], - SessionToken = steam3Credentials.SessionToken, - }; - } - - public static void DownloadApp(int appId, int depotId, string branch, bool bListOnly=false) + public static void DownloadApp(int appId, int depotId, string branch) { if(steam3 != null) steam3.RequestAppInfo((uint)appId); @@ -501,30 +326,20 @@ namespace DepotDownloader return; } - List depotIDs = null; + var depotIDs = new List(); + KeyValue depots = GetSteam3AppSection(appId, EAppInfoSection.Depots); - if (AppIsSteam3(appId)) + if (depots != null) { - depotIDs = new List(); - KeyValue depots = GetSteam3AppSection(appId, EAppInfoSection.Depots); - - if (depots != null) + foreach (var child in depots.Children) { - foreach (var child in depots.Children) + int id = -1; + if (int.TryParse(child.Name, out id) && child.Children.Count > 0 && (depotId == -1 || id == depotId)) { - int id = -1; - if (int.TryParse(child.Name, out id) && child.Children.Count > 0 && (depotId == -1 || id == depotId)) - { - depotIDs.Add(id); - } + depotIDs.Add(id); } } } - else - { - // steam2 path - depotIDs = CDRManager.GetDepotIDsForApp(appId, Config.DownloadAllPlatforms); - } if (depotIDs == null || (depotIDs.Count == 0 && depotId == -1)) { @@ -537,105 +352,22 @@ namespace DepotDownloader return; } - if ( bListOnly ) - { - Console.WriteLine( "\n {0} Depots:", appId ); - - foreach ( var depot in depotIDs ) - { - var depotName = CDRManager.GetDepotName( depot ); - Console.WriteLine( "{0} - {1}", depot, depotName ); - } - - return; - } - - var infos2 = new List(); - var infos3 = new List(); + var infos = new List(); foreach (var depot in depotIDs) { - int depotVersion = 0; - - if ( !AppIsSteam3( appId ) ) - { - // Steam2 dependency - depotVersion = CDRManager.GetLatestDepotVersion(depot, Config.PreferBetaVersions); - if (depotVersion == -1) - { - Console.WriteLine("Error: Unable to find DepotID {0} in the CDR!", depot); - return; - } - } - - IDepotDownloadInfo info = GetDepotInfo(depot, depotVersion, appId, branch); + DepotDownloadInfo info = GetDepotInfo(depot, appId, branch); if (info != null) { - if (info.GetDownloadType() == DownloadSource.Steam2) - infos2.Add((DepotDownloadInfo2)info); - else if (info.GetDownloadType() == DownloadSource.Steam3) - infos3.Add((DepotDownloadInfo3)info); + infos.Add(info); } } - if( infos2.Count() > 0 ) - DownloadSteam2( infos2 ); - - if( infos3.Count() > 0 ) - DownloadSteam3( infos3 ); - } - - public static void DownloadDepotsForGame(string game, string branch) - { - var infos2 = new List(); - var infos3 = new List(); - List depotIDs = CDRManager.GetDepotIDsForGameserver(game, ContentDownloader.Config.DownloadAllPlatforms); - foreach (var depot in depotIDs) - { - int depotVersion = CDRManager.GetLatestDepotVersion(depot, ContentDownloader.Config.PreferBetaVersions); - if (depotVersion == -1) - { - Console.WriteLine("Error: Unable to find DepotID {0} in the CDR!", depot); - ContentDownloader.ShutdownSteam3(); - continue; - } - - IDepotDownloadInfo info = GetDepotInfo(depot, depotVersion, 0, branch); - if (info.GetDownloadType() == DownloadSource.Steam2) - { - infos2.Add((DepotDownloadInfo2)info); - } - else if (info.GetDownloadType() == DownloadSource.Steam3) - { - infos3.Add((DepotDownloadInfo3)info); - } - } - - if (infos2.Count() > 0) - DownloadSteam2(infos2); - - if (infos3.Count() > 0) - DownloadSteam3(infos3); - } - - public static void DownloadDepot(int depotId, int depotVersion, string branch, int appId = 0) - { - IDepotDownloadInfo info = GetDepotInfo(depotId, depotVersion, appId, branch); - if (info.GetDownloadType() == DownloadSource.Steam2) - { - var infos = new List(); - infos.Add((DepotDownloadInfo2)info); - DownloadSteam2(infos); - } - else if (info.GetDownloadType() == DownloadSource.Steam3) - { - var infos = new List(); - infos.Add((DepotDownloadInfo3)info); - DownloadSteam3(infos); - } + if( infos.Count() > 0 ) + DownloadSteam3( infos ); } - static IDepotDownloadInfo GetDepotInfo(int depotId, int depotVersion, int appId, string branch) + static DepotDownloadInfo GetDepotInfo(int depotId, int appId, string branch) { if(steam3 != null && appId > 0) steam3.RequestAppInfo((uint)appId); @@ -649,17 +381,10 @@ namespace DepotDownloader return null; } - DownloadSource source = GetAppDownloadSource(appId); - - uint uVersion = (uint)depotVersion; - - if (source == DownloadSource.Steam3) - { - uVersion = GetSteam3AppBuildNumber(appId, branch); - } + uint uVersion = GetSteam3AppBuildNumber(appId, branch); string installDir; - if (!CreateDirectories(depotId, uVersion, source, out installDir)) + if (!CreateDirectories(depotId, uVersion, out installDir)) { Console.WriteLine("Error: Unable to create install directories!"); return null; @@ -668,37 +393,28 @@ namespace DepotDownloader if(steam3 != null) steam3.RequestAppTicket((uint)depotId); - if (source == DownloadSource.Steam3) + ulong manifestID = GetSteam3DepotManifest(depotId, appId, branch); + if (manifestID == 0) { - ulong manifestID = GetSteam3DepotManifest(depotId, appId, branch); - if (manifestID == 0) - { - Console.WriteLine("Depot {0} ({1}) missing public subsection or manifest section.", depotId, contentName); - return null; - } - - steam3.RequestDepotKey( ( uint )depotId, ( uint )appId ); - if (!steam3.DepotKeys.ContainsKey((uint)depotId)) - { - Console.WriteLine("No valid depot key for {0}, unable to download.", depotId); - return null; - } - - byte[] depotKey = steam3.DepotKeys[(uint)depotId]; - - var info = new DepotDownloadInfo3( depotId, manifestID, installDir, contentName ); - info.depotKey = depotKey; - return info; + Console.WriteLine("Depot {0} ({1}) missing public subsection or manifest section.", depotId, contentName); + return null; } - else + + steam3.RequestDepotKey( ( uint )depotId, ( uint )appId ); + if (!steam3.DepotKeys.ContainsKey((uint)depotId)) { - // steam2 path - var info = new DepotDownloadInfo2(depotId, depotVersion, installDir, contentName); - return info; + Console.WriteLine("No valid depot key for {0}, unable to download.", depotId); + return null; } + + byte[] depotKey = steam3.DepotKeys[(uint)depotId]; + + var info = new DepotDownloadInfo( depotId, manifestID, installDir, contentName ); + info.depotKey = depotKey; + return info; } - private static void DownloadSteam3( List depots ) + private static void DownloadSteam3( List depots ) { foreach (var depot in depots) { @@ -908,245 +624,6 @@ namespace DepotDownloader } } - private static ContentServerClient.StorageSession GetSteam2StorageSession(IPEndPoint [] contentServers, ContentServerClient csClient, int depotId, int depotVersion) - { - ContentServerClient.StorageSession session = null; - if (csClient.IsConnected && contentServers.Contains(lastSteam2ContentServer)) - { - try - { - session = csClient.OpenStorage( (uint)depotId, (uint)depotVersion, (uint)Config.CellID, null, false ); - - return session; - } - catch ( Steam2Exception ) - { - csClient.Disconnect(); - } - } - - int tries = 0; - int counterSocket = 0, counterSteam2 = 0; - for (int i = 0; ; i++) - { - IPEndPoint endpoint = contentServers[i % contentServers.Length]; - - try - { - csClient.Connect( endpoint ); - session = csClient.OpenStorage( (uint)depotId, (uint)depotVersion, (uint)Config.CellID, GetSteam2Credentials( (uint)depotId ), true ); - lastSteam2ContentServer = endpoint; - break; - } - catch ( SocketException ) - { - counterSocket++; - } - catch ( Steam2Exception ) - { - csClient.Disconnect(); - counterSteam2++; - } - - if (((i + 1) % contentServers.Length) == 0) - { - if (++tries > MAX_CONNECT_RETRIES) - { - Console.WriteLine("\nGiving up finding Steam2 content server."); - return null; - } - - Console.WriteLine("\nSearching for content servers... (socket error: {0}, steam2 error: {1})", counterSocket, counterSteam2); - counterSocket = 0; - counterSteam2 = 0; - Thread.Sleep(1000); - } - } - return session; - } - private static void DownloadSteam2( List depots ) - { - Console.WriteLine("Found depots:"); - foreach (var depot in depots) - { - Console.WriteLine("- {0}\t{1} (version {2})", depot.id, depot.contentName, depot.version); - } - - Console.Write("Finding content servers..."); - foreach( var depot in depots ) - { - depot.contentServers = GetStorageServer(depot.id, depot.version, Config.CellID); - if (depot.contentServers == null || depot.contentServers.Length == 0) - { - Console.WriteLine("\nError: Unable to find any Steam2 content servers for depot {0}, version {1}", depot.id, depot.version); - return; - } - } - - Console.WriteLine(" Done!"); - - ContentServerClient csClient = new ContentServerClient(); - csClient.ConnectionTimeout = TimeSpan.FromSeconds(STEAM2_CONNECT_TIMEOUT_SECONDS); - - ContentServerClient.StorageSession session; - - foreach (var depot in depots) - { - session = GetSteam2StorageSession(depot.contentServers, csClient, depot.id, depot.version); - if (session == null) - continue; - - Console.Write(String.Format("Downloading manifest for depot {0}...", depot.id)); - - string txtManifest = Path.Combine(depot.installDir, string.Format("manifest_{0}.txt", depot.id)); - Steam2ChecksumData checksums = null; - StringBuilder manifestBuilder = new StringBuilder(); - string[] excludeList = null; - - depot.cryptKey = CDRManager.GetDepotEncryptionKey(depot.id, depot.version); - depot.manifest = session.DownloadManifest(); - - Console.WriteLine(" Done!"); - - if (Config.UsingExclusionList) - excludeList = GetExcludeList(session, depot.manifest); - - // Build a list of files that need downloading. - for (int x = 0; x < depot.manifest.Nodes.Count; ++x) - { - var dirEntry = depot.manifest.Nodes[x]; - string downloadPath = Path.Combine(depot.installDir, dirEntry.FullName.ToLower()); - if (Config.DownloadManifestOnly) - { - if (dirEntry.FileID == -1) - continue; - - manifestBuilder.Append(string.Format("{0}\n", dirEntry.FullName)); - continue; - } - if (Config.UsingExclusionList && IsFileExcluded(dirEntry.FullName, excludeList)) - continue; - - if (!TestIsFileIncluded(dirEntry.FullName)) - continue; - - string path = Path.GetDirectoryName(downloadPath); - - if (path != "" && !Directory.Exists(path)) - Directory.CreateDirectory(path); - - if ( dirEntry.FileID == -1 ) - { - if ( !Directory.Exists( downloadPath ) ) - { - // this is a directory, so lets just create it - Directory.CreateDirectory( downloadPath ); - } - - continue; - } - - if (checksums == null) - { - // Skip downloading checksums if we're only interested in manifests. - Console.Write(String.Format("Downloading checksums for depot {0}...", depot.id)); - - checksums = session.DownloadChecksums(); - - Console.WriteLine(" Done!"); - } - - FileInfo fi = new FileInfo(downloadPath); - if (fi.Exists) - { - // Similar file, let's check checksums - if (fi.Length == dirEntry.SizeOrCount && - Util.ValidateSteam2FileChecksums(fi, checksums.GetFileChecksums(dirEntry.FileID))) - { - // checksums OK - float perc = ((float)x / (float)depot.manifest.Nodes.Count) * 100.0f; - Console.WriteLine("{0,6:#00.00}%\t{1}", perc, downloadPath); - - continue; - } - // Unlink the current file before we download a new one. - // This will keep symbolic/hard link targets from being overwritten. - fi.Delete(); - } - depot.NodesToDownload.Add(x); - } - - if (Config.DownloadManifestOnly) - { - File.WriteAllText(txtManifest, manifestBuilder.ToString()); - return; - } - } - - foreach( var depot in depots ) - { - Console.Write("Downloading requested files from depot {0}... ", depot.id); - if ( depot.NodesToDownload.Count == 0 ) - Console.WriteLine("none needed."); - else - Console.WriteLine(); - - session = GetSteam2StorageSession(depot.contentServers, csClient, depot.id, depot.version); - if(session == null) - continue; - - for ( int x = 0 ; x < depot.NodesToDownload.Count ; ++x ) - { - var dirEntry = depot.manifest.Nodes[ depot.NodesToDownload[ x ] ]; - string downloadPath = Path.Combine( depot.installDir, dirEntry.FullName.ToLower() ); - - float perc = ( ( float )x / ( float )depot.NodesToDownload.Count ) * 100.0f; - Console.WriteLine("{0,6:#00.00}%\t{1}", perc, downloadPath); - - using (var fs = new FileStream(downloadPath, FileMode.Create)) - { - session.DownloadFileToStream(dirEntry, fs, ContentServerClient.StorageSession.DownloadPriority.High, depot.cryptKey); - } - } - } - csClient.Disconnect(); - - } - - static IPEndPoint[] GetStorageServer( int depotId, int depotVersion, int cellId ) - { - foreach ( IPEndPoint csdServer in ServerCache.CSDSServers ) - { - ContentServer[] servers; - - try - { - ContentServerDSClient csdsClient = new ContentServerDSClient(); - csdsClient.Connect( csdServer ); - - servers = csdsClient.GetContentServerList( (uint)depotId, (uint)depotVersion, (uint)cellId ); - } - catch ( SocketException ) - { - servers = null; - continue; - } - - if ( servers == null ) - { - Console.WriteLine( "Warning: CSDS {0} rejected the given depotid or version!", csdServer ); - continue; - } - - if ( servers.Length == 0 ) - continue; - - return servers.OrderBy(x => x.Load).Select(x => x.StorageServer).ToArray(); - } - - return null; - } - static string EncodeHexString( byte[] input ) { return input.Aggregate( new StringBuilder(), diff --git a/DepotDownloader/Program.cs b/DepotDownloader/Program.cs index 7fff21bb..2efceda8 100644 --- a/DepotDownloader/Program.cs +++ b/DepotDownloader/Program.cs @@ -8,7 +8,6 @@ namespace DepotDownloader { class Program { - static void Main( string[] args ) { if ( args.Length == 0 ) @@ -19,40 +18,14 @@ namespace DepotDownloader DebugLog.Enabled = false; - ServerCache.Build(); - CDRManager.Update(); - - if (HasParameter( args, "-list" ) ) - { - CDRManager.ListGameServers(); - return; - } - - bool bGameserver = true; - bool bApp = false; - bool bListDepots = HasParameter(args, "-listdepots"); bool bDumpManifest = HasParameter( args, "-manifest" ); + int appId = GetIntParameter( args, "-app" ); + int depotId = GetIntParameter( args, "-depot" ); - int appId = -1; - int depotId = -1; - string gameName = GetStringParameter( args, "-game" ); - - if ( gameName == null ) + if ( appId == -1 ) { - appId = GetIntParameter( args, "-app" ); - bGameserver = false; - - depotId = GetIntParameter( args, "-depot" ); - - if ( depotId == -1 && appId == -1 ) - { - Console.WriteLine( "Error: -game, -app, or -depot not specified!" ); - return; - } - else if ( appId >= 0 ) - { - bApp = true; - } + Console.WriteLine( "Error: -app not specified!" ); + return; } ContentDownloader.Config.DownloadManifestOnly = bDumpManifest; @@ -70,39 +43,6 @@ namespace DepotDownloader ContentDownloader.Config.PreferBetaVersions = HasParameter( args, "-beta" ); ContentDownloader.Config.BetaPassword = GetStringParameter( args, "-betapassword" ); - // this is a Steam2 option - if ( !bGameserver && !bApp && depotVersion == -1 ) - { - int latestVer = CDRManager.GetLatestDepotVersion(depotId, ContentDownloader.Config.PreferBetaVersions); - - if ( latestVer == -1 ) - { - Console.WriteLine( "Error: Unable to find DepotID {0} in the CDR!", depotId ); - return; - } - - string strVersion = GetStringParameter( args, "-version" ); - if ( strVersion != null && strVersion.Equals( "latest", StringComparison.OrdinalIgnoreCase ) ) - { - Console.WriteLine( "Using latest version: {0}", latestVer ); - depotVersion = latestVer; - } - else if ( strVersion == null ) - { - // this could probably be combined with the above - Console.WriteLine( "No version specified." ); - Console.WriteLine( "Using latest version: {0}", latestVer ); - depotVersion = latestVer; - } - else - { - Console.WriteLine( "Available depot versions:" ); - Console.WriteLine( " Oldest: 0" ); - Console.WriteLine( " Newest: {0}", latestVer ); - return; - } - } - string fileList = GetStringParameter( args, "-filelist" ); string[] files = null; @@ -142,7 +82,6 @@ namespace DepotDownloader string username = GetStringParameter(args, "-username"); string password = GetStringParameter(args, "-password"); ContentDownloader.Config.InstallDirectory = GetStringParameter(args, "-dir"); - bool bNoExclude = HasParameter(args, "-no-exclude"); ContentDownloader.Config.DownloadAllPlatforms = HasParameter(args, "-all-platforms"); string branch = GetStringParameter(args, "-branch") ?? GetStringParameter(args, "-beta") ?? "Public"; @@ -154,46 +93,7 @@ namespace DepotDownloader } ContentDownloader.InitializeSteam3(username, password); - - if (bApp) - { - ContentDownloader.DownloadApp(appId, depotId, branch, bListDepots); - } - else if ( !bGameserver ) - { - ContentDownloader.DownloadDepot(depotId, depotVersion, branch, appId); - } - else - { - if (!bNoExclude) - { - ContentDownloader.Config.UsingExclusionList = true; - } - - List depotIDs = CDRManager.GetDepotIDsForGameserver( gameName, ContentDownloader.Config.DownloadAllPlatforms ); - - if ( depotIDs.Count == 0 ) - { - Console.WriteLine( "Error: No depots for specified game '{0}'", gameName ); - return; - } - - if ( bListDepots ) - { - Console.WriteLine( "\n '{0}' Depots:", gameName ); - - foreach ( var depot in depotIDs ) - { - var depotName = CDRManager.GetDepotName( depot ); - Console.WriteLine( "{0} - {1}", depot, depotName ); - } - } - else - { - ContentDownloader.DownloadDepotsForGame( gameName, branch ); - } - } - + ContentDownloader.DownloadApp(appId, depotId, branch); ContentDownloader.ShutdownSteam3(); } @@ -238,28 +138,18 @@ namespace DepotDownloader Console.WriteLine( "\nUse: depotdownloader [optional parameters]\n" ); Console.WriteLine( "Parameters:" ); - Console.WriteLine( "\t-depot #\t\t\t- the DepotID to download." ); - Console.WriteLine( "\t OR" ); - Console.WriteLine( "\t-app #\t\t\t\t- the AppID to download." ); - Console.WriteLine( "\t OR" ); - Console.WriteLine( "\t-game name\t\t\t- the HLDSUpdateTool game server to download." ); - Console.WriteLine( "\t OR" ); - Console.WriteLine( "\t-list\t\t\t\t- print list of game servers that can be downloaded using -game." ); - Console.WriteLine( "\t OR" ); - Console.WriteLine( "\t-dumpcdr-xml\t\t\t- exports CDR to XML (cdrdump.xml)." ); + Console.WriteLine("\t-app #\t\t\t\t- the AppID to download."); Console.WriteLine(); - Console.WriteLine( "\t-version [# or \"latest\"]\t- the version of the depot to download. Uses latest if none specified.\n" ); Console.WriteLine( "Optional Parameters:" ); + Console.WriteLine( "\t-depot #\t\t\t- the DepotID to download." ); Console.WriteLine( "\t-cellid #\t\t\t- the CellID of the content server to download from." ); Console.WriteLine( "\t-username user\t\t\t- the username of the account to login to for restricted content." ); Console.WriteLine( "\t-password pass\t\t\t- the password of the account to login to for restricted content." ); Console.WriteLine( "\t-dir installdir\t\t\t- the directory in which to place downloaded files." ); Console.WriteLine( "\t-filelist filename.txt\t\t- a list of files to download (from the manifest). Can optionally use regex to download only certain files." ); - Console.WriteLine( "\t-no-exclude\t\t\t- don't exclude any files when downloading depots with the -game parameter." ); - Console.WriteLine( "\t-all-platforms\t\t\t- downloads all platform-specific depots when -game or -app is used." ); + Console.WriteLine( "\t-all-platforms\t\t\t- downloads all platform-specific depots when -app is used." ); Console.WriteLine( "\t-beta\t\t\t\t- download beta version of depots if available." ); - Console.WriteLine( "\t-listdepots\t\t\t- When used with -app or -game, only list relevant depotIDs and quit." ); Console.WriteLine( "\t-manifest\t\t\t- downloads a human readable manifest for any depots that would be downloaded." ); } } diff --git a/DepotDownloader/ServerCache.cs b/DepotDownloader/ServerCache.cs deleted file mode 100644 index 9b68726b..00000000 --- a/DepotDownloader/ServerCache.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using SteamKit2; - -namespace DepotDownloader -{ - static class ServerCache - { - public static ServerList ConfigServers { get; private set; } - public static ServerList CSDSServers { get; private set; } - - static ServerCache() - { - ConfigServers = new ServerList(); - CSDSServers = new ServerList(); - } - - - public static void Build() - { - Console.Write( "\nBuilding Steam2 server cache..." ); - - if (DateTime.Now > ConfigCache.Instance.ServerCacheTime) - { - foreach (IPEndPoint gdServer in GeneralDSClient.GDServers) - { - BuildServer(gdServer, ConfigServers, ESteam2ServerType.ConfigServer); - BuildServer(gdServer, CSDSServers, ESteam2ServerType.CSDS); - } - - if (ConfigServers.Count > 0 && CSDSServers.Count > 0) - { - ConfigCache.Instance.ConfigServers = ConfigServers; - ConfigCache.Instance.CSDSServers = CSDSServers; - ConfigCache.Instance.ServerCacheTime = DateTime.Now.AddDays(30); - ConfigCache.Instance.Save(ConfigCache.CONFIG_FILENAME); - - Console.WriteLine(" Done!"); - return; - } else if(ConfigCache.Instance.CSDSServers == null || ConfigCache.Instance.ConfigServers == null) - { - Console.WriteLine(" Unable to get server list"); - return; - } - } - - ConfigServers = ConfigCache.Instance.ConfigServers; - CSDSServers = ConfigCache.Instance.CSDSServers; - - Console.WriteLine( " Done!" ); - } - - private static void BuildServer( IPEndPoint gdServer, ServerList list, ESteam2ServerType type ) - { - try - { - GeneralDSClient gdsClient = new GeneralDSClient(); - gdsClient.Connect( gdServer ); - - IPEndPoint[] servers = gdsClient.GetServerList( type ); - list.AddRange( servers ); - - gdsClient.Disconnect(); - } - catch(Exception) - { - Console.WriteLine( "Warning: Unable to connect to GDS {0} to get list of {1} servers.", gdServer, type ); - } - } - } - - class ServerList : List - { - public new void AddRange( IEnumerable endPoints ) - { - foreach ( IPEndPoint endPoint in endPoints ) - Add( endPoint ); - } - - public new void Add( IPEndPoint endPoint ) - { - if ( this.HasServer( endPoint ) ) - return; - - base.Add( endPoint ); - } - - public bool HasServer( IPEndPoint endPoint ) - { - foreach ( var server in this ) - { - if ( server.Equals( endPoint ) ) - return true; - } - return false; - } - } -} diff --git a/DepotDownloader/Steam3Session.cs b/DepotDownloader/Steam3Session.cs index 0baa4f15..4f4c88bf 100644 --- a/DepotDownloader/Steam3Session.cs +++ b/DepotDownloader/Steam3Session.cs @@ -16,11 +16,10 @@ namespace DepotDownloader { public bool LoggedOn { get; set; } public ulong SessionToken { get; set; } - public Steam2Ticket Steam2Ticket { get; set; } public bool IsValid { - get { return LoggedOn; }// && SessionToken > 0 && Steam2Ticket != null; } + get { return LoggedOn; } } } @@ -399,12 +398,6 @@ namespace DepotDownloader credentials.LoggedOn = true; - if (loggedOn.Steam2Ticket != null) - { - Console.WriteLine("Got Steam2 Ticket!"); - credentials.Steam2Ticket = loggedOn.Steam2Ticket; - } - if (ContentDownloader.Config.CellID == 0) { Console.WriteLine("Using Steam3 suggested CellID: " + loggedOn.CellID);