コード例 #1
0
        private void OnFreeLicenseCallback(SteamApps.FreeLicenseCallback callback)
        {
            JobManager.TryRemoveJob(callback.JobID);

            var packageIDs = callback.GrantedPackages;
            var appIDs     = callback.GrantedApps;

            Log.WriteDebug("FreeLicense", "Received free license: {0} ({1} apps: {2}, {3} packages: {4})",
                           callback.Result, appIDs.Count, string.Join(", ", appIDs), packageIDs.Count, string.Join(", ", packageIDs));

            if (appIDs.Any())
            {
                JobManager.AddJob(() => Steam.Instance.Apps.PICSGetAccessTokens(appIDs, Enumerable.Empty <uint>()));
            }

            if (packageIDs.Any())
            {
                JobManager.AddJob(() => Steam.Instance.Apps.PICSGetProductInfo(Enumerable.Empty <uint>(), packageIDs));

                TaskManager.RunAsync(() =>
                {
                    RefreshPackageNames();

                    foreach (var subID in packageIDs)
                    {
                        IRC.Instance.SendAnnounce("New free license granted: {0}{1}{2} -{3} {4}",
                                                  Colors.BLUE, Steam.GetPackageName(subID), Colors.NORMAL,
                                                  Colors.DARKBLUE, SteamDB.GetPackageURL(subID)
                                                  );
                    }
                });
            }
        }
コード例 #2
0
        private void OnLicenseListCallback(SteamApps.LicenseListCallback licenseList)
        {
            if (licenseList.Result != EResult.OK)
            {
                Log.WriteError("Steam", "Unable to get license list: {0}", licenseList.Result);

                return;
            }

            Log.WriteInfo("Steam", "{0} Licenses: {1}", licenseList.LicenseList.Count, string.Join(", ", licenseList.LicenseList.Select(lic => lic.PackageID)));

            var timeNow = DateTime.Now;

            foreach (var license in licenseList.LicenseList)
            {
                if (license.PackageID != 0 && !OwnedPackages.Contains(license.PackageID) && timeNow.Subtract(license.TimeCreated).TotalSeconds < 600)
                {
                    IRC.SendMain("New license granted: {0}{1}{2} -{3} {4} {5}({6}, {7})",
                                 Colors.OLIVE, SteamProxy.GetPackageName(license.PackageID), Colors.NORMAL,
                                 Colors.DARK_BLUE, SteamDB.GetPackageURL(license.PackageID), Colors.NORMAL,
                                 license.LicenseType, license.PaymentMethod
                                 );
                }

                OwnedPackages.Add(license.PackageID);
            }

            // TODO: Probably should handle deletions too, for OwnedPackages
        }
コード例 #3
0
        public override async Task OnCommand(CommandArguments command)
        {
            uint subID;

            if (command.Message.Length == 0 || !uint.TryParse(command.Message, out subID))
            {
                command.Reply("Usage:{0} sub <subid>", Colors.OLIVE);

                return;
            }

            var job = await Steam.Instance.Apps.PICSGetProductInfo(null, subID, false, false);

            var callback = job.Results.FirstOrDefault(x => x.Packages.ContainsKey(subID));

            if (callback == null)
            {
                command.Reply("Unknown SubID: {0}{1}{2}", Colors.BLUE, subID, LicenseList.OwnedSubs.ContainsKey(subID) ? SteamDB.StringCheckmark : string.Empty);

                return;
            }

            var info = callback.Packages[subID];

            info.KeyValues.SaveToFile(Path.Combine(Application.Path, "sub", string.Format("{0}.vdf", info.ID)), false);

            command.Reply("{0}{1}{2} -{3} {4}{5} - Dump:{6} {7}{8}{9}{10}",
                          Colors.BLUE, Steam.GetPackageName(info.ID), Colors.NORMAL,
                          Colors.DARKBLUE, SteamDB.GetPackageURL(info.ID), Colors.NORMAL,
                          Colors.DARKBLUE, SteamDB.GetRawPackageURL(info.ID), Colors.NORMAL,
                          info.MissingToken ? SteamDB.StringNeedToken : string.Empty,
                          LicenseList.OwnedSubs.ContainsKey(info.ID) ? SteamDB.StringCheckmark : string.Empty
                          );
        }
コード例 #4
0
        public override async Task OnCommand(CommandArguments command)
        {
            if (command.Message.Length == 0 || !uint.TryParse(command.Message, out var subID))
            {
                command.Reply("Usage:{0} sub <subid>", Colors.OLIVE);

                return;
            }

            var tokenTask = Steam.Instance.Apps.PICSGetAccessTokens(null, subID);

            tokenTask.Timeout = TimeSpan.FromSeconds(10);
            var tokenCallback = await tokenTask;

            SteamApps.PICSRequest request;

            if (tokenCallback.PackageTokens.ContainsKey(subID))
            {
                request = PICSTokens.NewPackageRequest(subID, tokenCallback.PackageTokens[subID]);
            }
            else
            {
                request = PICSTokens.NewPackageRequest(subID);
            }

            var infoTask = Steam.Instance.Apps.PICSGetProductInfo(Enumerable.Empty <SteamApps.PICSRequest>(), new List <SteamApps.PICSRequest> {
                request
            });

            infoTask.Timeout = TimeSpan.FromSeconds(10);
            var job      = await infoTask;
            var callback = job.Results.FirstOrDefault(x => x.Packages.ContainsKey(subID));

            if (callback == null)
            {
                command.Reply("Unknown SubID: {0}{1}{2}", Colors.BLUE, subID, LicenseList.OwnedSubs.ContainsKey(subID) ? SteamDB.StringCheckmark : string.Empty);

                return;
            }

            var info = callback.Packages[subID];

            info.KeyValues.SaveToFile(Path.Combine(Application.Path, "sub", string.Format("{0}.vdf", info.ID)), false);

            command.Reply("{0}{1}{2} -{3} {4}{5} - Dump:{6} {7}{8}{9}{10}",
                          Colors.BLUE, Steam.GetPackageName(info.ID), Colors.NORMAL,
                          Colors.DARKBLUE, SteamDB.GetPackageURL(info.ID), Colors.NORMAL,
                          Colors.DARKBLUE, SteamDB.GetRawPackageURL(info.ID), Colors.NORMAL,
                          info.MissingToken ? SteamDB.StringNeedToken : string.Empty,
                          LicenseList.OwnedSubs.ContainsKey(info.ID) ? SteamDB.StringCheckmark : string.Empty
                          );
        }
