コード例 #1
0
        public async Task ATest()
        {
            var path = AcRootFinder.Find();

            if (!Directory.Exists(path))
            {
                Debug.WriteLine("REQUIRED ASSET IS MISSING, TEST CANNOT BE DONE");
                return;
            }

            var cars = Directory.GetDirectories(Path.Combine(path, "content", "cars"), "ks_*").Select(x => new {
                CarId    = Path.GetFileName(x),
                SkinsIds = Directory.GetDirectories(Path.Combine(x, "skins")).Select(Path.GetFileName).ToList()
            }).Where(x => Regex.IsMatch(x.CarId, @"^ks_[a]")).ToList();

            var sw = Stopwatch.StartNew();
            var i  = 0;

            using (var updater = new DarkPreviewsUpdater(path)) {
                foreach (var car in cars)
                {
                    foreach (var skin in car.SkinsIds)
                    {
                        await updater.ShotAsync(car.CarId, skin);

                        i++;
                    }
                }
            }

            Console.WriteLine($"Done: {i} skins ({sw.Elapsed.TotalMilliseconds / i:F1} ms per skin)");
        }
コード例 #2
0
            private void PrepareUpdater()
            {
                var options = Settings.ToPreviewsOptions();

                if (_previewsUpdater == null)
                {
                    _previewsUpdater = new DarkPreviewsUpdater(AcRootDirectory.Instance.RequireValue, options);
                }
                else
                {
                    _previewsUpdater.SetOptions(options);
                }
            }
コード例 #3
0
            public Updater([NotNull] IReadOnlyList <ToUpdatePreview> entries, [NotNull] DarkPreviewsOptions options, [CanBeNull] string presetName,
                           [CanBeNull] DarkPreviewsUpdater updater)
            {
                _entries    = entries;
                _options    = options;
                _presetName = presetName;

                if (updater == null)
                {
                    _localUpdater = true;
                    _updater      = new DarkPreviewsUpdater(AcRootDirectory.Instance.RequireValue, options);
                }
                else
                {
                    _updater = updater;
                    _updater.SetOptions(options);
                }
            }
