Example #1
0
        public void GetNextServerCandidate_MarkIterateAllBadCandidates()
        {
            serverList.GetAllEndPoints();

            var recordA = ServerRecord.CreateWebSocketServer("10.0.0.1:27030");
            var recordB = ServerRecord.CreateWebSocketServer("10.0.0.2:27030");
            var recordC = ServerRecord.CreateWebSocketServer("10.0.0.3:27030");

            // Add all candidates and mark them bad
            serverList.ReplaceList(new List <ServerRecord>()
            {
                recordA, recordB, recordC
            });
            serverList.TryMark(recordA.EndPoint, ProtocolTypes.WebSocket, ServerQuality.Bad);
            serverList.TryMark(recordB.EndPoint, ProtocolTypes.WebSocket, ServerQuality.Bad);
            serverList.TryMark(recordC.EndPoint, ProtocolTypes.WebSocket, ServerQuality.Bad);

            var candidatesReturned = new HashSet <ServerRecord>();

            void DequeueAndMarkCandidate()
            {
                var candidate = serverList.GetNextServerCandidate(ProtocolTypes.WebSocket);

                Assert.True(candidatesReturned.Add(candidate), $"Candidate {candidate.EndPoint} already seen");
                Thread.Sleep(TimeSpan.FromMilliseconds(10));
                serverList.TryMark(candidate.EndPoint, ProtocolTypes.WebSocket, ServerQuality.Bad);
            }

            // We must dequeue all candidates from a bad list
            DequeueAndMarkCandidate();
            DequeueAndMarkCandidate();
            DequeueAndMarkCandidate();
            Assert.True(candidatesReturned.Count == 3, "All candidates returned");
        }
Example #2
0
        public void GetNextServerCandidate_AllEndpointsByHostAreBad()
        {
            serverList.GetAllEndPoints();

            var serverA = IPAddress.Parse("10.0.0.1");
            var serverB = IPAddress.Parse("10.0.0.2");

            var goodRecord    = ServerRecord.CreateSocketServer(new IPEndPoint(serverA, 27015));
            var neutralRecord = ServerRecord.CreateSocketServer(new IPEndPoint(serverA, 27016));
            var badRecord     = ServerRecord.CreateSocketServer(new IPEndPoint(serverA, 27017));
            var serverBRecord = ServerRecord.CreateSocketServer(new IPEndPoint(serverB, 27017));

            serverList.ReplaceList(new List <ServerRecord>()
            {
                goodRecord, neutralRecord, badRecord, serverBRecord
            });

            serverList.TryMark(goodRecord.EndPoint, goodRecord.ProtocolTypes, ServerQuality.Good);
            serverList.TryMark(badRecord.EndPoint, badRecord.ProtocolTypes, ServerQuality.Bad);

            // Server A's endpoints are all bad. Server B is our next candidate.
            var nextRecord = serverList.GetNextServerCandidate(ProtocolTypes.Tcp);

            Assert.Equal(serverBRecord.EndPoint, nextRecord.EndPoint);
            Assert.Equal(ProtocolTypes.Tcp, nextRecord.ProtocolTypes);
        }
Example #3
0
        public void GetNextServerCandidate_IsBiasedTowardsServerOrdering()
        {
            serverList.GetAllEndPoints();

            var serverA = IPAddress.Parse("10.0.0.1");
            var serverB = IPAddress.Parse("10.0.0.2");

            var goodRecord    = ServerRecord.CreateSocketServer(new IPEndPoint(serverA, 27015));
            var neutralRecord = ServerRecord.CreateSocketServer(new IPEndPoint(serverA, 27016));
            var badRecord     = ServerRecord.CreateSocketServer(new IPEndPoint(serverA, 27017));
            var serverBRecord = ServerRecord.CreateSocketServer(new IPEndPoint(serverB, 27017));

            serverList.ReplaceList(new List <ServerRecord>()
            {
                badRecord, neutralRecord, goodRecord, serverBRecord
            });

            serverList.TryMark(badRecord.EndPoint, badRecord.ProtocolTypes, ServerQuality.Bad);
            serverList.TryMark(goodRecord.EndPoint, goodRecord.ProtocolTypes, ServerQuality.Good);

            // Server A's endpoints were all marked bad, with goodRecord being recovered
            var nextRecord = serverList.GetNextServerCandidate(ProtocolTypes.Tcp);

            Assert.Equal(goodRecord.EndPoint, nextRecord.EndPoint);
            Assert.Equal(ProtocolTypes.Tcp, nextRecord.ProtocolTypes);

            serverList.TryMark(badRecord.EndPoint, badRecord.ProtocolTypes, ServerQuality.Good);

            // Server A's bad record is now at the front, having been marked good
            nextRecord = serverList.GetNextServerCandidate(ProtocolTypes.Tcp);
            Assert.Equal(badRecord.EndPoint, nextRecord.EndPoint);
            Assert.Equal(ProtocolTypes.Tcp, nextRecord.ProtocolTypes);
        }
