Add more Twitch condition types

Also simplifies some code and make it more consistent
This commit is contained in:
Przemek Pawlas 2023-10-23 16:49:29 +02:00 committed by WarmUpTill
parent 7bc1fc3d0d
commit 890792c270
5 changed files with 617 additions and 442 deletions

View File

@ -491,22 +491,55 @@ AdvSceneSwitcher.condition.slideshow.condition.slidePath="Current slide path is"
AdvSceneSwitcher.condition.slideshow.updateIntervalTooltip="Information about the slide show status will only be updated based on the configured time between slides"
AdvSceneSwitcher.condition.slideshow.entry="{{sources}}{{conditions}}{{index}}{{path}}"
AdvSceneSwitcher.condition.twitch="Twitch"
AdvSceneSwitcher.condition.twitch.type.channelIsLive="Is currently live"
AdvSceneSwitcher.condition.twitch.type.channelWentLive="Went live"
AdvSceneSwitcher.condition.twitch.type.channelStartedPlaylist="Started playlist"
AdvSceneSwitcher.condition.twitch.type.channelStartedWatchparty="Started watchparty"
AdvSceneSwitcher.condition.twitch.type.channelStartedPremiere="Started premiere"
AdvSceneSwitcher.condition.twitch.type.channelStartedRerun="Started rerun"
AdvSceneSwitcher.condition.twitch.type.channelWentOffline="Went offline"
AdvSceneSwitcher.condition.twitch.type.channelTitle="Title matches"
AdvSceneSwitcher.condition.twitch.type.category="Category is"
AdvSceneSwitcher.condition.twitch.type.channelUpdateEvent="Channel information was updated"
AdvSceneSwitcher.condition.twitch.type.channelFollow="Channel received a follow"
AdvSceneSwitcher.condition.twitch.type.channelSubscribe="Channel received a subscription"
AdvSceneSwitcher.condition.twitch.type.channelSubscribeEnd="Channel subscription expired"
AdvSceneSwitcher.condition.twitch.type.channelSubscribeGift="Channel received gifted subscriptions"
AdvSceneSwitcher.condition.twitch.type.channelSubscribeMessage="Channel received re-subscription chat message"
AdvSceneSwitcher.condition.twitch.type.channelCheer="Channel received a cheer chat message"
AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online="Stream went online"
AdvSceneSwitcher.condition.twitch.type.event.channel.stream.offline="Stream went offline"
AdvSceneSwitcher.condition.twitch.type.event.channel.info.update="Channel information updated"
AdvSceneSwitcher.condition.twitch.type.event.channel.follow="Follow received"
AdvSceneSwitcher.condition.twitch.type.event.channel.subscription.start="Subscription (no resubscriptions included) started"
AdvSceneSwitcher.condition.twitch.type.event.channel.subscription.end="Subscription ended"
AdvSceneSwitcher.condition.twitch.type.event.channel.subscription.gift="Subscription(s) gifted"
AdvSceneSwitcher.condition.twitch.type.event.channel.subscription.message="Resubscription chat message received"
AdvSceneSwitcher.condition.twitch.type.event.channel.cheer="Cheer chat message received"
AdvSceneSwitcher.condition.twitch.type.event.channel.raid.outbound="Raided someone's channel"
AdvSceneSwitcher.condition.twitch.type.event.channel.raid.inbound="Raid to your channel occured"
AdvSceneSwitcher.condition.twitch.type.event.channel.shoutout.outbound="Shoutout to someone's channel given"
AdvSceneSwitcher.condition.twitch.type.event.channel.shoutout.inbound="Shoutout to your channel received"
AdvSceneSwitcher.condition.twitch.type.event.channel.poll.start="Poll started"
AdvSceneSwitcher.condition.twitch.type.event.channel.poll.progress="Poll votes changed (progress)"
AdvSceneSwitcher.condition.twitch.type.event.channel.poll.end="Poll ended"
AdvSceneSwitcher.condition.twitch.type.event.channel.prediction.start="Prediction started"
AdvSceneSwitcher.condition.twitch.type.event.channel.prediction.progress="Prediction bets changed (progress)"
AdvSceneSwitcher.condition.twitch.type.event.channel.prediction.lock="Prediction bets locked"
AdvSceneSwitcher.condition.twitch.type.event.channel.prediction.end="Prediction ended"
AdvSceneSwitcher.condition.twitch.type.event.channel.goal.start="Goal started"
AdvSceneSwitcher.condition.twitch.type.event.channel.goal.progress="Goal follow stats changed (progress)"
AdvSceneSwitcher.condition.twitch.type.event.channel.goal.end="Goal ended"
AdvSceneSwitcher.condition.twitch.type.event.channel.hypeTrain.start="Hype Train started"
AdvSceneSwitcher.condition.twitch.type.event.channel.hypeTrain.progress="Hype Train stats changed (progress)"
AdvSceneSwitcher.condition.twitch.type.event.channel.hypeTrain.end="Hype Train ended"
AdvSceneSwitcher.condition.twitch.type.event.channel.charityCampaign.start="Charity campaign started"
AdvSceneSwitcher.condition.twitch.type.event.channel.charityCampaign.progress="Charity campaign stats changed (progress)"
AdvSceneSwitcher.condition.twitch.type.event.channel.charityCampaign.donation="Charity campaign donation occured"
AdvSceneSwitcher.condition.twitch.type.event.channel.charityCampaign.end="Charity campaign ended"
AdvSceneSwitcher.condition.twitch.type.event.channel.shieldMode.start="Shield Mode enabled"
AdvSceneSwitcher.condition.twitch.type.event.channel.shieldMode.end="Shield Mode disabled"
AdvSceneSwitcher.condition.twitch.type.event.channel.points.reward.addition="Points reward added"
AdvSceneSwitcher.condition.twitch.type.event.channel.points.reward.update="Points reward updated"
AdvSceneSwitcher.condition.twitch.type.event.channel.points.reward.deletion="Points reward deleted"
AdvSceneSwitcher.condition.twitch.type.event.channel.points.reward.redemption="Points reward redeemed"
AdvSceneSwitcher.condition.twitch.type.event.channel.points.reward.redemption.update="Points reward redemption updated"
AdvSceneSwitcher.condition.twitch.type.event.channel.user.ban="User banned from channel"
AdvSceneSwitcher.condition.twitch.type.event.channel.user.unban="User unbanned from channel"
AdvSceneSwitcher.condition.twitch.type.event.channel.user.moderator.addition="User added as channel moderator"
AdvSceneSwitcher.condition.twitch.type.event.channel.user.moderator.deletion="User deleted from channel moderation"
AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online.live="Stream went live"
AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online.playlist="Stream started playlist"
AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online.watchParty="Stream started watchparty"
AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online.premiere="Stream started premiere"
AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online.rerun="Stream started rerun"
AdvSceneSwitcher.condition.twitch.type.polling.channel.live="Stream is currently live"
AdvSceneSwitcher.condition.twitch.type.polling.channel.title="Current title matches"
AdvSceneSwitcher.condition.twitch.type.polling.channel.category="Current category is"
AdvSceneSwitcher.condition.twitch.categorySelectionDisabled="Cannot select category without selecting a Twitch account first!"
AdvSceneSwitcher.condition.twitch.entry="Channel{{channel}}{{conditions}}{{streamTitle}}{{regex}}{{category}}"
AdvSceneSwitcher.condition.twitch.entry.account="Check using account{{account}}"
@ -976,18 +1009,30 @@ AdvSceneSwitcher.twitchToken.request.success.browser="Authentication successful!
AdvSceneSwitcher.twitchToken.request.notSet="Account is not connected!"
AdvSceneSwitcher.twitchToken.permissions="Token permissions:"
AdvSceneSwitcher.twitchToken.permissionsInsufficient="Permissions of selected token are insufficient to perform selected action!"
AdvSceneSwitcher.twitchToken.analytics.readExtensions="View analytics data for the Twitch Extensions owned by the authenticated account."
AdvSceneSwitcher.twitchToken.analytics.readGames="View analytics data for the games owned by the authenticated account."
AdvSceneSwitcher.twitchToken.bits.read="View Bits information for a channel."
AdvSceneSwitcher.twitchToken.channel.manageBroadcast="Manage a channels broadcast configuration, including updating channel configuration and managing stream markers and stream tags."
AdvSceneSwitcher.twitchToken.channel.startCommercial="Run commercials on a channel."
AdvSceneSwitcher.twitchToken.channel.broadcast.manage="Manage a channels broadcast configuration, including updating channel configuration and managing stream markers and stream tags."
AdvSceneSwitcher.twitchToken.channel.commercial.edit="Run commercials on a channel."
AdvSceneSwitcher.twitchToken.clips.edit="Create clips from channel's broadcasts."
AdvSceneSwitcher.twitchToken.moderator.manageAnnouncements="Manage channel's chat announcements."
AdvSceneSwitcher.twitchToken.moderator.manageChatSettings="Manage channel's chat settings, such as emote-only or slow mode."
AdvSceneSwitcher.twitchToken.channel.raid="Manage a channel raiding another channel."
AdvSceneSwitcher.twitchToken.bits="View Bits information for a channel."
AdvSceneSwitcher.twitchToken.readSubscriptions="View a list of all subscribers to a channel and check if a user is subscribed to a channel."
AdvSceneSwitcher.twitchToken.readFollowers="Read the followers of a broadcaster."
AdvSceneSwitcher.twitchToken.moderator.announcements.manage="Manage channel's chat announcements."
AdvSceneSwitcher.twitchToken.moderator.chat.settings.manage="Manage channel's chat settings, such as emote-only or slow mode."
AdvSceneSwitcher.twitchToken.channel.raid="Manage channel's raids."
AdvSceneSwitcher.twitchToken.channel.subscriptions.read="Read channel's subscribers list and info."
AdvSceneSwitcher.twitchToken.moderator.followers.read="Read the followers of a broadcaster."
AdvSceneSwitcher.twitchToken.bits.read="Read channel's Bits information."
AdvSceneSwitcher.twitchToken.moderator.shoutouts.read="Read channel's shoutouts."
AdvSceneSwitcher.twitchToken.moderator.shoutouts.manage="Manage channel's shoutouts."
AdvSceneSwitcher.twitchToken.channel.polls.read="Read channel's polls' state."
AdvSceneSwitcher.twitchToken.channel.polls.manage="Manage channel's polls."
AdvSceneSwitcher.twitchToken.channel.predictions.read="Read channel's predictions' state."
AdvSceneSwitcher.twitchToken.channel.predictions.manage="Manage channel's predictions."
AdvSceneSwitcher.twitchToken.channel.goals.read="Read channel's creator goals."
AdvSceneSwitcher.twitchToken.channel.hypeTrain.read="Read channel's Hype Train state."
AdvSceneSwitcher.twitchToken.channel.charity.read="Read channel's charity campaigns' state and donations."
AdvSceneSwitcher.twitchToken.moderator.shieldMode.read="Read channel's Shield Mode state."
AdvSceneSwitcher.twitchToken.moderator.shieldMode.manage="Manage channel's Shield Mode."
AdvSceneSwitcher.twitchToken.channel.redemptions.read="Read channel's point rewards and their redemptions."
AdvSceneSwitcher.twitchToken.channel.redemptions.manage="Manage channel's point rewards and their redemptions."
AdvSceneSwitcher.twitchToken.channel.moderate="Moderate the channel."
AdvSceneSwitcher.twitchToken.channel.moderation.read="Read channel's moderation data."
AdvSceneSwitcher.channel.open="Show channel"

