示例#1
0
        /// <summary>
        /// Connects this client to a UFS server.
        /// This begins the process of connecting and encrypting the data channel between the client and the UFS server.
        /// Results are returned asynchronously in a <see cref="ConnectedCallback"/>.
        /// If the UFS server that this client attempts to connect to is down, a <see cref="DisconnectedCallback"/> will be posted instead.
        /// <see cref="UFSClient"/> will not attempt to reconnect to Steam, you must handle this callback and call <see cref="Connect"/> again, preferrably after a short delay.
        /// In order to connect to the UFS server, the parent <see cref="SteamClient"/> must be connected to the CM server.
        /// </summary>
        /// <param name="ufsServer">
        /// The <see cref="System.Net.IPEndPoint"/> of the UFS server to connect to.
        /// If <c>null</c>, <see cref="UFSClient"/> will randomly select a UFS server from the <see cref="SteamClient"/>'s list of servers.
        /// </param>
        public void Connect(IPEndPoint ufsServer = null)
        {
            DebugLog.Assert(steamClient.IsConnected, nameof(UFSClient), "CMClient is not connected!");

            Disconnect();
            Debug.Assert(connection == null);

            if (ufsServer == null)
            {
                var serverList = steamClient.GetServersOfType(EServerType.UFS);

                if (serverList.Count == 0)
                {
                    DebugLog.WriteLine(nameof(UFSClient), "No UFS server addresses were provided yet.");
                    Disconnected(this, new DisconnectedEventArgs(userInitiated: false));
                    return;
                }

                var random = new Random();
                ufsServer = serverList[random.Next(serverList.Count)];
            }

            // steamclient has the connection type hardcoded as TCP
            // todo: determine if UFS supports UDP and if we want to support it
            connection = new EnvelopeEncryptedConnection(new TcpConnection(), steamClient.Universe);

            connection.NetMsgReceived += NetMsgReceived;
            connection.Connected      += Connected;
            connection.Disconnected   += Disconnected;

            connection.Connect(ufsServer, ( int )ConnectionTimeout.TotalMilliseconds);
        }
示例#2
0
        /// <summary>
        /// Connects this client to a UFS server.
        /// This begins the process of connecting and encrypting the data channel between the client and the UFS server.
        /// Results are returned asynchronously in a <see cref="ConnectedCallback"/>.
        /// If the UFS server that this client attempts to connect to is down, a <see cref="DisconnectedCallback"/> will be posted instead.
        /// <see cref="UFSClient"/> will not attempt to reconnect to Steam, you must handle this callback and call <see cref="Connect"/> again, preferrably after a short delay.
        /// In order to connect to the UFS server, the parent <see cref="SteamClient"/> must be connected to the CM server.
        /// </summary>
        /// <param name="ufsServer">
        /// The <see cref="System.Net.IPEndPoint"/> of the UFS server to connect to.
        /// If <c>null</c>, <see cref="UFSClient"/> will randomly select a UFS server from the <see cref="SteamClient"/>'s list of servers.
        /// </param>
        public void Connect(IPEndPoint ufsServer = null)
        {
            DebugLog.Assert(steamClient.IsConnected, "UFSClient", "CMClient is not connected!");

            Disconnect();

            if (ufsServer == null)
            {
                var serverList = steamClient.GetServersOfType(EServerType.UFS);

                Random random = new Random();
                ufsServer = serverList[random.Next(serverList.Count)];
            }

            connection.Connect(ufsServer, ( int )ConnectionTimeout.TotalMilliseconds);
        }
示例#3
0
        /// <summary>
        /// Connects this client to a UFS server.
        /// This begins the process of connecting and encrypting the data channel between the client and the UFS server.
        /// Results are returned asynchronously in a <see cref="ConnectedCallback"/>.
        /// If the UFS server that this client attempts to connect to is down, a <see cref="DisconnectedCallback"/> will be posted instead.
        /// <see cref="UFSClient"/> will not attempt to reconnect to Steam, you must handle this callback and call <see cref="Connect"/> again, preferrably after a short delay.
        /// In order to connect to the UFS server, the parent <see cref="SteamClient"/> must be connected to the CM server.
        /// </summary>
        /// <param name="ufsServer">
        /// The <see cref="System.Net.IPEndPoint"/> of the UFS server to connect to.
        /// If <c>null</c>, <see cref="UFSClient"/> will randomly select a UFS server from the <see cref="SteamClient"/>'s list of servers.
        /// </param>
        public void Connect(IPEndPoint ufsServer = null)
        {
            DebugLog.Assert(steamClient.IsConnected, "UFSClient", "CMClient is not connected!");

            this.Disconnect();

            pendingNetFilterEncryption = null;

            if (ufsServer == null)
            {
                var serverList = steamClient.GetServersOfType(EServerType.UFS);

                Random random = new Random();
                ufsServer = serverList[random.Next(serverList.Count)];
            }

            connection.Connect(Task.FromResult(ufsServer), ( int )ConnectionTimeout.TotalMilliseconds);
        }
