public void Run() { if (_watcher != null) { return; } _resultFilename = AcPaths.GetResultJsonFilename(); FileUtils.EnsureFileDirectoryExists(_resultFilename); _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.5), IsEnabled = true }; _timer.Tick += OnTick; _watcher = new FileSystemWatcher(Path.GetDirectoryName(_resultFilename) ?? "") { NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName, IncludeSubdirectories = false, EnableRaisingEvents = true, }; _watcher.Changed += FileUpdate; _watcher.Created += FileUpdate; PreviewRun?.Invoke(this, new AcsRunEventArgs(null, null)); }
public static Result GetResult(DateTime gameStartTime) { try { var filename = OptionDebugMode ? AcPaths.GetResultJsonFilename().Replace("race_out", "race_out_debug") : AcPaths.GetResultJsonFilename(); var info = new FileInfo(filename); if (!info.Exists || info.LastWriteTime < gameStartTime) { return(null); } var result = JsonConvert.DeserializeObject <Result>(FileUtils.ReadAllText(filename)); return(result?.IsNotCancelled == true ? result : null); } catch (Exception e) { throw new Exception("Can’t parse “race_out.json”", e); } }
public void AddNewResult([NotNull] Game.StartProperties startProperties, [NotNull] Game.Result result) { var directory = SessionsDirectory; FileUtils.EnsureDirectoryExists(directory); var fileName = DateTime.Now.ToString("yyMMdd-HHmmss") + ".json"; var raceOut = AcPaths.GetResultJsonFilename(); JObject data = null; if (File.Exists(raceOut)) { try { // Let’s try to save original data instead in case we missed something during parsing. // But let’s remove formatting just in case. data = JObject.Parse(File.ReadAllText(raceOut)); } catch (Exception e) { Logging.Warning(e); } } if (data == null) { data = JObject.FromObject(result); } // Trying to keep race params as well… // TODO: Do it the other way around, from start params? var raceIni = AcPaths.GetRaceIniFilename(); if (File.Exists(raceIni)) { data[KeyRaceIni] = File.ReadAllText(raceIni); } var quickDrive = startProperties.GetAdditional <QuickDrivePresetProperty>(); if (quickDrive?.SerializedData != null) { data[KeyQuickDrive] = quickDrive.SerializedData; } File.WriteAllText(FileUtils.EnsureUnique(Path.Combine(directory, fileName)), data.ToString(Formatting.None)); }
public static void SendLogs(string message = null) { var logsDirectory = FilesStorage.Instance.GetDirectory("Logs"); using (var memory = new MemoryStream()) { using (var writer = WriterFactory.Open(memory, ArchiveType.Zip, CompressionType.Deflate)) { if (!string.IsNullOrWhiteSpace(message)) { try { writer.WriteString("Message.txt", message); } catch (Exception e) { Logging.Warning("Can’t attach Message.txt: " + e); } } try { writer.Write("AC Log.txt", AcPaths.GetLogFilename()); } catch (Exception e) { Logging.Warning("Can’t attach AC Log.txt: " + e); } string wpfVersion; try { using (var r = Registry.LocalMachine.OpenSubKey( @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.0\Setup\Windows Presentation Foundation")) { wpfVersion = r?.GetValue("Version")?.ToString(); } } catch (Exception e) { Logging.Warning("Can’t get WPF version: " + e); wpfVersion = null; } try { writer.WriteString("Description.txt", JsonConvert.SerializeObject(new { BuildInformation.AppVersion, BuildInformation.Platform, MainExecutingFile.Location, Environment.OSVersion, Environment.CommandLine, Environment = Environment.GetEnvironmentVariables(), SteamId = SteamIdHelper.Instance.Value, typeof(string).Assembly.ImageRuntimeVersion, WpfVersion = wpfVersion }, Formatting.Indented)); } catch (Exception e) { Logging.Warning("Can’t attach Description.txt: " + e); } try { writer.WriteString("Values.txt", ValuesStorage.Storage.GetData()); } catch (Exception e) { Logging.Warning("Can’t attach Values.data: " + e); } try { if (File.Exists(FilesStorage.Instance.GetFilename("Arguments.txt"))) { writer.Write("Arguments.txt", FilesStorage.Instance.GetFilename("Arguments.txt")); } } catch (Exception e) { Logging.Warning("Can’t attach Arguments.txt: " + e); } foreach (var fileInfo in new DirectoryInfo(AcPaths.GetDocumentsCfgDirectory()).GetFiles("*.ini").Where(x => x.Length < 500000).Take(100)) { try { writer.Write("Config/" + fileInfo.Name, fileInfo.FullName); } catch (Exception e) { Logging.Warning("Can’t attach Config/" + fileInfo.Name + ": " + e); } } if (AcRootDirectory.Instance.Value != null) { foreach (var fileInfo in new DirectoryInfo(AcPaths.GetSystemCfgDirectory(AcRootDirectory.Instance.RequireValue)).GetFiles("*.ini") .Where(x => x.Length < 500000) .Take(100)) { try { writer.Write("SysConfig/" + fileInfo.Name, fileInfo.FullName); } catch (Exception e) { Logging.Warning("Can’t attach SysConfig/" + fileInfo.Name + ": " + e); } } } var raceOut = AcPaths.GetResultJsonFilename(); if (File.Exists(raceOut)) { try { writer.Write("Race.json", raceOut); } catch (Exception e) { Logging.Warning("Can’t attach Race.json:" + e); } } var career = AcPaths.GetKunosCareerProgressFilename(); if (File.Exists(career)) { try { writer.Write("Career.ini", career); } catch (Exception e) { Logging.Warning("Can’t attach Career.ini:" + e); } } foreach (var filename in Directory.GetFiles(logsDirectory, "Main*.log").TakeLast(35) .Union(Directory.GetFiles(logsDirectory, "Packed*.log").TakeLast(35))) { var name = Path.GetFileName(filename); try { writer.Write("Logs/" + name, filename); } catch (Exception e) { Logging.Warning("Can’t attach Logs/" + name + ": " + e); } } } var data = memory.ToArray(); if (data.Length > 20000000) { File.WriteAllBytes(FilesStorage.Instance.GetTemporaryFilename("Report.zip"), data); throw new Exception("Size limit exceeded"); } InternalUtils.SendAppReport(memory.ToArray(), $@"Name: {GetUserName()}; Operating system: {GetWindowsName()}; App version: {BuildInformation.AppVersion}.", CmApiProvider.UserAgent); } }
private static void RemoveResultJson() { FileUtils.TryToDelete(AcPaths.GetResultJsonFilename()); }