コード例 #4
0
ファイル: Program.cs プロジェクト: WildGenie/actools
        private static int MainInner(string[] args)
        {
            var presets    = args.Where(x => x.EndsWith(".pu-preset")).ToList();
            var actualList = new List <string>();

            foreach (var preset in presets)
            {
                try {
                    actualList.AddRange(
                        File.ReadAllLines(preset)
                        .Where(x => !x.StartsWith("#"))
                        .Select(x => x.Split(new[] { " #" }, StringSplitOptions.None)[0].Trim())
                        .Where(x => x.Length > 0));
                } catch (Exception e) {
                    Console.Error.WriteLine($"Can't load preset {preset}: {e.Message}.");
                }
            }

            actualList.AddRange(args.ApartFrom(presets));

            var options = new Options();

            if (!Parser.Default.ParseArguments(actualList.ToArray(), options))
            {
                return(1);
            }

            if (options.ColorGradingFilename != null && presets.Count > 0 && !File.Exists(options.ColorGradingFilename))
            {
                var locations = presets.Select(Path.GetDirectoryName).ToList();
                var current   = Environment.CurrentDirectory;
                foreach (var location in locations)
                {
                    Environment.CurrentDirectory = location;
                    var path = Path.GetFullPath(options.ColorGradingFilename);
                    if (File.Exists(path))
                    {
                        options.ColorGradingFilename = path;
                    }
                }

                Environment.CurrentDirectory = current;
            }

            var acRoot = options.AcRoot == null?AcRootFinder.TryToFind() : Path.GetFullPath(options.AcRoot);

            if (acRoot == null)
            {
                Console.Error.WriteLine("Can't find AC root directory, you need to specify it manually.");
                Console.ReadLine();
                return(1);
            }

            var ids = options.Ids.ApartFrom(presets).ToList();

            if (ids.Count == 0)
            {
                Console.Error.WriteLine("You forgot to specify what cars to update: either list their IDs or filters.");
                Console.Error.WriteLine("To process all cars, use filter \"*\".");
                Console.ReadLine();
                return(1);
            }

            IFilter <string> filter;

            try {
                filter = Filter.Create(new CarTester(acRoot), ids.Select(x =>
                                                                         "(" + (x.EndsWith("/") ? x.Substring(0, x.Length - 1) : x) + ")").JoinToString("|"), true);
                if (options.FilterTest)
                {
                    Console.WriteLine(Directory.GetDirectories(FileUtils.GetCarsDirectory(acRoot))
                                      .Select(Path.GetFileName).Where(x => filter.Test(x)).JoinToString(", "));
                    return(0);
                }

                if (options.Verbose)
                {
                    Console.WriteLine("Filter: " + filter);
                }
            } catch (Exception e) {
                Console.Error.WriteLine("Can't parse filter: " + e.Message + ".");
                Console.ReadLine();
                return(2);
            }

            if (options.Verbose)
            {
                Console.WriteLine("AC root: " + acRoot);
                Console.WriteLine("ImageMagick: " + ImageUtils.IsMagickSupported);
                Console.WriteLine("Starting shoting...");
            }

            var sw = Stopwatch.StartNew();
            int i = 0, j = 0;

            using (var thing = new DarkPreviewsUpdater(acRoot, new DarkPreviewsOptions {
                PreviewName = options.FileName,
                Showroom = options.Showroom,
                AlignCar = options.AlignCar,
                AlignCameraHorizontally = options.AlignCamera,
                AlignCameraHorizontallyOffset = options.AlignCameraOffset.Split(',').Select(x => FlexibleParser.TryParseDouble(x) ?? 0d).ToArray()[0], // TODO
                SsaaMultiplier = options.SsaaMultiplier,
                UseFxaa = options.UseFxaa,
                UseMsaa = options.UseMsaa,
                SoftwareDownsize = options.SoftwareDownsize,
                MsaaSampleCount = options.MsaaSampleCount,
                PreviewWidth = options.PreviewWidth,
                PreviewHeight = options.PreviewHeight,
                BloomRadiusMultiplier = options.BloomRadiusMultiplier,
                FlatMirror = options.FlatMirror,
                WireframeMode = options.WireframeMode,
                MeshDebugMode = options.MeshDebugMode,
                SuspensionDebugMode = options.SuspensionDebugMode,
                HeadlightsEnabled = options.HeadlightsEnabled,
                BrakeLightsEnabled = options.BrakeLightsEnabled,
                LeftDoorOpen = options.LeftDoorOpen,
                RightDoorOpen = options.RightDoorOpen,
                SteerDeg = options.SteerAngle,
                CameraPosition = options.CameraPosition.Split(',').Select(x => FlexibleParser.TryParseDouble(x) ?? 0d).ToArray(),
                CameraLookAt = options.LookAt.Split(',').Select(x => FlexibleParser.TryParseDouble(x) ?? 0d).ToArray(),
                CameraFov = options.Fov,
                BackgroundColor = ParseColor(options.BackgroundColor),
                LightColor = ParseColor(options.LightColor),
                AmbientUp = ParseColor(options.AmbientUp),
                AmbientDown = ParseColor(options.AmbientDown),
                AmbientBrightness = options.AmbientBrightness,
                LightBrightness = options.LightBrightness,
                DelayedConvertation = !options.SingleThread,
                UseSslr = options.UseSslr,
                UseAo = options.UseSsao,
                UsePcss = options.UsePcss,
                EnableShadows = options.EnableShadows,
                ShadowMapSize = options.ShadowMapSize,
                MaterialsReflectiveness = options.ReflectionMultiplier,
                ReflectionCubemapAtCamera = options.ReflectionCubemapAtCamera,
                ReflectionsWithShadows = !options.NoShadowsWithReflections,
                FlatMirrorBlurred = options.FlatMirrorBlurred,
                FlatMirrorReflectiveness = options.FlatMirrorReflectiveness,
                LightDirection = options.LightDirection.Split(',').Select(x => FlexibleParser.TryParseDouble(x) ?? 0d).ToArray(),
            })) {
                foreach (var carId in Directory.GetDirectories(FileUtils.GetCarsDirectory(acRoot))
                         .Select(Path.GetFileName).Where(x => filter.Test(x)))
                {
                    Console.WriteLine($"  {carId}...");
                    j++;

                    foreach (var skinId in Directory.GetDirectories(FileUtils.GetCarSkinsDirectory(acRoot, carId))
                             .Where(x => !options.WithoutPreviews || !File.Exists(Path.Combine(x, options.FileName)))
                             .Select(Path.GetFileName))
                    {
                        var success = false;
                        for (var a = 0; a < options.AttemptsCount || a == 0; a++)
                        {
                            try {
                                if (options.Verbose)
                                {
                                    Console.Write($"    {skinId}... ");
                                }
                                thing.Shot(carId, skinId);
                                success = true;
                                break;
                            } catch (Exception e) {
                                Console.Error.WriteLine(e.Message);

                                if (options.Verbose)
                                {
                                    Console.Error.WriteLine(e.StackTrace);
                                }
                            }
                        }

                        if (success)
                        {
                            i++;
                            if (options.Verbose)
                            {
                                Console.WriteLine("OK");
                            }
                        }
                    }

                    if (options.Verbose && j % 10 == 0)
                    {
                        Console.WriteLine(
                            $"At this moment done: {i} skins ({sw.Elapsed.TotalMilliseconds / j:F1} ms per car; {sw.Elapsed.TotalMilliseconds / i:F1} ms per skin)");
                        Console.WriteLine($"Time taken: {ToMillisecondsString(sw.Elapsed)}");
                    }
                }

                Console.Write("Finishing convertation... ");
            }

            Console.WriteLine("OK");
            Console.WriteLine($"Done: {i} skins ({sw.Elapsed.TotalMilliseconds / j:F1} ms per car; {sw.Elapsed.TotalMilliseconds / i:F1} ms per skin)");
            Console.WriteLine($"Time taken: {ToMillisecondsString(sw.Elapsed)}");

            return(0);
        }
