public static void Cleanup() { Log.WriteInfo(nameof(Application), "Exiting..."); try { Steam.Instance.IsRunning = false; Steam.Instance.Client.Disconnect(); Steam.Instance.Dispose(); } catch (Exception e) { ErrorReporter.Notify(nameof(Application), e); } if (Settings.Current.IRC.Enabled) { Log.WriteInfo(nameof(Application), "Closing IRC connection..."); RssReader.Timer.Stop(); RssReader.Dispose(); IRC.Instance.Close(); IrcThread.Join(TimeSpan.FromSeconds(5)); } TaskManager.CancelAllTasks(); if (!Settings.IsFullRun) { LocalConfig.Update("backend.changenumber", Steam.Instance.PICSChanges.PreviousChangeNumber.ToString()) .GetAwaiter().GetResult(); } }
private static async void Tick(object sender, ElapsedEventArgs e) { DateTime lastPostDate; await using (var db = await Database.GetConnectionAsync()) { lastPostDate = db.ExecuteScalar <DateTime>("SELECT `Value` FROM `LocalConfig` WHERE `ConfigKey` = @Key", new { Key = "backend.lastrsspost" }); } var tasks = Settings.Current.RssFeeds.Select(uri => ProcessFeed(uri, lastPostDate)); var dates = await Task.WhenAll(tasks); var maxDate = dates.Max(); if (maxDate > lastPostDate) { await LocalConfig.Update("backend.lastrsspost", maxDate.ToString(CultureInfo.InvariantCulture)); } }
private Task Save() { return(LocalConfig.Update("backend.freelicense.requests", JsonConvert.SerializeObject(FreeLicensesToRequest))); }
private void OnPICSChanges(SteamApps.PICSChangesCallback callback) { if (PreviousChangeNumber == callback.CurrentChangeNumber) { return; } Log.WriteInfo(nameof(PICSChanges), $"Changelist {callback.LastChangeNumber} -> {callback.CurrentChangeNumber} ({callback.AppChanges.Count} apps, {callback.PackageChanges.Count} packages)"); PreviousChangeNumber = callback.CurrentChangeNumber; TaskManager.Run(async() => await HandleChangeNumbers(callback)); if (callback.RequiresFullAppUpdate || callback.RequiresFullPackageUpdate) { TaskManager.Run(async() => { if (callback.RequiresFullAppUpdate) { IRC.Instance.SendOps($"Changelist {callback.CurrentChangeNumber} has forced a full app update"); // When full update flag is set, presumably Steam client start hammering the servers // and the PICS service just does not return any data for a while until it clears up await FullUpdateProcessor.FullUpdateAppsMetadata(true); } if (callback.RequiresFullPackageUpdate) { IRC.Instance.SendOps($"Changelist {callback.CurrentChangeNumber} has forced a full package update"); await FullUpdateProcessor.FullUpdatePackagesMetadata(); } IRC.Instance.SendOps($"Changelist {callback.CurrentChangeNumber} full update has finished"); }); } if (callback.AppChanges.Count == 0 && callback.PackageChanges.Count == 0) { return; } const int appsPerJob = 50; if (callback.AppChanges.Count > appsPerJob) { foreach (var list in callback.AppChanges.Keys.Split(appsPerJob)) { JobManager.AddJob( () => Steam.Instance.Apps.PICSGetAccessTokens(list, Enumerable.Empty <uint>()), new PICSTokens.RequestedTokens { Apps = list.ToList() }); } } else if (callback.AppChanges.Count > 0) { JobManager.AddJob( () => Steam.Instance.Apps.PICSGetAccessTokens(callback.AppChanges.Keys, Enumerable.Empty <uint>()), new PICSTokens.RequestedTokens { Apps = callback.AppChanges.Keys.ToList() }); } if (callback.PackageChanges.Count > appsPerJob) { foreach (var list in callback.PackageChanges.Keys.Split(appsPerJob)) { JobManager.AddJob( () => Steam.Instance.Apps.PICSGetAccessTokens(Enumerable.Empty <uint>(), list), new PICSTokens.RequestedTokens { Packages = list.ToList() }); } } else if (callback.PackageChanges.Count > 0) { JobManager.AddJob( () => Steam.Instance.Apps.PICSGetAccessTokens(Enumerable.Empty <uint>(), callback.PackageChanges.Keys), new PICSTokens.RequestedTokens { Packages = callback.PackageChanges.Keys.ToList() }); } if (callback.AppChanges.Count > 0) { _ = TaskManager.Run(async() => await HandleApps(callback)); } if (callback.PackageChanges.Count > 0) { _ = TaskManager.Run(async() => await HandlePackages(callback)); _ = TaskManager.Run(async() => await HandlePackagesChangelists(callback)); } if (PreviousChangeNumber - LastStoredChangeNumber >= 1000) { LastStoredChangeNumber = PreviousChangeNumber; _ = TaskManager.Run(async() => await LocalConfig.Update("backend.changenumber", LastStoredChangeNumber.ToString())); } PrintImportants(callback); }
private Task SaveBetas() { return(LocalConfig.Update("backend.beta.requests", JsonConvert.SerializeObject(BetasToRequest))); }
/* * Here be dragons. */ public static async Task <EResult> DownloadFilesFromDepot(DepotProcessor.ManifestJob job, DepotManifest depotManifest) { var filesRegex = Files[job.DepotID]; var files = depotManifest.Files.Where(x => filesRegex.IsMatch(x.FileName.Replace('\\', '/'))).ToList(); var downloadState = EResult.Fail; ConcurrentDictionary <string, ExistingFileData> existingFileData; await using (var db = await Database.GetConnectionAsync()) { var data = db.ExecuteScalar <string>("SELECT `Value` FROM `LocalConfig` WHERE `ConfigKey` = @Key", new { Key = $"depot.{job.DepotID}" }); if (data != null) { existingFileData = JsonConvert.DeserializeObject <ConcurrentDictionary <string, ExistingFileData> >(data); } else { existingFileData = new ConcurrentDictionary <string, ExistingFileData>(); } } foreach (var file in existingFileData.Keys.Except(files.Select(x => x.FileName))) { Log.WriteWarn(nameof(FileDownloader), $"\"{file}\" no longer exists in manifest"); } Log.WriteInfo($"FileDownloader {job.DepotID}", $"Will download {files.Count} files"); var downloadedFiles = 0; var fileTasks = new Task[files.Count]; for (var i = 0; i < fileTasks.Length; i++) { var file = files[i]; fileTasks[i] = TaskManager.Run(async() => { var existingFile = existingFileData.GetOrAdd(file.FileName, _ => new ExistingFileData()); EResult fileState; try { await ChunkDownloadingSemaphore.WaitAsync().ConfigureAwait(false); fileState = await DownloadFile(job, file, existingFile); } finally { ChunkDownloadingSemaphore.Release(); } if (fileState == EResult.OK || fileState == EResult.SameAsPreviousValue) { existingFile.FileHash = file.FileHash; downloadedFiles++; } if (fileState != EResult.SameAsPreviousValue) { // Do not write progress info to log file Console.WriteLine($"{job.DepotName} [{downloadedFiles / (float) files.Count * 100.0f,6:#00.00}%] {files.Count - downloadedFiles} files left to download"); } if (downloadState == EResult.DataCorruption) { return; } if (fileState == EResult.OK || fileState == EResult.DataCorruption) { downloadState = fileState; } }); } await Task.WhenAll(fileTasks).ConfigureAwait(false); await LocalConfig.Update($"depot.{job.DepotID}", JsonConvert.SerializeObject(existingFileData)); job.Result = downloadState switch { EResult.OK => EResult.OK, EResult.DataCorruption => EResult.DataCorruption, _ => EResult.Ignored }; return(job.Result); }