Example #4
0
        private ServerRecord GetOldestContacted()
        {
            ServerRecord oldest = null;

            if (servers.Count == 0)
            {
                return(oldest);
            }

            lock (servers) {
                DateTime now = TimeBank.CurrentTime;

                foreach (var server in servers)
                {
                    if (now.Subtract(server.LastSendIPs).TotalMinutes >= 14)
                    {
                        oldest = (ServerRecord)((oldest == null) ? server : (server.LastSendIPs > oldest.LastSendIPs) ? server : oldest);
                    }
                }
            }

            if (oldest != null)
            {
                oldest.TryingIPs();
            }

            return(oldest);
        }
Example #5
0
        public void NullsAreEqualOperator()
        {
            ServerRecord l = null;
            ServerRecord r = null;

            Assert.True(l == r);
        }
Example #6
0
        public static void HandleSetServerStatus(SetServerStatusMessage message, TransitionClient client)
        {
            var server = ServerRecord.GetWorldServer(client.ServerId);

            ServersManager.Instance.SetServerStatus(client.ServerId, message.Status);
            logger.White("Server " + server.Name + " status is now " + message.Status.ToString());
        }
Example #7
0
        private static async Task StoreActiveDatabaseNames(ServerRecord server, AsyncServerClient client, IAsyncDocumentSession session)
        {
            AdminStatistics adminStatistics = await client.GlobalAdmin.GetStatisticsAsync();

            server.IsUnauthorized = false;

            server.ClusterName      = adminStatistics.ClusterName;
            server.ServerName       = adminStatistics.ServerName;
            server.MemoryStatistics = adminStatistics.Memory;

            foreach (var loadedDatabase in adminStatistics.LoadedDatabases)
            {
                var databaseRecord = await session.LoadAsync <DatabaseRecord>(server.Id + "/" + loadedDatabase.Name);

                if (databaseRecord == null)
                {
                    databaseRecord = new DatabaseRecord {
                        Name = loadedDatabase.Name, ServerId = server.Id, ServerUrl = server.Url
                    };
                    await session.StoreAsync(databaseRecord);
                }

                databaseRecord.LoadedDatabaseStatistics = loadedDatabase;
            }
            server.LoadedDatabases = adminStatistics.LoadedDatabases.Select(database => database.Name).ToArray();
        }
