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();
}
}