private void OnPICSProductInfo(SteamApps.PICSProductInfoCallback callback, JobID jobID) { var request = SteamProxy.Instance.IRCRequests.Find(r => r.JobID == jobID); if (request != null) { SteamProxy.Instance.IRCRequests.Remove(request); SecondaryPool.QueueWorkItem(SteamProxy.Instance.OnProductInfo, request, callback); return; } foreach (var app in callback.Apps) { Log.WriteInfo("Steam", "AppID: {0}", app.Key); var workaround = app; IWorkItemResult mostRecentItem; ProcessedApps.TryGetValue(workaround.Key, out mostRecentItem); var workerItem = ProcessorPool.QueueWorkItem(delegate { if (mostRecentItem != null && !mostRecentItem.IsCompleted) { Log.WriteDebug("Steam", "Waiting for app {0} to finish processing", workaround.Key); SmartThreadPool.WaitAll(new IWaitableResult[] { mostRecentItem }); } new AppProcessor(workaround.Key).Process(workaround.Value); }); ProcessedApps.AddOrUpdate(app.Key, workerItem, (key, oldValue) => workerItem); } foreach (var package in callback.Packages) { Log.WriteInfo("Steam", "SubID: {0}", package.Key); var workaround = package; IWorkItemResult mostRecentItem; ProcessedSubs.TryGetValue(workaround.Key, out mostRecentItem); var workerItem = ProcessorPool.QueueWorkItem(delegate { if (mostRecentItem != null && !mostRecentItem.IsCompleted) { Log.WriteDebug("Steam", "Waiting for package {0} to finish processing", workaround.Key); SmartThreadPool.WaitAll(new IWaitableResult[] { mostRecentItem }); } new SubProcessor(workaround.Key).Process(workaround.Value); }); ProcessedSubs.AddOrUpdate(package.Key, workerItem, (key, oldValue) => workerItem); } foreach (uint app in callback.UnknownApps) { Log.WriteInfo("Steam", "Unknown AppID: {0}", app); uint workaround = app; IWorkItemResult mostRecentItem; ProcessedApps.TryGetValue(workaround, out mostRecentItem); var workerItem = ProcessorPool.QueueWorkItem(delegate { if (mostRecentItem != null && !mostRecentItem.IsCompleted) { Log.WriteDebug("Steam", "Waiting for app {0} to finish processing (unknown)", workaround); SmartThreadPool.WaitAll(new IWaitableResult[] { mostRecentItem }); } new AppProcessor(workaround).ProcessUnknown(); }); ProcessedApps.AddOrUpdate(app, workerItem, (key, oldValue) => workerItem); } foreach (uint package in callback.UnknownPackages) { Log.WriteInfo("Steam", "Unknown SubID: {0}", package); uint workaround = package; IWorkItemResult mostRecentItem; ProcessedSubs.TryGetValue(workaround, out mostRecentItem); var workerItem = ProcessorPool.QueueWorkItem(delegate { if (mostRecentItem != null && !mostRecentItem.IsCompleted) { Log.WriteDebug("Steam", "Waiting for package {0} to finish processing (unknown)", workaround); SmartThreadPool.WaitAll(new IWaitableResult[] { mostRecentItem }); } new SubProcessor(workaround).ProcessUnknown(); }); ProcessedSubs.AddOrUpdate(package, workerItem, (key, oldValue) => workerItem); } }
private void OnPICSChanges(SteamApps.PICSChangesCallback callback, JobID job) { if (PreviousChange == callback.CurrentChangeNumber) { return; } if (ProcessorPool.IsIdle) { Log.WriteDebug("Steam", "Cleaning processed apps and subs"); ProcessedApps.Clear(); ProcessedSubs.Clear(); } var packageChangesCount = callback.PackageChanges.Count; var appChangesCount = callback.AppChanges.Count; Log.WriteInfo("Steam", "Changelist {0} -> {1} ({2} apps, {3} packages)", PreviousChange, callback.CurrentChangeNumber, appChangesCount, packageChangesCount); PreviousChange = callback.CurrentChangeNumber; DbWorker.ExecuteNonQuery("INSERT INTO `Changelists` (`ChangeID`) VALUES (@ChangeID) ON DUPLICATE KEY UPDATE `Date` = CURRENT_TIMESTAMP()", new MySqlParameter("@ChangeID", callback.CurrentChangeNumber)); if (appChangesCount == 0 && packageChangesCount == 0) { IRC.SendAnnounce("{0}»{1} Changelist {2}{3}{4} (empty)", Colors.RED, Colors.NORMAL, Colors.OLIVE, PreviousChange, Colors.DARK_GRAY); return; } SecondaryPool.QueueWorkItem(SteamProxy.Instance.OnPICSChanges, callback); // Packages have no tokens so we request info for them right away if (packageChangesCount > 0) { Apps.PICSGetProductInfo(Enumerable.Empty <SteamApps.PICSRequest>(), callback.PackageChanges.Keys.Select(package => NewPICSRequest(package))); } if (appChangesCount > 0) { // Get all app tokens Apps.PICSGetAccessTokens(callback.AppChanges.Keys, Enumerable.Empty <uint>()); SecondaryPool.QueueWorkItem(delegate { string changes = string.Empty; foreach (var app in callback.AppChanges.Values) { if (callback.CurrentChangeNumber != app.ChangeNumber) { DbWorker.ExecuteNonQuery("INSERT INTO `Changelists` (`ChangeID`) VALUES (@ChangeID) ON DUPLICATE KEY UPDATE `Date` = `Date`", new MySqlParameter("@ChangeID", app.ChangeNumber)); } DbWorker.ExecuteNonQuery("UPDATE `Apps` SET `LastUpdated` = CURRENT_TIMESTAMP() WHERE `AppID` = @AppID", new MySqlParameter("@AppID", app.ID)); changes += string.Format("({0}, {1}),", app.ChangeNumber, app.ID); } if (!changes.Equals(string.Empty)) { changes = string.Format("INSERT INTO `ChangelistsApps` (`ChangeID`, `AppID`) VALUES {0} ON DUPLICATE KEY UPDATE `AppID` = `AppID`", changes.Remove(changes.Length - 1)); DbWorker.ExecuteNonQuery(changes); } }); } if (packageChangesCount > 0) { SecondaryPool.QueueWorkItem(delegate { string changes = string.Empty; foreach (var package in callback.PackageChanges.Values) { if (callback.CurrentChangeNumber != package.ChangeNumber) { DbWorker.ExecuteNonQuery("INSERT INTO `Changelists` (`ChangeID`) VALUES (@ChangeID) ON DUPLICATE KEY UPDATE `Date` = `Date`", new MySqlParameter("@ChangeID", package.ChangeNumber)); } DbWorker.ExecuteNonQuery("UPDATE `Subs` SET `LastUpdated` = CURRENT_TIMESTAMP() WHERE `SubID` = @SubID", new MySqlParameter("@SubID", package.ID)); changes += string.Format("({0}, {1}),", package.ChangeNumber, package.ID); } if (!changes.Equals(string.Empty)) { changes = string.Format("INSERT INTO `ChangelistsSubs` (`ChangeID`, `SubID`) VALUES {0} ON DUPLICATE KEY UPDATE `SubID` = `SubID`", changes.Remove(changes.Length - 1)); DbWorker.ExecuteNonQuery(changes); } }); } }