Fix emotesets not loading properly (#2905)

* Initial work

fk I'm so tired...

* Updated Twitch API documentation

* Futher changes

* Removed debug output

* Added changelog entry

* Advice: don't code at 4am

removed all silly debug stuff

* Add missing lambda capture
This commit is contained in:
Paweł 2021-06-24 23:23:31 +02:00 committed by GitHub
parent ed6ef0b98e
commit 002129009d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 96 additions and 32 deletions

View file

@ -24,6 +24,7 @@
- Bugfix: Fixed pasting text with URLs included (#1688, #2855)
- Bugfix: Fix reconnecting when IRC write connection is lost (#1831, #2356, #2850, #2892)
- Bugfix: Fixed bit and new subscriber emotes not (re)loading in some rare cases. (#2856, #2857)
- Bugfix: Fixed subscription emotes showing up incorrectly in the emote menu. (#2905)
## 2.3.2

View file

@ -358,7 +358,6 @@ void TwitchAccount::loadUserstateEmotes()
name[0] = name[0].toUpper();
newUserEmoteSet->text = name;
newUserEmoteSet->type = QString();
newUserEmoteSet->channelName = ivrEmoteSet.login;
for (const auto &emote : ivrEmoteSet.emotes)
@ -508,38 +507,48 @@ void TwitchAccount::loadEmoteSetData(std::shared_ptr<EmoteSet> emoteSet)
return;
}
NetworkRequest(Env::get().twitchEmoteSetResolverUrl.arg(emoteSet->key))
.cache()
.onSuccess([emoteSet](NetworkResult result) -> Outcome {
auto root = result.parseJson();
if (root.isEmpty())
getHelix()->getEmoteSetData(
emoteSet->key,
[emoteSet](HelixEmoteSetData emoteSetData) {
if (emoteSetData.ownerId.isEmpty() ||
emoteSetData.setId != emoteSet->key)
{
return Failure;
qCWarning(chatterinoTwitch)
<< QString("Failed to fetch emoteSetData for %1, assuming "
"Twitch is the owner")
.arg(emoteSet->key);
// most (if not all) emotes that fail to load are time limited event emotes owned by Twitch
emoteSet->channelName = "twitch";
emoteSet->text = "Twitch";
return;
}
TwitchEmoteSetResolverResponse response(root);
// emote set 0 = global emotes
if (emoteSetData.ownerId == "0")
{
// emoteSet->channelName = QString();
emoteSet->text = "Twitch Global";
return;
}
auto name = response.channelName;
name.detach();
name[0] = name[0].toUpper();
emoteSet->text = name;
emoteSet->type = response.type;
emoteSet->channelName = response.channelName;
qCDebug(chatterinoTwitch)
<< QString("Loaded twitch emote set data for %1")
.arg(emoteSet->key);
return Success;
})
.onError([emoteSet](NetworkResult result) {
qCWarning(chatterinoTwitch)
<< QString("Error code %1 while loading emote set data for %2")
.arg(result.status())
.arg(emoteSet->key);
})
.execute();
getHelix()->getUserById(
emoteSetData.ownerId,
[emoteSet](HelixUser user) {
emoteSet->channelName = user.login;
emoteSet->text = user.displayName;
},
[emoteSetData] {
qCWarning(chatterinoTwitch)
<< "Failed to query user by id:" << emoteSetData.ownerId
<< emoteSetData.setId;
});
},
[emoteSet] {
// fetching emoteset data failed
return;
});
}
} // namespace chatterino

View file

@ -62,7 +62,6 @@ public:
QString key;
QString channelName;
QString text;
QString type;
std::vector<TwitchEmote> emotes;
};

View file

@ -761,6 +761,38 @@ void Helix::getCheermotes(
.execute();
}
void Helix::getEmoteSetData(QString emoteSetId,
ResultCallback<HelixEmoteSetData> successCallback,
HelixFailureCallback failureCallback)
{
QUrlQuery urlQuery;
urlQuery.addQueryItem("emote_set_id", emoteSetId);
this->makeRequest("chat/emotes/set", urlQuery)
.onSuccess([successCallback, failureCallback,
emoteSetId](auto result) -> Outcome {
QJsonObject root = result.parseJson();
auto data = root.value("data");
if (!data.isArray())
{
failureCallback();
return Failure;
}
HelixEmoteSetData emoteSetData(data.toArray()[0].toObject());
successCallback(emoteSetData);
return Success;
})
.onError([failureCallback](NetworkResult result) {
// TODO: make better xd
failureCallback();
})
.execute();
}
NetworkRequest Helix::makeRequest(QString url, QUrlQuery urlQuery)
{
assert(!url.startsWith("/"));

View file

@ -264,6 +264,17 @@ struct HelixCheermoteSet {
}
};
struct HelixEmoteSetData {
QString setId;
QString ownerId;
explicit HelixEmoteSetData(QJsonObject jsonObject)
: setId(jsonObject.value("emote_set_id").toString())
, ownerId(jsonObject.value("owner_id").toString())
{
}
};
enum class HelixClipError {
Unknown,
ClipsDisabled,
@ -398,6 +409,11 @@ public:
ResultCallback<std::vector<HelixCheermoteSet>> successCallback,
HelixFailureCallback failureCallback);
// https://dev.twitch.tv/docs/api/reference#get-emote-sets
void getEmoteSetData(QString emoteSetId,
ResultCallback<HelixEmoteSetData> successCallback,
HelixFailureCallback failureCallback);
void update(QString clientId, QString oauthToken);
static void initialize();

View file

@ -157,6 +157,14 @@ URL: https://dev.twitch.tv/docs/api/reference/#get-cheermotes
Used in:
- `providers/twitch/TwitchChannel.cpp` to resolve a chats available cheer emotes. This helps us parse incoming messages like `pajaCheer1000`
### Get Emote Sets
URL: https://dev.twitch.tv/docs/api/reference#get-emote-sets
- We implement this in `providers/twitch/api/Helix.cpp getEmoteSetData`
Used in:
- `providers/twitch/TwitchAccount.cpp` to set emoteset owner data upon loading subscriber emotes from Kraken
## TMI
The TMI api is undocumented.

View file

@ -71,8 +71,7 @@ namespace {
{
// TITLE
auto channelName = set->channelName;
auto text =
set->key == "0" || set->text.isEmpty() ? "Twitch" : set->text;
auto text = set->text.isEmpty() ? "Twitch" : set->text;
// EMOTES
MessageBuilder builder;