View File

@ -1118,11 +1118,9 @@ AdvSceneSwitcher.twitchToken.request.success="Jeton obtenu avec succès !"
AdvSceneSwitcher.twitchToken.request.success.browser="Authentification réussie ! Vous pouvez maintenant fermer cette fenêtre."
AdvSceneSwitcher.twitchToken.request.notSet="Aucun jeton défini - Veuillez demander un nouveau jeton !"
AdvSceneSwitcher.twitchToken.permissions="Permissions du jeton :"
AdvSceneSwitcher.twitchToken.analytics.readExtensions="Afficher les données d'analyse pour les extensions Twitch détenues par le compte authentifié."
AdvSceneSwitcher.twitchToken.analytics.readGames="Afficher les données d'analyse pour les jeux détenus par le compte authentifié."
AdvSceneSwitcher.twitchToken.bits.read="Afficher les informations sur les Bits pour une chaîne."
AdvSceneSwitcher.twitchToken.channel.manageBroadcast="Gérer la configuration de diffusion d'une chaîne, y compris la mise à jour de la configuration de la chaîne et la gestion des marqueurs de diffusion en continu et des balises de diffusion en continu."
AdvSceneSwitcher.twitchToken.channel.startCommercial="Lancer des publicités sur une chaîne."
AdvSceneSwitcher.twitchToken.channel.broadcast.manage="Gérer la configuration de diffusion d'une chaîne, y compris la mise à jour de la configuration de la chaîne et la gestion des marqueurs de diffusion en continu et des balises de diffusion en continu."
AdvSceneSwitcher.twitchToken.channel.commercial.edit="Lancer des publicités sur une chaîne."
AdvSceneSwitcher.twitchCategories.fetchStart="Récupération des catégories de streams..."
AdvSceneSwitcher.twitchCategories.fetchStatus="Obtenu %1 catégories de streams."

View File

