public virtual async Task<IReadOnlyList<ContentEntry>> GetEntriesAsync(IProgress<string> progress, CancellationToken cancellation) {
var result = new List<ContentEntry>();
var found = new List<string>();
var list = (await GetFileEntriesAsync()).ToList();
foreach (var fileInfo in list) {
var name = Path.GetFileName(fileInfo.Filename)?.ToLower();
if (name == null) continue;
progress?.Report(name);
if (cancellation.IsCancellationRequested) break;
ContentType type;
string entryDirectory;
switch (name) {
case "ui_car.json": {
type = ContentType.Car;
var directory = Path.GetDirectoryName(fileInfo.Filename);
if (!string.Equals(Path.GetFileName(directory), @"ui", StringComparison.OrdinalIgnoreCase)) continue;
entryDirectory = Path.GetDirectoryName(directory);
break;
}
case "//ui_skin.json": {
// TODO (disabled atm)
// TODO: detect by preview.jpg & livery.png
type = ContentType.CarSkin;
entryDirectory = Path.GetDirectoryName(fileInfo.Filename);
break;
}
case "ui_track.json": {
type = ContentType.Track;
var directory = Path.GetDirectoryName(fileInfo.Filename);
if (!string.Equals(Path.GetFileName(directory), @"ui", StringComparison.OrdinalIgnoreCase)) {
directory = Path.GetDirectoryName(directory);
}
if (!string.Equals(Path.GetFileName(directory), @"ui", StringComparison.OrdinalIgnoreCase)) continue;
entryDirectory = Path.GetDirectoryName(directory);
break;
}
case "ui_showroom.json": {
type = ContentType.Showroom;
var directory = Path.GetDirectoryName(fileInfo.Filename);
if (!string.Equals(Path.GetFileName(directory), @"ui", StringComparison.OrdinalIgnoreCase)) continue;
entryDirectory = Path.GetDirectoryName(directory);
break;
}
default:
continue;
}
if (entryDirectory == null) {
Logging.Warning("Entry directory is null: " + fileInfo.Filename);
continue;
}
if (found.Contains(entryDirectory)) continue;
found.Add(entryDirectory);
var id = entryDirectory != string.Empty ? Path.GetFileName(entryDirectory) : Path.GetFileNameWithoutExtension(GetBaseId() ?? "");
if (string.IsNullOrEmpty(id)) {
Logging.Warning("ID is empty: " + fileInfo.Filename);
continue;
}
JObject jObject;
try {
var jsonBytes = await fileInfo.ReadAsync();
jObject = JsonExtension.Parse(jsonBytes.ToUtf8String());
} catch (Exception e) {
Logging.Warning("Can’t read as a JSON (" + fileInfo.Filename + "): " + e);
continue;
}
result.Add(new ContentEntry(type, entryDirectory, id.ToLower(), jObject.GetStringValueOnly("name"),
jObject.GetStringValueOnly("version")));
}
result.AddRange(from fileInfo in list
select fileInfo.Filename
into filename
let directory = Path.GetDirectoryName(filename)
// only something in fonts/ or directly in root
where string.IsNullOrWhiteSpace(directory) ||
String.Equals(Path.GetFileName(directory), @"fonts", StringComparison.OrdinalIgnoreCase)
// only something ends on .txt
where filename.EndsWith(FontObject.FontExtension, StringComparison.OrdinalIgnoreCase)
let withoutExtension = filename.ApartFromLast(FontObject.FontExtension)
// only something with a name which is a valid id
where AcStringValues.IsAppropriateId(Path.GetFileName(withoutExtension))
let bitmap = FontObject.BitmapExtensions.Select(x => list.GetByPathOrDefault(withoutExtension + x)).FirstOrDefault(x => x != null)
// only something with a bitmap nearby
where bitmap != null
select new ContentEntry(ContentType.Font, bitmap.Filename, Path.GetFileName(filename)?.ToLower() ?? "",
Path.GetFileName(withoutExtension)));
return result;
}