コード例 #5
0
        private static async Task <IReadOnlyList <UpdatePreviewError> > UpdatePreview(IReadOnlyList <ToUpdatePreview> entries, DarkPreviewsOptions options, string presetName = null,
                                                                                      DarkPreviewsUpdater updater = null)
        {
            var localUpdater = updater == null;

            if (localUpdater)
            {
                updater = new DarkPreviewsUpdater(AcRootDirectory.Instance.RequireValue, options);
            }
            else
            {
                updater.SetOptions(options);
            }

            var errors = new List <UpdatePreviewError>();

            try {
                if (options.Showroom != null && ShowroomsManager.Instance.GetById(options.Showroom) == null)
                {
                    if (options.Showroom == "at_previews" && MissingShowroomHelper != null)
                    {
                        await MissingShowroomHelper.OfferToInstall("Kunos Previews Showroom (AT Previews Special)", "at_previews",
                                                                   "http://www.assettocorsa.net/assetto-corsa-v1-5-dev-diary-part-33/");

                        if (ShowroomsManager.Instance.GetById(options.Showroom) != null)
                        {
                            goto Action;
                        }
                    }

                    throw new InformativeException("Can’t update preview", $"Showroom “{options.Showroom}” is missing");
                }

Action:
                var checksum = options.GetChecksum();

                var finished = false;
                var j        = 0;

                using (var waiting = new WaitingDialog()) {
                    var cancellation = waiting.CancellationToken;

                    var singleMode     = entries.Count == 1;
                    var verySingleMode = singleMode && entries[0].Skins?.Count == 1;
                    var recycled       = 0;

                    if (!verySingleMode)
                    {
                        waiting.SetImage(null);

                        if (SettingsHolder.CustomShowroom.PreviewsRecycleOld)
                        {
                            waiting.SetMultiline(true);
                        }
                    }

                    var step    = 1d / entries.Count;
                    var postfix = string.Empty;

                    var started = Stopwatch.StartNew();
                    var approximateSkinsPerCarCars  = 1;
                    var approximateSkinsPerCarSkins = 10;

                    Action <int> updateApproximate = skinsPerCar => {
                        approximateSkinsPerCarCars++;
                        approximateSkinsPerCarSkins += skinsPerCar;
                    };

                    Func <int, int> leftSkins = currentEntry => {
                        var skinsPerCar = (double)approximateSkinsPerCarSkins / approximateSkinsPerCarCars;

                        var result = 0d;
                        for (var k = currentEntry; k < entries.Count; k++)
                        {
                            var entry = entries[k];
                            result += entry.Skins?.Count ?? skinsPerCar;
                        }

                        return(result.RoundToInt());
                    };

                    var shotSkins        = 0;
                    var recyclingWarning = false;
                    Func <CarObject, CarSkinObject, int?, IEnumerable <string> > getDetails = (car, skin, currentEntrySkinsLeft) => {
                        var left = leftSkins(j) + (currentEntrySkinsLeft ?? approximateSkinsPerCarSkins / approximateSkinsPerCarCars);

                        // ReSharper disable once AccessToModifiedClosure
                        var speed          = shotSkins / started.Elapsed.TotalMinutes;
                        var remainingTime  = speed < 0.0001 ? "Unknown" : $"About {TimeSpan.FromMinutes(left / speed).ToReadableTime()}";
                        var remainingItems = $"About {left} {PluralizingConverter.Pluralize(left, ControlsStrings.CustomShowroom_SkinHeader).ToSentenceMember()}";

                        return(new[] {
                            $"Car: {car?.DisplayName}",
                            $"Skin: {skin?.DisplayName ?? "?"}",
                            $"Speed: {speed:F2} {PluralizingConverter.Pluralize(10, ControlsStrings.CustomShowroom_SkinHeader).ToSentenceMember()}/{"min"}",
                            $"Time remaining: {remainingTime}",
                            $"Items remaining: {remainingItems}",

                            // ReSharper disable once AccessToModifiedClosure
                            recyclingWarning ? "[i]Recycling seems to take too long? If so, it can always be disabled in Settings.[/i]" : null
                        }.NonNull());
                    };

                    for (j = 0; j < entries.Count; j++)
                    {
                        if (cancellation.IsCancellationRequested)
                        {
                            goto Cancel;
                        }

                        var entry    = entries[j];
                        var progress = step * j;

                        var car   = entry.Car;
                        var skins = entry.Skins;

                        if (skins == null)
                        {
                            waiting.Report(new AsyncProgressEntry("Loading skins…" + postfix, verySingleMode ? 0d : progress));
                            waiting.SetDetails(getDetails(car, null, null));

                            await car.SkinsManager.EnsureLoadedAsync();

                            if (cancellation.IsCancellationRequested)
                            {
                                goto Cancel;
                            }

                            skins = car.EnabledOnlySkins.ToList();
                            updateApproximate(skins.Count);
                        }

                        var halfstep = step * 0.5 / skins.Count;
                        for (var i = 0; i < skins.Count; i++)
                        {
                            if (cancellation.IsCancellationRequested)
                            {
                                goto Cancel;
                            }

                            var skin = skins[i];
                            waiting.SetDetails(getDetails(car, skin, skins.Count - i));

                            var subprogress = progress + step * (0.1 + 0.8 * i / skins.Count);
                            if (SettingsHolder.CustomShowroom.PreviewsRecycleOld && File.Exists(skin.PreviewImage))
                            {
                                if (++recycled > 5)
                                {
                                    recyclingWarning = true;
                                }

                                waiting.Report(new AsyncProgressEntry($"Recycling current preview for {skin.DisplayName}…" + postfix, verySingleMode ? 0d : subprogress));
                                await Task.Run(() => FileUtils.Recycle(skin.PreviewImage));
                            }

                            waiting.Report(new AsyncProgressEntry($"Updating skin {skin.DisplayName}…" + postfix, verySingleMode ? 0d : subprogress + halfstep));

                            try {
                                await updater.ShotAsync(car.Id, skin.Id, skin.PreviewImage, car.AcdData, GetInformation(car, skin, presetName, checksum),
                                                        () => {
                                    if (!verySingleMode)
                                    {
                                        ActionExtension.InvokeInMainThreadAsync(() => {
                                            // ReSharper disable once AccessToModifiedClosure
                                            if (!finished)
                                            {
                                                // ReSharper disable once AccessToDisposedClosure
                                                waiting.SetImage(skin.PreviewImage);
                                            }
                                        });
                                    }
                                });

                                shotSkins++;
                            } catch (Exception e) {
                                if (errors.All(x => x.ToUpdate != entry))
                                {
                                    errors.Add(new UpdatePreviewError(entry, e.Message, null));
                                }
                            }
                        }
                    }

                    waiting.Report(new AsyncProgressEntry("Saving…" + postfix, verySingleMode ? 0d : 0.999999d));
                    await updater.WaitForProcessing();

                    finished = true;
                }

                if (errors.Count > 0)
                {
                    NonfatalError.Notify("Can’t update previews:\n" + errors.Select(x => @"• " + x.Message.ToSentence()).JoinToString(";" + Environment.NewLine));
                }

                goto End;

Cancel:
                for (; j < entries.Count; j++)
                {
                    errors.Add(new UpdatePreviewError(entries[j], ControlsStrings.Common_Cancelled, null));
                }

End:
                return(errors);
            } catch (Exception e) {
                NonfatalError.Notify("Can’t update preview", e);
                return(null);
            } finally {
                if (localUpdater)
                {
                    updater.Dispose();
                    GC.Collect();
                }
            }
        }