コード例 #5
0
        public override async void OnCommand(CommandArguments command)
        {
            uint subID;

            if (command.Message.Length == 0 || !uint.TryParse(command.Message, out subID))
            {
                CommandHandler.ReplyToCommand(command, "Usage:{0} sub <subid>", Colors.OLIVE);

                return;
            }

            var count = PICSProductInfo.ProcessedSubs.Count;

            if (count > 100)
            {
                CommandHandler.ReplyToCommand(command, "There are currently {0} packages awaiting to be processed, try again later.", count);

                return;
            }

            var job = await Steam.Instance.Apps.PICSGetProductInfo(null, subID, false, false);

            var callback = job.Results.First(x => !x.ResponsePending);

            if (!callback.Packages.ContainsKey(subID))
            {
                CommandHandler.ReplyToCommand(command, "Unknown SubID: {0}{1}{2}", Colors.BLUE, subID, LicenseList.OwnedSubs.ContainsKey(subID) ? SteamDB.StringCheckmark : string.Empty);

                return;
            }

            var info = callback.Packages[subID];

            info.KeyValues.SaveToFile(Path.Combine(Application.Path, "sub", string.Format("{0}.vdf", info.ID)), false);

            CommandHandler.ReplyToCommand(command, "{0}{1}{2} -{3} {4}{5} - Dump:{6} {7}{8}{9}{10}",
                                          Colors.BLUE, Steam.GetPackageName(info.ID), Colors.NORMAL,
                                          Colors.DARKBLUE, SteamDB.GetPackageURL(info.ID), Colors.NORMAL,
                                          Colors.DARKBLUE, SteamDB.GetRawPackageURL(info.ID), Colors.NORMAL,
                                          info.MissingToken ? SteamDB.StringNeedToken : string.Empty,
                                          LicenseList.OwnedSubs.ContainsKey(info.ID) ? SteamDB.StringCheckmark : string.Empty
                                          );
        }
コード例 #6
0
        private static void OnFreeLicenseCallback(SteamApps.FreeLicenseCallback callback)
        {
            JobManager.TryRemoveJob(callback.JobID);

            var packageIDs = callback.GrantedPackages;
            var appIDs     = callback.GrantedApps;

            Log.WriteDebug("FreeLicense", "Received free license: {0} ({1} apps: {2}, {3} packages: {4})",
                           callback.Result, appIDs.Count, string.Join(", ", appIDs), packageIDs.Count, string.Join(", ", packageIDs));

            if (appIDs.Count > 0)
            {
                JobManager.AddJob(() => Steam.Instance.Apps.PICSGetAccessTokens(appIDs, Enumerable.Empty <uint>()));
            }

            if (packageIDs.Count > 0)
            {
                JobManager.AddJob(() => Steam.Instance.Apps.PICSGetProductInfo(Enumerable.Empty <uint>(), packageIDs));

                // We don't want to block our main thread with web requests
                TaskManager.Run(() =>
                {
                    string data = null;

                    try
                    {
                        var response = WebAuth.PerformRequest("GET", "https://store.steampowered.com/account/licenses/");

                        using (var responseStream = response.GetResponseStream())
                        {
                            using (var reader = new StreamReader(responseStream))
                            {
                                data = reader.ReadToEnd();
                            }
                        }
                    }
                    catch (WebException e)
                    {
                        Log.WriteError("FreeLicense", "Failed to fetch account details page: {0}", e.Message);
                    }

                    using (var db = Database.GetConnection())
                    {
                        foreach (var package in packageIDs)
                        {
                            var packageData = db.Query <Package>("SELECT `SubID`, `Name`, `LastKnownName` FROM `Subs` WHERE `SubID` = @SubID", new { SubID = package }).FirstOrDefault();

                            if (!string.IsNullOrEmpty(data))
                            {
                                // Tell me all about using regex
                                var match = Regex.Match(data, string.Format("RemoveFreeLicense\\( ?{0}, ?'(.+)' ?\\)", package));

                                if (match.Success)
                                {
                                    var grantedName = Encoding.UTF8.GetString(Convert.FromBase64String(match.Groups[1].Value));

                                    // Update last known name if we can
                                    if (packageData.SubID > 0 && (string.IsNullOrEmpty(packageData.LastKnownName) || packageData.LastKnownName.StartsWith("Steam Sub ", StringComparison.Ordinal)))
                                    {
                                        db.Execute("UPDATE `Subs` SET `LastKnownName` = @Name WHERE `SubID` = @SubID", new { SubID = package, Name = grantedName });

                                        db.Execute(SubProcessor.GetHistoryQuery(),
                                                   new PICSHistory
                                        {
                                            ID       = package,
                                            Key      = SteamDB.DATABASE_NAME_TYPE,
                                            OldValue = "free on demand; account page",
                                            NewValue = grantedName,
                                            Action   = "created_info"
                                        }
                                                   );

                                        // Add a app comment on each app in this package
                                        var comment = string.Format("This app is in a free on demand package called <b>{0}</b>", SecurityElement.Escape(grantedName));
                                        var apps    = db.Query <PackageApp>("SELECT `AppID` FROM `SubsApps` WHERE `SubID` = @SubID", new { SubID = package }).ToList();
                                        var types   = db.Query <App>("SELECT `AppID` FROM `Apps` WHERE `AppType` > 0 AND `AppID` IN @Ids", new { Ids = apps.Select(x => x.AppID) }).ToDictionary(x => x.AppID, x => true);
                                        var key     = db.ExecuteScalar <uint>("SELECT `ID` FROM `KeyNames` WHERE `Name` = 'website_comment'");

                                        foreach (var app in apps)
                                        {
                                            if (types.ContainsKey(app.AppID))
                                            {
                                                continue;
                                            }

                                            db.Execute("INSERT INTO `AppsInfo` VALUES (@AppID, @Key, @Value) ON DUPLICATE KEY UPDATE `Key` = `Key`", new { app.AppID, Key = key, value = comment });
                                        }
                                    }

                                    packageData.LastKnownName = grantedName;
                                }
                            }

                            IRC.Instance.SendMain("New free license granted: {0}{1}{2} -{3} {4}",
                                                  Colors.BLUE, Steam.FormatPackageName(package, packageData), Colors.NORMAL,
                                                  Colors.DARKBLUE, SteamDB.GetPackageURL(package)
                                                  );
                        }
                    }
                });
            }
        }
