From 7b48d13ebfd54221e5ac355e3049164ed9654337 Mon Sep 17 00:00:00 2001 From: lay295 Date: Sun, 13 Feb 2022 23:47:28 -0500 Subject: [PATCH] Missed some kraken endpoints --- .../TwitchDownloaderCLI.csproj | 2 +- TwitchDownloaderCore/TwitchHelper.cs | 101 +++++++++++------- .../TwitchObjects/GqlCheerResponse.cs | 51 +++++++++ TwitchDownloaderWPF/MainWindow.xaml.cs | 2 +- 4 files changed, 116 insertions(+), 40 deletions(-) create mode 100644 TwitchDownloaderCore/TwitchObjects/GqlCheerResponse.cs diff --git a/TwitchDownloaderCLI/TwitchDownloaderCLI.csproj b/TwitchDownloaderCLI/TwitchDownloaderCLI.csproj index dd4aef6d..9a5fbe1c 100644 --- a/TwitchDownloaderCLI/TwitchDownloaderCLI.csproj +++ b/TwitchDownloaderCLI/TwitchDownloaderCLI.csproj @@ -3,7 +3,7 @@ Exe netcoreapp3.1 - 1.40.6 + 1.40.7 AnyCPU;x64 diff --git a/TwitchDownloaderCore/TwitchHelper.cs b/TwitchDownloaderCore/TwitchHelper.cs index 16cc746f..7f5ddc34 100644 --- a/TwitchDownloaderCore/TwitchHelper.cs +++ b/TwitchDownloaderCore/TwitchHelper.cs @@ -562,54 +562,78 @@ public static List GetBits(string cacheFolder, string channel_id = " using (WebClient client = new WebClient()) { - client.Headers.Add("Accept", "application/vnd.twitchtv.v5+json"); + client.Encoding = Encoding.UTF8; client.Headers.Add("Client-ID", "kimne78kx3ncx6brgo4mv6wki5h1ko"); - JObject globalCheer = JObject.Parse(client.DownloadString("https://api.twitch.tv/kraken/bits/actions?channel_id=" + channel_id)); + GqlCheerResponse cheerResponse = JsonConvert.DeserializeObject(client.UploadString("https://gql.twitch.tv/gql", "{\"query\":\"query{cheerConfig{groups{nodes{id, prefix, tiers{bits}}, templateURL}},user(id:\\\"" + channel_id + "\\\"){cheer{cheerGroups{nodes{id,prefix,tiers{bits}},templateURL}}}}\",\"variables\":{}}")); - foreach (JToken emoteToken in globalCheer["actions"]) + if (cheerResponse != null && cheerResponse.data != null) { - string prefix = emoteToken["prefix"].ToString(); - List> tierList = new List>(); - CheerEmote newEmote = new CheerEmote() { prefix = prefix, tierList = tierList }; - foreach (JToken tierToken in emoteToken["tiers"]) + List groupList = new List(); + + foreach (CheerGroup group in cheerResponse.data.cheerConfig.groups) { - try + groupList.Add(group); + } + + if (cheerResponse.data.user != null && cheerResponse.data.user.cheer != null && cheerResponse.data.user.cheer.cheerGroups != null) + { + foreach (var group in cheerResponse.data.user.cheer.cheerGroups) { - int minBits = tierToken["min_bits"].ToObject(); - string fileName = Path.Combine(bitsFolder, prefix + minBits + "_2x.gif"); - byte[] finalBytes = null; + groupList.Add(group); + } + } - if (File.Exists(fileName)) - { - try - { - finalBytes = File.ReadAllBytes(fileName); - } - catch { } - } - if (finalBytes == null) + foreach (CheerGroup group in groupList) + { + string templateURL = group.templateURL; + + foreach (CheerNode node in group.nodes) + { + string prefix = node.prefix; + List> tierList = new List>(); + CheerEmote newEmote = new CheerEmote() { prefix = prefix, tierList = tierList }; + foreach (Tier tier in node.tiers) { - byte[] bytes = client.DownloadData(tierToken["images"]["dark"]["animated"]["2"].ToString()); try { - File.WriteAllBytes(fileName, bytes); - } - catch { } - finalBytes = bytes; - } + int minBits = tier.bits; + string fileName = Path.Combine(bitsFolder, prefix + minBits + "_2x.gif"); + byte[] finalBytes = null; - if (finalBytes != null) - { - MemoryStream ms = new MemoryStream(finalBytes); - TwitchEmote emote = new TwitchEmote(new List() { SKBitmap.Decode(finalBytes) }, SKCodec.Create(ms), prefix, "gif", "", 2, finalBytes); - tierList.Add(new KeyValuePair(minBits, emote)); + if (File.Exists(fileName)) + { + try + { + finalBytes = File.ReadAllBytes(fileName); + } + catch { } + } + if (finalBytes == null) + { + string url = templateURL.Replace("PREFIX", node.prefix.ToLower()).Replace("BACKGROUND", "dark").Replace("ANIMATION", "animated").Replace("TIER", tier.bits.ToString()).Replace("SCALE.EXTENSION", "2.gif"); + byte[] bytes = client.DownloadData(url); + try + { + File.WriteAllBytes(fileName, bytes); + } + catch { } + finalBytes = bytes; + } + + if (finalBytes != null) + { + MemoryStream ms = new MemoryStream(finalBytes); + TwitchEmote emote = new TwitchEmote(new List() { SKBitmap.Decode(finalBytes) }, SKCodec.Create(ms), prefix, "gif", "", 2, finalBytes); + tierList.Add(new KeyValuePair(minBits, emote)); + } + } + catch + { } } + cheerEmotes.Add(newEmote); } - catch - { } } - cheerEmotes.Add(newEmote); } } @@ -669,11 +693,12 @@ public static string GetStreamerName(int id) { using (WebClient client = new WebClient()) { - client.Headers.Add("Accept", "application/vnd.twitchtv.v5+json; charset=UTF-8"); - client.Headers.Add("Client-Id", "v8kfhyc2980it9e7t5hhc7baukzuj2"); + client.Encoding = Encoding.UTF8; + client.Headers.Add("Client-ID", "kimne78kx3ncx6brgo4mv6wki5h1ko"); + + JObject response = JObject.Parse(client.UploadString("https://gql.twitch.tv/gql", "{\"query\":\"query{user(id:\\\"" + id.ToString() + "\\\"){login}}\",\"variables\":{}}")); - JObject response = JObject.Parse(client.DownloadString("https://api.twitch.tv/kraken/users/" + id)); - return response["name"].ToString(); + return response["data"]["user"]["login"].ToString(); } } catch { return ""; } diff --git a/TwitchDownloaderCore/TwitchObjects/GqlCheerResponse.cs b/TwitchDownloaderCore/TwitchObjects/GqlCheerResponse.cs new file mode 100644 index 00000000..c848fb40 --- /dev/null +++ b/TwitchDownloaderCore/TwitchObjects/GqlCheerResponse.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace TwitchDownloaderCore.TwitchObjects +{ + public class Tier + { + public int bits { get; set; } + } + + public class CheerNode + { + public string id { get; set; } + public string prefix { get; set; } + public List tiers { get; set; } + } + + public class CheerGroup + { + public List nodes { get; set; } + public string templateURL { get; set; } + } + + public class CheerConfig + { + public List groups { get; set; } + } + + public class Cheer + { + public List cheerGroups { get; set; } + } + + public class CheerUser + { + public Cheer cheer { get; set; } + } + + public class CheerData + { + public CheerConfig cheerConfig { get; set; } + public CheerUser user { get; set; } + } + + public class GqlCheerResponse + { + public CheerData data { get; set; } + public Extensions extensions { get; set; } + } +} diff --git a/TwitchDownloaderWPF/MainWindow.xaml.cs b/TwitchDownloaderWPF/MainWindow.xaml.cs index 9d19d798..a8d090b6 100644 --- a/TwitchDownloaderWPF/MainWindow.xaml.cs +++ b/TwitchDownloaderWPF/MainWindow.xaml.cs @@ -79,7 +79,7 @@ private async void Window_Loaded(object sender, RoutedEventArgs e) if (!File.Exists("ffmpeg.exe")) await FFmpegDownloader.GetLatestVersion(FFmpegVersion.Full); - AutoUpdater.InstalledVersion = new Version("1.40.6.0"); + AutoUpdater.InstalledVersion = new Version("1.40.7.0"); AutoUpdater.Start("https://downloader-update.twitcharchives.workers.dev"); }