@ -14,94 +14,226 @@ bool MacroConditionTwitch::_registered = MacroConditionFactory::Register(
"AdvSceneSwitcher.condition.twitch"});
const static std::map<MacroConditionTwitch::Condition, std::string> conditionTypes = {
{MacroConditionTwitch::Condition::LIVE_EVENT_REGULAR,
"AdvSceneSwitcher.condition.twitch.type.channelWentLive"},
{MacroConditionTwitch::Condition::LIVE_EVENT_PLAYLIST,
"AdvSceneSwitcher.condition.twitch.type.channelStartedPlaylist"},
{MacroConditionTwitch::Condition::LIVE_EVENT_WATCHPARTY,
"AdvSceneSwitcher.condition.twitch.type.channelStartedWatchparty"},
{MacroConditionTwitch::Condition::LIVE_EVENT_PREMIERE,
"AdvSceneSwitcher.condition.twitch.type.channelStartedPremiere"},
{MacroConditionTwitch::Condition::LIVE_EVENT_RERUN,
"AdvSceneSwitcher.condition.twitch.type.channelStartedRerun"},
{MacroConditionTwitch::Condition::OFFLINE_EVENT,
"AdvSceneSwitcher.condition.twitch.type.channelWentOffline"},
{MacroConditionTwitch::Condition::STREAM_ONLINE_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online"},
{MacroConditionTwitch::Condition::STREAM_OFFLINE_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.stream.offline"},
{MacroConditionTwitch::Condition::CHANNEL_INFO_UPDATE_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.info.update"},
{MacroConditionTwitch::Condition::FOLLOW_EVENT,
"AdvSceneSwitcher.condition.twitch.type.channelFollow"},
{MacroConditionTwitch::Condition::SUBSCRIBE_EVENT,
"AdvSceneSwitcher.condition.twitch.type.channelSubscribe"},
{MacroConditionTwitch::Condition::SUBSCRIBE_END_EVENT,
"AdvSceneSwitcher.condition.twitch.type.channelSubscribeEnd"},
{MacroConditionTwitch::Condition::SUBSCRIBE_GIFT_EVENT,
"AdvSceneSwitcher.condition.twitch.type.channelSubscribeGift"},
{MacroConditionTwitch::Condition::SUBSCRIBE_MESSAGE_EVENT,
"AdvSceneSwitcher.condition.twitch.type.channelSubscribeMessage"},
"AdvSceneSwitcher.condition.twitch.type.event.channel.follow"},
{MacroConditionTwitch::Condition::SUBSCRIPTION_START_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.subscription.start"},
{MacroConditionTwitch::Condition::SUBSCRIPTION_END_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.subscription.end"},
{MacroConditionTwitch::Condition::SUBSCRIPTION_GIFT_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.subscription.gift"},
{MacroConditionTwitch::Condition::SUBSCRIPTION_MESSAGE_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.subscription.message"},
{MacroConditionTwitch::Condition::CHEER_EVENT,
"AdvSceneSwitcher.condition.twitch.type.channelCheer"},
{MacroConditionTwitch::Condition::LIVE,
"AdvSceneSwitcher.condition.twitch.type.channelIsLive"},
{MacroConditionTwitch::Condition::TITLE,
"AdvSceneSwitcher.condition.twitch.type.channelTitle"},
{MacroConditionTwitch::Condition::CATEGORY,
"AdvSceneSwitcher.condition.twitch.type.category"},
{MacroConditionTwitch::Condition::CHANNEL_UPDATE_EVENT,
"AdvSceneSwitcher.condition.twitch.type.channelUpdateEvent"},
"AdvSceneSwitcher.condition.twitch.type.event.channel.cheer"},
{MacroConditionTwitch::Condition::RAID_OUTBOUND_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.raid.outbound"},
{MacroConditionTwitch::Condition::RAID_INBOUND_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.raid.inbound"},
{MacroConditionTwitch::Condition::SHOUTOUT_OUTBOUND_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.shoutout.outbound"},
{MacroConditionTwitch::Condition::SHOUTOUT_INBOUND_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.shoutout.inbound"},
{MacroConditionTwitch::Condition::POLL_START_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.poll.start"},
{MacroConditionTwitch::Condition::POLL_PROGRESS_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.poll.progress"},
{MacroConditionTwitch::Condition::POLL_END_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.poll.end"},
{MacroConditionTwitch::Condition::PREDICTION_START_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.prediction.start"},
{MacroConditionTwitch::Condition::PREDICTION_PROGRESS_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.prediction.progress"},
{MacroConditionTwitch::Condition::PREDICTION_LOCK_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.prediction.lock"},
{MacroConditionTwitch::Condition::PREDICTION_END_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.prediction.end"},
{MacroConditionTwitch::Condition::GOAL_START_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.goal.start"},
{MacroConditionTwitch::Condition::GOAL_PROGRESS_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.goal.progress"},
{MacroConditionTwitch::Condition::GOAL_END_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.goal.end"},
{MacroConditionTwitch::Condition::HYPE_TRAIN_START_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.hypeTrain.start"},
{MacroConditionTwitch::Condition::HYPE_TRAIN_PROGRESS_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.hypeTrain.progress"},
{MacroConditionTwitch::Condition::HYPE_TRAIN_END_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.hypeTrain.end"},
{MacroConditionTwitch::Condition::CHARITY_CAMPAIGN_START_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.charityCampaign.start"},
{MacroConditionTwitch::Condition::CHARITY_CAMPAIGN_PROGRESS_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.charityCampaign.progress"},
{MacroConditionTwitch::Condition::CHARITY_CAMPAIGN_DONATION_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.charityCampaign.donation"},
{MacroConditionTwitch::Condition::CHARITY_CAMPAIGN_END_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.charityCampaign.end"},
{MacroConditionTwitch::Condition::SHIELD_MODE_START_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.shieldMode.start"},
{MacroConditionTwitch::Condition::SHIELD_MODE_END_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.shieldMode.end"},
{MacroConditionTwitch::Condition::POINTS_REWARD_ADDITION_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.points.reward.addition"},
{MacroConditionTwitch::Condition::POINTS_REWARD_UPDATE_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.points.reward.update"},
{MacroConditionTwitch::Condition::POINTS_REWARD_DELETION_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.points.reward.deletion"},
{MacroConditionTwitch::Condition::POINTS_REWARD_REDEMPTION_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.points.reward.redemption"},
{MacroConditionTwitch::Condition::POINTS_REWARD_REDEMPTION_UPDATE_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.points.reward.redemption.update"},
{MacroConditionTwitch::Condition::USER_BAN_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.user.ban"},
{MacroConditionTwitch::Condition::USER_UNBAN_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.user.unban"},
{MacroConditionTwitch::Condition::USER_MODERATOR_ADDITION_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.user.moderator.addition"},
{MacroConditionTwitch::Condition::USER_MODERATOR_DELETION_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.user.moderator.deletion"},
{MacroConditionTwitch::Condition::STREAM_ONLINE_LIVE_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online.live"},
{MacroConditionTwitch::Condition::STREAM_ONLINE_PLAYLIST_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online.playlist"},
{MacroConditionTwitch::Condition::STREAM_ONLINE_WATCHPARTY_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online.watchParty"},
{MacroConditionTwitch::Condition::STREAM_ONLINE_PREMIERE_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online.premiere"},
{MacroConditionTwitch::Condition::STREAM_ONLINE_RERUN_EVENT,
"AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online.rerun"},
{MacroConditionTwitch::Condition::LIVE_POLLING,
"AdvSceneSwitcher.condition.twitch.type.polling.channel.live"},
{MacroConditionTwitch::Condition::TITLE_POLLING,
"AdvSceneSwitcher.condition.twitch.type.polling.channel.title"},
{MacroConditionTwitch::Condition::CATEGORY_POLLING,
"AdvSceneSwitcher.condition.twitch.type.polling.channel.category"},
};
const static std::map<MacroConditionTwitch::Condition, std::string>
eventIdentifiers = {
{MacroConditionTwitch::Condition::LIVE_EVENT_REGULAR,
"stream.online"},
{MacroConditionTwitch::Condition::LIVE_EVENT_PLAYLIST,
"stream.online"},
{MacroConditionTwitch::Condition::LIVE_EVENT_WATCHPARTY,
"stream.online"},
{MacroConditionTwitch::Condition::LIVE_EVENT_PREMIERE,
"stream.online"},
{MacroConditionTwitch::Condition::LIVE_EVENT_RERUN,
"stream.online"},
{MacroConditionTwitch::Condition::OFFLINE_EVENT,
"stream.offline"},
{MacroConditionTwitch::Condition::CHANNEL_UPDATE_EVENT,
"channel.update"},
{MacroConditionTwitch::Condition::FOLLOW_EVENT,
"channel.follow"},
{MacroConditionTwitch::Condition::SUBSCRIBE_EVENT,
"channel.subscribe"},
{MacroConditionTwitch::Condition::SUBSCRIBE_END_EVENT,
"channel.subscription.end"},
{MacroConditionTwitch::Condition::SUBSCRIBE_GIFT_EVENT,
"channel.subscription.gift"},
{MacroConditionTwitch::Condition::SUBSCRIBE_MESSAGE_EVENT,
"channel.subscription.message"},
{MacroConditionTwitch::Condition::CHEER_EVENT, "channel.cheer"},
const static std::map<MacroConditionTwitch::Condition, std::string> eventIdentifiers = {
{MacroConditionTwitch::Condition::STREAM_ONLINE_EVENT, "stream.online"},
{MacroConditionTwitch::Condition::STREAM_OFFLINE_EVENT,
"stream.offline"},
{MacroConditionTwitch::Condition::CHANNEL_INFO_UPDATE_EVENT,
"channel.update"},
{MacroConditionTwitch::Condition::FOLLOW_EVENT, "channel.follow"},
{MacroConditionTwitch::Condition::SUBSCRIPTION_START_EVENT,
"channel.subscribe"},
{MacroConditionTwitch::Condition::SUBSCRIPTION_END_EVENT,
"channel.subscription.end"},
{MacroConditionTwitch::Condition::SUBSCRIPTION_GIFT_EVENT,
"channel.subscription.gift"},
{MacroConditionTwitch::Condition::SUBSCRIPTION_MESSAGE_EVENT,
"channel.subscription.message"},
{MacroConditionTwitch::Condition::CHEER_EVENT, "channel.cheer"},
{MacroConditionTwitch::Condition::RAID_OUTBOUND_EVENT, "channel.raid"},
{MacroConditionTwitch::Condition::RAID_INBOUND_EVENT, "channel.raid"},
{MacroConditionTwitch::Condition::SHOUTOUT_OUTBOUND_EVENT,
"channel.shoutout.create"},
{MacroConditionTwitch::Condition::SHOUTOUT_INBOUND_EVENT,
"channel.shoutout.receive"},
{MacroConditionTwitch::Condition::POLL_START_EVENT,
"channel.poll.begin"},
{MacroConditionTwitch::Condition::POLL_PROGRESS_EVENT,
"channel.poll.progress"},
{MacroConditionTwitch::Condition::POLL_END_EVENT, "channel.poll.end"},
{MacroConditionTwitch::Condition::PREDICTION_START_EVENT,
"channel.prediction.begin"},
{MacroConditionTwitch::Condition::PREDICTION_PROGRESS_EVENT,
"channel.prediction.progress"},
{MacroConditionTwitch::Condition::PREDICTION_LOCK_EVENT,
"channel.prediction.lock"},
{MacroConditionTwitch::Condition::PREDICTION_END_EVENT,
"channel.prediction.end"},
{MacroConditionTwitch::Condition::GOAL_START_EVENT,
"channel.goal.begin"},
{MacroConditionTwitch::Condition::GOAL_PROGRESS_EVENT,
"channel.goal.progress"},
{MacroConditionTwitch::Condition::GOAL_END_EVENT, "channel.goal.end"},
{MacroConditionTwitch::Condition::HYPE_TRAIN_START_EVENT,
"channel.hype_train.begin"},
{MacroConditionTwitch::Condition::HYPE_TRAIN_PROGRESS_EVENT,
"channel.hype_train.progress"},
{MacroConditionTwitch::Condition::HYPE_TRAIN_END_EVENT,
"channel.hype_train.end"},
{MacroConditionTwitch::Condition::CHARITY_CAMPAIGN_START_EVENT,
"channel.charity_campaign.start"},
{MacroConditionTwitch::Condition::CHARITY_CAMPAIGN_PROGRESS_EVENT,
"channel.charity_campaign.progress"},
{MacroConditionTwitch::Condition::CHARITY_CAMPAIGN_DONATION_EVENT,
"channel.charity_campaign.donate"},
{MacroConditionTwitch::Condition::CHARITY_CAMPAIGN_END_EVENT,
"channel.charity_campaign.stop"},
{MacroConditionTwitch::Condition::SHIELD_MODE_START_EVENT,
"channel.shield_mode.begin"},
{MacroConditionTwitch::Condition::SHIELD_MODE_END_EVENT,
"channel.shield_mode.end"},
{MacroConditionTwitch::Condition::POINTS_REWARD_ADDITION_EVENT,
"channel.channel_points_custom_reward.add"},
{MacroConditionTwitch::Condition::POINTS_REWARD_UPDATE_EVENT,
"channel.channel_points_custom_reward.update"},
{MacroConditionTwitch::Condition::POINTS_REWARD_DELETION_EVENT,
"channel.channel_points_custom_reward.remove"},
{MacroConditionTwitch::Condition::POINTS_REWARD_REDEMPTION_EVENT,
"channel.channel_points_custom_reward_redemption.add"},
{MacroConditionTwitch::Condition::POINTS_REWARD_REDEMPTION_UPDATE_EVENT,
"channel.channel_points_custom_reward_redemption.update"},
{MacroConditionTwitch::Condition::USER_BAN_EVENT, "channel.ban"},
{MacroConditionTwitch::Condition::USER_UNBAN_EVENT, "channel.unban"},
{MacroConditionTwitch::Condition::USER_MODERATOR_ADDITION_EVENT,
"channel.moderator.add"},
{MacroConditionTwitch::Condition::USER_MODERATOR_DELETION_EVENT,
"channel.moderator.remove"},
{MacroConditionTwitch::Condition::STREAM_ONLINE_LIVE_EVENT,
"stream.online"},
{MacroConditionTwitch::Condition::STREAM_ONLINE_PLAYLIST_EVENT,
"stream.online"},
{MacroConditionTwitch::Condition::STREAM_ONLINE_WATCHPARTY_EVENT,
"stream.online"},
{MacroConditionTwitch::Condition::STREAM_ONLINE_PREMIERE_EVENT,
"stream.online"},
{MacroConditionTwitch::Condition::STREAM_ONLINE_RERUN_EVENT,
"stream.online"},
};
const static std::map<MacroConditionTwitch::Condition, std::string>
liveEventIDs = {
{MacroConditionTwitch::Condition::LIVE_EVENT_REGULAR, "live"},
{MacroConditionTwitch::Condition::LIVE_EVENT_PLAYLIST,
{MacroConditionTwitch::Condition::STREAM_ONLINE_LIVE_EVENT,
"live"},
{MacroConditionTwitch::Condition::STREAM_ONLINE_PLAYLIST_EVENT,
"playlist"},
{MacroConditionTwitch::Condition::LIVE_EVENT_WATCHPARTY,
{MacroConditionTwitch::Condition::STREAM_ONLINE_WATCHPARTY_EVENT,
"watch_party"},
{MacroConditionTwitch::Condition::LIVE_EVENT_PREMIERE,
{MacroConditionTwitch::Condition::STREAM_ONLINE_PREMIERE_EVENT,
"premiere"},
{MacroConditionTwitch::Condition::LIVE_EVENT_RERUN, "rerun"},
{MacroConditionTwitch::Condition::STREAM_ONLINE_RERUN_EVENT,
"rerun"},
};
static bool titleMatches(const RegexConfig &conf, const std::string &title,
const std::string &expr)
bool MacroConditionTwitch::CheckChannelGenericEvents(
TwitchToken &token, const char *mainUserIdFieldName)
{
if (!conf.Enabled()) {
return title == expr;
}
auto regex = conf.GetRegularExpression(expr);
if (!regex.isValid()) {
auto eventSub = token.GetEventSub();
if (!eventSub) {
return false;
}
auto match = regex.match(QString::fromStdString(title));
return match.hasMatch();
auto events = eventSub->Events();
for (const auto &event : events) {
if (event.type != eventIdentifiers.find(_condition)->second) {
continue;
}
auto id = obs_data_get_string(event.data, mainUserIdFieldName);
if (id != _channel.GetUserID(token)) {
continue;
}
SetVariableValue(event.ToString());
return true;
}
return false;
}
bool MacroConditionTwitch::CheckChannelLiveEvents(TwitchToken &token)
@ -135,114 +267,19 @@ bool MacroConditionTwitch::CheckChannelLiveEvents(TwitchToken &token)
return false;
}
bool MacroConditionTwitch::CheckChannelOfflineEvents(TwitchToken &token)
static bool titleMatches(const RegexConfig &conf, const std::string &title,
const std::string &expr)
{
auto eventSub = token.GetEventSub();
if (!eventSub) {
return false;
if (!conf.Enabled()) {
return title == expr;
}
auto events = eventSub->Events();
for (const auto &event : events) {
if (event.type != eventIdentifiers.find(_condition)->second) {
continue;
}
auto id =
obs_data_get_string(event.data, "broadcaster_user_id");
if (id != _channel.GetUserID(token)) {
continue;
}
SetVariableValue(event.ToString());
return true;
}
return false;
}
bool MacroConditionTwitch::CheckChannelUpdateEvents(TwitchToken &token)
{
auto eventSub = token.GetEventSub();
if (!eventSub) {
auto regex = conf.GetRegularExpression(expr);
if (!regex.isValid()) {
return false;
}
auto events = eventSub->Events();
for (const auto &event : events) {
if (event.type != eventIdentifiers.find(_condition)->second) {
continue;
}
auto id =
obs_data_get_string(event.data, "broadcaster_user_id");
if (id != _channel.GetUserID(token)) {
continue;
}
SetVariableValue(event.ToString());
return true;
}
return false;
}
bool MacroConditionTwitch::CheckChannelFollowEvents(TwitchToken &token)
{
auto eventSub = token.GetEventSub();
if (!eventSub) {
return false;
}
auto events = eventSub->Events();
for (const auto &event : events) {
if (event.type != eventIdentifiers.find(_condition)->second) {
continue;
}
auto id =
obs_data_get_string(event.data, "broadcaster_user_id");
if (id != _channel.GetUserID(token)) {
continue;
}
SetVariableValue(event.ToString());
return true;
}
return false;
}
bool MacroConditionTwitch::CheckChannelSubscribeEvents(TwitchToken &token)
{
auto eventSub = token.GetEventSub();
if (!eventSub) {
return false;
}
auto events = eventSub->Events();
for (const auto &event : events) {
if (event.type != eventIdentifiers.find(_condition)->second) {
continue;
}
auto id =
obs_data_get_string(event.data, "broadcaster_user_id");
if (id != _channel.GetUserID(token)) {
continue;
}
SetVariableValue(event.ToString());
return true;
}
return false;
}
bool MacroConditionTwitch::CheckChannelCheerEvents(TwitchToken &token)
{
auto eventSub = token.GetEventSub();
if (!eventSub) {
return false;
}
auto events = eventSub->Events();
for (const auto &event : events) {
if (event.type != eventIdentifiers.find(_condition)->second) {
continue;
}
auto id =
obs_data_get_string(event.data, "broadcaster_user_id");
if (id != _channel.GetUserID(token)) {
continue;
}
SetVariableValue(event.ToString());
return true;
}
return false;
auto match = regex.match(QString::fromStdString(title));
return match.hasMatch();
}
bool MacroConditionTwitch::CheckCondition()
@ -267,20 +304,66 @@ bool MacroConditionTwitch::CheckCondition()
}
switch (_condition) {
case Condition::LIVE: {
case Condition::STREAM_ONLINE_EVENT:
case Condition::STREAM_OFFLINE_EVENT:
case Condition::CHANNEL_INFO_UPDATE_EVENT:
case Condition::FOLLOW_EVENT:
case Condition::SUBSCRIPTION_START_EVENT:
case Condition::SUBSCRIPTION_END_EVENT:
case Condition::SUBSCRIPTION_GIFT_EVENT:
case Condition::SUBSCRIPTION_MESSAGE_EVENT:
case Condition::CHEER_EVENT:
case Condition::SHOUTOUT_OUTBOUND_EVENT:
case Condition::SHOUTOUT_INBOUND_EVENT:
case Condition::POLL_START_EVENT:
case Condition::POLL_PROGRESS_EVENT:
case Condition::POLL_END_EVENT:
case Condition::PREDICTION_START_EVENT:
case Condition::PREDICTION_PROGRESS_EVENT:
case Condition::PREDICTION_LOCK_EVENT:
case Condition::PREDICTION_END_EVENT:
case Condition::GOAL_START_EVENT:
case Condition::GOAL_PROGRESS_EVENT:
case Condition::GOAL_END_EVENT:
case Condition::HYPE_TRAIN_START_EVENT:
case Condition::HYPE_TRAIN_PROGRESS_EVENT:
case Condition::HYPE_TRAIN_END_EVENT:
case Condition::CHARITY_CAMPAIGN_START_EVENT:
case Condition::CHARITY_CAMPAIGN_PROGRESS_EVENT:
case Condition::CHARITY_CAMPAIGN_DONATION_EVENT:
case Condition::CHARITY_CAMPAIGN_END_EVENT:
case Condition::SHIELD_MODE_START_EVENT:
case Condition::SHIELD_MODE_END_EVENT:
case Condition::POINTS_REWARD_ADDITION_EVENT:
case Condition::POINTS_REWARD_UPDATE_EVENT:
case Condition::POINTS_REWARD_DELETION_EVENT:
case Condition::POINTS_REWARD_REDEMPTION_EVENT:
case Condition::POINTS_REWARD_REDEMPTION_UPDATE_EVENT:
case Condition::USER_BAN_EVENT:
case Condition::USER_UNBAN_EVENT:
case Condition::USER_MODERATOR_ADDITION_EVENT:
case Condition::USER_MODERATOR_DELETION_EVENT:
return CheckChannelGenericEvents(*token);
case Condition::RAID_OUTBOUND_EVENT:
return CheckChannelGenericEvents(*token,
"from_broadcaster_user_id");
case Condition::RAID_INBOUND_EVENT:
return CheckChannelGenericEvents(*token,
"to_broadcaster_user_id");
case Condition::STREAM_ONLINE_LIVE_EVENT:
case Condition::STREAM_ONLINE_PLAYLIST_EVENT:
case Condition::STREAM_ONLINE_WATCHPARTY_EVENT:
case Condition::STREAM_ONLINE_PREMIERE_EVENT:
case Condition::STREAM_ONLINE_RERUN_EVENT:
return CheckChannelLiveEvents(*token);
case Condition::LIVE_POLLING: {
auto info = _channel.GetLiveInfo(*token);
if (!info) {
return false;
}
return info->IsLive();
}
case Condition::LIVE_EVENT_REGULAR:
case Condition::LIVE_EVENT_PLAYLIST:
case Condition::LIVE_EVENT_WATCHPARTY:
case Condition::LIVE_EVENT_PREMIERE:
case Condition::LIVE_EVENT_RERUN:
return CheckChannelLiveEvents(*token);
case Condition::TITLE: {
case Condition::TITLE_POLLING: {
auto info = _channel.GetInfo(*token);
if (!info) {
return false;
@ -288,7 +371,7 @@ bool MacroConditionTwitch::CheckCondition()
SetVariableValue(info->title);
return titleMatches(_regex, info->title, _streamTitle);
}
case Condition::CATEGORY: {
case Condition::CATEGORY_POLLING: {
auto info = _channel.GetInfo(*token);
if (!info) {
return false;
@ -296,17 +379,6 @@ bool MacroConditionTwitch::CheckCondition()
SetVariableValue(info->game_name);
return info->game_id == std::to_string(_category.id);
}
case Condition::CHANNEL_UPDATE_EVENT:
return CheckChannelUpdateEvents(*token);
case Condition::FOLLOW_EVENT:
return CheckChannelFollowEvents(*token);
case Condition::SUBSCRIBE_EVENT:
case Condition::SUBSCRIBE_END_EVENT:
case Condition::SUBSCRIBE_GIFT_EVENT:
case Condition::SUBSCRIBE_MESSAGE_EVENT:
return CheckChannelSubscribeEvents(*token);
case Condition::CHEER_EVENT:
return CheckChannelCheerEvents(*token);
default:
break;
}
@ -368,38 +440,122 @@ std::string MacroConditionTwitch::GetShortDesc() const
bool MacroConditionTwitch::ConditionIsSupportedByToken()
{
static const std::unordered_map<Condition, TokenOption> requiredOption = {
{Condition::LIVE_EVENT_REGULAR, {""}},
{Condition::LIVE_EVENT_PLAYLIST, {""}},
{Condition::LIVE_EVENT_WATCHPARTY, {""}},
{Condition::LIVE_EVENT_PREMIERE, {""}},
{Condition::LIVE_EVENT_RERUN, {""}},
{Condition::OFFLINE_EVENT, {""}},
{Condition::CHANNEL_UPDATE_EVENT, {""}},
{Condition::FOLLOW_EVENT, {"moderator:read:followers"}},
{Condition::SUBSCRIBE_EVENT, {"channel:read:subscriptions"}},
{Condition::SUBSCRIBE_END_EVENT,
{"channel:read:subscriptions"}},
{Condition::SUBSCRIBE_GIFT_EVENT,
{"channel:read:subscriptions"}},
{Condition::SUBSCRIBE_MESSAGE_EVENT,
{"channel:read:subscriptions"}},
{Condition::CHEER_EVENT, {"bits:read"}},
{Condition::LIVE, {""}},
{Condition::TITLE, {""}},
{Condition::CATEGORY, {""}},
};
static const std::unordered_map<Condition, std::vector<TokenOption>>
requiredOption = {
{Condition::STREAM_ONLINE_EVENT, {}},
{Condition::STREAM_OFFLINE_EVENT, {}},
{Condition::CHANNEL_INFO_UPDATE_EVENT, {}},
{Condition::FOLLOW_EVENT,
{{"moderator:read:followers"}}},
{Condition::SUBSCRIPTION_START_EVENT,
{{"channel:read:subscriptions"}}},
{Condition::SUBSCRIPTION_END_EVENT,
{{"channel:read:subscriptions"}}},
{Condition::SUBSCRIPTION_GIFT_EVENT,
{{"channel:read:subscriptions"}}},
{Condition::SUBSCRIPTION_MESSAGE_EVENT,
{{"channel:read:subscriptions"}}},
{Condition::CHEER_EVENT, {{"bits:read"}}},
{Condition::RAID_OUTBOUND_EVENT, {}},
{Condition::RAID_INBOUND_EVENT, {}},
{Condition::SHOUTOUT_OUTBOUND_EVENT,
{{"moderator:read:shoutouts"},
{"moderator:manage:shoutouts"}}},
{Condition::SHOUTOUT_INBOUND_EVENT,
{{"moderator:read:shoutouts"},
{"moderator:manage:shoutouts"}}},
{Condition::POLL_START_EVENT,
{{"channel:read:polls"}, {"channel:manage:polls"}}},
{Condition::POLL_PROGRESS_EVENT,
{{"channel:read:polls"}, {"channel:manage:polls"}}},
{Condition::POLL_END_EVENT,
{{"channel:read:polls"}, {"channel:manage:polls"}}},
{Condition::PREDICTION_START_EVENT,
{{"channel:read:predictions"},
{"channel:manage:predictions"}}},
{Condition::PREDICTION_PROGRESS_EVENT,
{{"channel:read:predictions"},
{"channel:manage:predictions"}}},
{Condition::PREDICTION_LOCK_EVENT,
{{"channel:read:predictions"},
{"channel:manage:predictions"}}},
{Condition::PREDICTION_END_EVENT,
{{"channel:read:predictions"},
{"channel:manage:predictions"}}},
{Condition::GOAL_START_EVENT, {{"channel:read:goals"}}},
{Condition::GOAL_PROGRESS_EVENT,
{{"channel:read:goals"}}},
{Condition::GOAL_END_EVENT, {{"channel:read:goals"}}},
{Condition::HYPE_TRAIN_START_EVENT,
{{"channel:read:hype_train"}}},
{Condition::HYPE_TRAIN_PROGRESS_EVENT,
{{"channel:read:hype_train"}}},
{Condition::HYPE_TRAIN_END_EVENT,
{{"channel:read:hype_train"}}},
{Condition::CHARITY_CAMPAIGN_START_EVENT,
{{"channel:read:charity"}}},
{Condition::CHARITY_CAMPAIGN_PROGRESS_EVENT,
{{"channel:read:charity"}}},
{Condition::CHARITY_CAMPAIGN_DONATION_EVENT,
{{"channel:read:charity"}}},
{Condition::CHARITY_CAMPAIGN_END_EVENT,
{{"channel:read:charity"}}},
{Condition::SHIELD_MODE_START_EVENT,
{{"moderator:read:shield_mode"},
{"moderator:manage:shield_mode"}}},
{Condition::SHIELD_MODE_END_EVENT,
{{"moderator:read:shield_mode"},
{"moderator:manage:shield_mode"}}},
{Condition::POINTS_REWARD_ADDITION_EVENT,
{{"channel:read:redemptions"},
{"channel:manage:redemptions"}}},
{Condition::POINTS_REWARD_UPDATE_EVENT,
{{"channel:read:redemptions"},
{"channel:manage:redemptions"}}},
{Condition::POINTS_REWARD_DELETION_EVENT,
{{"channel:read:redemptions"},
{"channel:manage:redemptions"}}},
{Condition::POINTS_REWARD_REDEMPTION_EVENT,
{{"channel:read:redemptions"},
{"channel:manage:redemptions"}}},
{Condition::POINTS_REWARD_REDEMPTION_UPDATE_EVENT,
{{"channel:read:redemptions"},
{"channel:manage:redemptions"}}},
{Condition::USER_BAN_EVENT, {{"channel:moderate"}}},
{Condition::USER_UNBAN_EVENT, {{"channel:moderate"}}},
{Condition::USER_MODERATOR_ADDITION_EVENT,
{{"moderation:read"}}},
{Condition::USER_MODERATOR_DELETION_EVENT,
{{"moderation:read"}}},
{Condition::STREAM_ONLINE_LIVE_EVENT, {}},
{Condition::STREAM_ONLINE_PLAYLIST_EVENT, {}},
{Condition::STREAM_ONLINE_WATCHPARTY_EVENT, {}},
{Condition::STREAM_ONLINE_PREMIERE_EVENT, {}},
{Condition::STREAM_ONLINE_RERUN_EVENT, {}},
{Condition::LIVE_POLLING, {}},
{Condition::TITLE_POLLING, {}},
{Condition::CATEGORY_POLLING, {}},
};
auto token = _token.lock();
if (!token) {
return false;
}
auto option = requiredOption.find(_condition);
assert(option != requiredOption.end());
if (option == requiredOption.end()) {
auto it = requiredOption.find(_condition);
assert(it != requiredOption.end());
if (it == requiredOption.end()) {
return false;
}
return option->second.apiId.empty() ||
token->OptionIsEnabled(option->second);
const auto &[_, options] = *it;
for (const auto &tokenOption : options) {
if (!token->OptionIsEnabled(tokenOption)) {
return false;
}
}
return true;
}
void MacroConditionTwitch::SetupEventSubscriptions()
@ -409,27 +565,66 @@ void MacroConditionTwitch::SetupEventSubscriptions()
}
switch (_condition) {
case MacroConditionTwitch::Condition::LIVE_EVENT_REGULAR:
case MacroConditionTwitch::Condition::LIVE_EVENT_PLAYLIST:
case MacroConditionTwitch::Condition::LIVE_EVENT_WATCHPARTY:
case MacroConditionTwitch::Condition::LIVE_EVENT_PREMIERE:
case MacroConditionTwitch::Condition::LIVE_EVENT_RERUN:
AddChannelLiveEventSubscription();
case MacroConditionTwitch::Condition::STREAM_ONLINE_EVENT:
case MacroConditionTwitch::Condition::STREAM_OFFLINE_EVENT:
case MacroConditionTwitch::Condition::SUBSCRIPTION_START_EVENT:
case MacroConditionTwitch::Condition::SUBSCRIPTION_END_EVENT:
case MacroConditionTwitch::Condition::SUBSCRIPTION_GIFT_EVENT:
case MacroConditionTwitch::Condition::SUBSCRIPTION_MESSAGE_EVENT:
case MacroConditionTwitch::Condition::CHEER_EVENT:
case MacroConditionTwitch::Condition::POLL_START_EVENT:
case MacroConditionTwitch::Condition::POLL_PROGRESS_EVENT:
case MacroConditionTwitch::Condition::POLL_END_EVENT:
case MacroConditionTwitch::Condition::PREDICTION_START_EVENT:
case MacroConditionTwitch::Condition::PREDICTION_PROGRESS_EVENT:
case MacroConditionTwitch::Condition::PREDICTION_LOCK_EVENT:
case MacroConditionTwitch::Condition::PREDICTION_END_EVENT:
case MacroConditionTwitch::Condition::GOAL_START_EVENT:
case MacroConditionTwitch::Condition::GOAL_PROGRESS_EVENT:
case MacroConditionTwitch::Condition::GOAL_END_EVENT:
case MacroConditionTwitch::Condition::HYPE_TRAIN_START_EVENT:
case MacroConditionTwitch::Condition::HYPE_TRAIN_PROGRESS_EVENT:
case MacroConditionTwitch::Condition::HYPE_TRAIN_END_EVENT:
case MacroConditionTwitch::Condition::CHARITY_CAMPAIGN_START_EVENT:
case MacroConditionTwitch::Condition::CHARITY_CAMPAIGN_PROGRESS_EVENT:
case MacroConditionTwitch::Condition::CHARITY_CAMPAIGN_DONATION_EVENT:
case MacroConditionTwitch::Condition::CHARITY_CAMPAIGN_END_EVENT:
case MacroConditionTwitch::Condition::POINTS_REWARD_ADDITION_EVENT:
case MacroConditionTwitch::Condition::POINTS_REWARD_UPDATE_EVENT:
case MacroConditionTwitch::Condition::POINTS_REWARD_DELETION_EVENT:
case MacroConditionTwitch::Condition::POINTS_REWARD_REDEMPTION_EVENT:
case MacroConditionTwitch::Condition::USER_BAN_EVENT:
case MacroConditionTwitch::Condition::USER_UNBAN_EVENT:
case MacroConditionTwitch::Condition::USER_MODERATOR_ADDITION_EVENT:
case MacroConditionTwitch::Condition::USER_MODERATOR_DELETION_EVENT:
case MacroConditionTwitch::Condition::
POINTS_REWARD_REDEMPTION_UPDATE_EVENT:
case MacroConditionTwitch::Condition::STREAM_ONLINE_LIVE_EVENT:
case MacroConditionTwitch::Condition::STREAM_ONLINE_PLAYLIST_EVENT:
case MacroConditionTwitch::Condition::STREAM_ONLINE_WATCHPARTY_EVENT:
case MacroConditionTwitch::Condition::STREAM_ONLINE_PREMIERE_EVENT:
case MacroConditionTwitch::Condition::STREAM_ONLINE_RERUN_EVENT:
AddChannelGenericEventSubscription("1");
break;
case MacroConditionTwitch::Condition::OFFLINE_EVENT:
AddChannelOfflineEventSubscription();
case MacroConditionTwitch::Condition::CHANNEL_INFO_UPDATE_EVENT:
AddChannelGenericEventSubscription("2");
break;
case MacroConditionTwitch::Condition::CHANNEL_UPDATE_EVENT:
AddChannelUpdateEventSubscription();
case MacroConditionTwitch::Condition::SHOUTOUT_OUTBOUND_EVENT:
case MacroConditionTwitch::Condition::SHOUTOUT_INBOUND_EVENT:
case MacroConditionTwitch::Condition::SHIELD_MODE_START_EVENT:
case MacroConditionTwitch::Condition::SHIELD_MODE_END_EVENT:
AddChannelGenericEventSubscription("1", true);
break;
case MacroConditionTwitch::Condition::FOLLOW_EVENT:
AddChannelFollowEventSubscription();
AddChannelGenericEventSubscription("2", true);
break;
case MacroConditionTwitch::Condition::SUBSCRIBE_EVENT:
case MacroConditionTwitch::Condition::SUBSCRIBE_END_EVENT:
case MacroConditionTwitch::Condition::SUBSCRIBE_GIFT_EVENT:
case MacroConditionTwitch::Condition::SUBSCRIBE_MESSAGE_EVENT:
AddChannelSubscribeEventSubscription();
case MacroConditionTwitch::Condition::RAID_OUTBOUND_EVENT:
AddChannelGenericEventSubscription("1", false,
"from_broadcaster_user_id");
break;
case MacroConditionTwitch::Condition::RAID_INBOUND_EVENT:
AddChannelGenericEventSubscription("1", false,
"to_broadcaster_user_id");
break;
default:
break;
@ -438,21 +633,7 @@ void MacroConditionTwitch::SetupEventSubscriptions()
bool MacroConditionTwitch::IsUsingEventSubCondition()
{
const static std::set<Condition> eventConditions{
Condition::LIVE_EVENT_REGULAR,
Condition::LIVE_EVENT_PLAYLIST,
Condition::LIVE_EVENT_WATCHPARTY,
Condition::LIVE_EVENT_PREMIERE,
Condition::LIVE_EVENT_RERUN,
Condition::CHANNEL_UPDATE_EVENT,
Condition::FOLLOW_EVENT,
Condition::SUBSCRIBE_EVENT,
Condition::SUBSCRIBE_END_EVENT,
Condition::SUBSCRIBE_GIFT_EVENT,
Condition::SUBSCRIBE_MESSAGE_EVENT,
Condition::CHEER_EVENT,
};
return eventConditions.find(_condition) != eventConditions.end();
return eventIdentifiers.find(_condition) != eventIdentifiers.end();
}
std::future<std::string>
@ -465,7 +646,9 @@ waitForSubscription(const std::shared_ptr<TwitchToken> &token,
});
}
void MacroConditionTwitch::AddChannelLiveEventSubscription()
void MacroConditionTwitch::AddChannelGenericEventSubscription(
const char *version, bool includeModeratorId,
const char *mainUserIdFieldName)
{
if (!IsUsingEventSubCondition()) {
return;
@ -480,127 +663,16 @@ void MacroConditionTwitch::AddChannelLiveEventSubscription()
Subscription subscription{temp.Get()};
obs_data_set_string(subscription.data, "type",
eventIdentifiers.find(_condition)->second.c_str());
obs_data_set_string(subscription.data, "version", "1");
obs_data_set_string(subscription.data, "version", version);
OBSDataAutoRelease condition = obs_data_create();
obs_data_set_string(condition, "broadcaster_user_id",
obs_data_set_string(condition, mainUserIdFieldName,
_channel.GetUserID(*token).c_str());
obs_data_set_obj(subscription.data, "condition", condition);
_subscriptionIDFuture = waitForSubscription(token, subscription);
}
void MacroConditionTwitch::AddChannelOfflineEventSubscription()
{
if (!IsUsingEventSubCondition()) {
return;
if (includeModeratorId) {
obs_data_set_string(condition, "moderator_user_id",
token->GetUserID().c_str());
}
auto token = _token.lock();
if (!token) {
return;
}
OBSDataAutoRelease temp = obs_data_create();
Subscription subscription{temp.Get()};
obs_data_set_string(subscription.data, "type",
eventIdentifiers.find(_condition)->second.c_str());
obs_data_set_string(subscription.data, "version", "1");
OBSDataAutoRelease condition = obs_data_create();
obs_data_set_string(condition, "broadcaster_user_id",
_channel.GetUserID(*token).c_str());
obs_data_set_obj(subscription.data, "condition", condition);
_subscriptionIDFuture = waitForSubscription(token, subscription);
}
void MacroConditionTwitch::AddChannelUpdateEventSubscription()
{
if (!IsUsingEventSubCondition()) {
return;
}
auto token = _token.lock();
if (!token) {
return;
}
OBSDataAutoRelease temp = obs_data_create();
Subscription subscription{temp.Get()};
obs_data_set_string(subscription.data, "type",
eventIdentifiers.find(_condition)->second.c_str());
obs_data_set_string(subscription.data, "version", "2");
OBSDataAutoRelease condition = obs_data_create();
obs_data_set_string(condition, "broadcaster_user_id",
_channel.GetUserID(*token).c_str());
obs_data_set_obj(subscription.data, "condition", condition);
_subscriptionIDFuture = waitForSubscription(token, subscription);
}
void MacroConditionTwitch::AddChannelFollowEventSubscription()
{
if (!IsUsingEventSubCondition()) {
return;
}
auto token = _token.lock();
if (!token) {
return;
}
OBSDataAutoRelease temp = obs_data_create();
Subscription subscription{temp.Get()};
obs_data_set_string(subscription.data, "type",
eventIdentifiers.find(_condition)->second.c_str());
obs_data_set_string(subscription.data, "version", "2");
OBSDataAutoRelease condition = obs_data_create();
obs_data_set_string(condition, "broadcaster_user_id",
_channel.GetUserID(*token).c_str());
obs_data_set_string(condition, "moderator_user_id",
token->GetUserID().c_str());
obs_data_set_obj(subscription.data, "condition", condition);
_subscriptionIDFuture = waitForSubscription(token, subscription);
}
void MacroConditionTwitch::AddChannelSubscribeEventSubscription()
{
if (!IsUsingEventSubCondition()) {
return;
}
auto token = _token.lock();
if (!token) {
return;
}
OBSDataAutoRelease temp = obs_data_create();
Subscription subscription{temp.Get()};
obs_data_set_string(subscription.data, "type",
eventIdentifiers.find(_condition)->second.c_str());
obs_data_set_string(subscription.data, "version", "1");
OBSDataAutoRelease condition = obs_data_create();
obs_data_set_string(condition, "broadcaster_user_id",
_channel.GetUserID(*token).c_str());
obs_data_set_obj(subscription.data, "condition", condition);
_subscriptionIDFuture = waitForSubscription(token, subscription);
}
void MacroConditionTwitch::AddChannelCheerEventSubscription()
{
if (!IsUsingEventSubCondition()) {
return;
}
auto token = _token.lock();
if (!token) {
return;
}
OBSDataAutoRelease temp = obs_data_create();
Subscription subscription{temp.Get()};
obs_data_set_string(subscription.data, "type",
eventIdentifiers.find(_condition)->second.c_str());
obs_data_set_string(subscription.data, "version", "1");
OBSDataAutoRelease condition = obs_data_create();
obs_data_set_string(condition, "broadcaster_user_id",
_channel.GetUserID(*token).c_str());
obs_data_set_obj(subscription.data, "condition", condition);
_subscriptionIDFuture = waitForSubscription(token, subscription);
}
@ -721,12 +793,13 @@ void MacroConditionTwitchEdit::CheckTokenPermissions()
void MacroConditionTwitchEdit::SetupWidgetVisibility()
{
auto condition = _entryData->GetCondition();
_streamTitle->setVisible(condition ==
MacroConditionTwitch::Condition::TITLE);
_regex->setVisible(condition == MacroConditionTwitch::Condition::TITLE);
_category->setVisible(condition ==
MacroConditionTwitch::Condition::CATEGORY);
if (condition == MacroConditionTwitch::Condition::TITLE) {
_streamTitle->setVisible(
condition == MacroConditionTwitch::Condition::TITLE_POLLING);
_regex->setVisible(condition ==
MacroConditionTwitch::Condition::TITLE_POLLING);
_category->setVisible(
condition == MacroConditionTwitch::Condition::CATEGORY_POLLING);
if (condition == MacroConditionTwitch::Condition::TITLE_POLLING) {
RemoveStretchIfPresent(_layout);
} else {
AddStretchIfNecessary(_layout);

View File

@ -24,25 +24,60 @@ public:
bool ConditionIsSupportedByToken();
enum class Condition {
// Event based
LIVE_EVENT_REGULAR = 10,
LIVE_EVENT_PLAYLIST = 20,
LIVE_EVENT_WATCHPARTY = 30,
LIVE_EVENT_PREMIERE = 40,
LIVE_EVENT_RERUN = 50,
OFFLINE_EVENT = 60,
CHANNEL_UPDATE_EVENT = 70,
FOLLOW_EVENT = 80,
SUBSCRIBE_EVENT = 90,
SUBSCRIBE_END_EVENT = 100,
SUBSCRIBE_GIFT_EVENT = 110,
SUBSCRIBE_MESSAGE_EVENT = 120,
CHEER_EVENT = 130,
// Generic event based
STREAM_ONLINE_EVENT = 0,
STREAM_OFFLINE_EVENT = 100,
CHANNEL_INFO_UPDATE_EVENT = 200,
FOLLOW_EVENT = 300,
SUBSCRIPTION_START_EVENT = 400,
SUBSCRIPTION_END_EVENT = 500,
SUBSCRIPTION_GIFT_EVENT = 600,
SUBSCRIPTION_MESSAGE_EVENT = 700,
CHEER_EVENT = 800,
RAID_OUTBOUND_EVENT = 900,
RAID_INBOUND_EVENT = 1000,
SHOUTOUT_OUTBOUND_EVENT = 1100,
SHOUTOUT_INBOUND_EVENT = 1200,
POLL_START_EVENT = 1300,
POLL_PROGRESS_EVENT = 1400,
POLL_END_EVENT = 1500,
PREDICTION_START_EVENT = 1600,
PREDICTION_PROGRESS_EVENT = 1700,
PREDICTION_LOCK_EVENT = 1800,
PREDICTION_END_EVENT = 1900,
GOAL_START_EVENT = 2000,
GOAL_PROGRESS_EVENT = 2100,
GOAL_END_EVENT = 2200,
HYPE_TRAIN_START_EVENT = 2300,
HYPE_TRAIN_PROGRESS_EVENT = 2400,
HYPE_TRAIN_END_EVENT = 2500,
CHARITY_CAMPAIGN_START_EVENT = 2600,
CHARITY_CAMPAIGN_PROGRESS_EVENT = 2700,
CHARITY_CAMPAIGN_DONATION_EVENT = 2800,
CHARITY_CAMPAIGN_END_EVENT = 2900,
SHIELD_MODE_START_EVENT = 3000,
SHIELD_MODE_END_EVENT = 3100,
POINTS_REWARD_ADDITION_EVENT = 3200,
POINTS_REWARD_UPDATE_EVENT = 3300,
POINTS_REWARD_DELETION_EVENT = 3400,
POINTS_REWARD_REDEMPTION_EVENT = 3500,
POINTS_REWARD_REDEMPTION_UPDATE_EVENT = 3600,
USER_BAN_EVENT = 3700,
USER_UNBAN_EVENT = 3800,
USER_MODERATOR_ADDITION_EVENT = 3900,
USER_MODERATOR_DELETION_EVENT = 4000,
// Event based with custom logic
STREAM_ONLINE_LIVE_EVENT = 1,
STREAM_ONLINE_PLAYLIST_EVENT = 2,
STREAM_ONLINE_WATCHPARTY_EVENT = 3,
STREAM_ONLINE_PREMIERE_EVENT = 4,
STREAM_ONLINE_RERUN_EVENT = 5,
// Polling
LIVE = 1000,
TITLE = 1010,
CATEGORY = 1020,
LIVE_POLLING = 1000000,
TITLE_POLLING = 1000100,
CATEGORY_POLLING = 1000200,
};
void SetCondition(const Condition &);
@ -56,24 +91,19 @@ public:
TwitchCategory _category;
private:
bool CheckChannelGenericEvents(
TwitchToken &,
const char *mainUserIdFieldName = "broadcaster_user_id");
bool CheckChannelLiveEvents(TwitchToken &);
bool CheckChannelOfflineEvents(TwitchToken &);
bool CheckChannelUpdateEvents(TwitchToken &);
bool CheckChannelFollowEvents(TwitchToken &);
bool CheckChannelSubscribeEvents(TwitchToken &);
bool CheckChannelCheerEvents(TwitchToken &);
bool IsUsingEventSubCondition();
void SetupEventSubscriptions();
void CheckEventSubscription(EventSub &);
void AddChannelLiveEventSubscription();
void AddChannelOfflineEventSubscription();
void AddChannelUpdateEventSubscription();
void AddChannelFollowEventSubscription();
void AddChannelSubscribeEventSubscription();
void AddChannelCheerEventSubscription();
void AddChannelGenericEventSubscription(
const char *version, bool includeModeratorId = false,
const char *mainUserIdFieldName = "broadcaster_user_id");
Condition _condition = Condition::LIVE;
Condition _condition = Condition::LIVE_POLLING;
std::future<std::string> _subscriptionIDFuture;
std::string _subscriptionID;
static bool _registered;

View File

@ -12,20 +12,49 @@ static std::deque<std::shared_ptr<Item>> twitchTokens;
const std::unordered_map<std::string, std::string> TokenOption::_apiIdToLocale{
{"channel:manage:broadcast",
"AdvSceneSwitcher.twitchToken.channel.manageBroadcast"},
"AdvSceneSwitcher.twitchToken.channel.broadcast.manage"},
{"clips:edit", "AdvSceneSwitcher.twitchToken.clips.edit"},
{"channel:edit:commercial",
"AdvSceneSwitcher.twitchToken.channel.startCommercial"},
"AdvSceneSwitcher.twitchToken.channel.commercial.edit"},
{"moderator:manage:announcements",
"AdvSceneSwitcher.twitchToken.moderator.manageAnnouncements"},
"AdvSceneSwitcher.twitchToken.moderator.announcements.manage"},
{"moderator:manage:chat_settings",
"AdvSceneSwitcher.twitchToken.moderator.manageChatSettings"},
"AdvSceneSwitcher.twitchToken.moderator.chat.settings.manage"},
{"channel:manage:raids", "AdvSceneSwitcher.twitchToken.channel.raid"},
{"moderator:read:followers",
"AdvSceneSwitcher.twitchToken.readSubscriptions"},
"AdvSceneSwitcher.twitchToken.moderator.followers.read"},
{"channel:read:subscriptions",
"AdvSceneSwitcher.twitchToken.readFollowers"},
{"bits:read", "AdvSceneSwitcher.twitchToken.bits"},
"AdvSceneSwitcher.twitchToken.channel.subscriptions.read"},
{"bits:read", "AdvSceneSwitcher.twitchToken.bits.read"},
{"moderator:read:shoutouts",
"AdvSceneSwitcher.twitchToken.moderator.shoutouts.read"},
{"moderator:manage:shoutouts",
"AdvSceneSwitcher.twitchToken.moderator.shoutouts.manage"},
{"channel:read:polls",
"AdvSceneSwitcher.twitchToken.channel.polls.read"},
{"channel:manage:polls",
"AdvSceneSwitcher.twitchToken.channel.polls.manage"},
{"channel:read:predictions",
"AdvSceneSwitcher.twitchToken.channel.predictions.read"},
{"channel:manage:predictions",
"AdvSceneSwitcher.twitchToken.channel.predictions.manage"},
{"channel:read:goals",
"AdvSceneSwitcher.twitchToken.channel.goals.read"},
{"channel:read:hype_train",
"AdvSceneSwitcher.twitchToken.channel.hypeTrain.read"},
{"channel:read:charity",
"AdvSceneSwitcher.twitchToken.channel.charity.read"},
{"moderator:read:shield_mode",
"AdvSceneSwitcher.twitchToken.moderator.shieldMode.read"},
{"moderator:manage:shield_mode",
"AdvSceneSwitcher.twitchToken.moderator.shieldMode.manage"},
{"channel:read:redemptions",
"AdvSceneSwitcher.twitchToken.channel.redemptions.read"},
{"channel:manage:redemptions",
"AdvSceneSwitcher.twitchToken.channel.redemptions.manage"},
{"channel:moderate", "AdvSceneSwitcher.twitchToken.channel.moderate"},
{"moderation:read",
"AdvSceneSwitcher.twitchToken.channel.moderation.read"},
};
static void saveConnections(obs_data_t *obj);