コード例 #7
0
        private void PrintImportants(SteamApps.PICSChangesCallback callback)
        {
            // Apps
            var    important = callback.AppChanges.Keys.Intersect(Application.ImportantApps.Keys);
            string appType;
            string appName;

            foreach (var app in important)
            {
                appName = Steam.GetAppName(app, out appType);

                IRC.Instance.AnnounceImportantAppUpdate(app, "{0} update: {1}{2}{3} -{4} {5}",
                                                        appType,
                                                        Colors.BLUE, appName, Colors.NORMAL,
                                                        Colors.DARKBLUE, SteamDB.GetAppURL(app, "history"));
            }

            // Packages
            important = callback.PackageChanges.Keys.Intersect(Application.ImportantSubs.Keys);

            foreach (var package in important)
            {
                IRC.Instance.AnnounceImportantPackageUpdate(package, "Package update: {0}{1}{2} -{3} {4}", Colors.BLUE, Steam.GetPackageName(package), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetPackageURL(package, "history"));
            }
        }
コード例 #8
0
        private async Task ProcessKey(string keyName, string displayName, string value, bool isJSON = false)
        {
            if (keyName.Length > 90)
            {
                Log.WriteError("Sub Processor", "Key {0} for SubID {1} is too long, not inserting info.", keyName, SubID);

                return;
            }

            // All keys in PICS are supposed to be lower case.
            // But currently some keys in packages are not lowercased,
            // this lowercases everything to make sure nothing breaks in future
            keyName = keyName.ToLower().Trim();

            if (!CurrentData.ContainsKey(keyName))
            {
                var key = await GetKeyNameID(keyName);

                if (key == 0)
                {
                    var type = isJSON ? 86 : 0; // 86 is a hardcoded const for the website

                    await DbConnection.ExecuteAsync("INSERT INTO `KeyNamesSubs` (`Name`, `Type`, `DisplayName`) VALUES(@Name, @Type, @DisplayName)", new { Name = keyName, DisplayName = displayName, Type = type });

                    key = await GetKeyNameID(keyName);

                    if (key == 0)
                    {
                        // We can't insert anything because key wasn't created
                        Log.WriteError("Sub Processor", "Failed to create key {0} for SubID {1}, not inserting info.", keyName, SubID);

                        return;
                    }

                    IRC.Instance.SendOps("New package keyname: {0}{1} {2}(ID: {3}) ({4}) - {5}", Colors.BLUE, keyName, Colors.LIGHTGRAY, key, displayName, SteamDB.GetPackageURL(SubID, "history"));
                }

                await DbConnection.ExecuteAsync("INSERT INTO `SubsInfo` (`SubID`, `Key`, `Value`) VALUES (@SubID, @Key, @Value)", new { SubID, Key = key, Value = value });
                await MakeHistory("created_key", key, string.Empty, value);

                return;
            }

            var data = CurrentData[keyName];

            if (data.Processed)
            {
                Log.WriteWarn("Sub Processor", "Duplicate key {0} in SubID {1}", keyName, SubID);

                return;
            }

            data.Processed = true;

            CurrentData[keyName] = data;

            if (data.Value.Equals(value))
            {
                return;
            }

            await DbConnection.ExecuteAsync("UPDATE `SubsInfo` SET `Value` = @Value WHERE `SubID` = @SubID AND `Key` = @Key", new { SubID, data.Key, Value = value });

            await MakeHistory("modified_key", data.Key, data.Value, value);
        }
