예제 #1
0
        public bool Test(string carId, string key, ITestEntry value)
        {
            switch (key)
            {
            case null:
                return(value.Test(carId));

            case "l":
            case "len":
            case "length":
                return(value.Test(carId.Length));

            case "k":
            case "kunos": {
                return(value.Test(TestIfKunosUsingGuids(carId)));
            }

            case "a":
            case "age": {
                var directory = AcPaths.GetCarDirectory(_acRoot, carId);
                var age       = File.GetCreationTime(directory);
                return(value.Test(DateTime.Now - age));
            }

            case "n":
            case "new": {
                var directory = AcPaths.GetCarDirectory(_acRoot, carId);
                var age       = File.GetCreationTime(directory);
                return(value.Test((DateTime.Now - age).TotalDays < 7d));
            }

            default:
                return(false);
            }
        }
예제 #2
0
        private CarDescription GetCarDescription([NotNull] string carId, [CanBeNull] DataWrapper carData)
        {
            var carDirectory = AcPaths.GetCarDirectory(_acRoot, carId);
            var carKn5       = carData == null?AcPaths.GetMainCarFilename(carDirectory) : AcPaths.GetMainCarFilename(carDirectory, carData);

            return(new CarDescription(carKn5, carDirectory));
        }
예제 #3
0
        public void Wrapper()
        {
            var rulesSet = Path.Combine(TestDir, "analyzer", "rules.txt");
            var storage  = Path.Combine(TestDir, "analyzer", "storage.data");
            var ids      = AcKunosContent.GetKunosCarIds(AcRoot).ToArray();

            var wrapper = RulesWrapper.FromFile(AcRoot, rulesSet, storage, ids);

            wrapper.EnsureActual();

            var d = ids.Where(x => Directory.Exists(AcPaths.GetCarDirectory(AcRoot, x)))
                    .Select(x => new { Id = x, Data = DataWrapper.FromCarDirectory(AcRoot, x) })
                    .ToList();

            var w = Stopwatch.StartNew();
            var j = 0;

            foreach (var car in d)
            {
                foreach (var s in wrapper.FindSimular(car.Data, "aero", false, 0.85))
                {
                    AcToolsLogging.Write($"{car.Id} is similar to {s.CarId} by {s.Value * 100:F1}%");
                    j++;
                }
            }

            AcToolsLogging.Write($"Check time: {w.Elapsed.TotalMilliseconds / j:F2} ms");
        }
예제 #4
0
        private HashStorage CreateNew([NotNull] RulesEntry[] rulesSet, string[] carIds)
        {
            var hashStorage = new HashStorage(_rulesKeys);

            foreach (var car in carIds)
            {
                var carLocation = AcPaths.GetCarDirectory(_acRoot, car);
                if (!Directory.Exists(carLocation))
                {
                    continue;
                }

                var carData = DataWrapper.FromCarDirectory(carLocation);
                var bytes   = new byte[rulesSet.Length][];
                for (var i = 0; i < rulesSet.Length; i++)
                {
                    var set = rulesSet[i];
                    bytes[i] = set.Rules.GetHash(carData);
                }

                hashStorage.Add(car, bytes);
            }

            hashStorage.ParamsHashCode = _paramsHashCode;
            hashStorage.SaveTo(_storageLocation);
            return(hashStorage);
        }
예제 #5
0
        public IEnumerable <HashStorage.Simular> FindSimular(string carId, string setId, bool keepWorkedRules, double threshold)
        {
            var carLocation = AcPaths.GetCarDirectory(_acRoot, carId);

            return(Directory.Exists(carLocation) ?
                   FindSimular(DataWrapper.FromCarDirectory(carLocation), setId, keepWorkedRules, threshold) :
                   new HashStorage.Simular[0]);
        }