Example #8
0
        public static async Task FetchServerDatabasesAsync(ServerRecord server, IAsyncDocumentSession session)
        {
            var client = await ServerHelpers.CreateAsyncServerClient(session, server);

            try
            {
                await StoreDatabaseNames(server, client, session);

                // Mark server as online now, so if one of the later steps throw we'll have this value.
                server.NotifyServerIsOnline();

                await StoreActiveDatabaseNames(server, client, session);
                await CheckReplicationStatusOfEachActiveDatabase(server, client, session);

                // Mark server as online at the LastOnlineTime.
                server.NotifyServerIsOnline();
            }
            catch (HttpRequestException ex)
            {
                Log.ErrorException("Error", ex);

                var webException = ex.InnerException as WebException;
                if (webException != null)
                {
                    var socketException = webException.InnerException as SocketException;
                    if (socketException != null)
                    {
                        server.IsOnline = false;
                    }
                }
            }
            catch (AggregateException ex)
            {
                Log.ErrorException("Error", ex);

                var exception = ex.ExtractSingleInnerException();

                var webException = exception as WebException;
                if (webException != null)
                {
                    var response = webException.Response as HttpWebResponse;
                    if (response != null && response.StatusCode == HttpStatusCode.Unauthorized)
                    {
                        server.IsUnauthorized = true;
                    }
                    else
                    {
                        server.IsOnline = false;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.ErrorException("Error", ex);
            }
            finally
            {
                server.LastTriedToConnectAt = DateTimeOffset.UtcNow;
            }
        }
Example #9
0
        private void CheckFirewall()
        {
            ServerRecord server = null;
            DateTime     now    = TimeBank.CurrentTime;

            lock (servers)
                server = (ServerRecord)servers.Find((s) => now.Subtract(s.LastAskedFirewall).TotalMinutes > 5);

            if (server != null)
            {
                server.LastAskedFirewall = now;
                IPAddress ip = server.ExternalIp;

                if (!ip.IsLocal())
                {
                    lock (myfirewalltests) myfirewalltests.Add(server);

                    socket.SendAsync(
                        new CheckFirewallWanted(server.Port),
                        new IPEndPoint(ip, server.Port));
                }
            }
            else
            {
                FinishedTestingFirewall = true;
            }
        }
Example #10
0
        public void TreatsProtocolsForSameServerIndividiaully()
        {
            var record1 = ServerRecord.CreateServer(IPAddress.Loopback.ToString(), 27015, ProtocolTypes.Tcp | ProtocolTypes.Udp);
            var record2 = ServerRecord.CreateServer(IPAddress.Loopback.ToString(), 27016, ProtocolTypes.Tcp | ProtocolTypes.Udp);

            serverList.ReplaceList(new[] { record1, record2 });

            var nextTcp = serverList.GetNextServerCandidate(ProtocolTypes.Tcp);
            var nextUdp = serverList.GetNextServerCandidate(ProtocolTypes.Udp);

            Assert.Equal(record1.EndPoint, nextTcp.EndPoint);
            Assert.Equal(record1.EndPoint, nextUdp.EndPoint);

            serverList.TryMark(record1.EndPoint, ProtocolTypes.Tcp, ServerQuality.Bad);

            nextTcp = serverList.GetNextServerCandidate(ProtocolTypes.Tcp);
            nextUdp = serverList.GetNextServerCandidate(ProtocolTypes.Udp);

            Assert.Equal(record2.EndPoint, nextTcp.EndPoint);
            Assert.Equal(record1.EndPoint, nextUdp.EndPoint);

            serverList.TryMark(record1.EndPoint, ProtocolTypes.Udp, ServerQuality.Bad);

            nextTcp = serverList.GetNextServerCandidate(ProtocolTypes.Tcp);
            nextUdp = serverList.GetNextServerCandidate(ProtocolTypes.Udp);

            Assert.Equal(record2.EndPoint, nextTcp.EndPoint);
            Assert.Equal(record2.EndPoint, nextUdp.EndPoint);
        }
Example #11
0
        public void GetNextServerCandidate_IsBiasedTowardsServerOrdering()
        {
            serverList.GetAllEndPoints();

            var goodRecord    = ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27015));
            var neutralRecord = ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27016));
            var badRecord     = ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27017));

            serverList.ReplaceList(new List <ServerRecord>()
            {
                badRecord, neutralRecord, goodRecord
            });

            serverList.TryMark(badRecord.EndPoint, badRecord.ProtocolTypes, ServerQuality.Bad);
            serverList.TryMark(goodRecord.EndPoint, goodRecord.ProtocolTypes, ServerQuality.Good);

            var nextRecord = serverList.GetNextServerCandidate(ProtocolTypes.Tcp);

            Assert.Equal(neutralRecord.EndPoint, nextRecord.EndPoint);
            Assert.Equal(ProtocolTypes.Tcp, nextRecord.ProtocolTypes);

            serverList.TryMark(badRecord.EndPoint, badRecord.ProtocolTypes, ServerQuality.Good);

            nextRecord = serverList.GetNextServerCandidate(ProtocolTypes.Tcp);
            Assert.Equal(badRecord.EndPoint, nextRecord.EndPoint);
            Assert.Equal(ProtocolTypes.Tcp, nextRecord.ProtocolTypes);
        }
Example #12
0
        public void TryMergeWithList_AddsToHead_AndMovesExisting()
        {
            serverList.GetAllEndPoints();

            var seedList = new[]
            {
                ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27025)),
                ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27035)),
                ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27045)),
                ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27105)),
            };

            serverList.ReplaceList(seedList);
            Assert.Equal(4, seedList.Length);

            var listToReplace = new[]
            {
                ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27015)),
                ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27035)),
                ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27105)),
            };

            serverList.ReplaceList(listToReplace);

            var addresses = serverList.GetAllEndPoints();

            Assert.Equal(3, addresses.Length);
            Assert.Equal(listToReplace[0], addresses[0]);
            Assert.Equal(listToReplace[1], addresses[1]);
            Assert.Equal(listToReplace[2], addresses[2]);
        }