コード例 #9
0
        private void PrintImportants(SteamApps.PICSChangesCallback callback)
        {
            // Apps
            var important = callback.AppChanges.Keys.Intersect(Application.ImportantApps.Keys);

            foreach (var app in important)
            {
                var appName = Steam.GetAppName(app, out var appType);

                IRC.Instance.AnnounceImportantAppUpdate(app, "{0} update: {1}{2}{3} -{4} {5}",
                                                        appType,
                                                        Colors.BLUE, appName, Colors.NORMAL,
                                                        Colors.DARKBLUE, SteamDB.GetAppURL(app, "history"));

                if (Settings.Current.CanQueryStore)
                {
                    Steam.Instance.UnifiedMessages.SendMessage("ChatRoom.SendChatMessage#1", new CChatRoom_SendChatMessage_Request
                    {
                        chat_group_id = 1147,
                        chat_id       = 10208600,
                        message       = $"[Changelist {callback.CurrentChangeNumber}] {appType} update: {appName}\n{SteamDB.GetAppURL(app, "history")}?utm_source=Steam&utm_medium=Steam&utm_campaign=SteamDB%20Group%20Chat"
                    });
                }
            }

            // Packages
            important = callback.PackageChanges.Keys.Intersect(Application.ImportantSubs.Keys);

            foreach (var package in important)
            {
                IRC.Instance.AnnounceImportantPackageUpdate(package, "Package update: {0}{1}{2} -{3} {4}", Colors.BLUE, Steam.GetPackageName(package), Colors.NORMAL, Colors.DARKBLUE, SteamDB.GetPackageURL(package, "history"));
            }
        }
コード例 #10
0
        public void OnPICSChanges(SteamApps.PICSChangesCallback callback)
        {
            // Print any apps importants first
            var important = callback.AppChanges.Keys.Intersect(ImportantApps);

            if (important.Count() > 5)
            {
                IRC.SendMain("{0}{1}{2} important apps updated -{3} {4}", Colors.OLIVE, important.Count(), Colors.NORMAL, Colors.DARK_BLUE, SteamDB.GetChangelistURL(callback.CurrentChangeNumber));
            }
            else
            {
                foreach (var app in important)
                {
                    IRC.SendMain("Important app update: {0}{1}{2} -{3} {4}", Colors.OLIVE, GetAppName(app), Colors.NORMAL, Colors.DARK_BLUE, SteamDB.GetAppURL(app, "history"));
                }
            }

            // And then important packages
            important = callback.PackageChanges.Keys.Intersect(ImportantSubs);

            if (important.Count() > 5)
            {
                IRC.SendMain("{0}{1}{2} important packages updated -{3} {4}", Colors.OLIVE, important.Count(), Colors.NORMAL, Colors.DARK_BLUE, SteamDB.GetChangelistURL(callback.CurrentChangeNumber));
            }
            else
            {
                foreach (var package in important)
                {
                    IRC.SendMain("Important package update: {0}{1}{2} -{3} {4}", Colors.OLIVE, GetPackageName(package), Colors.NORMAL, Colors.DARK_BLUE, SteamDB.GetPackageURL(package, "history"));
                }
            }

            // Group apps and package changes by changelist, this will seperate into individual changelists
            var appGrouping     = callback.AppChanges.Values.GroupBy(a => a.ChangeNumber);
            var packageGrouping = callback.PackageChanges.Values.GroupBy(p => p.ChangeNumber);

            // Join apps and packages back together based on changelist number
            var changeLists = Utils.FullOuterJoin(appGrouping, packageGrouping, a => a.Key, p => p.Key, (a, p, key) => new
            {
                ChangeNumber = key,

                Apps     = a.ToList(),
                Packages = p.ToList(),
            },
                                                  new EmptyGrouping <uint, SteamApps.PICSChangesCallback.PICSChangeData>(),
                                                  new EmptyGrouping <uint, SteamApps.PICSChangesCallback.PICSChangeData>())
                              .OrderBy(c => c.ChangeNumber);

            foreach (var changeList in changeLists)
            {
                var appCount     = changeList.Apps.Count;
                var packageCount = changeList.Packages.Count;

                string Message = string.Format("Changelist {0}{1}{2} {3}({4:N0} apps and {5:N0} packages){6} -{7} {8}",
                                               Colors.OLIVE, changeList.ChangeNumber, Colors.NORMAL,
                                               Colors.DARK_GRAY, appCount, packageCount, Colors.NORMAL,
                                               Colors.DARK_BLUE, SteamDB.GetChangelistURL(changeList.ChangeNumber)
                                               );

                var changesCount = appCount + packageCount;

                if (changesCount >= 50)
                {
                    IRC.SendMain(Message);
                }

                IRC.SendAnnounce("{0}»{1} {2}", Colors.RED, Colors.NORMAL, Message);

                // If this changelist is very big, freenode will hate us forever if we decide to print all that stuff
                if (changesCount > 500)
                {
                    IRC.SendAnnounce("{0}  This changelist is too big to be printed in IRC, please view it on our website", Colors.RED);

                    continue;
                }

                string name;

                if (appCount > 0)
                {
                    foreach (var app in changeList.Apps)
                    {
                        name = GetAppName(app.ID, true);

                        if (string.IsNullOrEmpty(name))
                        {
                            name = string.Format("{0}{1}{2}", Colors.GREEN, app.ID, Colors.NORMAL);
                        }
                        else
                        {
                            name = string.Format("{0}{1}{2} - {3}", Colors.LIGHT_GRAY, app.ID, Colors.NORMAL, name);
                        }

                        IRC.SendAnnounce("  App: {0}{1}", name, app.NeedsToken ? StringNeedToken : string.Empty);
                    }
                }

                if (packageCount > 0)
                {
                    foreach (var package in changeList.Packages)
                    {
                        name = GetPackageName(package.ID, true);

                        if (string.IsNullOrEmpty(name))
                        {
                            name = string.Format("{0}{1}{2}", Colors.GREEN, package.ID, Colors.NORMAL);
                        }
                        else
                        {
                            name = string.Format("{0}{1}{2} - {3}", Colors.LIGHT_GRAY, package.ID, Colors.NORMAL, name);
                        }

                        IRC.SendAnnounce("  Package: {0}{1}{2}",
                                         name,
                                         package.NeedsToken ? StringNeedToken : string.Empty,
                                         Steam.Instance.OwnedPackages.Contains(package.ID) ? StringCheckmark : string.Empty
                                         );
                    }
                }
            }
        }
