AcManager.Tools.Managers.Online.ServerEntry.UpdateInner C# (CSharp) Method

UpdateInner() private method

private UpdateInner ( UpdateMode mode, bool background = false ) : System.Threading.Tasks.Task
mode UpdateMode
background bool
return System.Threading.Tasks.Task
        private async Task UpdateInner(UpdateMode mode, bool background = false) {
            var errorMessage = "";

            try {
                if (!background) {
                    CurrentDrivers.Clear();
                    OnPropertyChanged(nameof(CurrentDrivers));

                    Status = ServerStatus.Loading;
                    IsAvailable = false;
                }

                SetMissingTrackErrorIfNeeded(ref errorMessage);
                SetMissingCarErrorIfNeeded(ref errorMessage);
                if (!string.IsNullOrWhiteSpace(errorMessage)) return;

                if (!IsLan && SteamIdHelper.Instance.Value == null) {
                    throw new InformativeException(ToolsStrings.Common_SteamIdIsMissing);
                }

                if (mode == UpdateMode.Full) {
                    var newInformation = await Task.Run(() => IsLan || SettingsHolder.Online.LoadServerInformationDirectly
                            ? KunosApiProvider.TryToGetInformationDirect(Ip, PortC) : KunosApiProvider.TryToGetInformation(Ip, Port));
                    if (newInformation == null) {
                        errorMessage = ToolsStrings.Online_Server_CannotRefresh;
                        return;
                    } else if (!UpdateValuesFrom(newInformation)) {
                        errorMessage = ToolsStrings.Online_Server_NotImplemented;
                        return;
                    }
                }

                var pair = SettingsHolder.Online.ThreadsPing
                        ? await Task.Run(() => KunosApiProvider.TryToPingServer(Ip, Port, SettingsHolder.Online.PingTimeout))
                        : await KunosApiProvider.TryToPingServerAsync(Ip, Port, SettingsHolder.Online.PingTimeout);
                if (pair != null) {
                    Ping = (long)pair.Item2.TotalMilliseconds;
                } else {
                    Ping = null;
                    errorMessage = ToolsStrings.Online_Server_CannotPing;
                    return;
                }

                var information = await KunosApiProvider.TryToGetCurrentInformationAsync(Ip, PortC);
                if (information == null) {
                    errorMessage = ToolsStrings.Online_Server_Unavailable;
                    return;
                }

                ActualInformation = information;
                if (CurrentDrivers.ReplaceIfDifferBy(from x in information.Cars
                                                     where x.IsConnected
                                                     select new CurrentDriver {
                                                         Name = x.DriverName,
                                                         Team = x.DriverTeam,
                                                         CarId = x.CarId,
                                                         CarSkinId = x.CarSkinId
                                                     })) {
                    OnPropertyChanged(nameof(CurrentDrivers));
                }

                // CurrentDriversCount = information.Cars.Count(x => x.IsConnected);
                
                List<CarObject> carObjects;
                if (CarsOrTheirIds.Select(x => x.CarObjectWrapper).Any(x => x?.IsLoaded == false)) {
                    await Task.Delay(50);
                    carObjects = new List<CarObject>(CarsOrTheirIds.Count);
                    foreach (var carOrOnlyCarIdEntry in CarsOrTheirIds.Select(x => x.CarObjectWrapper).Where(x => x != null)) {
                        var loaded = await carOrOnlyCarIdEntry.LoadedAsync();
                        carObjects.Add((CarObject)loaded);
                    }
                } else {
                    carObjects = (from x in CarsOrTheirIds
                                  where x.CarObjectWrapper != null
                                  select (CarObject)x.CarObjectWrapper.Value).ToList();
                }

                foreach (var carObject in carObjects.Where(carObject => carObjects.Any(x => !x.SkinsManager.IsLoaded))) {
                    await Task.Delay(50);
                    await carObject.SkinsManager.EnsureLoadedAsync();
                }

                List<CarEntry> cars;
                if (BookingMode) {
                    cars = CarsOrTheirIds.Select(x => x.CarObject == null ? null : new CarEntry(x.CarObject) {
                        AvailableSkin = x.CarObject.SelectedSkin
                    }).ToList();
                } else {
                    cars = information.Cars.Where(x => x.IsEntryList)
                                      .GroupBy(x => x.CarId)
                                      .Select(g => {
                                          var group = g.ToList();
                                          var id = group[0].CarId;
                                          var existing = Cars?.GetByIdOrDefault(id);
                                          if (existing != null) {
                                              var car = existing.CarObject;
                                              var availableSkinId = group.FirstOrDefault(y => y.IsConnected == false)?.CarSkinId;
                                              existing.Total = group.Count;
                                              existing.Available = group.Count(y => !y.IsConnected && y.IsEntryList);
                                              existing.AvailableSkin = availableSkinId == null
                                                      ? null : availableSkinId == string.Empty ? car.GetFirstSkinOrNull() : car.GetSkinById(availableSkinId);
                                              return existing;
                                          } else {
                                              var car = carObjects.GetByIdOrDefault(id, StringComparison.OrdinalIgnoreCase);
                                              if (car == null) return null;

                                              var availableSkinId = group.FirstOrDefault(y => y.IsConnected == false)?.CarSkinId;
                                              return new CarEntry(car) {
                                                  Total = group.Count,
                                                  Available = group.Count(y => !y.IsConnected && y.IsEntryList),
                                                  AvailableSkin = availableSkinId == null ? null : availableSkinId == string.Empty
                                                          ? car.GetFirstSkinOrNull() : car.GetSkinById(availableSkinId)
                                              };
                                          }
                                      }).ToList();
                }

                if (cars.Contains(null)) {
                    errorMessage = ToolsStrings.Online_Server_CarsDoNotMatch;
                    return;
                }

                var changed = true;
                if (Cars == null || CarsView == null) {
                    Cars = new BetterObservableCollection<CarEntry>(cars);
                    CarsView = new ListCollectionView(Cars) { CustomSort = this };
                    CarsView.CurrentChanged += SelectedCarChanged;
                } else {
                    // temporary removing listener to avoid losing selected car
                    CarsView.CurrentChanged -= SelectedCarChanged;
                    if (Cars.ReplaceIfDifferBy(cars)) {
                        OnPropertyChanged(nameof(Cars));
                    } else {
                        changed = false;
                    }

                    CarsView.CurrentChanged += SelectedCarChanged;
                }

                if (changed) {
                    LoadSelectedCar();
                }
            } catch (InformativeException e) {
                errorMessage = $"{e.Message}.";
            } catch (Exception e) {
                errorMessage = string.Format(ToolsStrings.Online_Server_UnhandledError, e.Message);
                Logging.Warning("UpdateInner(): " + e);
            } finally {
                ErrorMessage = errorMessage;
                if (!string.IsNullOrWhiteSpace(errorMessage)) {
                    Status = ServerStatus.Error;
                } else if (Status == ServerStatus.Loading) {
                    Status = ServerStatus.Ready;
                }

                AvailableUpdate();
            }
        }