Example #13
0
        public bool OpenChannel(string jchannel)
        {
            ServerRecord channel = Json.Deserialize <ServerRecord>(jchannel);

            if (channel == null)
            {
                return(false);
            }

            if (ChatClient.ActiveChat.Channel.Equals(channel))
            {
                return(true);
            }

            ChatClient.JoiningChannel = null;
            ChatClient.JoiningChannel = channel;

            var instance = ChatClient.OpenChannel(ChatClient.JoiningChannel, new Uri(Interop.Navigation.BaseUri));

            if (instance != null)
            {
                Interop.Navigation.NavigateTo(string.Format("/chatrooms/{0}", instance.Channel.HashlinkUri));
                return(true);
            }

            return(false);
        }
Example #14
0
        public bool DisconnectClient(AuthClient newClient)
        {
            bool       succes = false;
            AuthClient client = AuthServer.Instance.GetClients().Find(x => x.Account != null && x.Account.Id == newClient.Account.Id);

            if (client != null)
            {
                client.Disconnect();
                succes = true;
            }
            else
            {
                if (newClient.Account.LastSelectedServerId != 0)
                {
                    TransitionClient server = TransitionServer.Instance.GetServerClient(newClient.Account.LastSelectedServerId);
                    var serverData          = ServerRecord.GetWorldServer(newClient.Account.LastSelectedServerId);
                    if (server != null && server.IsConnected && serverData != null && serverData.Status != ServerStatusEnum.STARTING) // Online
                    {
                        MessagePool.SendRequest <DisconnectClientResultMessage>(server,
                                                                                new DisconnectClientRequestMessage {
                            AccountId = newClient.Account.Id,
                        },
                                                                                delegate(DisconnectClientResultMessage message) { succes = message.IsSucces; },
                                                                                delegate() { this.OnTransitionFailed(newClient); });
                    }
                    else
                    {
                        succes = false;
                    }
                }
            }

            return(succes);
        }
Example #15
0
        static async Task <IReadOnlyCollection <ServerRecord> > LoadCoreAsync(SteamConfiguration configuration, int?maxNumServers, CancellationToken cancellationToken)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            var directory = configuration.GetAsyncWebAPIInterface("ISteamDirectory");
            var args      = new Dictionary <string, object?>
            {
                ["cellid"] = configuration.CellID.ToString(CultureInfo.InvariantCulture)
            };

            if (maxNumServers.HasValue)
            {
                args["maxcount"] = maxNumServers.Value.ToString(CultureInfo.InvariantCulture);
            }

            cancellationToken.ThrowIfCancellationRequested();

            var response = await directory.CallAsync(HttpMethod.Get, "GetCMList", version : 1, args : args).ConfigureAwait(false);

            var result = ( EResult )response["result"].AsInteger(( int )EResult.Invalid);

            if (result != EResult.OK)
            {
                throw new InvalidOperationException(string.Format("Steam Web API returned EResult.{0}", result));
            }

            var socketList    = response["serverlist"];
            var websocketList = response["serverlist_websockets"];

            cancellationToken.ThrowIfCancellationRequested();

            var serverRecords = new List <ServerRecord>(capacity: socketList.Children.Count + websocketList.Children.Count);

            foreach (var child in socketList.Children)
            {
                if (child.Value is null || !ServerRecord.TryCreateSocketServer(child.Value, out var record))
                {
                    continue;
                }

                serverRecords.Add(record);
            }

            foreach (var child in websocketList.Children)
            {
                if (child.Value is null)
                {
                    continue;
                }

                serverRecords.Add(ServerRecord.CreateWebSocketServer(child.Value));
            }

            return(serverRecords.AsReadOnly());
        }
Example #16
0
        private static async Task CheckReplicationStatusOfEachActiveDatabase(ServerRecord server, AsyncServerClient client, IAsyncDocumentSession session)
        {
            await HandleDatabaseInServerAsync(server, Constants.SystemDatabase, client, session);

            foreach (var databaseName in server.LoadedDatabases)
            {
                await HandleDatabaseInServerAsync(server, databaseName, client.ForDatabase(databaseName), session);
            }
        }
Example #17
0
            internal CMListCallback(CMsgClientCMList cmMsg)
            {
                var cmList = cmMsg.cm_addresses
                             .Zip(cmMsg.cm_ports, (addr, port) => ServerRecord.CreateSocketServer(new IPEndPoint(NetHelpers.GetIPAddress(addr), ( int )port)));

                var websocketList = cmMsg.cm_websocket_addresses.Select((addr) => ServerRecord.CreateWebSocketServer(addr));

                Servers = new ReadOnlyCollection <ServerRecord>(cmList.Concat(websocketList).ToList());
            }