コード例 #11
0
        private void TryProcess(SteamApps.PICSProductInfoCallback.PICSProductInfo productInfo)
        {
            string packageName = string.Empty;
            var    apps        = new Dictionary <uint, string>();

            using (MySqlDataReader Reader = DbWorker.ExecuteReader("SELECT `Name`, `Value` FROM `SubsInfo` INNER JOIN `KeyNamesSubs` ON `SubsInfo`.`Key` = `KeyNamesSubs`.`ID` WHERE `SubID` = @SubID", new MySqlParameter("@SubID", SubID)))
            {
                while (Reader.Read())
                {
                    CurrentData.Add(DbWorker.GetString("Name", Reader), DbWorker.GetString("Value", Reader));
                }
            }

            using (MySqlDataReader Reader = DbWorker.ExecuteReader("SELECT `Name` FROM `Subs` WHERE `SubID` = @SubID LIMIT 1", new MySqlParameter("@SubID", SubID)))
            {
                if (Reader.Read())
                {
                    packageName = DbWorker.GetString("Name", Reader);
                }
            }

            using (MySqlDataReader Reader = DbWorker.ExecuteReader("SELECT `AppID`, `Type` FROM `SubsApps` WHERE `SubID` = @SubID", new MySqlParameter("@SubID", SubID)))
            {
                while (Reader.Read())
                {
                    apps.Add(Reader.GetUInt32("AppID"), Reader.GetString("Type"));
                }
            }

            var kv = productInfo.KeyValues.Children.FirstOrDefault();

            if (kv["name"].Value != null)
            {
                if (string.IsNullOrEmpty(packageName))
                {
                    DbWorker.ExecuteNonQuery("INSERT INTO `Subs` (`SubID`, `Name`) VALUES (@SubID, @Name) ON DUPLICATE KEY UPDATE `Name` = @Name",
                                             new MySqlParameter("@SubID", SubID),
                                             new MySqlParameter("@Name", kv["name"].Value)
                                             );

                    MakeHistory("created_sub");
                    MakeHistory("created_info", DATABASE_NAME_TYPE, string.Empty, kv["name"].Value);
                }
                else if (!packageName.Equals(kv["name"].Value))
                {
                    DbWorker.ExecuteNonQuery("UPDATE `Subs` SET `Name` = @Name WHERE `SubID` = @SubID",
                                             new MySqlParameter("@SubID", SubID),
                                             new MySqlParameter("@Name", kv["name"].Value)
                                             );

                    MakeHistory("modified_info", DATABASE_NAME_TYPE, packageName, kv["name"].Value);
                }
            }

            foreach (KeyValue section in kv.Children)
            {
                string sectionName = section.Name.ToLower();

                if (string.IsNullOrEmpty(sectionName) || sectionName.Equals("packageid") || sectionName.Equals("name"))
                {
                    // Ignore common keys
                    continue;
                }

                if (sectionName.Equals("appids") || sectionName.Equals("depotids"))
                {
                    string type = sectionName.Replace("ids", string.Empty); // Remove "ids", so we get app from appids and depot from depotids

                    uint typeID = (uint)(type.Equals("app") ? 0 : 1);       // TODO: Remove legacy 0/1 and replace with type

                    foreach (KeyValue childrenApp in section.Children)
                    {
                        uint appID = uint.Parse(childrenApp.Value);

                        // Is this appid already in this package?
                        if (apps.ContainsKey(appID))
                        {
                            // Is this appid's type the same?
                            if (apps[appID] != type)
                            {
                                DbWorker.ExecuteNonQuery("UPDATE `SubsApps` SET `Type` = @Type WHERE `SubID` = @SubID AND `AppID` = @AppID",
                                                         new MySqlParameter("@SubID", SubID),
                                                         new MySqlParameter("@AppID", appID),
                                                         new MySqlParameter("@Type", type)
                                                         );

                                MakeHistory("added_to_sub", typeID, apps[appID].Equals("app") ? "0" : "1", childrenApp.Value);
                            }

                            apps.Remove(appID);
                        }
                        else
                        {
                            DbWorker.ExecuteNonQuery("INSERT INTO `SubsApps` (`SubID`, `AppID`, `Type`) VALUES(@SubID, @AppID, @Type) ON DUPLICATE KEY UPDATE `Type` = @Type",
                                                     new MySqlParameter("@SubID", SubID),
                                                     new MySqlParameter("@AppID", appID),
                                                     new MySqlParameter("@Type", type)
                                                     );

                            MakeHistory("added_to_sub", typeID, string.Empty, childrenApp.Value);
                            AppProcessor.MakeHistory(appID, ChangeNumber, "added_to_sub", typeID, string.Empty, SubID.ToString());

                            if (SteamProxy.Instance.ImportantApps.Contains(appID))
                            {
                                IRC.SendMain("Important app {0}{1}{2} was added to package {3}{4}{5} -{6} {7}",
                                             Colors.OLIVE, SteamProxy.GetAppName(appID), Colors.NORMAL,
                                             Colors.OLIVE, packageName, Colors.NORMAL,
                                             Colors.DARK_BLUE, SteamDB.GetPackageURL(SubID, "history")
                                             );
                            }
                        }
                    }
                }
                else if (sectionName.Equals("extended"))
                {
                    string keyName;

                    foreach (KeyValue children in section.Children)
                    {
                        if (children.Children.Count > 0)
                        {
                            Log.WriteError("Sub Processor", "SubID {0} has childen in extended section", SubID);
                        }

                        keyName = string.Format("{0}_{1}", sectionName, children.Name);

                        ProcessKey(keyName, children.Name, children.Value);
                    }
                }
                else if (section.Children.Count > 0)
                {
                    sectionName = string.Format("root_{0}", sectionName);

                    ProcessKey(sectionName, sectionName, DbWorker.JsonifyKeyValue(section), true);
                }
                else if (!string.IsNullOrEmpty(section.Value))
                {
                    string keyName = string.Format("root_{0}", sectionName);

                    ProcessKey(keyName, sectionName, section.Value);
                }
            }

            foreach (string keyName in CurrentData.Keys)
            {
                if (!keyName.StartsWith("website", StringComparison.Ordinal))
                {
                    uint ID = GetKeyNameID(keyName);

                    DbWorker.ExecuteNonQuery("DELETE FROM `SubsInfo` WHERE `SubID` = @SubID AND `Key` = @KeyNameID",
                                             new MySqlParameter("@SubID", SubID),
                                             new MySqlParameter("@KeyNameID", ID)
                                             );

                    MakeHistory("removed_key", ID, CurrentData[keyName]);
                }
            }

            foreach (var app in apps)
            {
                DbWorker.ExecuteNonQuery("DELETE FROM `SubsApps` WHERE `SubID` = @SubID AND `AppID` = @AppID AND `Type` = @Type",
                                         new MySqlParameter("@SubID", SubID),
                                         new MySqlParameter("@AppID", app.Key),
                                         new MySqlParameter("@Type", app.Value)
                                         );

                uint typeID = (uint)(app.Value.Equals("app") ? 0 : 1); // TODO: Remove legacy 0/1 and replace with type

                MakeHistory("removed_from_sub", typeID, app.Key.ToString());
                AppProcessor.MakeHistory(app.Key, ChangeNumber, "removed_from_sub", typeID, SubID.ToString());

                if (SteamProxy.Instance.ImportantApps.Contains(app.Key))
                {
                    IRC.SendMain("Important app {0}{1}{2} was removed from package {3}{4}{5} -{6} {7}",
                                 Colors.OLIVE, SteamProxy.GetAppName(app.Key), Colors.NORMAL,
                                 Colors.OLIVE, packageName, Colors.NORMAL,
                                 Colors.DARK_BLUE, SteamDB.GetPackageURL(SubID, "history")
                                 );
                }
            }

#if DEBUG
            if (kv["name"].Value == null)
            {
                if (string.IsNullOrEmpty(packageName)) // We don't have the package in our database yet
                {
                    // Don't do anything then
                    Log.WriteError("Sub Processor", "Got a package without a name, and we don't have it in our database: {0}", SubID);
                }
                else
                {
                    ////MakeHistory("deleted_sub", "0", packageName, "", true);

                    Log.WriteError("Sub Processor", "Got a package without a name, but we have it in our database: {0}", SubID);
                }
            }
#endif
        }
