2017-09-16 00:05:06 +02:00
|
|
|
#pragma once
|
|
|
|
|
2018-08-11 22:23:06 +02:00
|
|
|
#include "common/Aliases.hpp"
|
2018-08-11 17:15:17 +02:00
|
|
|
#include "common/Atomic.hpp"
|
2018-06-26 15:33:51 +02:00
|
|
|
#include "common/Channel.hpp"
|
2019-09-17 12:10:38 +02:00
|
|
|
#include "common/ChannelChatters.hpp"
|
2023-11-08 18:14:48 +01:00
|
|
|
#include "common/Common.hpp"
|
2018-07-15 20:28:54 +02:00
|
|
|
#include "common/UniqueAccess.hpp"
|
2024-02-25 12:18:57 +01:00
|
|
|
#include "providers/ffz/FfzBadges.hpp"
|
|
|
|
#include "providers/ffz/FfzEmotes.hpp"
|
2018-08-13 13:54:39 +02:00
|
|
|
#include "providers/twitch/TwitchEmotes.hpp"
|
2021-07-11 11:12:49 +02:00
|
|
|
#include "util/QStringHash.hpp"
|
2024-02-25 12:18:57 +01:00
|
|
|
#include "util/ThreadGuard.hpp"
|
2018-04-15 15:09:31 +02:00
|
|
|
|
2023-11-08 18:14:48 +01:00
|
|
|
#include <boost/circular_buffer/space_optimized.hpp>
|
2022-05-07 17:22:39 +02:00
|
|
|
#include <boost/signals2.hpp>
|
2023-11-08 18:14:48 +01:00
|
|
|
#include <IrcMessage>
|
2018-08-11 22:23:06 +02:00
|
|
|
#include <pajlada/signals/signalholder.hpp>
|
Sort and force grouping of includes (#4172)
This change enforces strict include grouping using IncludeCategories
In addition to adding this to the .clang-format file and applying it in the tests/src and src directories, I also did the following small changes:
In ChatterSet.hpp, I changed lrucache to a <>include
In Irc2.hpp, I change common/SignalVector.hpp to a "project-include"
In AttachedWindow.cpp, NativeMessaging.cpp, WindowsHelper.hpp, BaseWindow.cpp, and StreamerMode.cpp, I disabled clang-format for the windows-includes
In WindowDescriptors.hpp, I added the missing vector include. It was previously not needed because the include was handled by another file that was previously included first.
clang-format minimum version has been bumped, so Ubuntu version used in the check-formatting job has been bumped to 22.04 (which is the latest LTS)
2022-11-27 19:32:53 +01:00
|
|
|
#include <QColor>
|
|
|
|
#include <QElapsedTimer>
|
|
|
|
#include <QRegularExpression>
|
2020-03-14 12:13:57 +01:00
|
|
|
|
2022-08-06 18:18:34 +02:00
|
|
|
#include <atomic>
|
2020-03-14 12:13:57 +01:00
|
|
|
#include <mutex>
|
2023-07-02 15:52:15 +02:00
|
|
|
#include <optional>
|
2018-08-02 14:23:27 +02:00
|
|
|
#include <unordered_map>
|
2018-03-30 15:05:33 +02:00
|
|
|
|
2017-09-16 00:05:06 +02:00
|
|
|
namespace chatterino {
|
2018-03-24 12:02:07 +01:00
|
|
|
|
2018-08-29 19:25:37 +02:00
|
|
|
enum class HighlightState;
|
|
|
|
|
2018-08-11 22:23:06 +02:00
|
|
|
struct Emote;
|
|
|
|
using EmotePtr = std::shared_ptr<const Emote>;
|
|
|
|
class EmoteMap;
|
|
|
|
|
2018-08-14 17:45:17 +02:00
|
|
|
class TwitchBadges;
|
2018-08-12 00:01:37 +02:00
|
|
|
class FfzEmotes;
|
|
|
|
class BttvEmotes;
|
2023-01-21 15:06:55 +01:00
|
|
|
struct BttvLiveUpdateEmoteUpdateAddMessage;
|
|
|
|
struct BttvLiveUpdateEmoteRemoveMessage;
|
2023-02-04 13:42:52 +01:00
|
|
|
|
2022-10-16 13:22:17 +02:00
|
|
|
class SeventvEmotes;
|
2023-02-04 13:42:52 +01:00
|
|
|
namespace seventv::eventapi {
|
|
|
|
struct EmoteAddDispatch;
|
|
|
|
struct EmoteUpdateDispatch;
|
|
|
|
struct EmoteRemoveDispatch;
|
|
|
|
struct UserConnectionUpdateDispatch;
|
|
|
|
} // namespace seventv::eventapi
|
|
|
|
|
2022-12-31 15:41:01 +01:00
|
|
|
struct ChannelPointReward;
|
|
|
|
class MessageThread;
|
|
|
|
struct CheerEmoteSet;
|
|
|
|
struct HelixStream;
|
2018-08-12 00:01:37 +02:00
|
|
|
|
2019-09-15 13:02:02 +02:00
|
|
|
class TwitchIrcServer;
|
2018-03-24 12:02:07 +01:00
|
|
|
|
2023-11-08 18:14:48 +01:00
|
|
|
const int MAX_QUEUED_REDEMPTIONS = 16;
|
|
|
|
|
2023-10-25 18:13:48 +02:00
|
|
|
class TwitchChannel final : public Channel, public ChannelChatters
|
2017-09-16 00:05:06 +02:00
|
|
|
{
|
|
|
|
public:
|
2018-03-30 15:05:33 +02:00
|
|
|
struct StreamStatus {
|
|
|
|
bool live = false;
|
2018-04-08 15:14:14 +02:00
|
|
|
bool rerun = false;
|
2018-03-30 15:05:33 +02:00
|
|
|
unsigned viewerCount = 0;
|
|
|
|
QString title;
|
|
|
|
QString game;
|
2020-03-14 12:13:57 +01:00
|
|
|
QString gameId;
|
2018-03-30 15:05:33 +02:00
|
|
|
QString uptime;
|
2024-02-03 19:12:00 +01:00
|
|
|
int uptimeSeconds = 0;
|
2018-05-26 16:31:43 +02:00
|
|
|
QString streamType;
|
2024-07-14 11:45:21 +02:00
|
|
|
QString streamId;
|
2018-03-30 15:05:33 +02:00
|
|
|
};
|
|
|
|
|
2018-05-24 08:58:34 +02:00
|
|
|
struct RoomModes {
|
|
|
|
bool submode = false;
|
|
|
|
bool r9k = false;
|
|
|
|
bool emoteOnly = false;
|
2022-12-31 12:56:47 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Number of minutes required for users to be followed before typing in chat
|
|
|
|
*
|
|
|
|
* Special cases:
|
|
|
|
* -1 = follower mode off
|
|
|
|
* 0 = follower mode on, no time requirement
|
|
|
|
**/
|
2019-08-25 19:08:04 +02:00
|
|
|
int followerOnly = -1;
|
2022-12-31 12:56:47 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Number of seconds required to wait before typing emotes
|
|
|
|
*
|
|
|
|
* 0 = slow mode off
|
|
|
|
**/
|
2018-05-24 08:58:34 +02:00
|
|
|
int slowMode = 0;
|
|
|
|
};
|
|
|
|
|
2022-07-31 12:45:25 +02:00
|
|
|
explicit TwitchChannel(const QString &channelName);
|
2023-02-04 13:42:52 +01:00
|
|
|
~TwitchChannel() override;
|
2022-07-31 12:45:25 +02:00
|
|
|
|
2024-01-17 21:05:44 +01:00
|
|
|
TwitchChannel(const TwitchChannel &) = delete;
|
|
|
|
TwitchChannel(TwitchChannel &&) = delete;
|
|
|
|
TwitchChannel &operator=(const TwitchChannel &) = delete;
|
|
|
|
TwitchChannel &operator=(TwitchChannel &&) = delete;
|
|
|
|
|
2018-08-13 13:54:39 +02:00
|
|
|
void initialize();
|
2018-01-17 17:17:26 +01:00
|
|
|
|
2018-07-15 20:28:54 +02:00
|
|
|
// Channel methods
|
2023-10-25 18:13:48 +02:00
|
|
|
bool isEmpty() const override;
|
|
|
|
bool canSendMessage() const override;
|
|
|
|
void sendMessage(const QString &message) override;
|
|
|
|
void sendReply(const QString &message, const QString &replyId);
|
|
|
|
bool isMod() const override;
|
2019-10-07 20:31:34 +02:00
|
|
|
bool isVip() const;
|
2019-04-13 15:26:47 +02:00
|
|
|
bool isStaff() const;
|
2023-10-25 18:13:48 +02:00
|
|
|
bool isBroadcaster() const override;
|
|
|
|
bool hasHighRateLimit() const override;
|
|
|
|
bool canReconnect() const override;
|
|
|
|
void reconnect() override;
|
2024-07-14 11:45:21 +02:00
|
|
|
QString getCurrentStreamID() const override;
|
2021-01-17 14:47:34 +01:00
|
|
|
void createClip();
|
2018-07-14 14:24:18 +02:00
|
|
|
|
2018-08-12 00:01:37 +02:00
|
|
|
// Data
|
|
|
|
const QString &subscriptionUrl();
|
|
|
|
const QString &channelUrl();
|
|
|
|
const QString &popoutPlayerUrl();
|
2024-01-17 21:05:44 +01:00
|
|
|
int chatterCount() const;
|
2023-10-25 18:13:48 +02:00
|
|
|
bool isLive() const override;
|
2024-02-18 17:22:53 +01:00
|
|
|
bool isRerun() const override;
|
2018-08-11 17:15:17 +02:00
|
|
|
QString roomId() const;
|
2021-05-01 17:19:41 +02:00
|
|
|
SharedAccessGuard<const RoomModes> accessRoomModes() const;
|
|
|
|
SharedAccessGuard<const StreamStatus> accessStreamStatus() const;
|
2017-12-23 23:24:35 +01:00
|
|
|
|
2023-12-09 19:46:30 +01:00
|
|
|
/**
|
2023-12-16 13:38:35 +01:00
|
|
|
* Records that the channel is no longer joined.
|
2023-12-09 19:46:30 +01:00
|
|
|
*/
|
2023-12-16 13:38:35 +01:00
|
|
|
void markDisconnected();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Records that the channel's read connection is healthy.
|
|
|
|
*/
|
|
|
|
void markConnected();
|
2023-12-09 19:46:30 +01:00
|
|
|
|
2018-08-12 00:01:37 +02:00
|
|
|
// Emotes
|
2024-09-01 11:22:54 +02:00
|
|
|
std::optional<EmotePtr> twitchEmote(const EmoteName &name) const;
|
2023-10-08 18:50:48 +02:00
|
|
|
std::optional<EmotePtr> bttvEmote(const EmoteName &name) const;
|
|
|
|
std::optional<EmotePtr> ffzEmote(const EmoteName &name) const;
|
|
|
|
std::optional<EmotePtr> seventvEmote(const EmoteName &name) const;
|
2024-09-01 11:22:54 +02:00
|
|
|
|
|
|
|
std::shared_ptr<const EmoteMap> localTwitchEmotes() const;
|
2018-08-11 17:15:17 +02:00
|
|
|
std::shared_ptr<const EmoteMap> bttvEmotes() const;
|
|
|
|
std::shared_ptr<const EmoteMap> ffzEmotes() const;
|
2022-10-16 13:22:17 +02:00
|
|
|
std::shared_ptr<const EmoteMap> seventvEmotes() const;
|
2017-09-16 00:05:06 +02:00
|
|
|
|
2024-09-01 11:22:54 +02:00
|
|
|
void refreshTwitchChannelEmotes(bool manualRefresh);
|
2023-10-25 18:13:48 +02:00
|
|
|
void refreshBTTVChannelEmotes(bool manualRefresh);
|
|
|
|
void refreshFFZChannelEmotes(bool manualRefresh);
|
|
|
|
void refreshSevenTVChannelEmotes(bool manualRefresh);
|
2017-09-16 00:05:06 +02:00
|
|
|
|
2024-01-07 13:15:36 +01:00
|
|
|
void setBttvEmotes(std::shared_ptr<const EmoteMap> &&map);
|
|
|
|
void setFfzEmotes(std::shared_ptr<const EmoteMap> &&map);
|
|
|
|
void setSeventvEmotes(std::shared_ptr<const EmoteMap> &&map);
|
|
|
|
|
2022-11-13 12:07:41 +01:00
|
|
|
const QString &seventvUserID() const;
|
|
|
|
const QString &seventvEmoteSetID() const;
|
|
|
|
|
2023-01-21 15:06:55 +01:00
|
|
|
/** Adds a BTTV channel emote to this channel. */
|
|
|
|
void addBttvEmote(const BttvLiveUpdateEmoteUpdateAddMessage &message);
|
|
|
|
/** Updates a BTTV channel emote in this channel. */
|
|
|
|
void updateBttvEmote(const BttvLiveUpdateEmoteUpdateAddMessage &message);
|
|
|
|
/** Removes a BTTV channel emote from this channel. */
|
|
|
|
void removeBttvEmote(const BttvLiveUpdateEmoteRemoveMessage &message);
|
|
|
|
|
2022-11-13 12:07:41 +01:00
|
|
|
/** Adds a 7TV channel emote to this channel. */
|
2023-02-04 13:42:52 +01:00
|
|
|
void addSeventvEmote(const seventv::eventapi::EmoteAddDispatch &dispatch);
|
2022-11-13 12:07:41 +01:00
|
|
|
/** Updates a 7TV channel emote's name in this channel */
|
2023-02-04 13:42:52 +01:00
|
|
|
void updateSeventvEmote(
|
|
|
|
const seventv::eventapi::EmoteUpdateDispatch &dispatch);
|
2022-11-13 12:07:41 +01:00
|
|
|
/** Removes a 7TV channel emote from this channel */
|
2023-02-04 13:42:52 +01:00
|
|
|
void removeSeventvEmote(
|
|
|
|
const seventv::eventapi::EmoteRemoveDispatch &dispatch);
|
2022-11-13 12:07:41 +01:00
|
|
|
/** Updates the current 7TV user. Currently, only the emote-set is updated. */
|
|
|
|
void updateSeventvUser(
|
2023-02-04 13:42:52 +01:00
|
|
|
const seventv::eventapi::UserConnectionUpdateDispatch &dispatch);
|
2022-11-13 12:07:41 +01:00
|
|
|
|
|
|
|
// Update the channel's 7TV information (the channel's 7TV user ID and emote set ID)
|
|
|
|
void updateSeventvData(const QString &newUserID,
|
|
|
|
const QString &newEmoteSetID);
|
|
|
|
|
2018-08-13 13:54:39 +02:00
|
|
|
// Badges
|
2023-10-08 18:50:48 +02:00
|
|
|
std::optional<EmotePtr> ffzCustomModBadge() const;
|
|
|
|
std::optional<EmotePtr> ffzCustomVipBadge() const;
|
|
|
|
std::optional<EmotePtr> twitchBadge(const QString &set,
|
|
|
|
const QString &version) const;
|
2024-02-25 12:18:57 +01:00
|
|
|
/**
|
|
|
|
* Returns a list of channel-specific FrankerFaceZ badges for the given user
|
|
|
|
*/
|
|
|
|
std::vector<FfzBadges::Badge> ffzChannelBadges(const QString &userID) const;
|
2018-08-02 14:23:27 +02:00
|
|
|
|
2019-09-08 12:45:25 +02:00
|
|
|
// Cheers
|
2024-10-05 12:31:52 +02:00
|
|
|
std::optional<CheerEmote> cheerEmote(const QString &string) const;
|
2019-09-08 12:45:25 +02:00
|
|
|
|
2022-07-31 12:45:25 +02:00
|
|
|
// Replies
|
|
|
|
/**
|
|
|
|
* Stores the given thread in this channel.
|
|
|
|
*
|
|
|
|
* Note: This method not take ownership of the MessageThread; this
|
|
|
|
* TwitchChannel instance will store a weak_ptr to the thread.
|
|
|
|
*/
|
|
|
|
void addReplyThread(const std::shared_ptr<MessageThread> &thread);
|
|
|
|
const std::unordered_map<QString, std::weak_ptr<MessageThread>> &threads()
|
|
|
|
const;
|
|
|
|
|
2023-10-31 14:54:14 +01:00
|
|
|
/**
|
|
|
|
* Get the thread for the given message
|
|
|
|
* If no thread can be found for the message, create one
|
|
|
|
*/
|
|
|
|
std::shared_ptr<MessageThread> getOrCreateThread(const MessagePtr &message);
|
|
|
|
|
2023-12-09 19:46:30 +01:00
|
|
|
/**
|
|
|
|
* This signal fires when the local user has joined the channel
|
|
|
|
**/
|
|
|
|
pajlada::Signals::NoArgSignal joined;
|
|
|
|
|
2023-09-16 13:52:51 +02:00
|
|
|
// Only TwitchChannel may invoke this signal
|
2018-04-03 02:55:32 +02:00
|
|
|
pajlada::Signals::NoArgSignal userStateChanged;
|
2023-07-02 15:52:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This signal fires whenever the stream status is changed
|
|
|
|
*
|
|
|
|
* This includes when the stream goes from offline to online,
|
|
|
|
* or the viewer count changes, or the title has been updated
|
|
|
|
**/
|
|
|
|
pajlada::Signals::NoArgSignal streamStatusChanged;
|
|
|
|
|
2018-05-24 08:58:34 +02:00
|
|
|
pajlada::Signals::NoArgSignal roomModesChanged;
|
2017-12-28 00:03:52 +01:00
|
|
|
|
2020-08-08 15:37:22 +02:00
|
|
|
// Channel point rewards
|
2023-11-08 18:14:48 +01:00
|
|
|
void addQueuedRedemption(const QString &rewardId,
|
|
|
|
const QString &originalContent,
|
|
|
|
Communi::IrcMessage *message);
|
|
|
|
/**
|
|
|
|
* A rich & hydrated redemption from PubSub has arrived, add it to the channel.
|
|
|
|
* This will look at queued up partial messages, and if one is found it will add the queued up partial messages fully hydrated.
|
|
|
|
**/
|
2020-08-08 15:37:22 +02:00
|
|
|
void addChannelPointReward(const ChannelPointReward &reward);
|
|
|
|
bool isChannelPointRewardKnown(const QString &rewardId);
|
2023-10-08 18:50:48 +02:00
|
|
|
std::optional<ChannelPointReward> channelPointReward(
|
2020-08-08 15:37:22 +02:00
|
|
|
const QString &rewardId) const;
|
|
|
|
|
2023-07-02 15:52:15 +02:00
|
|
|
// Live status
|
2024-07-20 14:19:27 +02:00
|
|
|
void updateStreamStatus(const std::optional<HelixStream> &helixStream,
|
|
|
|
bool isInitialUpdate);
|
2023-07-02 15:52:15 +02:00
|
|
|
void updateStreamTitle(const QString &title);
|
|
|
|
|
2024-02-24 14:21:29 +01:00
|
|
|
/**
|
|
|
|
* Returns the display name of the user
|
|
|
|
*
|
|
|
|
* If the display name contained chinese, japenese, or korean characters, the user's login name is returned instead
|
|
|
|
**/
|
|
|
|
const QString &getDisplayName() const override;
|
2023-07-02 15:52:15 +02:00
|
|
|
void updateDisplayName(const QString &displayName);
|
|
|
|
|
2017-09-16 00:05:06 +02:00
|
|
|
private:
|
2018-07-15 20:28:54 +02:00
|
|
|
struct NameOptions {
|
2023-07-23 12:11:57 +02:00
|
|
|
// displayName is the non-CJK-display name for this user
|
|
|
|
// This will always be the same as their `name_`, but potentially with different casing
|
2018-07-15 20:28:54 +02:00
|
|
|
QString displayName;
|
2023-07-23 12:11:57 +02:00
|
|
|
|
|
|
|
// localizedName is their display name that *may* contain CJK characters
|
|
|
|
// If the display name does not contain any CJK characters, this will be
|
|
|
|
// the same as `displayName`
|
2018-07-15 20:28:54 +02:00
|
|
|
QString localizedName;
|
2023-07-23 12:11:57 +02:00
|
|
|
|
|
|
|
// actualDisplayName is the raw display name string received from Twitch
|
|
|
|
QString actualDisplayName;
|
2020-12-06 14:07:33 +01:00
|
|
|
} nameOptions;
|
2018-07-15 20:28:54 +02:00
|
|
|
|
2023-11-08 18:14:48 +01:00
|
|
|
struct QueuedRedemption {
|
|
|
|
QString rewardID;
|
|
|
|
QString originalContent;
|
|
|
|
QObjectPtr<Communi::IrcMessage> message;
|
|
|
|
};
|
|
|
|
|
2022-05-07 17:22:39 +02:00
|
|
|
void refreshPubSub();
|
2018-08-13 13:54:39 +02:00
|
|
|
void refreshChatters();
|
|
|
|
void refreshBadges();
|
|
|
|
void refreshCheerEmotes();
|
2018-07-14 14:24:18 +02:00
|
|
|
void loadRecentMessages();
|
2022-08-06 18:18:34 +02:00
|
|
|
void loadRecentMessagesReconnect();
|
2022-07-31 12:45:25 +02:00
|
|
|
void cleanUpReplyThreads();
|
|
|
|
void showLoginMessage();
|
2023-09-16 13:52:51 +02:00
|
|
|
|
|
|
|
/// roomIdChanged is called whenever this channel's ID has been changed
|
|
|
|
/// This should only happen once per channel, whenever the ID goes from unset to set
|
|
|
|
void roomIdChanged();
|
|
|
|
|
2023-01-21 15:06:55 +01:00
|
|
|
/** Joins (subscribes to) a Twitch channel for updates on BTTV. */
|
|
|
|
void joinBttvChannel() const;
|
2023-07-29 11:49:44 +02:00
|
|
|
/**
|
|
|
|
* Indicates an activity to 7TV in this channel for this user.
|
|
|
|
* This is done at most once every 60s.
|
|
|
|
*/
|
|
|
|
void updateSevenTVActivity();
|
2024-01-17 21:05:44 +01:00
|
|
|
void listenSevenTVCosmetics() const;
|
2018-07-14 14:24:18 +02:00
|
|
|
|
2023-07-02 15:52:15 +02:00
|
|
|
/**
|
|
|
|
* @brief Sets the live status of this Twitch channel
|
|
|
|
*
|
|
|
|
* Returns true if the live status changed with this call
|
|
|
|
**/
|
|
|
|
bool setLive(bool newLiveStatus);
|
2018-08-13 13:54:39 +02:00
|
|
|
void setMod(bool value);
|
2019-04-13 15:26:47 +02:00
|
|
|
void setVIP(bool value);
|
|
|
|
void setStaff(bool value);
|
2018-08-13 13:54:39 +02:00
|
|
|
void setRoomId(const QString &id);
|
2024-01-17 21:05:44 +01:00
|
|
|
void setRoomModes(const RoomModes &newRoomModes);
|
2020-12-06 14:07:33 +01:00
|
|
|
void setDisplayName(const QString &name);
|
|
|
|
void setLocalizedName(const QString &name);
|
|
|
|
|
2024-07-20 14:19:27 +02:00
|
|
|
void onLiveStatusChanged(bool isLive, bool isInitialUpdate);
|
|
|
|
|
2023-07-02 15:52:15 +02:00
|
|
|
/**
|
|
|
|
* Returns the localized name of the user
|
|
|
|
**/
|
2020-12-06 14:07:33 +01:00
|
|
|
const QString &getLocalizedName() const override;
|
2017-11-04 14:57:29 +01:00
|
|
|
|
2022-07-31 12:45:25 +02:00
|
|
|
QString prepareMessage(const QString &message) const;
|
|
|
|
|
2022-11-13 12:07:41 +01:00
|
|
|
/**
|
|
|
|
* Either adds a message mentioning the updated emotes
|
|
|
|
* or replaces an existing message. For criteria on existing messages,
|
|
|
|
* see `tryReplaceLastLiveUpdateAddOrRemove`.
|
|
|
|
*
|
|
|
|
* @param isEmoteAdd true if the emote was added, false if it was removed.
|
|
|
|
* @param platform The platform the emote was updated on ("7TV", "BTTV", "FFZ")
|
|
|
|
* @param actor The actor performing the update (possibly empty)
|
|
|
|
* @param emoteName The emote's name
|
|
|
|
*/
|
|
|
|
void addOrReplaceLiveUpdatesAddRemove(bool isEmoteAdd,
|
|
|
|
const QString &platform,
|
|
|
|
const QString &actor,
|
|
|
|
const QString &emoteName);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tries to replace the last emote update message.
|
|
|
|
*
|
|
|
|
* A last message is valid if:
|
|
|
|
* * The actors match
|
|
|
|
* * The operations match
|
|
|
|
* * The platform matches
|
|
|
|
* * The last message isn't older than 5s
|
|
|
|
*
|
|
|
|
* @param op The emote operation (LiveUpdatesAdd or LiveUpdatesRemove)
|
|
|
|
* @param platform The emote platform ("7TV", "BTTV", "FFZ")
|
|
|
|
* @param actor The actor performing the action (possibly empty)
|
|
|
|
* @param emoteName The updated emote's name
|
|
|
|
* @return true, if the last message was replaced
|
|
|
|
*/
|
|
|
|
bool tryReplaceLastLiveUpdateAddOrRemove(MessageFlag op,
|
|
|
|
const QString &platform,
|
|
|
|
const QString &actor,
|
|
|
|
const QString &emoteName);
|
|
|
|
|
2018-08-12 00:01:37 +02:00
|
|
|
// Data
|
2018-07-15 20:28:54 +02:00
|
|
|
const QString subscriptionUrl_;
|
|
|
|
const QString channelUrl_;
|
|
|
|
const QString popoutPlayerUrl_;
|
2023-09-09 13:11:19 +02:00
|
|
|
int chatterCount_{};
|
2018-07-15 20:28:54 +02:00
|
|
|
UniqueAccess<StreamStatus> streamStatus_;
|
2024-01-17 21:05:44 +01:00
|
|
|
UniqueAccess<RoomModes> roomModes;
|
2023-12-16 13:38:35 +01:00
|
|
|
bool disconnected_{};
|
2023-12-09 19:46:30 +01:00
|
|
|
std::optional<std::chrono::time_point<std::chrono::system_clock>>
|
2023-12-16 13:38:35 +01:00
|
|
|
lastConnectedAt_{};
|
2022-08-06 18:18:34 +02:00
|
|
|
std::atomic_flag loadingRecentMessages_ = ATOMIC_FLAG_INIT;
|
2022-07-31 12:45:25 +02:00
|
|
|
std::unordered_map<QString, std::weak_ptr<MessageThread>> threads_;
|
2018-03-30 15:05:33 +02:00
|
|
|
|
2019-02-26 21:00:57 +01:00
|
|
|
protected:
|
2023-09-16 13:52:51 +02:00
|
|
|
void messageRemovedFromStart(const MessagePtr &msg) override;
|
|
|
|
|
2024-09-01 11:22:54 +02:00
|
|
|
Atomic<std::shared_ptr<const EmoteMap>> localTwitchEmotes_;
|
|
|
|
Atomic<QString> localTwitchEmoteSetID_;
|
2018-08-11 17:15:17 +02:00
|
|
|
Atomic<std::shared_ptr<const EmoteMap>> bttvEmotes_;
|
|
|
|
Atomic<std::shared_ptr<const EmoteMap>> ffzEmotes_;
|
2022-10-16 13:22:17 +02:00
|
|
|
Atomic<std::shared_ptr<const EmoteMap>> seventvEmotes_;
|
2023-10-08 18:50:48 +02:00
|
|
|
Atomic<std::optional<EmotePtr>> ffzCustomModBadge_;
|
|
|
|
Atomic<std::optional<EmotePtr>> ffzCustomVipBadge_;
|
2018-04-15 15:09:31 +02:00
|
|
|
|
2024-02-25 12:18:57 +01:00
|
|
|
FfzChannelBadgeMap ffzChannelBadges_;
|
|
|
|
ThreadGuard tgFfzChannelBadges_;
|
|
|
|
|
2019-02-26 21:00:57 +01:00
|
|
|
private:
|
2018-08-13 13:54:39 +02:00
|
|
|
// Badges
|
|
|
|
UniqueAccess<std::map<QString, std::map<QString, EmotePtr>>>
|
|
|
|
badgeSets_; // "subscribers": { "0": ... "3": ... "6": ...
|
|
|
|
UniqueAccess<std::vector<CheerEmoteSet>> cheerEmoteSets_;
|
2020-08-08 15:37:22 +02:00
|
|
|
UniqueAccess<std::map<QString, ChannelPointReward>> channelPointRewards_;
|
2023-11-08 18:14:48 +01:00
|
|
|
boost::circular_buffer_space_optimized<QueuedRedemption>
|
|
|
|
waitingRedemptions_{MAX_QUEUED_REDEMPTIONS};
|
2018-04-15 15:09:31 +02:00
|
|
|
|
2018-07-06 19:23:47 +02:00
|
|
|
bool mod_ = false;
|
2019-04-13 15:26:47 +02:00
|
|
|
bool vip_ = false;
|
|
|
|
bool staff_ = false;
|
2018-08-10 19:00:14 +02:00
|
|
|
UniqueAccess<QString> roomID_;
|
2018-01-17 17:17:26 +01:00
|
|
|
|
2018-07-15 20:28:54 +02:00
|
|
|
// --
|
|
|
|
QString lastSentMessage_;
|
|
|
|
QObject lifetimeGuard_;
|
2018-07-14 14:24:18 +02:00
|
|
|
QTimer chattersListTimer_;
|
2022-07-31 12:45:25 +02:00
|
|
|
QTimer threadClearTimer_;
|
2021-03-13 17:54:34 +01:00
|
|
|
QElapsedTimer titleRefreshedTimer_;
|
|
|
|
QElapsedTimer clipCreationTimer_;
|
2021-01-17 14:47:34 +01:00
|
|
|
bool isClipCreationInProgress{false};
|
2019-10-12 15:09:12 +02:00
|
|
|
|
2022-11-13 12:07:41 +01:00
|
|
|
/**
|
|
|
|
* This channels 7TV user-id,
|
|
|
|
* empty if this channel isn't connected with 7TV.
|
|
|
|
*/
|
|
|
|
QString seventvUserID_;
|
|
|
|
/**
|
|
|
|
* This channels current 7TV emote-set-id,
|
|
|
|
* empty if this channel isn't connected with 7TV
|
|
|
|
*/
|
|
|
|
QString seventvEmoteSetID_;
|
|
|
|
/**
|
|
|
|
* The index of the twitch connection in
|
|
|
|
* 7TV's user representation.
|
|
|
|
*/
|
2023-09-09 13:11:19 +02:00
|
|
|
size_t seventvUserTwitchConnectionIndex_{};
|
2022-11-13 12:07:41 +01:00
|
|
|
|
2023-07-29 11:49:44 +02:00
|
|
|
/**
|
|
|
|
* The next moment in time to signal activity in this channel to 7TV.
|
|
|
|
* Or: Up until this moment we don't need to send activity.
|
|
|
|
*/
|
|
|
|
QDateTime nextSeventvActivity_;
|
|
|
|
|
2022-11-13 12:07:41 +01:00
|
|
|
/** The platform of the last live emote update ("7TV", "BTTV", "FFZ"). */
|
|
|
|
QString lastLiveUpdateEmotePlatform_;
|
|
|
|
/** The actor name of the last live emote update. */
|
|
|
|
QString lastLiveUpdateEmoteActor_;
|
|
|
|
/** A weak reference to the last live emote update message. */
|
|
|
|
std::weak_ptr<const Message> lastLiveUpdateMessage_;
|
|
|
|
/** A list of the emotes listed in the lat live emote update message. */
|
|
|
|
std::vector<QString> lastLiveUpdateEmoteNames_;
|
|
|
|
|
2021-12-19 15:57:56 +01:00
|
|
|
pajlada::Signals::SignalHolder signalHolder_;
|
2022-05-07 17:22:39 +02:00
|
|
|
std::vector<boost::signals2::scoped_connection> bSignals_;
|
2021-12-19 15:57:56 +01:00
|
|
|
|
2019-09-15 13:02:02 +02:00
|
|
|
friend class TwitchIrcServer;
|
2024-08-24 12:18:27 +02:00
|
|
|
friend class MessageBuilder;
|
2018-08-13 13:54:39 +02:00
|
|
|
friend class IrcMessageHandler;
|
2024-06-16 12:22:51 +02:00
|
|
|
friend class Commands_E2E_Test;
|
2018-02-05 15:11:50 +01:00
|
|
|
};
|
2018-03-24 12:02:07 +01:00
|
|
|
|
2017-11-04 14:57:29 +01:00
|
|
|
} // namespace chatterino
|