This commit is contained in:
fourtf 2018-08-14 17:45:17 +02:00
parent d7566665d8
commit 44c16f1b3a
10 changed files with 100 additions and 153 deletions

View file

@ -160,13 +160,14 @@ void Channel::disableAllMessages()
LimitedQueueSnapshot<MessagePtr> snapshot = this->getMessageSnapshot(); LimitedQueueSnapshot<MessagePtr> snapshot = this->getMessageSnapshot();
int snapshotLength = snapshot.getLength(); int snapshotLength = snapshot.getLength();
for (int i = 0; i < snapshotLength; i++) { for (int i = 0; i < snapshotLength; i++) {
auto &s = snapshot[i]; auto &message = snapshot[i];
if (s->flags.hasAny({MessageFlag::System, MessageFlag::Timeout})) { if (message->flags.hasAny(
{MessageFlag::System, MessageFlag::Timeout})) {
continue; continue;
} }
// FOURTF: disabled for now // FOURTF: disabled for now
// s->flags.EnableFlag(MessageFlag::Disabled); const_cast<Message *>(message.get())->flags.set(MessageFlag::Disabled);
} }
} }

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "debug/Log.hpp"
#include "util/RapidjsonHelpers.hpp" #include "util/RapidjsonHelpers.hpp"
#include "debug/Log.hpp" #include "debug/Log.hpp"
#include <boost/asio.hpp> #include <boost/asio.hpp>

View file