コード例 #12
0
        protected override async Task ProcessData()
        {
            await LoadData();

            ChangeNumber = ProductInfo.ChangeNumber;

            if (Settings.IsFullRun)
            {
                await DbConnection.ExecuteAsync("INSERT INTO `Changelists` (`ChangeID`) VALUES (@ChangeNumber) ON DUPLICATE KEY UPDATE `Date` = `Date`", new { ProductInfo.ChangeNumber });

                await DbConnection.ExecuteAsync("INSERT INTO `ChangelistsSubs` (`ChangeID`, `SubID`) VALUES (@ChangeNumber, @SubID) ON DUPLICATE KEY UPDATE `SubID` = `SubID`", new { SubID, ProductInfo.ChangeNumber });
            }

            await ProcessKey("root_changenumber", "changenumber", ChangeNumber.ToString());

            var appAddedToThisPackage = false;
            var packageOwned          = LicenseList.OwnedSubs.ContainsKey(SubID);
            var newPackageName        = ProductInfo.KeyValues["name"].AsString();
            var apps = (await DbConnection.QueryAsync <PackageApp>("SELECT `AppID`, `Type` FROM `SubsApps` WHERE `SubID` = @SubID", new { SubID })).ToDictionary(x => x.AppID, x => x.Type);

            // TODO: Ideally this should be SteamDB Unknown Package and proper checks like app processor does
            if (newPackageName == null)
            {
                newPackageName = string.Concat("Steam Sub ", SubID);
            }

            if (newPackageName != null)
            {
                if (string.IsNullOrEmpty(PackageName))
                {
                    await DbConnection.ExecuteAsync("INSERT INTO `Subs` (`SubID`, `Name`, `LastKnownName`) VALUES (@SubID, @Name, @Name)", new { SubID, Name = newPackageName });

                    await MakeHistory("created_sub");
                    await MakeHistory("created_info", SteamDB.DATABASE_NAME_TYPE, string.Empty, newPackageName);
                }
                else if (!PackageName.Equals(newPackageName))
                {
                    if (newPackageName.StartsWith("Steam Sub ", StringComparison.Ordinal))
                    {
                        await DbConnection.ExecuteAsync("UPDATE `Subs` SET `Name` = @Name WHERE `SubID` = @SubID", new { SubID, Name = newPackageName });
                    }
                    else
                    {
                        await DbConnection.ExecuteAsync("UPDATE `Subs` SET `Name` = @Name, `LastKnownName` = @Name WHERE `SubID` = @SubID", new { SubID, Name = newPackageName });
                    }

                    await MakeHistory("modified_info", SteamDB.DATABASE_NAME_TYPE, PackageName, newPackageName);
                }
            }

            foreach (var section in ProductInfo.KeyValues.Children)
            {
                var sectionName = section.Name.ToLower();

                if (string.IsNullOrEmpty(sectionName) || sectionName.Equals("packageid") || sectionName.Equals("changenumber") || sectionName.Equals("name"))
                {
                    // Ignore common keys
                    continue;
                }

                if (sectionName.Equals("appids") || sectionName.Equals("depotids"))
                {
                    // Remove "ids", so we get "app" from appids and "depot" from depotids
                    var type         = sectionName.Replace("ids", string.Empty);
                    var isAppSection = type.Equals("app");
                    var typeID       = (uint)(isAppSection ? 0 : 1); // 0 = app, 1 = depot; can't store as string because it's in the `key` field

                    foreach (var childrenApp in section.Children)
                    {
                        var appID = uint.Parse(childrenApp.Value);

                        // Is this appid already in this package?
                        if (apps.ContainsKey(appID))
                        {
                            // Is this appid's type the same?
                            if (apps[appID] != type)
                            {
                                await DbConnection.ExecuteAsync("UPDATE `SubsApps` SET `Type` = @Type WHERE `SubID` = @SubID AND `AppID` = @AppID", new { SubID, AppID = appID, Type = type });
                                await MakeHistory("added_to_sub", typeID, apps[appID].Equals("app")? "0" : "1", childrenApp.Value);

                                appAddedToThisPackage = true;

                                // TODO: Log relevant add/remove history for depot/app?
                            }

                            apps.Remove(appID);
                        }
                        else
                        {
                            await DbConnection.ExecuteAsync("INSERT INTO `SubsApps` (`SubID`, `AppID`, `Type`) VALUES(@SubID, @AppID, @Type)", new { SubID, AppID = appID, Type = type });
                            await MakeHistory("added_to_sub", typeID, string.Empty, childrenApp.Value);

                            if (isAppSection)
                            {
                                await DbConnection.ExecuteAsync(AppProcessor.HistoryQuery,
                                                                new PICSHistory
                                {
                                    ID       = appID,
                                    ChangeID = ChangeNumber,
                                    NewValue = SubID.ToString(),
                                    Action   = "added_to_sub"
                                }
                                                                );
                            }
                            else
                            {
                                await DbConnection.ExecuteAsync(DepotProcessor.HistoryQuery,
                                                                new DepotHistory
                                {
                                    DepotID  = appID,
                                    ChangeID = ChangeNumber,
                                    NewValue = SubID,
                                    Action   = "added_to_sub"
                                }
                                                                );
                            }

                            appAddedToThisPackage = true;

                            if (packageOwned && !LicenseList.OwnedApps.ContainsKey(appID))
                            {
                                LicenseList.OwnedApps.Add(appID, 1);
                            }

                            if (Application.ImportantApps.ContainsKey(appID))
                            {
                                IRC.Instance.AnnounceImportantAppUpdate(appID, $"Important app {Colors.BLUE}{Steam.GetAppName(appID)}{Colors.NORMAL} was added to package -{Colors.DARKBLUE} {SteamDB.GetPackageURL(SubID, "history")}");
                            }
                        }
                    }
                }
                else if (sectionName.Equals("extended"))
                {
                    foreach (var children in section.Children)
                    {
                        var keyName = string.Format("{0}_{1}", sectionName, children.Name);

                        if (children.Children.Count > 0)
                        {
                            await ProcessKey(keyName, children.Name, Utils.JsonifyKeyValue(children), true);
                        }
                        else
                        {
                            await ProcessKey(keyName, children.Name, children.Value);
                        }
                    }
                }
                else if (section.Children.Any())
                {
                    sectionName = string.Format("root_{0}", sectionName);

                    await ProcessKey(sectionName, sectionName, Utils.JsonifyKeyValue(section), true);
                }
                else if (!string.IsNullOrEmpty(section.Value))
                {
                    var keyName = string.Format("root_{0}", sectionName);

                    await ProcessKey(keyName, sectionName, section.Value);
                }
            }

            foreach (var data in CurrentData.Values.Where(data => !data.Processed && !data.KeyName.StartsWith("website", StringComparison.Ordinal)))
            {
                await DbConnection.ExecuteAsync("DELETE FROM `SubsInfo` WHERE `SubID` = @SubID AND `Key` = @Key", new { SubID, data.Key });
                await MakeHistory("removed_key", data.Key, data.Value);
            }

            var appsRemoved = apps.Any();

            foreach (var app in apps)
            {
                await DbConnection.ExecuteAsync("DELETE FROM `SubsApps` WHERE `SubID` = @SubID AND `AppID` = @AppID AND `Type` = @Type", new { SubID, AppID = app.Key, Type = app.Value });

                var isAppSection = app.Value.Equals("app");

                var typeID = (uint)(isAppSection ? 0 : 1); // 0 = app, 1 = depot; can't store as string because it's in the `key` field

                await MakeHistory("removed_from_sub", typeID, app.Key.ToString());

                if (isAppSection)
                {
                    await DbConnection.ExecuteAsync(AppProcessor.HistoryQuery,
                                                    new PICSHistory
                    {
                        ID       = app.Key,
                        ChangeID = ChangeNumber,
                        OldValue = SubID.ToString(),
                        Action   = "removed_from_sub"
                    }
                                                    );
                }
                else
                {
                    await DbConnection.ExecuteAsync(DepotProcessor.HistoryQuery,
                                                    new DepotHistory
                    {
                        DepotID  = app.Key,
                        ChangeID = ChangeNumber,
                        OldValue = SubID,
                        Action   = "removed_from_sub"
                    }
                                                    );
                }
            }

            if (appsRemoved)
            {
                LicenseList.RefreshApps();
            }

            if (!packageOwned && SubID != 17906)
            {
                FreeLicense.RequestFromPackage(SubID, ProductInfo.KeyValues);
            }

            // Re-queue apps in this package so we can update depots and whatnot
            if (appAddedToThisPackage && !Settings.IsFullRun && !string.IsNullOrEmpty(PackageName))
            {
                JobManager.AddJob(() => Steam.Instance.Apps.PICSGetAccessTokens(ProductInfo.KeyValues["appids"].Children.Select(x => (uint)x.AsInteger()), Enumerable.Empty <uint>()));
            }

            // Maintain a list of anonymous content
            if (appAddedToThisPackage && SubID == 17906)
            {
                LicenseList.RefreshAnonymous();
            }
        }
