public static string JsonifyKeyValue(KeyValue keys) { string value = string.Empty; using (var sw = new StringWriter(new StringBuilder())) { using (JsonWriter w = new JsonTextWriter(sw)) { DbWorker.JsonifyKeyValue(w, keys.Children); } value = sw.ToString(); } return(value); }
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 }
private void TryProcess(SteamApps.PICSProductInfoCallback.PICSProductInfo productInfo) { using (MySqlDataReader Reader = DbWorker.ExecuteReader("SELECT `Name`, `Value` FROM `AppsInfo` INNER JOIN `KeyNames` ON `AppsInfo`.`Key` = `KeyNames`.`ID` WHERE `AppID` = @AppID", new MySqlParameter("AppID", AppID))) { while (Reader.Read()) { CurrentData.Add(DbWorker.GetString("Name", Reader), DbWorker.GetString("Value", Reader)); } } string appName = string.Empty; string appType = "0"; using (MySqlDataReader Reader = DbWorker.ExecuteReader("SELECT `Name`, `AppType` FROM `Apps` WHERE `AppID` = @AppID LIMIT 1", new MySqlParameter("AppID", AppID))) { if (Reader.Read()) { appName = DbWorker.GetString("Name", Reader); appType = DbWorker.GetString("AppType", Reader); } } if (productInfo.KeyValues["common"]["name"].Value != null) { string newAppType = "0"; string currentType = productInfo.KeyValues["common"]["type"].AsString().ToLower(); using (MySqlDataReader Reader = DbWorker.ExecuteReader("SELECT `AppType` FROM `AppsTypes` WHERE `Name` = @Type LIMIT 1", new MySqlParameter("Type", currentType))) { if (Reader.Read()) { newAppType = DbWorker.GetString("AppType", Reader); } else { // TODO: Create it? Log.WriteError("App Processor", "AppID {0} - unknown app type: {1}", AppID, currentType); // TODO: This is debuggy just so we are aware of new app types IRC.SendAnnounce("Unknown app type \"{0}\" for appid {1}, cc Alram and xPaw", currentType, AppID); } } if (string.IsNullOrEmpty(appName) || appName.StartsWith(SteamDB.UNKNOWN_APP, StringComparison.Ordinal)) { DbWorker.ExecuteNonQuery("INSERT INTO `Apps` (`AppID`, `AppType`, `Name`) VALUES (@AppID, @Type, @AppName) ON DUPLICATE KEY UPDATE `Name` = @AppName, `AppType` = @Type", new MySqlParameter("@AppID", AppID), new MySqlParameter("@Type", newAppType), new MySqlParameter("@AppName", productInfo.KeyValues["common"]["name"].Value) ); MakeHistory("created_app"); MakeHistory("created_info", DATABASE_NAME_TYPE, string.Empty, productInfo.KeyValues["common"]["name"].Value); // TODO: Testy testy if (!Settings.IsFullRun && Settings.Current.ChatRooms.Count > 0 && !appName.StartsWith("SteamApp", StringComparison.Ordinal) && !appName.StartsWith("ValveTest", StringComparison.Ordinal)) { Steam.Instance.Friends.SendChatRoomMessage(Settings.Current.ChatRooms[0], EChatEntryType.ChatMsg, string.Format( ":retreat: New {0} was published: {1}\nSteamDB: {2}\nSteam: http://store.steampowered.com/app/{3}/", currentType, productInfo.KeyValues["common"]["name"].AsString(), SteamDB.GetAppURL(AppID), AppID ) ); } } else if (!appName.Equals(productInfo.KeyValues["common"]["name"].Value)) { string newAppName = productInfo.KeyValues["common"]["name"].AsString(); DbWorker.ExecuteNonQuery("UPDATE `Apps` SET `Name` = @AppName WHERE `AppID` = @AppID", new MySqlParameter("@AppID", AppID), new MySqlParameter("@AppName", newAppName) ); MakeHistory("modified_info", DATABASE_NAME_TYPE, appName, newAppName); // TODO: Testy testy if (!Settings.IsFullRun && Settings.Current.ChatRooms.Count > 0 && !string.Equals(appName, newAppName, StringComparison.OrdinalIgnoreCase) && !newAppName.StartsWith("SteamApp", StringComparison.Ordinal) && !newAppName.StartsWith("ValveTest", StringComparison.Ordinal)) { Steam.Instance.Friends.SendChatRoomMessage(Settings.Current.ChatRooms[0], EChatEntryType.ChatMsg, string.Format( ":retreat: {0} name was changed - {1}\n« {2}\n» {3}", currentType, SteamDB.GetAppURL(AppID, "history"), appName, newAppName ) ); } } if (appType.Equals("0")) { DbWorker.ExecuteNonQuery("UPDATE `Apps` SET `AppType` = @Type WHERE `AppID` = @AppID", new MySqlParameter("@AppID", AppID), new MySqlParameter("@Type", newAppType) ); MakeHistory("created_info", DATABASE_APPTYPE, string.Empty, newAppType); } else if (!appType.Equals(newAppType)) { DbWorker.ExecuteNonQuery("UPDATE `Apps` SET `AppType` = @Type WHERE `AppID` = @AppID", new MySqlParameter("@AppID", AppID), new MySqlParameter("@Type", newAppType) ); MakeHistory("modified_info", DATABASE_APPTYPE, appType, newAppType); } } // If we are full running, process depots too bool depotsSectionModified = Settings.IsFullRun && productInfo.KeyValues["depots"].Children.Count > 0; foreach (KeyValue section in productInfo.KeyValues.Children) { string sectionName = section.Name.ToLower(); if (sectionName == "appid" || sectionName == "public_only") { continue; } if (sectionName == "change_number") // Carefully handle change_number { sectionName = "root_change_number"; // TODO: Remove this key, move it to Apps table itself ProcessKey(sectionName, "change_number", productInfo.ChangeNumber.ToString()); //section.AsString()); } else if (sectionName == "common" || sectionName == "extended") { string keyName; foreach (KeyValue keyvalue in section.Children) { keyName = string.Format("{0}_{1}", sectionName, keyvalue.Name); if (keyName.Equals("common_type") || keyName.Equals("common_gameid") || keyName.Equals("common_name") || keyName.Equals("extended_order")) { // Ignore common keys that are either duplicated or serve no real purpose continue; } if (keyvalue.Children.Count > 0) { if (keyName.Equals("common_languages")) { ProcessKey(keyName, keyvalue.Name, string.Join(",", keyvalue.Children.Select(x => x.Name))); } else { ProcessKey(keyName, keyvalue.Name, DbWorker.JsonifyKeyValue(keyvalue), true); } } else if (!string.IsNullOrEmpty(keyvalue.Value)) { ProcessKey(keyName, keyvalue.Name, keyvalue.Value); } } } else { sectionName = string.Format("root_{0}", sectionName); if (ProcessKey(sectionName, sectionName, DbWorker.JsonifyKeyValue(section), true) && sectionName.Equals("root_depots")) { depotsSectionModified = true; } } } foreach (string keyName in CurrentData.Keys) { if (!keyName.StartsWith("website", StringComparison.Ordinal)) { uint ID = GetKeyNameID(keyName); DbWorker.ExecuteNonQuery("DELETE FROM AppsInfo WHERE `AppID` = @AppID AND `Key` = @KeyNameID", new MySqlParameter("@AppID", AppID), new MySqlParameter("@KeyNameID", ID) ); MakeHistory("removed_key", ID, CurrentData[keyName]); } } if (productInfo.KeyValues["common"]["name"].Value == null) { if (string.IsNullOrEmpty(appName)) // We don't have the app in our database yet { DbWorker.ExecuteNonQuery("INSERT INTO `Apps` (`AppID`, `Name`) VALUES (@AppID, @AppName) ON DUPLICATE KEY UPDATE `AppType` = `AppType`", new MySqlParameter("@AppID", AppID), new MySqlParameter("@AppName", string.Format("{0} {1}", SteamDB.UNKNOWN_APP, AppID)) ); } else if (!appName.StartsWith(SteamDB.UNKNOWN_APP, StringComparison.Ordinal)) // We do have the app, replace it with default name { DbWorker.ExecuteNonQuery("UPDATE `Apps` SET `Name` = @AppName, `AppType` = 0 WHERE `AppID` = @AppID", new MySqlParameter("@AppID", AppID), new MySqlParameter("@AppName", string.Format("{0} {1}", SteamDB.UNKNOWN_APP, AppID)) ); MakeHistory("deleted_app", 0, appName); } } if (depotsSectionModified) { DepotProcessor.Process(AppID, ChangeNumber, productInfo.KeyValues["depots"]); } }