protected void LoadCountry(JObject json) { var value = json.GetStringValueOnly("country")?.Trim(); Country = value != null?AcStringValues.CountryFromTag(value) ?? value: Tags.Select(AcStringValues.CountryFromTag).FirstOrDefault(x => x != null); }
private static string GetItemName(string key, out string category) { string name; var pieces = key.Split(new[] { '@' }, 2); if (pieces.Length == 2) { category = AcStringValues.NameFromId(pieces[0].ToLower()); name = pieces[1]; } else { category = null; name = key; } name = AcStringValues.NameFromId(name.ToLowerInvariant(), false); name = Regex.Replace(name, @"\bk\b", "coefficient"); name = Regex.Replace(name, @"\bmult\b", "multiplier"); name = Regex.Replace(name, @"\bref\b", "reference"); name = Regex.Replace(name, @"\bd\b", "Δ"); name = Regex.Replace(name, @"\b(?:Cx|Fz|Ls|rr|Xmu)\b", m => m.Value.ToUpperInvariant()); name = Regex.Replace(name, @"\b(?<= )\d\b", m => $"#{m.Value}"); name = Regex.Replace(name, @"\b[dD](x|y|camber)\b", m => $"Δ{m.Groups[1].Value.ToTitle()}"); name = Regex.Replace(name, @"\bexp([xy])\b", m => $"exp({m.Groups[1].Value.ToUpperInvariant()})"); return(name); }
protected override void LoadData(JObject json) { base.LoadData(json); Brand = json.GetStringValueOnly("brand"); if (string.IsNullOrEmpty(Brand)) { AddError(AcErrorType.Data_CarBrandIsMissing); } if (Country == null && Brand != null) { Country = AcStringValues.CountryFromBrand(Brand); } CarClass = json.GetStringValueOnly("class"); ParentId = json.GetStringValueOnly("parent"); var specsObj = json["specs"] as JObject; SpecsBhp = specsObj?.GetStringValueOnly("bhp"); SpecsTorque = specsObj?.GetStringValueOnly("torque"); SpecsWeight = specsObj?.GetStringValueOnly("weight"); SpecsTopSpeed = specsObj?.GetStringValueOnly("topspeed"); SpecsAcceleration = specsObj?.GetStringValueOnly("acceleration"); SpecsPwRatio = specsObj?.GetStringValueOnly("pwratio"); SpecsTorqueCurve = new GraphData(json["torqueCurve"] as JArray); SpecsPowerCurve = new GraphData(json["powerCurve"] as JArray); }
public static IEnumerable <string> CleanUp(IEnumerable <string> tags) { return(tags.Select(x => { var s = x.Trim().ApartFromLast("\"]").ApartFromFirst("[\"").Trim(); if (Regex.IsMatch(s, @"^#?[abAB]\d\d?$")) { return null; } if (s[0] == '#') { return s; } var t = s.ToLower(); switch (t) { case "natural": return null; case "racing": return @"race"; case "american": return @"usa"; case "road": return @"street"; default: return AcStringValues.CountryFromTag(t)?.ToLower() ?? t; } }).Where(x => !string.IsNullOrWhiteSpace(x)).Distinct()); }
protected override void LoadData(JObject json) { base.LoadData(json); if (Version == null && Description != null) { string description; Version = AcStringValues.GetVersionFromName(Description, out description); if (Version != null) { Description = description; } } City = json.GetStringValueOnly("city"); GeoTags = json.GetGeoTagsValueOnly("geotags"); if (Country == null) { foreach (var country in Tags.Select(AcStringValues.CountryFromTag).Where(x => x != null)) { Country = country; break; } } SpecsLength = json.GetStringValueOnly("length"); SpecsWidth = json.GetStringValueOnly("width"); SpecsPitboxes = json.GetStringValueOnly("pitboxes"); }
private WorkshopValidatedItem TestCarBrand() { var originalBrand = Target.Brand; if (string.IsNullOrWhiteSpace(originalBrand)) { var brandFromName = AcStringValues.BrandFromName(Target.NameEditable ?? ""); if (brandFromName != null) { return(new WorkshopValidatedItem($"Car brand will be “{brandFromName}”", () => Target.Brand = brandFromName, () => Target.Brand = originalBrand)); } return(new WorkshopValidatedItem("Car brand is required", WorkshopValidatedState.Failed)); } var trimmed = originalBrand.Trim(); var knownBrand = FilesStorage.Instance.GetContentFiles(ContentCategory.BrandBadges).Select(x => x.Name).FirstOrDefault(x => string.Equals(x, trimmed, StringComparison.OrdinalIgnoreCase)); if (knownBrand != null) { return(knownBrand == originalBrand ? new WorkshopValidatedItem("Car brand is correct") : new WorkshopValidatedItem($"Car brand might contain a typo, will be changed to {knownBrand}", () => Target.Brand = knownBrand, () => Target.Brand = originalBrand)); } return(new WorkshopValidatedItem("Car brand is unknown, car won’t be in any known car brand category", WorkshopValidatedState.Warning)); }
protected override void LoadData(IniFile ini) { Name = ini["SERIES"].GetPossiblyEmpty("NAME"); Code = ini["SERIES"].GetPossiblyEmpty("CODE"); Description = AcStringValues.DecodeDescription(ini["SERIES"].GetPossiblyEmpty("DESCRIPTION")); PointsForPlace = ini["SERIES"].GetPossiblyEmpty("POINTS")?.Split(',').Select(x => FlexibleParser.TryParseInt(x)).OfType <int>().ToArray(); ChampionshipPointsGoal = ini["GOALS"].GetIntNullable("POINTS") ?? 0; ChampionshipRankingGoal = ini["GOALS"].GetIntNullable("RANKING") ?? 0; ThirdPlacesGoal = ini["GOALS"].GetIntNullable("TIER1") ?? 0; SecondPlacesGoal = ini["GOALS"].GetIntNullable("TIER2") ?? 0; FirstPlacesGoal = ini["GOALS"].GetIntNullable("TIER3") ?? 0; Type = ChampionshipPointsGoal == 0 && ChampionshipRankingGoal == 0 || PointsForPlace?.Sum() == 0 ? KunosCareerObjectType.SingleEvents : KunosCareerObjectType.Championship; RequiredSeries = ini["SERIES"].GetStrings("REQUIRES").ToArray(); RequiredAnySeries = ini["SERIES"].GetBool("REQUIRESANY", false); ChampionshipPointsPerPlace = ini["SERIES"].GetStrings("POINTS").Select(x => FlexibleParser.TryParseInt(x)).OfType <int>().ToArray(); if (Type == KunosCareerObjectType.Championship) { LoadOpponents(); } }
protected virtual void LoadYear(JObject json) { Year = json.GetIntValueOnly("year"); if (!Year.HasValue && Name != null) { Year = AcStringValues.GetYearFromName(Name) ?? AcStringValues.GetYearFromId(Name); } }
protected override bool LoadJsonOrThrow() { if (!File.Exists(JsonFilename)) { ClearData(); Name = AcStringValues.NameFromId(Id); Changed = true; return(true); } return(base.LoadJsonOrThrow()); }
private static int GetCategory(string s) { if (s[0] == '#') { return(0); } switch (s.ToLower()) { case "4wd": case "awd": case "fwd": case "rwd": return(10); case "automatic": case "manual": case "semiautomatic": case "sequential": return(20); case "h-shifter": return(21); case "compressor": case "turbo": case "v4": case "v6": case "v8": case "v10": case "v12": return(25); case "lightweight": case "heavyweight": case "subcompact": return(28); case "drift": case "rally": case "race": case "racing": case "street": case "sportscar": case "trackday": case "wrc": return(30); default: return(AcStringValues.CountryFromTag(s) != null ? 100 : 50); } }
public CarSkinObject([NotNull] string carId, IFileAcManager manager, string id, bool enabled) : base(manager, id, enabled) { CarId = carId; _nameFromId = new Lazy <string>(() => { var cut = Regex.Replace(Id, @"^\d\d?_", ""); if (string.IsNullOrEmpty(cut)) { cut = Id; } return(AcStringValues.NameFromId(cut)); }); }
protected override IEnumerable <string> GetForcedTags() { var drivetrainIni = Target.AcdData?.GetIniFile("drivetrain.ini"); var tractionType = drivetrainIni?["TRACTION"].GetNonEmpty("TYPE"); if (tractionType == "RWD") { yield return("rwd"); } else if (tractionType == "FWD") { yield return("fwd"); } else if (tractionType == "AWD") { yield return("awd"); } var gearsCount = drivetrainIni?["GEARS"].GetIntNullable("COUNT"); var supportsShifter = drivetrainIni?["GEARBOX"].GetBoolNullable("SUPPORTS_SHIFTER"); if (gearsCount > 1 && supportsShifter.HasValue) { yield return(supportsShifter.Value ? "manual" : "semiautomatic"); } if (Target.CarClass == "street") { yield return("street"); } else if (Target.CarClass == "race") { yield return("race"); } else { yield return(GuessCarClass()); } yield return(Target.Country != null?AcStringValues.CountryFromTag(Target.Country) : GuessCountry()); if (Target.AcdData?.GetIniFile("engine.ini")["TURBO_0"].ContainsKey("MAX_BOOST") == true) { yield return("turbo"); } if (Target.Year < 1990) { yield return("vintage"); } }
public override void SaveData(IniFile ini) { ini["SERIES"].Set("NAME", Name); ini["SERIES"].Set("CODE", Code); ini["SERIES"].Set("DESCRIPTION", AcStringValues.EncodeDescription(Description)); ini["SERIES"].Set("POINTS", PointsForPlace.JoinToString(@",")); ini["GOALS"].Set("POINTS", ChampionshipPointsGoal); ini["GOALS"].Set("RANKING", ChampionshipRankingGoal); ini["GOALS"].Set("TIER1", ThirdPlacesGoal); ini["GOALS"].Set("TIER2", SecondPlacesGoal); ini["GOALS"].Set("TIER3", FirstPlacesGoal); ini["SERIES"].Set("REQUIRES", RequiredSeries); ini["SERIES"].Set("REQUIRESANY", RequiredAnySeries); }
protected void LoadVersionInfo(JObject json) { Author = json.GetStringValueOnly("author")?.Trim() ?? (TestIfKunos() ? AuthorKunos : null); Version = json.GetStringValueOnly("version")?.Trim(); Url = json.GetStringValueOnly("url")?.Trim(); if (Version == null && Name != null) { string name; Version = AcStringValues.GetVersionFromName(Name, out name); if (Version != null) { Name = name; } } }
protected override void LoadYear(JObject json) { Year = json.GetIntValueOnly("year"); if (Year.HasValue) { return; } int year; if (DataProvider.Instance.CarYears.TryGetValue(Id, out year)) { Year = year; } else if (Name != null) { Year = AcStringValues.GetYearFromName(Name) ?? AcStringValues.GetYearFromId(Name); } }
protected override void LoadData(IniFile ini) { Name = ini["EVENT"].GetPossiblyEmpty("NAME"); Description = AcStringValues.DecodeDescription(ini["EVENT"].GetPossiblyEmpty("DESCRIPTION")); TrackId = ini["RACE"].GetNonEmpty("TRACK"); TrackConfigurationId = ini["RACE"].GetNonEmpty("CONFIG_TRACK"); CarId = ini["RACE"].GetNonEmpty("MODEL"); CarSkinId = ini["CAR_0"].GetNonEmpty("SKIN"); WeatherId = ini["WEATHER"].GetNonEmpty("NAME") ?? WeatherManager.Instance.GetDefault()?.Id; Time = (int)Game.ConditionProperties.GetSeconds(ini["LIGHTING"].GetInt("SUN_ANGLE", 40)); Temperature = ini["TEMPERATURE"].GetDouble("AMBIENT", 26); RoadTemperature = ini["TEMPERATURE"].GetDouble("ROAD", 32); TrackPreset = Game.DefaultTrackPropertiesPresets.GetByIdOrDefault(ini["DYNAMIC_TRACK"].GetIntNullable("PRESET")) ?? Game.DefaultTrackPropertiesPresets[4]; DisplayType = ini.ContainsKey(@"SESSION_1") ? ToolsStrings.Common_Weekend : (ini["SESSION_0"].GetNonEmpty("NAME")?.Replace(@" Session", "") ?? ToolsStrings.Session_Race); StartingPosition = ini["SESSION_0"].GetIntNullable("STARTING_POSITION"); OpponentsCount = ini["RACE"].GetInt("CARS", 1) - 1; if (OpponentsCount > 0 && StartingPosition == null) { StartingPosition = OpponentsCount + 1; } if (StartingPosition != null || ini.ContainsKey(@"SESSION_1")) { Laps = ini["SESSION_0"].GetIntNullable("LAPS") ?? ini["RACE"].GetIntNullable("RACE_LAPS") ?? 0; } else { Laps = null; } AiLevel = ini["RACE"].GetInt("AI_LEVEL", 100); LoadObjects(); LoadConditions(ini); LoadProgress(); }
public static MultiSolution TryToCreateNewFile(AcJsonObjectNew target) { if (target is ShowroomObject) { return(new MultiSolution( ToolsStrings.Solving_CreateNewFile, ToolsStrings.Solving_CreateNewFile_Commentary, e => { var jObject = new JObject { [@"name"] = AcStringValues.NameFromId(e.Target.Id) }; FileUtils.EnsureFileDirectoryExists(((AcJsonObjectNew)e.Target).JsonFilename); File.WriteAllText(((AcJsonObjectNew)e.Target).JsonFilename, jObject.ToString()); })); } if (target is CarSkinObject) { return(new MultiSolution( ToolsStrings.Solving_CreateNewFile, ToolsStrings.Solving_CreateNewFile_Commentary, e => { var jObject = new JObject { [@"skinname"] = CarSkinObject.NameFromId(e.Target.Id), [@"drivername"] = "", [@"country"] = "", [@"team"] = "", [@"number"] = @"0" }; if (!SettingsHolder.Content.SkinsSkipPriority) { jObject[@"priority"] = 1; } FileUtils.EnsureFileDirectoryExists(((AcJsonObjectNew)e.Target).JsonFilename); File.WriteAllText(((AcJsonObjectNew)e.Target).JsonFilename, jObject.ToString()); })); } return(null); }
protected override bool IsTagAllowed(string tag) { if (tag.StartsWith("#")) { return(tag.Length > 3 || tag.Length > 1 && tag[1] != 'A'); } if (tag == "vintage" && Target.Year > 2005) { return(false); } if (_prohibitedTags.Contains(tag)) { return(false); } if (AcStringValues.CountryFromTag(tag) != null) { return(false); } return(base.IsTagAllowed(tag)); }
public IAcObjectNew AddNew(string id = null) { var mainDirectory = Directories.GetMainDirectory(); if (id == null) { var uniqueId = Path.GetFileName(FileUtils.EnsureUnique(Path.Combine(mainDirectory, "skin"))); id = Prompt.Show("Choose a name for a new car skin:", "New car skin", required: true, maxLength: 80, placeholder: "?", defaultValue: uniqueId); if (id == null) { return(null); } } var directory = Directories.GetLocation(id, true); if (Directory.Exists(directory)) { throw new InformativeException("Can’t add a new object", $"ID “{id}” is already taken."); } using (IgnoreChanges()) { Directory.CreateDirectory(directory); File.WriteAllText(Path.Combine(directory, "ui_skin.json"), new JObject { ["skinname"] = AcStringValues.NameFromId(id), ["drivername"] = "", ["country"] = "", ["team"] = "", ["number"] = "", ["priority"] = 0 }.ToString(Formatting.Indented)); var obj = CreateAndLoadAcObject(id, true); InnerWrappersList.Add(new AcItemWrapper(this, obj)); UpdateList(true); return(obj); } }
protected virtual WorkshopValidatedItem TestCountry() { var originalCountry = Target.Country; var country = originalCountry != null?AcStringValues.CountryFromTag(originalCountry) : GuessCountry(); if (country != null) { return(country != originalCountry ? new WorkshopValidatedItem($"There might be a typo in the country’s name, will be changed to “{country}”", () => Target.Country = country, () => Target.Country = originalCountry) : new WorkshopValidatedItem("Country is correct")); } if (originalCountry != null) { return(new WorkshopValidatedItem("There might be a typo in the country’s name, it’s unknown to CM", WorkshopValidatedState.Failed)); } return(CountryRequired ? new WorkshopValidatedItem("Country is required", WorkshopValidatedState.Failed) : new WorkshopValidatedItem("Country is not set, but it’s optional")); }
protected sealed override void AddNewIfMissing(IList <SelectTag> list, TObject obj) { var value = obj.Tags; for (var j = value.Count - 1; j >= 0; j--) { var tagValue = value[j]; if (_ignored.Contains(tagValue)) { continue; } var isSpecial = tagValue.StartsWith(@"#"); var tagName = isSpecial ? tagValue.Substring(1).TrimStart() : tagValue; for (var i = list.Count - 1; i >= 0; i--) { var item = list[i]; if (string.Equals(item.DisplayName, tagName, StringComparison.Ordinal)) { IncreaseCounter(obj, item); item.Accented |= isSpecial; goto Next; } } if (!isSpecial && (AcStringValues.CountryFromTag(tagValue) != null || IsIgnored(obj, tagValue))) { _ignored.Add(tagValue); continue; } AddNewIfMissing(list, obj, new SelectTag(tagName, tagValue)); Next :; } }
public TagsCollection CleanUp() { // TODO: Special case for tracks? return(new TagsCollection(this.Select(x => { var s = x.Trim(); if (Regex.IsMatch(s, @"^#?[abAB]\d\d?$")) { return null; } if (s[0] == '#') { return s; } var t = s.ToLower(); switch (t) { case "natural": return null; case "racing": return @"race"; case "american": return @"usa"; case "road": return @"street"; default: return AcStringValues.CountryFromTag(t)?.ToLower() ?? t; } }).Where(x => !string.IsNullOrWhiteSpace(x)).Distinct())); }
public CmThemeEntry([NotNull] string path, [NotNull] string id, string version) : base(path, id, AcStringValues.NameFromId(id.ApartFromLast(".xaml", StringComparison.OrdinalIgnoreCase)), version) { }
private static string GetName(string id, string name) { return(name ?? AcStringValues.NameFromId(id)); }
public SystemConfigEntry([NotNull] string path, [NotNull] string id, string name = null) : base(path, id, name ?? AcStringValues.NameFromId(id.ApartFromLast(".ini", StringComparison.OrdinalIgnoreCase))) { _destination = Path.Combine(AcPaths.GetSystemCfgDirectory(AcRootDirectory.Instance.RequireValue), id); }
public TexturesConfigEntry([NotNull] string path, [NotNull] string id, string name = null) : base(path, id, name ?? AcStringValues.NameFromId(id)) { _destination = Path.Combine(AcRootDirectory.Instance.RequireValue, "content", "texture", id); }
protected override string GetBaseId() { var id = Path.GetFileNameWithoutExtension(_filename)?.ToLower(); return(AcStringValues.IsAppropriateId(id) ? id : null); }
protected override string GuessCountry() { return(base.GuessCountry() ?? (Target.Brand != null ? AcStringValues.CountryFromBrand(Target.Brand) : null)); }
private async Task <ContentEntryBase> CheckDirectoryNode(DirectoryNode directory, CancellationToken cancellation) { if (directory.Parent?.NameLowerCase == "python" && directory.Parent.Parent?.NameLowerCase == "apps" || directory.HasSubFile(directory.Name + ".py")) { var id = directory.Name; if (id == null) { // It’s unlikely there will be a car or a track in apps/python directory return(null); } // App? var root = directory.Parent?.Parent?.Parent; var gui = root?.GetSubDirectory("content")?.GetSubDirectory("gui")?.GetSubDirectory("icons"); // Collecting values… var missing = false; var uiAppFound = false; string version = null, name = null; // Maybe, it’s done nicely? var uiApp = directory.GetSubDirectory("ui")?.GetSubFile("ui_app.json"); if (uiApp != null) { uiAppFound = true; var data = await uiApp.Info.ReadAsync(); if (data == null) { missing = true; } else { var parsed = JsonExtension.Parse(data.ToUtf8String()); name = parsed.GetStringValueOnly("name"); version = parsed.GetStringValueOnly("version"); } } // Let’s try to guess version if (version == null && !uiAppFound) { foreach (var c in PythonAppObject.VersionSources.Select(directory.GetSubFile).NonNull()) { var r = await c.Info.ReadAsync(); if (r == null) { missing = true; } else { version = PythonAppObject.GetVersion(r.ToUtf8String()); if (version != null) { break; } } } } // And icon byte[] icon; List <FileNode> icons; if (gui != null) { icons = gui.Files.Where(x => x.NameLowerCase.EndsWith("_on.png") || x.NameLowerCase.EndsWith("_off.png")).ToList(); var mainIcon = icons.GetByIdOrDefault(directory.NameLowerCase + "_off.png") ?? icons.OrderByDescending(x => x.NameLowerCase.Length).FirstOrDefault(); icon = await(mainIcon?.Info.ReadAsync() ?? Task.FromResult((byte[])null)); if (mainIcon != null && icon == null) { missing = true; } cancellation.ThrowIfCancellationRequested(); } else { icon = null; icons = null; } if (missing) { throw new MissingContentException(); } return(new PythonAppContentEntry(directory.Key ?? "", id, name ?? id, version, icon, icons?.Select(x => x.Key))); } var ui = directory.GetSubDirectory("ui"); if (ui != null) { // Is it a car? var uiCar = ui.GetSubFile("ui_car.json"); if (uiCar != null) { var icon = await(ui.GetSubFile("badge.png")?.Info.ReadAsync() ?? Task.FromResult((byte[])null)); cancellation.ThrowIfCancellationRequested(); var data = await uiCar.Info.ReadAsync() ?? throw new MissingContentException(); var parsed = JsonExtension.Parse(data.ToUtf8String()); var carId = directory.Name ?? directory.GetSubDirectory("sfx")?.Files.Select(x => x.NameLowerCase) .FirstOrDefault(x => x.EndsWith(@".bank") && x.Count('.') == 1 && x != @"common.bank")?.ApartFromLast(@".bank"); if (carId != null) { return(new CarContentEntry(directory.Key ?? "", carId, parsed.GetStringValueOnly("parent") != null, parsed.GetStringValueOnly("name"), parsed.GetStringValueOnly("version"), icon)); } } // A track? var foundTrack = await CheckDirectoryNodeForTrack(directory, cancellation); if (foundTrack != null) { return(foundTrack); } // Or maybe a showroom? var uiShowroom = ui.GetSubFile(@"ui_showroom.json"); if (uiShowroom != null) { var icon = await(directory.GetSubFile(@"preview.jpg")?.Info.ReadAsync() ?? Task.FromResult((byte[])null)); cancellation.ThrowIfCancellationRequested(); var data = await uiShowroom.Info.ReadAsync() ?? throw new MissingContentException(); var parsed = JsonExtension.Parse(data.ToUtf8String()); var showroomId = directory.Name ?? directory.Files.Where(x => x.NameLowerCase.EndsWith(@".kn5")).OrderByDescending(x => x.Info.Size) .FirstOrDefault()?.NameLowerCase.ApartFromLast(@".kn5"); if (showroomId != null) { return(new ShowroomContentEntry(directory.Key ?? "", showroomId, parsed.GetStringValueOnly("name"), parsed.GetStringValueOnly("version"), icon)); } } } else { // Another case for showrooms if (directory.Name != null && directory.HasSubFile(directory.Name + @".kn5") && directory.HasSubFile(@"colorCurves.ini") && directory.HasSubFile(@"ppeffects.ini")) { var icon = directory.HasSubFile(@"preview.jpg") ? await(directory.GetSubFile(@"preview.jpg")?.Info.ReadAsync() ?? throw new MissingContentException()) : null; cancellation.ThrowIfCancellationRequested(); return(new ShowroomContentEntry(directory.Key ?? "", directory.Name ?? throw new ArgumentException(), iconData: icon)); } } var uiTrackSkin = directory.GetSubFile("ui_track_skin.json"); if (uiTrackSkin != null && TracksManager.Instance != null) { var icon = await(directory.GetSubFile("preview.png")?.Info.ReadAsync() ?? Task.FromResult((byte[])null)); cancellation.ThrowIfCancellationRequested(); var data = await uiTrackSkin.Info.ReadAsync() ?? throw new MissingContentException(); var parsed = JsonExtension.Parse(data.ToUtf8String()); var skinId = parsed.GetStringValueOnly("id") ?? directory.Name; var trackId = parsed.GetStringValueOnly("track"); var name = parsed.GetStringValueOnly("name"); if (skinId != null && trackId != null) { return(new TrackSkinContentEntry(directory.Key ?? "", skinId, trackId, name, parsed.GetStringValueOnly("version"), icon)); } } if (directory.HasSubFile("settings.ini")) { var kn5 = directory.Files.Where(x => x.NameLowerCase.EndsWith(@".kn5")).ToList(); var id = directory.Name; if (id != null) { if (kn5.Any(x => x.NameLowerCase.ApartFromLast(@".kn5") == directory.NameLowerCase)) { var icon = await(directory.GetSubFile("preview.jpg")?.Info.ReadAsync() ?? Task.FromResult((byte[])null)); cancellation.ThrowIfCancellationRequested(); return(new ShowroomContentEntry(directory.Key ?? "", id, AcStringValues.NameFromId(id), null, icon)); } } } var weatherIni = directory.GetSubFile("weather.ini"); if (weatherIni != null) { var icon = await(directory.GetSubFile("preview.jpg")?.Info.ReadAsync() ?? Task.FromResult((byte[])null)); cancellation.ThrowIfCancellationRequested(); var data = await weatherIni.Info.ReadAsync() ?? throw new MissingContentException(); var parsed = IniFile.Parse(data.ToUtf8String()); var name = parsed["LAUNCHER"].GetNonEmpty("NAME"); if (name != null) { var id = directory.Name ?? name; return(new WeatherContentEntry(directory.Key ?? "", id, name, icon)); } } var uiCarSkin = directory.GetSubFile("ui_skin.json"); if ((uiCarSkin != null || directory.HasSubFile("preview.jpg") && directory.HasSubFile("livery.png")) && CarsManager.Instance != null /* for crawlers only */) { var icon = await(directory.GetSubFile("livery.png")?.Info.ReadAsync() ?? Task.FromResult((byte[])null)); cancellation.ThrowIfCancellationRequested(); string carId; var skinFor = await(directory.GetSubFile("cm_skin_for.json")?.Info.ReadAsync() ?? Task.FromResult((byte[])null)); if (skinFor != null) { carId = JsonExtension.Parse(skinFor.ToUtf8String())[@"id"]?.ToString(); } else { carId = _installationParams.CarId; if (carId == null && directory.Parent?.NameLowerCase == "skins") { carId = directory.Parent.Parent?.Name; } if (carId == null) { carId = AcContext.Instance.CurrentCar?.Id; } } if (carId == null) { throw new Exception("Can’t figure out car’s ID"); } var skinId = directory.Name; if (skinId != null) { string name; if (uiCarSkin != null) { var data = await uiCarSkin.Info.ReadAsync() ?? throw new MissingContentException(); var parsed = JsonExtension.Parse(data.ToUtf8String()); name = parsed.GetStringValueOnly("name"); } else { name = AcStringValues.NameFromId(skinId); } return(new CarSkinContentEntry(directory.Key ?? "", skinId, carId, name, icon)); } } // New textures if (directory.NameLowerCase == "damage" && directory.HasSubFile("flatspot_fl.png")) { return(new TexturesConfigEntry(directory.Key ?? "", directory.Name ?? @"damage")); } if (directory.Parent?.NameLowerCase == "crew_brand" && directory.HasSubFile("Brands_Crew.dds") && directory.HasSubFile("Brands_Crew.jpg") && directory.HasSubFile("Brands_Crew_NM.dds")) { return(new CrewBrandEntry(directory.Key ?? "", directory.Name ?? @"unknown")); } if (directory.Parent?.NameLowerCase == "crew_helmet" && directory.HasSubFile("Crew_HELMET_Color.dds")) { return(new CrewHelmetEntry(directory.Key ?? "", directory.Name ?? @"unknown")); } // TODO: More driver and crew textures if (directory.NameLowerCase == "clouds" && directory.Files.Any( x => (x.NameLowerCase.StartsWith(@"cloud") || directory.Parent?.NameLowerCase == "texture") && x.NameLowerCase.EndsWith(@".dds"))) { return(new TexturesConfigEntry(directory.Key ?? "", directory.Name ?? @"clouds")); } if (directory.NameLowerCase == "clouds_shared" && directory.Files.Any( x => (x.NameLowerCase.StartsWith(@"cloud") || directory.Parent?.NameLowerCase == "texture") && x.NameLowerCase.EndsWith(@".dds"))) { return(new TexturesConfigEntry(directory.Key ?? "", directory.Name ?? @"clouds_shared")); } if (directory.NameLowerCase == "people" && (directory.HasSubFile("crowd_sit.dds") || directory.HasSubFile("people_sit.dds"))) { return(new TexturesConfigEntry(directory.Key ?? "", directory.Name ?? @"people")); } if (directory.HasSubFile(PatchHelper.MainFileName) && directory.HasSubDirectory("extension")) { var dwrite = directory.GetSubFile(PatchHelper.MainFileName); var extension = directory.GetSubDirectory("extension"); var manifest = directory.GetSubDirectory("extension")?.GetSubDirectory("config")?.GetSubFile("data_manifest.ini"); string version; if (manifest != null) { var data = await manifest.Info.ReadAsync() ?? throw new MissingContentException(); version = IniFile.Parse(data.ToUtf8String())["VERSION"].GetNonEmpty("SHADERS_PATCH"); } else { var description = directory.GetSubFile("description.jsgme"); if (description != null) { var data = await description.Info.ReadAsync() ?? throw new MissingContentException(); version = Regex.Match(data.ToUtf8String(), @"(?<=v)\d.*").Value?.TrimEnd('.').Or(null); } else { var parent = directory; while (parent.Parent?.Name != null) { parent = parent.Parent; } version = parent.Name != null?Regex.Match(parent.Name, @"(?<=v)\d.*").Value?.TrimEnd('.').Or(null) : null; } } return(new ShadersPatchEntry(directory.Key ?? "", new[] { dwrite.Key, extension.Key }, version)); } if (directory.NameLowerCase == "__gbwsuite") { return(new CustomFolderEntry(directory.Key ?? "", new[] { directory.Key }, "GBW scripts", "__gbwSuite")); } if (directory.HasSubFile("weather.lua") && directory.Parent.NameLowerCase == "weather") { return(new CustomFolderEntry(directory.Key ?? "", new[] { directory.Key }, $"Weather FX script “{AcStringValues.NameFromId(directory.Name)}”", Path.Combine(AcRootDirectory.Instance.RequireValue, "extension", "weather", directory.Name), 1e5)); } if (directory.HasSubFile("controller.lua") && directory.Parent.NameLowerCase == "weather-controllers") { return(new CustomFolderEntry(directory.Key ?? "", new[] { directory.Key }, $"Weather FX controller “{AcStringValues.NameFromId(directory.Name)}”", Path.Combine(AcRootDirectory.Instance.RequireValue, "extension", "weather-controllers", directory.Name), 1e5)); } // Mod if (directory.Parent?.NameLowerCase == "mods" && (directory.HasAnySubDirectory("content", "apps", "system", "launcher", "extension") || directory.HasSubFile(PatchHelper.MainFileName))) { var name = directory.Name; if (name != null && directory.GetSubDirectory("content")?.GetSubDirectory("tracks")?.Directories.Any( x => x.GetSubDirectory("skins")?.GetSubDirectory("default")?.GetSubFile("ui_track_skin.json") != null) != true) { var description = directory.Files.FirstOrDefault(x => x.NameLowerCase.EndsWith(@".jsgme")); if (description == null && directory.HasSubDirectory("documentation")) { description = directory.GetSubDirectory("documentation")?.Files.FirstOrDefault(x => x.NameLowerCase.EndsWith(@".jsgme")); } if (description != null) { var data = await description.Info.ReadAsync() ?? throw new MissingContentException(); return(new GenericModConfigEntry(directory.Key ?? "", name, data.ToUtf8String())); } return(new GenericModConfigEntry(directory.Key ?? "", name)); } } return(null); }
public static string NameFromId([NotNull] string id) { return(AcStringValues.NameFromId(IdFix.Replace(id, ""))); }