コード例 #13
0
        private static void OnPICSProductInfo(SteamApps.PICSProductInfoCallback callback)
        {
            JobAction job;

            if (!JobManager.TryRemoveJob(callback.JobID, out job) || !job.IsCommand)
            {
                return;
            }

            var request = job.CommandRequest;

            if (request.Type == JobManager.IRCRequestType.TYPE_SUB)
            {
                if (!callback.Packages.ContainsKey(request.Target))
                {
                    CommandHandler.ReplyToCommand(request.Command, "Unknown SubID: {0}{1}{2}", Colors.BLUE, request.Target, LicenseList.OwnedSubs.ContainsKey(request.Target) ? SteamDB.StringCheckmark : string.Empty);

                    return;
                }

                var    info = callback.Packages[request.Target];
                var    kv   = info.KeyValues.Children.FirstOrDefault();
                string name;

                if (kv["name"].Value != null)
                {
                    name = Utils.RemoveControlCharacters(kv["name"].AsString());
                }
                else
                {
                    name = Steam.GetPackageName(info.ID);
                }

                try
                {
                    kv.SaveToFile(Path.Combine(Application.Path, "sub", string.Format("{0}.vdf", info.ID)), false);
                }
                catch (Exception e)
                {
                    CommandHandler.ReplyToCommand(request.Command, "Unable to save file for {0}: {1}", name, e.Message);

                    return;
                }

                CommandHandler.ReplyToCommand(request.Command, "{0}{1}{2} -{3} {4}{5} - Dump:{6} {7}{8}{9}{10}",
                                              Colors.BLUE, name, Colors.NORMAL,
                                              Colors.DARKBLUE, SteamDB.GetPackageURL(info.ID), Colors.NORMAL,
                                              Colors.DARKBLUE, SteamDB.GetRawPackageURL(info.ID), Colors.NORMAL,
                                              info.MissingToken ? SteamDB.StringNeedToken : string.Empty,
                                              LicenseList.OwnedSubs.ContainsKey(info.ID) ? SteamDB.StringCheckmark : string.Empty
                                              );
            }
            else if (request.Type == JobManager.IRCRequestType.TYPE_APP)
            {
                if (!callback.Apps.ContainsKey(request.Target))
                {
                    CommandHandler.ReplyToCommand(request.Command, "Unknown AppID: {0}{1}{2}", Colors.BLUE, request.Target, LicenseList.OwnedApps.ContainsKey(request.Target) ? SteamDB.StringCheckmark : string.Empty);

                    return;
                }

                var    info = callback.Apps[request.Target];
                string name;

                if (info.KeyValues["common"]["name"].Value != null)
                {
                    name = Utils.RemoveControlCharacters(info.KeyValues["common"]["name"].AsString());
                }
                else
                {
                    name = Steam.GetAppName(info.ID);
                }

                try
                {
                    info.KeyValues.SaveToFile(Path.Combine(Application.Path, "app", string.Format("{0}.vdf", info.ID)), false);
                }
                catch (Exception e)
                {
                    CommandHandler.ReplyToCommand(request.Command, "Unable to save file for {0}: {1}", name, e.Message);

                    return;
                }

                CommandHandler.ReplyToCommand(request.Command, "{0}{1}{2} -{3} {4}{5} - Dump:{6} {7}{8}{9}{10}",
                                              Colors.BLUE, name, Colors.NORMAL,
                                              Colors.DARKBLUE, SteamDB.GetAppURL(info.ID), Colors.NORMAL,
                                              Colors.DARKBLUE, SteamDB.GetRawAppURL(info.ID), Colors.NORMAL,
                                              info.MissingToken ? SteamDB.StringNeedToken : string.Empty,
                                              LicenseList.OwnedApps.ContainsKey(info.ID) ? SteamDB.StringCheckmark : string.Empty
                                              );
            }
            else
            {
                CommandHandler.ReplyToCommand(request.Command, "I have no idea what happened here!");
            }
        }