@ -4,21 +4,14 @@
#include <QJsonObject> #include <QJsonObject>
#include <QJsonValue> #include <QJsonValue>
#include <QThread> #include <QThread>
#include "common/NetworkRequest.hpp" #include "common/NetworkRequest.hpp"
#include "common/Outcome.hpp" #include "common/Outcome.hpp"
#include "debug/Log.hpp"
#include "messages/Emote.hpp" #include "messages/Emote.hpp"
namespace chatterino { namespace chatterino {
TwitchBadges::TwitchBadges()
{
}
void TwitchBadges::initialize(Settings &settings, Paths &paths)
{
this->loadTwitchBadges();
}
void TwitchBadges::loadTwitchBadges() void TwitchBadges::loadTwitchBadges()
{ {
static QString url( static QString url(
@ -28,32 +21,34 @@ void TwitchBadges::loadTwitchBadges()
req.setCaller(QThread::currentThread()); req.setCaller(QThread::currentThread());
req.onSuccess([this](auto result) -> Outcome { req.onSuccess([this](auto result) -> Outcome {
auto root = result.parseJson(); auto root = result.parseJson();
QJsonObject sets = root.value("badge_sets").toObject(); auto badgeSets = this->badgeSets_.access();
for (QJsonObject::iterator it = sets.begin(); it != sets.end(); ++it) { auto jsonSets = root.value("badge_sets").toObject();
QJsonObject versions = for (auto sIt = jsonSets.begin(); sIt != jsonSets.end(); ++sIt) {
it.value().toObject().value("versions").toObject(); auto key = sIt.key();
auto versions = sIt.value().toObject().value("versions").toObject();
for (auto vIt = versions.begin(); vIt != versions.end(); ++vIt) {
auto versionObj = vIt.value().toObject();
for (auto versionIt = std::begin(versions);
versionIt != std::end(versions); ++versionIt) {
auto emote = Emote{ auto emote = Emote{
{""}, {""},
ImageSet{ ImageSet{
Image::fromUrl({root.value("image_url_1x").toString()}, Image::fromUrl(
1), {versionObj.value("image_url_1x").toString()}, 1),
Image::fromUrl({root.value("image_url_2x").toString()}, Image::fromUrl(
0.5), {versionObj.value("image_url_2x").toString()}, .5),
Image::fromUrl({root.value("image_url_4x").toString()}, Image::fromUrl(
0.25), {versionObj.value("image_url_4x").toString()}, .25),
}, },
Tooltip{root.value("description").toString()}, Tooltip{root.value("description").toString()},
Url{root.value("clickURL").toString()}}; Url{root.value("clickURL").toString()}};
// "title" // "title"
// "clickAction" // "clickAction"
QJsonObject versionObj = versionIt.value().toObject(); log("{} {}", key, vIt.key());
this->badges.emplace(versionIt.key(),
std::make_shared<Emote>(emote)); (*badgeSets)[key][vIt.key()] = std::make_shared<Emote>(emote);
} }
} }
@ -63,4 +58,18 @@ void TwitchBadges::loadTwitchBadges()
req.execute(); req.execute();
} }
boost::optional<EmotePtr> TwitchBadges::badge(const QString &set,
const QString &version) const
{
auto badgeSets = this->badgeSets_.access();
auto it = badgeSets->find(set);
if (it != badgeSets->end()) {
auto it2 = it->second.find(version);
if (it2 != it->second.end()) {
return it2->second;
}
}
return boost::none;
}
} // namespace chatterino } // namespace chatterino

View file

@ -1,7 +1,10 @@
#pragma once #pragma once
#include <QString> #include <QString>
#include <boost/optional.hpp>
#include <unordered_map> #include <unordered_map>
#include "common/UniqueAccess.hpp"
#include "util/QStringHash.hpp" #include "util/QStringHash.hpp"
namespace chatterino { namespace chatterino {
@ -15,14 +18,15 @@ class Paths;
class TwitchBadges class TwitchBadges
{ {
public: public:
TwitchBadges();
void initialize(Settings &settings, Paths &paths);
private:
void loadTwitchBadges(); void loadTwitchBadges();
std::unordered_map<QString, EmotePtr> badges; boost::optional<EmotePtr> badge(const QString &set,
const QString &version) const;
private:
UniqueAccess<
std::unordered_map<QString, std::unordered_map<QString, EmotePtr>>>
badgeSets_; // "bits": { "100": ... "500": ...
}; };
} // namespace chatterino } // namespace chatterino

View file

@ -69,12 +69,14 @@ std::pair<Outcome, UsernameSet> parseChatters(const QJsonObject &jsonRoot)
} }
} // namespace } // namespace
TwitchChannel::TwitchChannel(const QString &name, BttvEmotes &bttv, TwitchChannel::TwitchChannel(const QString &name,
TwitchBadges &globalTwitchBadges, BttvEmotes &bttv,
FfzEmotes &ffz) FfzEmotes &ffz)
: Channel(name, Channel::Type::Twitch) : Channel(name, Channel::Type::Twitch)
, subscriptionUrl_("https://www.twitch.tv/subs/" + name) , subscriptionUrl_("https://www.twitch.tv/subs/" + name)
, channelUrl_("https://twitch.tv/" + name) , channelUrl_("https://twitch.tv/" + name)
, popoutPlayerUrl_("https://player.twitch.tv/?channel=" + name) , popoutPlayerUrl_("https://player.twitch.tv/?channel=" + name)
, globalTwitchBadges_(globalTwitchBadges)
, globalBttv_(bttv) , globalBttv_(bttv)
, globalFfz_(ffz) , globalFfz_(ffz)
, bttvEmotes_(std::make_shared<EmoteMap>()) , bttvEmotes_(std::make_shared<EmoteMap>())
@ -317,6 +319,11 @@ AccessGuard<const UsernameSet> TwitchChannel::accessChatters() const
return this->chatters_.accessConst(); return this->chatters_.accessConst();
} }
const TwitchBadges &TwitchChannel::globalTwitchBadges() const
{
return this->globalTwitchBadges_;
}
const BttvEmotes &TwitchChannel::globalBttv() const const BttvEmotes &TwitchChannel::globalBttv() const
{ {
return this->globalBttv_; return this->globalBttv_;

View file

@ -23,6 +23,7 @@ struct Emote;
using EmotePtr = std::shared_ptr<const Emote>; using EmotePtr = std::shared_ptr<const Emote>;
class EmoteMap; class EmoteMap;
class TwitchBadges;
class FfzEmotes; class FfzEmotes;
class BttvEmotes; class BttvEmotes;
@ -70,6 +71,7 @@ public:
AccessGuard<const UsernameSet> accessChatters() const; AccessGuard<const UsernameSet> accessChatters() const;
// Emotes // Emotes
const TwitchBadges &globalTwitchBadges() const;
const BttvEmotes &globalBttv() const; const BttvEmotes &globalBttv() const;
const FfzEmotes &globalFfz() const; const FfzEmotes &globalFfz() const;
boost::optional<EmotePtr> bttvEmote(const EmoteName &name) const; boost::optional<EmotePtr> bttvEmote(const EmoteName &name) const;
@ -98,8 +100,9 @@ private:
QString localizedName; QString localizedName;
}; };
explicit TwitchChannel(const QString &channelName, BttvEmotes &globalBttv, explicit TwitchChannel(const QString &channelName,
FfzEmotes &globalFfz); TwitchBadges &globalTwitchBadges,
BttvEmotes &globalBttv, FfzEmotes &globalFfz);
// Methods // Methods
void refreshLiveStatus(); void refreshLiveStatus();
@ -126,6 +129,7 @@ private:
UniqueAccess<UsernameSet> chatters_; // maps 2 char prefix to set of names UniqueAccess<UsernameSet> chatters_; // maps 2 char prefix to set of names
// Emotes // Emotes
TwitchBadges &globalTwitchBadges_;
BttvEmotes &globalBttv_; BttvEmotes &globalBttv_;
FfzEmotes &globalFfz_; FfzEmotes &globalFfz_;
Atomic<std::shared_ptr<const EmoteMap>> bttvEmotes_; Atomic<std::shared_ptr<const EmoteMap>> bttvEmotes_;

View file

@ -6,6 +6,7 @@
#include "controllers/ignores/IgnoreController.hpp" #include "controllers/ignores/IgnoreController.hpp"
#include "debug/Log.hpp" #include "debug/Log.hpp"
#include "messages/Message.hpp" #include "messages/Message.hpp"
#include "providers/twitch/TwitchBadges.hpp"
#include "providers/twitch/TwitchChannel.hpp" #include "providers/twitch/TwitchChannel.hpp"
#include "singletons/Emotes.hpp" #include "singletons/Emotes.hpp"
#include "singletons/Resources.hpp" #include "singletons/Resources.hpp"
@ -91,13 +92,6 @@ MessagePtr TwitchMessageBuilder::build()
this->senderIsBroadcaster = true; this->senderIsBroadcaster = true;
} }
//#ifdef XD
// if (this->originalMessage.length() > 100) {
// this->message->flags.has(MessageFlag::Collapsed);
// this->emplace<EmoteElement>(getApp()->resources->badgeCollapsed,
// MessageElementFlag::Collapsed);
// }
//#endif
this->message().flags.has(MessageFlag::Collapsed); this->message().flags.has(MessageFlag::Collapsed);
// PARSING // PARSING
@ -203,11 +197,7 @@ void TwitchMessageBuilder::addWords(
// split words // split words
for (auto &variant : getApp()->emotes->emojis.parse(word)) { for (auto &variant : getApp()->emotes->emojis.parse(word)) {
boost::apply_visitor(/*overloaded{[&](EmotePtr arg) { boost::apply_visitor([&](auto &&arg) { this->addTextOrEmoji(arg); },
this->addTextOrEmoji(arg); },
[&](const QString &arg) {
this->addTextOrEmoji(arg); }}*/
[&](auto &&arg) { this->addTextOrEmoji(arg); },
variant); variant);
} }
@ -659,32 +649,15 @@ Outcome TwitchMessageBuilder::tryAppendEmote(const EmoteName &name)
} }
// fourtf: this is ugly // fourtf: this is ugly
// maybe put the individual badges into a map instead of this
// mess
void TwitchMessageBuilder::appendTwitchBadges() void TwitchMessageBuilder::appendTwitchBadges()
{ {
auto app = getApp(); auto app = getApp();
auto iterator = this->tags.find("badges"); auto iterator = this->tags.find("badges");
if (iterator == this->tags.end()) return;
if (iterator == this->tags.end()) { for (QString badge : iterator.value().toString().split(',')) {
// No badges in this message
return;
}
QStringList badges = iterator.value().toString().split(',');
for (QString badge : badges) {
if (badge.isEmpty()) {
continue;
}
if (badge.startsWith("bits/")) { if (badge.startsWith("bits/")) {
// if (!app->resources->dynamicBadgesLoaded) {
// // Do nothing
// continue;
// }
QString cheerAmount = badge.mid(5); QString cheerAmount = badge.mid(5);
QString tooltip = QString("Twitch cheer ") + cheerAmount; QString tooltip = QString("Twitch cheer ") + cheerAmount;
@ -703,16 +676,12 @@ void TwitchMessageBuilder::appendTwitchBadges()
} }
// Use default bit badge // Use default bit badge
// try { if (auto badge = this->twitchChannel->globalTwitchBadges().badge(
// const auto &badge = "bits", cheerAmount)) {
// app->resources->badgeSets.at("bits").versions.at(cheerAmount); this->emplace<EmoteElement>(badge.get(),
// this->emplace<ImageElement>(badge.badgeImage1x, MessageElementFlag::BadgeVanity)
// MessageElementFlag::BadgeVanity) ->setTooltip(tooltip);
// ->setTooltip(tooltip); }
//} catch (const std::out_of_range &) {
// Log("No default bit badge for version {} found", cheerAmount);
// continue;
//}
} else if (badge == "staff/1") { } else if (badge == "staff/1") {
this->emplace<ImageElement>( this->emplace<ImageElement>(
Image::fromPixmap(app->resources->twitch.staff), Image::fromPixmap(app->resources->twitch.staff),
@ -766,80 +735,30 @@ void TwitchMessageBuilder::appendTwitchBadges()
} break; } break;
} }
} else if (badge.startsWith("subscriber/")) { } else if (badge.startsWith("subscriber/")) {
// if (channelResources.loaded == false) { if (auto badgeEmote = this->twitchChannel->twitchBadge(
// // qDebug() << "Channel resources are not loaded, "subscriber", badge.mid(11))) {
// can't add the subscriber this->emplace<EmoteElement>(
// // badge"; badgeEmote.get(), MessageElementFlag::BadgeSubscription)
// continue; ->setTooltip((*badgeEmote)->tooltip.string);
// } continue;
}
// auto badgeSetIt = channelResources.badgeSets.find("subscriber"); // use default subscriber badge if custom one not found
// if (badgeSetIt == channelResources.badgeSets.end()) { this->emplace<ImageElement>(
// // Fall back to default badge Image::fromPixmap(app->resources->twitch.subscriber, 0.25),
// this->emplace<ImageElement>(app->resources->badgeSubscriber, MessageElementFlag::BadgeSubscription)
// MessageElementFlag::BadgeSubscription) ->setTooltip("Twitch Subscriber");
// ->setTooltip("Twitch Subscriber");
// continue;
//}
// const auto &badgeSet = badgeSetIt->second;
// std::string versionKey = badge.mid(11).toStdString();
// auto badgeVersionIt = badgeSet.versions.find(versionKey);
// if (badgeVersionIt == badgeSet.versions.end()) {
// // Fall back to default badge
// this->emplace<ImageElement>(app->resources->badgeSubscriber,
// MessageElementFlag::BadgeSubscription)
// ->setTooltip("Twitch Subscriber");
// continue;
//}
// auto &badgeVersion = badgeVersionIt->second;
// this->emplace<ImageElement>(badgeVersion.badgeImage1x,
// MessageElementFlag::BadgeSubscription)
// ->setTooltip("Twitch " +
// QString::fromStdString(badgeVersion.title));
} else { } else {
// if (!app->resources->dynamicBadgesLoaded) { auto splits = badge.split('/');
// // Do nothing if (splits.size() != 2) continue;
// continue;
//}
// QStringList parts = badge.split('/'); if (auto badgeEmote =
this->twitchChannel->twitchBadge(splits[0], splits[1])) {
// if (parts.length() != 2) { this->emplace<EmoteElement>(badgeEmote.get(),
// qDebug() << "Bad number of parts: " << parts.length() << " in MessageElementFlag::BadgeVanity)
// " << parts; continue; ->setTooltip((*badgeEmote)->tooltip.string);
//} continue;
}
// MessageElementFlags badgeType =
// MessageElementFlag::BadgeVanity;
// std::string badgeSetKey = parts[0].toStdString();
// std::string versionKey = parts[1].toStdString();
// try {
// auto &badgeSet = app->resources->badgeSets.at(badgeSetKey);
// try {
// auto &badgeVersion = badgeSet.versions.at(versionKey);
// this->emplace<ImageElement>(badgeVersion.badgeImage1x,
// badgeType)
// ->setTooltip("Twitch " +
// QString::fromStdString(badgeVersion.title));
// } catch (const std::exception &e) {
// qDebug() << "Exception caught:" << e.what()
// << "when trying to fetch badge version " <<
// versionKey.c_str();
// }
//} catch (const std::exception &e) {
// qDebug() << "No badge set with key" << badgeSetKey.c_str()
// << ". Exception: " << e.what();
//}
} }
} }
} }