示例#4
0
        /// <summary>
        /// Connects this client to a UFS server.
        /// This begins the process of connecting and encrypting the data channel between the client and the UFS server.
        /// Results are returned asynchronously in a <see cref="ConnectedCallback"/>.
        /// If the UFS server that this client attempts to connect to is down, a <see cref="DisconnectedCallback"/> will be posted instead.
        /// <see cref="UFSClient"/> will not attempt to reconnect to Steam, you must handle this callback and call <see cref="Connect"/> again, preferrably after a short delay.
        /// In order to connect to the UFS server, the parent <see cref="SteamClient"/> must be connected to the CM server.
        /// </summary>
        /// <param name="ufsServer">
        /// The <see cref="System.Net.IPEndPoint"/> of the UFS server to connect to.
        /// If <c>null</c>, <see cref="UFSClient"/> will randomly select a UFS server from the <see cref="SteamClient"/>'s list of servers.
        /// </param>
        public void Connect(IPEndPoint ufsServer = null)
        {
            DebugLog.Assert(steamClient.IsConnected, nameof(UFSClient), "CMClient is not connected!");

            Disconnect();

            if (ufsServer == null)
            {
                var serverList = steamClient.GetServersOfType(EServerType.UFS);

                if (serverList.Count == 0)
                {
                    DebugLog.WriteLine(nameof(UFSClient), "No UFS server addresses were provided yet.");
                    Disconnected(this, new DisconnectedEventArgs(userInitiated: false));
                    return;
                }

                var random = new Random();
                ufsServer = serverList[random.Next(serverList.Count)];
            }

            connection.Connect(ufsServer, ( int )ConnectionTimeout.TotalMilliseconds);
        }
示例#5
0
        /// <summary>
        /// Fetches a list of content servers.
        /// </summary>
        /// <param name="csServer">
        /// The optional Steam3 content server to fetch the list from.
        /// If this parameter is not specified, a random CS server will be selected.
        /// </param>
        /// <param name="cellId">
        /// The optional CellID used to specify which regional servers should be returned in the list.
        /// If this parameter is not specified, Steam's GeoIP suggested CellID will be used instead.
        /// </param>
        /// <param name="maxServers">The maximum amount of servers to request.</param>
        /// <returns>A list of servers.</returns>
        /// <exception cref="System.InvalidOperationException">
        /// No Steam CS servers available, or the suggested CellID is unavailable.
        /// Check that the <see cref="SteamClient"/> associated with this <see cref="CDNClient"/> instance is logged onto Steam.
        /// </exception>
        public List <Server> FetchServerList(IPEndPoint csServer = null, uint?cellId = null, int maxServers = 20)
        {
            DebugLog.Assert(steamClient.IsConnected, "CDNClient", "CMClient is not connected!");
            DebugLog.Assert(steamClient.CellID != null, "CDNClient", "CMClient is not logged on!");

            if (csServer == null)
            {
                // if we're not specifying what CS server we want to fetch a server list from, randomly select a cached CS server
                var csServers = steamClient.GetServersOfType(EServerType.CS);

                if (csServers.Count == 0)
                {
                    // steamclient doesn't know about any CS servers yet
                    throw new InvalidOperationException("No CS servers available!");
                }

                Random random = new Random();
                csServer = csServers[random.Next(csServers.Count)];
            }

            if (cellId == null)
            {
                if (steamClient.CellID == null)
                {
                    throw new InvalidOperationException("Recommended CellID is not available. CMClient not logged on?");
                }

                // fallback to recommended cellid
                cellId = steamClient.CellID.Value;
            }

            KeyValue serverKv = DoCommand(csServer, "serverlist", args: string.Format("{0}/{1}/", cellId, maxServers));

            var serverList = new List <Server>(maxServers);

            if (serverKv["deferred"].AsBoolean())
            {
                return(serverList);
            }

            foreach (var server in serverKv.Children)
            {
                string type = server["type"].AsString();
                string host = server["host"].AsString();

                string[] hostSplits = host.Split(':');

                int port = 80;
                if (hostSplits.Length > 1)
                {
                    int parsedPort;
                    if (int.TryParse(hostSplits[1], out parsedPort))
                    {
                        port = parsedPort;
                    }
                }

                uint serverCell   = ( uint )server["cell"].AsInteger();
                int  load         = server["load"].AsInteger();
                int  weightedLoad = server["weightedload"].AsInteger();

                serverList.Add(new Server
                {
                    Host = host,
                    Port = port,

                    Type = type,

                    CellID = serverCell,

                    Load         = load,
                    WeightedLoad = weightedLoad,
                });
            }

            return(serverList);
        }