예제 #6
0
        private static void PrepareCar([NotNull] string carId)
        {
            var root       = AcRootDirectory.Instance.RequireValue;
            var actualData = new FileInfo(Path.Combine(AcPaths.GetCarDirectory(root, carId), "data.acd"));
            var serverData = new FileInfo(Path.Combine(root, @"server", @"content", @"cars", carId, @"data.acd"));

            if (actualData.Exists && (!serverData.Exists || actualData.LastWriteTime > serverData.LastWriteTime))
            {
                Directory.CreateDirectory(serverData.DirectoryName ?? "");
                FileUtils.HardLinkOrCopy(actualData.FullName, serverData.FullName, true);
            }
        }
예제 #7
0
        public async Task <List <PackedEntry> > PackServerData(bool saveExecutable, ServerPresetPackMode mode, bool evbMode, CancellationToken cancellation)
        {
            var result = new List <PackedEntry>();

            // Wrapper
            if (ProvideDetails && DetailsMode == ServerPresetDetailsMode.ViaWrapper)
            {
                if (saveExecutable)
                {
                    string wrapper;
                    switch (mode)
                    {
                    case ServerPresetPackMode.Linux32:
                        wrapper = await LoadLinux32Wrapper(cancellation);

                        break;

                    case ServerPresetPackMode.Linux64:
                        wrapper = await LoadLinux64Wrapper(cancellation);

                        break;

                    case ServerPresetPackMode.Windows:
                        wrapper = await LoadWinWrapper(cancellation);

                        break;

                    default:
                        throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
                    }

                    if (cancellation.IsCancellationRequested)
                    {
                        return(null);
                    }

                    if (wrapper == null)
                    {
                        throw new InformativeException("Can’t pack server", "Can’t load server wrapper.");
                    }

                    // Actual wrapper, compiled to a single exe-file
                    result.Add(PackedEntry.FromFile(
                                   mode == ServerPresetPackMode.Windows ? @"acServerWrapper.exe" : @"acServerWrapper",
                                   wrapper));

                    // For EVB
                    if (evbMode)
                    {
                        result.Add(PackedEntry.FromContent("arguments.json", new JArray {
                            @"--copy-executable-to=acServer_tmp.exe",
                        }.ToString(Formatting.Indented)));
                    }
                }

                // Params
                var wrapperParams = _wrapperParamsJson?.DeepClone() as JObject;
                SetWrapperParams(ref wrapperParams);
                result.Add(PackedEntry.FromContent(@"cfg/cm_wrapper_params.json", wrapperParams.ToString(Formatting.Indented)));

                // Content
                if (DetailsContentJObject != null)
                {
                    void ProcessPiece(JObject piece)
                    {
                        var file = (string)piece?[@"file"];

                        if (piece == null || file == null)
                        {
                            return;
                        }

                        var filename = Path.IsPathRooted(file) ? file : Path.Combine(WrapperContentDirectory, file);

                        if (!FileUtils.ArePathsEqual(WrapperContentDirectory, Path.GetDirectoryName(filename)))
                        {
                            piece[@"file"] = Path.GetFileName(filename);
                        }

                        result.Add(PackedEntry.FromFile($"cfg/cm_content/{Path.GetFileName(filename)}", filename));
                    }

                    void ProcessPieces(JToken token, string childrenKey = null)
                    {
                        if (!(token is JObject o))
                        {
                            return;
                        }
                        foreach (var t in o)
                        {
                            var b = (JObject)t.Value;
                            if (b == null)
                            {
                                continue;
                            }
                            ProcessPiece(b);
                            if (childrenKey != null)
                            {
                                ProcessPieces(b[childrenKey]);
                            }
                        }
                    }

                    var content = DetailsContentJObject.DeepClone();
                    ProcessPieces(content[@"cars"], @"skins");
                    ProcessPiece(content[@"track"] as JObject);
                    ProcessPieces(content[@"weather"]);
                    result.Add(PackedEntry.FromContent("cfg/cm_content/content.json", content.ToString(Formatting.Indented)));
                }
                else
                {
                    result.Add(PackedEntry.FromContent("cfg/cm_content/content.json", @"{}"));
                }
            }

            // Executable
            if (saveExecutable)
            {
                var serverDirectory = ServerPresetsManager.ServerDirectory;
                result.Add(PackedEntry.FromFile(
                               mode == ServerPresetPackMode.Windows ? @"acServer.exe" : @"acServer",
                               Path.Combine(serverDirectory, mode == ServerPresetPackMode.Windows ? @"acServer.exe" : @"acServer")));
            }

            // Main config file
            var serverCfg   = IniObject?.Clone() ?? new IniFile(IniFileMode.ValuesWithSemicolons);
            var dataSection = serverCfg["DATA"];

            SaveData(serverCfg);

            if (ProvideDetails)
            {
                if (DetailsMode == ServerPresetDetailsMode.ViaWrapper)
                {
                    serverCfg["SERVER"].Set("NAME", $"{Name} {ServerEntry.ExtendedSeparator}{WrapperPort}");
                }
                else
                {
                    await EnsureDetailsNameIsActualAsync(serverCfg);
                }
            }

            // Welcome message
            if (!string.IsNullOrEmpty(WelcomeMessage))
            {
                result.Add(PackedEntry.FromContent("cfg/welcome.txt", WelcomeMessage));
                serverCfg["SERVER"].Set("WELCOME_MESSAGE", "cfg/welcome.txt");
                dataSection.Set("WELCOME_PATH", "cfg/welcome.txt");
            }

            // Setups
            var setupIndex = 0;

            foreach (var key in dataSection.Keys.Where(x => x.StartsWith(@"FIXED_SETUP_")).ToList())
            {
                dataSection.Remove(key);
            }
            foreach (var item in SetupItems)
            {
                if (!File.Exists(item.Filename))
                {
                    continue;
                }
                var name = $@"cfg/setup_{setupIndex}_{item.CarId}.ini";
                result.Add(PackedEntry.FromFile(name, item.Filename));
                dataSection[@"FIXED_SETUP_" + setupIndex] = $@"{(item.IsDefault ? @"1" : @"0")}|{name}";
                setupIndex++;
            }

            result.Add(PackedEntry.FromContent("cfg/server_cfg.ini", serverCfg.Stringify()));

            // Entry list
            var entryList = EntryListIniObject?.Clone() ?? new IniFile();

            entryList.SetSections("CAR", DriverEntries, (entry, section) => entry.SaveTo(section));
            result.Add(PackedEntry.FromContent("cfg/entry_list.ini", entryList.Stringify()));

            // Cars
            var root = AcRootDirectory.Instance.RequireValue;

            for (var i = 0; i < CarIds.Length; i++)
            {
                var carId      = CarIds[i];
                var packedData = Path.Combine(AcPaths.GetCarDirectory(root, carId), "data.acd");
                if (File.Exists(packedData))
                {
                    result.Add(PackedEntry.FromFile(Path.Combine(@"content", @"cars", carId, @"data.acd"), packedData));
                }
            }

            // Track
            var localPath = TrackLayoutId != null?Path.Combine(TrackId, TrackLayoutId) : TrackId;

            foreach (var file in TrackDataToKeep)
            {
                var actualData = Path.Combine(AcPaths.GetTracksDirectory(root), localPath, @"data", file);
                if (File.Exists(actualData))
                {
                    result.Add(PackedEntry.FromFile(Path.Combine(@"content", @"tracks", localPath, @"data", file), actualData));
                }
            }

            // System
            var systemSurfaces = Path.Combine(ServerPresetsManager.ServerDirectory, "system", "data", "surfaces.ini");

            if (File.Exists(systemSurfaces))
            {
                result.Add(PackedEntry.FromFile("system/data/surfaces.ini", systemSurfaces));
            }

            return(result);
        }
예제 #8
0
 private static string GetSoundbankChecksum(string carId)
 {
     return(ChecksumFast(Path.Combine(AcPaths.GetCarDirectory(AcRootDirectory.Instance.RequireValue, carId), @"sfx",
                                      carId + @".bank")));
 }
예제 #9
0
 public static DataWrapper FromCarDirectory([NotNull] string acRoot, [NotNull] string carId)
 {
     return(FromCarDirectory(AcPaths.GetCarDirectory(acRoot, carId)));
 }