Represents a client that is capable of connecting to a Steam2 content server.
Inheritance: ServerClient
            internal StorageSession(ContentServerClient cli, uint depotId, uint depotVersion, Credentials credentials)
            {
                this.DepotID      = depotId;
                this.DepotVersion = depotVersion;

                this.client = cli;


                bool bRet = false;

                if (credentials == null)
                {
                    bRet = this.SendCommand(
                        9, // open storage
                        ConnectionID,
                        MessageID,
                        depotId,
                        depotVersion
                        );
                }
                else
                {
                    byte[] serverTgt = credentials.Steam2Ticket.Entries[14].Data;   // god help this never change

                    bRet = this.SendCommand(
                        10, // open storage with login
                        ConnectionID,
                        MessageID,
                        depotId,
                        depotVersion,
                        ( ushort )serverTgt.Length,
                        serverTgt,
                        NetHelpers.EndianSwap(credentials.SessionToken),
                        ( byte )credentials.AppTicket.Length,
                        credentials.AppTicket
                        );
                }

                // the server sends us back the connection and message ids
                // the client probably performs a sanity check?
                uint connId = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());
                uint msgId  = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());

                byte hasDepot = this.Socket.Reader.ReadByte();

                // the server gives us 0x1 if the depot doesn't exist or requires authentication
                if (hasDepot != 0)
                {
                    throw new Steam2Exception("Content server does not have depot, or valid credentials were not given");
                }

                StorageID = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());
                uint storageChecksum = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32());

                this.ConnectionID++;
            }
Beispiel #2
0
        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;
        }
Beispiel #3
0
        private static void DownloadSteam2( List<DepotDownloadInfo2> 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();

        }
Beispiel #4
0
        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;
        }
Beispiel #5
0
        private static void DownloadSteam2( int depotId, int depotVersion, string installDir )
        {
            Console.Write("Finding content servers...");
            IPEndPoint[] contentServers = GetStorageServer(depotId, depotVersion, Config.CellID);

            if (contentServers == null || contentServers.Length == 0)
            {
                Console.WriteLine("\nError: Unable to find any Steam2 content servers for depot {0}, version {1}", depotId, depotVersion);
                return;
            }

            Console.WriteLine(" Done!");
            Console.Write("Downloading depot manifest...");

            string txtManifest = Path.Combine(installDir, "manifest.txt");

            ContentServerClient csClient = new ContentServerClient();

            ContentServerClient.StorageSession session = GetSteam2StorageSession(contentServers, csClient, depotId, depotVersion);
            if(session == null)
                return;

            Steam2Manifest manifest = null;
            Steam2ChecksumData checksums = null;
            List<int> NodesToDownload = new List<int>();
            StringBuilder manifestBuilder = new StringBuilder();       
            byte[] cryptKey = CDRManager.GetDepotEncryptionKey( depotId, depotVersion );
            string[] excludeList = null;
            using ( session )
            {
                manifest = session.DownloadManifest();

                Console.WriteLine( " Done!" );

                if(!Config.DownloadManifestOnly)
                {
                    // Skip downloading checksums if we're only interested in manifests.   
                    Console.Write("Downloading depot checksums...");

                    checksums = session.DownloadChecksums();

                    Console.WriteLine(" Done!");
                }

                if ( Config.UsingExclusionList )
                    excludeList = GetExcludeList( session, manifest );
            }
            csClient.Disconnect();

            if(!Config.DownloadManifestOnly)
                Console.WriteLine("Building list of files to download and checking existing files...");
            // Build a list of files that need downloading.
            for ( int x = 0 ; x < manifest.Nodes.Count ; ++x )
            {
                var dirEntry = manifest.Nodes[ x ];
                string downloadPath = Path.Combine( 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 (!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;
                }

                FileInfo fi = new FileInfo( downloadPath );
                if (fi.Exists)
                {
                    float perc = ( ( float )x / ( float )manifest.Nodes.Count ) * 100.0f;
                    Console.WriteLine("{0,6:#00.00}%\t{1}", perc, downloadPath);
                    // Similar file, let's check checksums
                    if(fi.Length == dirEntry.SizeOrCount && 
                        Util.ValidateFileChecksums(fi, checksums.GetFileChecksums(dirEntry.FileID)))
                    {
                        // checksums OK
                        continue;
                    }
                    // Unlink the current file before we download a new one.
                    // This will keep symbolic/hard link targets from being overwritten.
                    fi.Delete();
                }
                NodesToDownload.Add(x);
            }

            if ( Config.DownloadManifestOnly )
            {
                    File.WriteAllText( txtManifest, manifestBuilder.ToString() );
                    return;
            }
            
            
            session = GetSteam2StorageSession(contentServers, csClient, depotId, depotVersion);
            if(session == null)
                return;
            
            using ( session )
            {
                Console.WriteLine("Downloading selected files.");
                for ( int x = 0 ; x < NodesToDownload.Count ; ++x )
                {
                    var dirEntry = manifest.Nodes[ NodesToDownload[ x ] ];
                    string downloadPath = Path.Combine( installDir, dirEntry.FullName.ToLower() );

                    float perc = ( ( float )x / ( float )NodesToDownload.Count ) * 100.0f;
                    Console.WriteLine("{0,6:#00.00}%\t{1}", perc, downloadPath);
                    
                    var file = session.DownloadFile( dirEntry, ContentServerClient.StorageSession.DownloadPriority.High, cryptKey );
                    File.WriteAllBytes( downloadPath, file );
                }
            }
            csClient.Disconnect();

        }
Beispiel #6
0
 internal PackageSession( ContentServerClient cli, uint cellId )
 {
     this.client = cli;
     this.CellID = cellId;
 }
Beispiel #7
0
            internal StorageSession( ContentServerClient cli, uint depotId, uint depotVersion, Credentials credentials )
            {
                this.DepotID = depotId;
                this.DepotVersion = depotVersion;

                this.client = cli;


                bool bRet = false;

                if ( credentials == null )
                {
                    bRet = this.SendCommand(
                        9, // open storage
                        ConnectionID,
                        MessageID,
                        depotId,
                        depotVersion
                    );
                }
                else
                {
                    byte[] serverTgt = credentials.Steam2Ticket.Entries[ 14 ].Data; // god help this never change

                    bRet = this.SendCommand(
                        10, // open storage with login
                        ConnectionID,
                        MessageID,
                        depotId,
                        depotVersion,
                        ( ushort )serverTgt.Length,
                        serverTgt,
                        NetHelpers.EndianSwap( credentials.SessionToken ),
                        ( byte )credentials.AppTicket.Length,
                        credentials.AppTicket
                    );
                }

                // the server sends us back the connection and message ids
                // the client probably performs a sanity check?
                uint connId = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() );
                uint msgId = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() );

                byte hasDepot = this.Socket.Reader.ReadByte();

                // the server gives us 0x1 if the depot doesn't exist or requires authentication
                if ( hasDepot != 0 )
                    throw new Steam2Exception( "Content server does not have depot, or valid credentials were not given" );

                StorageID = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() );
                uint storageChecksum = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() );

                this.ConnectionID++;

            }
 internal PackageSession(ContentServerClient cli, uint cellId)
 {
     this.client = cli;
     this.CellID = cellId;
 }