示例#6
0
        /// <summary>
        /// Fetches a list of content servers.
        /// </summary>
        /// <param name="csServer">
        /// The optional Steam3 content server to fetch the list from.
        /// If this parameter is not specified, a random CS server will be selected.
        /// </param>
        /// <param name="cellId">
        /// The optional CellID used to specify which regional servers should be returned in the list.
        /// If this parameter is not specified, Steam's GeoIP suggested CellID will be used instead.
        /// </param>
        /// <param name="maxServers">The maximum amount of servers to request.</param>
        /// <returns>A list of servers.</returns>
        /// <exception cref="System.InvalidOperationException">
        /// No Steam CS servers available, or the suggested CellID is unavailable.
        /// Check that the <see cref="SteamClient"/> associated with this <see cref="CDNClient"/> instance is logged onto Steam.
        /// </exception>
        /// <exception cref="HttpRequestException">An network error occurred when performing the request.</exception>
        /// <exception cref="SteamKitWebRequestException">A network error occurred when performing the request.</exception>
        public async Task <IList <Server> > FetchServerListAsync(IPEndPoint csServer = null, uint?cellId = null, int maxServers = 20)
        {
            DebugLog.Assert(steamClient.IsConnected, "CDNClient", "CMClient is not connected!");
            DebugLog.Assert(steamClient.CellID != null, "CDNClient", "CMClient is not logged on!");

            if (csServer == null)
            {
                // if we're not specifying what CS server we want to fetch a server list from, randomly select a cached CS server
                var csServers = steamClient.GetServersOfType(EServerType.CS);

                if (csServers.Count == 0)
                {
                    // steamclient doesn't know about any CS servers yet
                    throw new InvalidOperationException("No CS servers available!");
                }

                Random random = new Random();
                csServer = csServers[random.Next(csServers.Count)];
            }

            if (cellId == null)
            {
                if (steamClient.CellID == null)
                {
                    throw new InvalidOperationException("Recommended CellID is not available. CMClient not logged on?");
                }

                // fallback to recommended cellid
                cellId = steamClient.CellID.Value;
            }

            var serverKv = await DoCommandAsync(csServer, HttpMethod.Get, "serverlist", args : string.Format("{0}/{1}/", cellId, maxServers)).ConfigureAwait(false);

            var serverList = new List <Server>(maxServers);

            if (serverKv["deferred"].AsBoolean())
            {
                return(serverList);
            }

            foreach (var server in serverKv.Children)
            {
                string type  = server["type"].AsString();
                string host  = server["host"].AsString();
                string vhost = server["vhost"].AsString();

                string[] hostSplits = host.Split(':');

                int port = 80;
                if (hostSplits.Length > 1)
                {
                    int parsedPort;
                    if (int.TryParse(hostSplits[1], out parsedPort))
                    {
                        port = parsedPort;
                    }
                }

                uint   serverCell   = ( uint )server["cell"].AsInteger();
                int    load         = server["load"].AsInteger();
                int    weightedLoad = server["weightedload"].AsInteger();
                int    entries      = server["NumEntriesInClientList"].AsInteger(1);
                int    useTokenAuth = server["usetokenauth"].AsInteger();
                string httpsSupport = server["https_support"].AsString();

                // If usetokenauth is specified, we can treat this server as a CDN and request tokens
                if (useTokenAuth > 0)
                {
                    type = "CDN";
                }

                Server.ConnectionProtocol protocol = (httpsSupport == "optional" || httpsSupport == "mandatory") ? Server.ConnectionProtocol.HTTPS : Server.ConnectionProtocol.HTTP;

                serverList.Add(new Server
                {
                    Protocol = protocol,
                    Host     = host,
                    VHost    = vhost,
                    Port     = protocol == Server.ConnectionProtocol.HTTPS ? 443 : port,

                    Type = type,

                    CellID = serverCell,

                    Load         = load,
                    WeightedLoad = weightedLoad,
                    NumEntries   = entries
                });
            }

            return(serverList);
        }