private async Task ProcessKey(string keyName, string displayName, string value, bool isJSON = false)
        {
            if (keyName.Length > 90)
            {
                Log.WriteError(nameof(SubProcessor), $"Key {keyName} for SubID {SubID} is too long, not inserting info.");

                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.ToLowerInvariant().Trim();

            if (!CurrentData.ContainsKey(keyName))
            {
                CurrentData[keyName] = new PICSInfo
                {
                    Processed = true,
                };

                var key = KeyNameCache.GetSubKeyID(keyName);

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

                    key = await KeyNameCache.CreateSubKey(keyName, displayName, type);

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

                        return;
                    }

                    IRC.Instance.SendOps($"New package keyname: {Colors.BLUE}{keyName} {Colors.LIGHTGRAY}(ID: {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(nameof(SubProcessor), $"Duplicate key {keyName} in SubID {SubID}");

                return;
            }

            data.Processed = true;

            CurrentData[keyName] = data;

            if (data.Value == 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);
        }
        private async Task <bool> ProcessKey(string keyName, string displayName, string value, KeyValue newKv = null)
        {
            if (keyName.Length > 90)
            {
                Log.WriteError(nameof(AppProcessor), $"Key {keyName} for AppID {AppID} is too long, not inserting info.");

                return(false);
            }

            // All keys in PICS are supposed to be lower case
            keyName = keyName.ToLowerInvariant().Trim();

            if (!CurrentData.ContainsKey(keyName))
            {
                CurrentData[keyName] = new PICSInfo
                {
                    Processed = true,
                };

                var key = KeyNameCache.GetAppKeyID(keyName);

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

                    key = await KeyNameCache.CreateAppKey(keyName, displayName, type);

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

                        return(false);
                    }

                    IRC.Instance.SendOps($"New app keyname: {Colors.BLUE}{keyName} {Colors.LIGHTGRAY}(ID: {key}) ({displayName}) - {SteamDB.GetAppUrl(AppID, "history")}");
                }

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

                if ((keyName == "extended_developer" || keyName == "extended_publisher") && value == "Valve")
                {
                    IRC.Instance.SendOps($"New {displayName}=Valve app: {Colors.BLUE}{Steam.GetAppName(AppID)}{Colors.NORMAL} -{Colors.DARKBLUE} {SteamDB.GetAppUrl(AppID, "history")}");
                }

                if (keyName == "common_oslist" && value.Contains("linux"))
                {
                    PrintLinux();
                }

                return(true);
            }

            var data = CurrentData[keyName];

            if (data.Processed)
            {
                Log.WriteWarn(nameof(AppProcessor), $"Duplicate key {keyName} in AppID {AppID}");

                return(false);
            }

            data.Processed = true;

            CurrentData[keyName] = data;

            if (data.Value == value)
            {
                return(false);
            }

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

            if (newKv != null)
            {
                await MakeHistoryForJson(data.Key, data.Value, newKv);
            }
            else
            {
                await MakeHistory("modified_key", data.Key, data.Value, value);
            }

            if (keyName == "common_oslist" && value.Contains("linux") && !data.Value.Contains("linux"))
            {
                PrintLinux();
            }

            return(true);
        }