Example #18
0
 private void EnsureServerRecordExists(string url)
 {
     if (!server_records.ContainsKey(url))
     {
         ServerRecord server_record = new ServerRecord();
         server_record.url = url;
         server_records[server_record.url] = server_record;
     }
 }
Example #19
0
        /// <summary>
        /// Connects this client to a Steam3 server.
        /// This begins the process of connecting and encrypting the data channel between the client and the server.
        /// Results are returned asynchronously in a <see cref="SteamClient.ConnectedCallback"/>.
        /// If the server that SteamKit attempts to connect to is down, a <see cref="SteamClient.DisconnectedCallback"/>
        /// will be posted instead.
        /// SteamKit will not attempt to reconnect to Steam, you must handle this callback and call Connect again
        /// preferrably after a short delay.
        /// </summary>
        /// <param name="cmServer">
        /// The <see cref="IPEndPoint"/> of the CM server to connect to.
        /// If <c>null</c>, SteamKit will randomly select a CM server from its internal list.
        /// </param>
        public void Connect(ServerRecord cmServer = null)
        {
            lock ( connectionLock )
            {
                this.Disconnect();
                Debug.Assert(connection == null);

                Debug.Assert(connectionCancellation == null);

                connectionCancellation = new CancellationTokenSource();
                var token = connectionCancellation.Token;

                ExpectDisconnection = false;

                Task <ServerRecord> recordTask = null;

                if (cmServer == null)
                {
                    recordTask = Servers.GetNextServerCandidateAsync(Configuration.ProtocolTypes);
                }
                else
                {
                    recordTask = Task.FromResult(cmServer);
                }

                connectionSetupTask = recordTask.ContinueWith(t =>
                {
                    if (token.IsCancellationRequested)
                    {
                        DebugLog.WriteLine(nameof(CMClient), "Connection cancelled before a server could be chosen.");
                        OnClientDisconnected(userInitiated: true);
                        return;
                    }
                    else if (t.IsFaulted || t.IsCanceled)
                    {
                        DebugLog.WriteLine(nameof(CMClient), "Server record task threw exception: {0}", t.Exception);
                        OnClientDisconnected(userInitiated: false);
                        return;
                    }

                    var record = t.Result;

                    connection = CreateConnection(record.ProtocolTypes & Configuration.ProtocolTypes);
                    connection.NetMsgReceived += NetMsgReceived;
                    connection.Connected      += Connected;
                    connection.Disconnected   += Disconnected;
                    connection.Connect(record.EndPoint, ( int )ConnectionTimeout.TotalMilliseconds);
                }, TaskContinuationOptions.ExecuteSynchronously).ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        DebugLog.WriteLine(nameof(CMClient), "Unhandled exception when attempting to connect to Steam: {0}", t.Exception);
                        OnClientDisconnected(userInitiated: false);
                    }
                }, TaskContinuationOptions.ExecuteSynchronously);
            }
        }
Example #20
0
        public void SetServerStatus(ushort serverId, ServerStatusEnum state)
        {
            ServerRecord.SetServerStatus(serverId, state);

            foreach (var client in AuthServer.Instance.GetClients())
            {
                client.SendServerList();
            }
        }
Example #21
0
        public void NullIsNotEqual()
        {
            var s = ServerRecord.CreateWebSocketServer("host:1");

            Assert.True(s != null);
            Assert.True(null != s);
            Assert.False(s.Equals(null));
            Assert.False(s == null);
            Assert.False(null == s);
        }
Example #22
0
            public ServerRecord GetServerRecord()
            {
                if (IsWebSocket)
                {
                    return(ServerRecord.CreateWebSocketServer(Address));
                }

                ServerRecord.TryCreateSocketServer(Address, out var record);
                return(record);
            }
Example #23
0
 private static void WriteValidity(ServerRecord server)
 {
     if (server.IsValid)
     {
         return;
     }
     Console.ForegroundColor = ConsoleColor.Red;
     Console.Out.Write(" <INVALID>");
     Console.ResetColor();
 }
Example #24
0
 private void ListServer(ServerRecord server, int position)
 {
     Console.Out.Write(_serverPool.Default == server.Name ? "* " : "   ");
     Console.Out.Write(position);
     Console.Out.Write(") ");
     WriteName(server.Name, server.Colour);
     Console.Out.Write($" ({server.Host}:{server.Port})");
     WriteValidity(server);
     Console.Out.WriteLine();
 }
