private async Task<BatchResult> TryGetServersFromSteam(uint appId, IReadOnlyCollection<IPEndPoint> addresses,
     ServerQueryOptions options, Action<Server> act) {
     try {
         return await GetServersFromSteam(appId, addresses, options, act).ConfigureAwait(false);
     } catch (Exception ex) {
         MainLog.Logger.FormattedWarnException(ex, "Problem while processing info from Steam!");
         return await GetFromGameServerQuery(addresses, options, act).ConfigureAwait(false);
     }
 }
 async Task<BatchResult> GetServersFromSteam(uint appId, IEnumerable<IPEndPoint> addresses,
     ServerQueryOptions options, Action<Server> act) {
     var cvt = GetConverter(options.InclExtendedDetails);
     var r = await Task.WhenAll(addresses.Batch(15).Select(b => {
         // Ports adjusted because it expects the Connection Port!
         var filter =
             ServerFilterBuilder.Build()
                 .FilterByAddresses(b.Select(x => new IPEndPoint(x.Address, x.Port - 1)).ToList());
         return _steamHelperService.GetServers<ArmaServerInfoModel>(appId,
             new GetServers {
                 Filter = filter.Value,
                 IncludeDetails = options.InclExtendedDetails,
                 IncludeRules = options.InclExtendedDetails,
                 PageSize = 1
             }, CancellationToken.None, x => {
                 foreach (var s in x.Select(cvt))
                     act(s);
             });
     }));
     return new BatchResult(r.Sum(x => x.Count));
 }
 // todo; use factory
 private static async Task<BatchResult> GetFromGameServerQuery(
     IEnumerable<IPEndPoint> addresses, ServerQueryOptions options, Action<Server> act) {
     var q = new ReactiveSource();
     using (var client = q.CreateUdpClient()) {
         return new BatchResult(await q.ProcessResults(q.GetResults(addresses, client, new QuerySettings {
                 InclPlayers = options.InclPlayers,
                 InclRules = options.InclExtendedDetails
             }))
             .Do(x => {
                 var serverInfo = new Server {QueryAddress = x.Address};
                 var r = (SourceParseResult) x.Settings;
                 r.MapTo(serverInfo);
                 serverInfo.Ping = x.Ping;
                 var tags = r.Keywords;
                 if (tags != null) {
                     var p = GameTags.Parse(tags);
                     p.MapTo(serverInfo);
                 }
                 act(serverInfo);
             }).Count());
     }
 }
 public Task<BatchResult> GetServerInfo(uint appId, IReadOnlyCollection<IPEndPoint> addresses,
     ServerQueryOptions options, Action<Server> act) => options.InclExtendedDetails
     ? TryGetServersFromSteam(appId, addresses, options, act)
     : GetFromGameServerQuery(addresses, options, act);
        private static async Task<BatchResult> GetFromGameServerQuery(
            IEnumerable<IPEndPoint> addresses, ServerQueryOptions options, Action<Server> act) {
            var q = new ReactiveSource();
            using (var client = q.CreateUdpClient()) {
                var results = q.ProcessResults(q.GetResults(addresses, client, new QuerySettings {
                    InclPlayers = options.InclPlayers,
                    InclRules = options.InclExtendedDetails
                }));
                results = options.InclPlayers ? results.Do(x => MapServerInclPlayers(act, x)) : results.Do(x => MapServer(act, x));

                return new BatchResult(await results.Count());
            }
        }
 public Task<BatchResult> GetServerInfos(IServerQueryFactory factory, IReadOnlyCollection<IPEndPoint> addresses,
         Action<Server> act, ServerQueryOptions options)
     => GetFromGameServerQuery(addresses, options, act);