View file

@ -13,7 +13,6 @@
#include "util/PostToThread.hpp" #include "util/PostToThread.hpp"
#include <IrcCommand> #include <IrcCommand>
#include <cassert> #include <cassert>
// using namespace Communi; // using namespace Communi;
@ -41,6 +40,7 @@ void TwitchServer::initialize(Settings &settings, Paths &paths)
getApp()->accounts->twitch.currentUserChanged.connect( getApp()->accounts->twitch.currentUserChanged.connect(
[this]() { postToThread([this] { this->connect(); }); }); [this]() { postToThread([this] { this->connect(); }); });
this->twitchBadges.loadTwitchBadges();
this->bttv.loadEmotes(); this->bttv.loadEmotes();
this->ffz.loadEmotes(); this->ffz.loadEmotes();
} }
@ -83,8 +83,8 @@ void TwitchServer::initializeConnection(IrcConnection *connection, bool isRead,
std::shared_ptr<Channel> TwitchServer::createChannel(const QString &channelName) std::shared_ptr<Channel> TwitchServer::createChannel(const QString &channelName)
{ {
auto channel = std::shared_ptr<TwitchChannel>( auto channel = std::shared_ptr<TwitchChannel>(new TwitchChannel(
new TwitchChannel(channelName, this->bttv, this->ffz)); channelName, this->twitchBadges, this->bttv, this->ffz));
channel->initialize(); channel->initialize();
channel->sendMessageSignal.connect( channel->sendMessageSignal.connect(

View file

@ -7,6 +7,7 @@
#include "providers/bttv/BttvEmotes.hpp" #include "providers/bttv/BttvEmotes.hpp"
#include "providers/ffz/FfzEmotes.hpp" #include "providers/ffz/FfzEmotes.hpp"
#include "providers/irc/AbstractIrcServer.hpp" #include "providers/irc/AbstractIrcServer.hpp"
#include "providers/twitch/TwitchBadges.hpp"
#include <chrono> #include <chrono>
#include <memory> #include <memory>
@ -68,6 +69,7 @@ private:
std::chrono::steady_clock::time_point lastErrorTimeAmount_; std::chrono::steady_clock::time_point lastErrorTimeAmount_;
bool singleConnection_ = false; bool singleConnection_ = false;
TwitchBadges twitchBadges;
BttvEmotes bttv; BttvEmotes bttv;
FfzEmotes ffz; FfzEmotes ffz;

View file

@ -92,10 +92,10 @@ auto formatTitle(const TwitchChannel::StreamStatus &s, Settings &settings)
// description // description
if (settings.showViewerCount) if (settings.showViewerCount)
title += " - " + QString::number(s.viewerCount) + " viewers"; title += " - " + QString::number(s.viewerCount);
if (settings.showTitle) title += " - " + s.title; if (settings.showTitle) title += " - " + s.title;
if (settings.showGame) title += " - " + s.game; if (settings.showGame) title += " - " + s.game;
if (settings.showUptime) title += " - uptime: " + s.uptime; if (settings.showUptime) title += " - " + s.uptime;
return title; return title;
} }