Example #25
0
        public void UnregisterWorld(ushort serverId)
        {
            ServerRecord world = ServerRecord.GetWorldServer(serverId);

            if (world != null)
            {
                this.SetServerStatus(serverId, ServerStatusEnum.OFFLINE);
                logger.White("Server Unregistred (" + world.Name + ")");
            }
        }
Example #26
0
        public void DifferentEndPointsAndProtocolsAreNotEqual()
        {
            var l = ServerRecord.CreateServer("host", 1, ProtocolTypes.Tcp);
            var r = ServerRecord.CreateServer("host", 2, ProtocolTypes.WebSocket);

            Assert.True(l != r);
            Assert.True(r != l);
            Assert.False(l == r);
            Assert.False(r == l);
            Assert.False(l.Equals(r));
            Assert.False(r.Equals(l));
        }
Example #27
0
        public void CanTryCreateSocketServer()
        {
            Assert.True(ServerRecord.TryCreateSocketServer("127.0.0.1:1234", out var record));
            Assert.NotNull(record);
            Assert.Equal(new IPEndPoint(IPAddress.Loopback, 1234), record.EndPoint);
            Assert.Equal(ProtocolTypes.Tcp | ProtocolTypes.Udp, record.ProtocolTypes);

            Assert.True(ServerRecord.TryCreateSocketServer("192.168.0.1:5678", out record));
            Assert.NotNull(record);
            Assert.Equal(new IPEndPoint(IPAddress.Parse("192.168.0.1"), 5678), record.EndPoint);
            Assert.Equal(ProtocolTypes.Tcp | ProtocolTypes.Udp, record.ProtocolTypes);
        }
Example #28
0
        public void TryMark_ReturnsFalse_IfServerNotInList()
        {
            var record = ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27015));

            serverList.ReplaceList(new List <ServerRecord>()
            {
                record
            });

            var marked = serverList.TryMark(new IPEndPoint(IPAddress.Loopback, 27016), record.ProtocolTypes, ServerQuality.Good);

            Assert.False(marked);
        }
 public static void ReleasServerRecord(ServerRecord serverRecord)
 {
     if (_servers.ContainsKey(serverRecord))
     {
         var uses = _servers[serverRecord];
         uses -= 1;
         if (uses < 0)
         {
             uses = 0;
         }
         _servers[serverRecord] = uses;
     }
 }
Example #30
0
        /// <summary>
        /// Load a list of servers from the Steam Directory.
        /// </summary>
        /// <param name="configuration">Configuration Object</param>
        /// <param name="cancellationToken">Cancellation Token</param>
        /// <returns>A <see cref="System.Threading.Tasks.Task"/> with the Result set to an enumerable list of <see cref="ServerRecord"/>s.</returns>
        public static Task <IReadOnlyCollection <ServerRecord> > LoadAsync(SteamConfiguration configuration, CancellationToken cancellationToken)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            var directory = configuration.GetAsyncWebAPIInterface("ISteamDirectory");
            var args      = new Dictionary <string, string>
            {
                ["cellid"] = configuration.CellID.ToString(CultureInfo.InvariantCulture)
            };

            cancellationToken.ThrowIfCancellationRequested();

            var task = directory.CallAsync(HttpMethod.Get, "GetCMList", version: 1, args: args);

            return(task.ContinueWith(t =>
            {
                var response = task.Result;
                var result = ( EResult )response["result"].AsInteger(( int )EResult.Invalid);
                if (result != EResult.OK)
                {
                    throw new InvalidOperationException(string.Format("Steam Web API returned EResult.{0}", result));
                }

                var socketList = response["serverlist"];
                var websocketList = response["serverlist_websockets"];

                cancellationToken.ThrowIfCancellationRequested();

                var serverRecords = new List <ServerRecord>(capacity: socketList.Children.Count + websocketList.Children.Count);

                foreach (var child in socketList.Children)
                {
                    if (!NetHelpers.TryParseIPEndPoint(child.Value, out var endpoint))
                    {
                        continue;
                    }

                    serverRecords.Add(ServerRecord.CreateSocketServer(endpoint));
                }

                foreach (var child in websocketList.Children)
                {
                    serverRecords.Add(ServerRecord.CreateWebSocketServer(child.Value));
                }

                return (IReadOnlyCollection <ServerRecord>)serverRecords;
            }, cancellationToken, TaskContinuationOptions.NotOnCanceled | TaskContinuationOptions.NotOnFaulted, TaskScheduler.Current));
        }