예제 #1
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);
        }
예제 #2
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);
        }
예제 #3
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]);
        }
예제 #4
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);
        }
예제 #5
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());
            }
예제 #6
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);
        }
예제 #7
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));
        }
예제 #8
0
        public void GetNextServerCandidate_OnlyReturnsMatchingServerOfType()
        {
            var record = ServerRecord.CreateWebSocketServer("localhost:443");

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

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

            Assert.Null(endPoint);
            endPoint = serverList.GetNextServerCandidate(ProtocolTypes.Udp);
            Assert.Null(endPoint);
            endPoint = serverList.GetNextServerCandidate(ProtocolTypes.Tcp | ProtocolTypes.Udp);
            Assert.Null(endPoint);

            endPoint = serverList.GetNextServerCandidate(ProtocolTypes.WebSocket);
            Assert.Equal(record.EndPoint, endPoint.EndPoint);
            Assert.Equal(ProtocolTypes.WebSocket, endPoint.ProtocolTypes);

            endPoint = serverList.GetNextServerCandidate(ProtocolTypes.All);
            Assert.Equal(record.EndPoint, endPoint.EndPoint);
            Assert.Equal(ProtocolTypes.WebSocket, endPoint.ProtocolTypes);

            record = ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27015));
            serverList.ReplaceList(new List <ServerRecord>()
            {
                record
            });

            endPoint = serverList.GetNextServerCandidate(ProtocolTypes.WebSocket);
            Assert.Null(endPoint);

            endPoint = serverList.GetNextServerCandidate(ProtocolTypes.Tcp);
            Assert.Equal(record.EndPoint, endPoint.EndPoint);
            Assert.Equal(ProtocolTypes.Tcp, endPoint.ProtocolTypes);

            endPoint = serverList.GetNextServerCandidate(ProtocolTypes.Udp);
            Assert.Equal(record.EndPoint, endPoint.EndPoint);
            Assert.Equal(ProtocolTypes.Udp, endPoint.ProtocolTypes);

            endPoint = serverList.GetNextServerCandidate(ProtocolTypes.Tcp | ProtocolTypes.Udp);
            Assert.Equal(record.EndPoint, endPoint.EndPoint);
            Assert.Equal(ProtocolTypes.Tcp, endPoint.ProtocolTypes);

            endPoint = serverList.GetNextServerCandidate(ProtocolTypes.All);
            Assert.Equal(record.EndPoint, endPoint.EndPoint);
            Assert.Equal(ProtocolTypes.Tcp, endPoint.ProtocolTypes);
        }
예제 #9
0
        void HandleCMList(IPacketMsg packetMsg)
        {
            var cmMsg = new ClientMsgProtobuf <CMsgClientCMList>(packetMsg);

            DebugLog.Assert(cmMsg.Body.cm_addresses.Count == cmMsg.Body.cm_ports.Count, "CMClient", "HandleCMList received malformed message");

            var cmList = cmMsg.Body.cm_addresses
                         .Zip(cmMsg.Body.cm_ports, (addr, port) => ServerRecord.CreateSocketServer(new IPEndPoint(NetHelpers.GetIPAddress(addr), ( int )port)));

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

            // update our list with steam's list of CMs
            Servers.ReplaceList(cmList.Concat(webSocketList));
        }
예제 #10
0
        public void GetNextServerCandidate_ReturnsServer_IfListHasServers()
        {
            serverList.GetAllEndPoints();

            var record = ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27015));

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

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

            Assert.Equal(record.EndPoint, nextRecord.EndPoint);
            Assert.Equal(ProtocolTypes.Tcp, nextRecord.ProtocolTypes);
        }
        public async Task ReadsUpdatedServerList()
        {
            await isolatedStorageProvider.UpdateServerListAsync(new List <ServerRecord>()
            {
                ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Any, 1234)),
                ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 4321))
            });

            var servers = await isolatedStorageProvider.FetchServerListAsync();

            Assert.Equal(2, servers.Count());
            Assert.Equal(IPAddress.Any.ToString(), servers.First().GetHost());
            Assert.Equal(1234, servers.First().GetPort());
            Assert.Equal(ProtocolTypes.Tcp | ProtocolTypes.Udp, servers.First().ProtocolTypes);

            await isolatedStorageProvider.UpdateServerListAsync(new List <ServerRecord>());
        }