mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-08-29 04:36:21 -05:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb7ee17362 | ||
|
|
70854ef012 | ||
|
|
053c14056d | ||
|
|
9397d50764 | ||
|
|
473e24cc42 | ||
|
|
d9394605f4 | ||
|
|
d2b9074852 | ||
|
|
b525eb7a0e |
@@ -295,7 +295,6 @@ AdvSceneSwitcher.condition.record="Recording"
|
||||
AdvSceneSwitcher.condition.record.state.start="Recording running"
|
||||
AdvSceneSwitcher.condition.record.state.pause="Recording paused"
|
||||
AdvSceneSwitcher.condition.record.state.stop="Recording stopped"
|
||||
AdvSceneSwitcher.condition.record.state.saveDone="Recording saved"
|
||||
AdvSceneSwitcher.condition.record.entry="{{recordState}}"
|
||||
AdvSceneSwitcher.condition.process="Process"
|
||||
AdvSceneSwitcher.condition.process.entry="{{processes}}is running{{focused}}and is focused"
|
||||
@@ -853,15 +852,15 @@ AdvSceneSwitcher.action.sceneLock.type.unlock="unlock"
|
||||
AdvSceneSwitcher.action.sceneLock.type.toggle="toggle lock of"
|
||||
AdvSceneSwitcher.action.sceneLock.entry="On{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.twitch="Twitch"
|
||||
AdvSceneSwitcher.action.twitch.type.title="Set stream title"
|
||||
AdvSceneSwitcher.action.twitch.type.category="Set stream category"
|
||||
AdvSceneSwitcher.action.twitch.type.marker="Create stream marker"
|
||||
AdvSceneSwitcher.action.twitch.type.clip="Create stream clip"
|
||||
AdvSceneSwitcher.action.twitch.type.commercial="Start commercial with duration"
|
||||
AdvSceneSwitcher.action.twitch.type.announcement="Send chat announcement"
|
||||
AdvSceneSwitcher.action.twitch.type.emoteOnlyEnable="Enable chat's emote-only mode"
|
||||
AdvSceneSwitcher.action.twitch.type.emoteOnlyDisable="Disable chat's emote-only mode"
|
||||
AdvSceneSwitcher.action.twitch.type.raid="Raid channel"
|
||||
AdvSceneSwitcher.action.twitch.type.channel.info.title.set="Set stream title"
|
||||
AdvSceneSwitcher.action.twitch.type.channel.info.category.set="Set stream category"
|
||||
AdvSceneSwitcher.action.twitch.type.raid.start="Start raid"
|
||||
AdvSceneSwitcher.action.twitch.type.commercial.start="Start commercial"
|
||||
AdvSceneSwitcher.action.twitch.type.marker.create="Create stream marker"
|
||||
AdvSceneSwitcher.action.twitch.type.clip.create="Create stream clip"
|
||||
AdvSceneSwitcher.action.twitch.type.chat.announcement.send="Send chat announcement"
|
||||
AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.enable="Enable chat's emote-only mode"
|
||||
AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.disable="Disable chat's emote-only mode"
|
||||
AdvSceneSwitcher.action.twitch.type.sendChatMessage="Send chat message"
|
||||
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Cannot select category without selecting a Twitch account first!"
|
||||
AdvSceneSwitcher.action.twitch.entry.default="On{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}"
|
||||
@@ -1028,14 +1027,10 @@ 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.channel.broadcast.manage="Manage a channel’s 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.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.channel.raids.manage="Manage channel's raids."
|
||||
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."
|
||||
@@ -1050,7 +1045,17 @@ AdvSceneSwitcher.twitchToken.moderator.shieldMode.manage="Manage channel's Shiel
|
||||
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.twitchToken.moderator.bannedUsers.manage="Manage channel's banned users."
|
||||
AdvSceneSwitcher.twitchToken.user.blockedUsers.manage="Manage user's blocked users."
|
||||
AdvSceneSwitcher.twitchToken.moderation.read="Read channel's moderation data."
|
||||
AdvSceneSwitcher.twitchToken.channel.moderators.manage="Manage channel's moderators."
|
||||
AdvSceneSwitcher.twitchToken.channel.vips.manage="Manage channel's VIPs."
|
||||
AdvSceneSwitcher.twitchToken.channel.commercial.edit="Run commercials on a channel."
|
||||
AdvSceneSwitcher.twitchToken.channel.ads.manage="Manage channel's commercials."
|
||||
AdvSceneSwitcher.twitchToken.clips.edit="Create clips from channel's broadcasts."
|
||||
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.user.whispers.manage="Manage user's whispers."
|
||||
AdvSceneSwitcher.twitchToken.chat.read="View live stream chat messages."
|
||||
AdvSceneSwitcher.twitchToken.chat.edit="Send live stream chat messages."
|
||||
|
||||
@@ -1413,6 +1418,20 @@ AdvSceneSwitcher.tempVar.twitch.chatter="User login"
|
||||
AdvSceneSwitcher.tempVar.twitch.chatter.description="The user login of the person who sent the chat message."
|
||||
AdvSceneSwitcher.tempVar.twitch.chat_message="Chat message"
|
||||
|
||||
AdvSceneSwitcher.tempVar.twitch.from_broadcaster_user_id.raid="Raid creator user ID"
|
||||
AdvSceneSwitcher.tempVar.twitch.from_broadcaster_user_id.raid.description="The broadcaster ID that created the raid."
|
||||
AdvSceneSwitcher.tempVar.twitch.from_broadcaster_user_login.raid="Raid creator user login"
|
||||
AdvSceneSwitcher.tempVar.twitch.from_broadcaster_user_login.raid.description="The broadcaster login that created the raid."
|
||||
AdvSceneSwitcher.tempVar.twitch.from_broadcaster_user_name.raid="Raid creator user name"
|
||||
AdvSceneSwitcher.tempVar.twitch.from_broadcaster_user_name.raid.description="The broadcaster display name that created the raid."
|
||||
AdvSceneSwitcher.tempVar.twitch.to_broadcaster_user_id.raid="Raid receiver user ID"
|
||||
AdvSceneSwitcher.tempVar.twitch.to_broadcaster_user_id.raid.description="The broadcaster ID that created the raid."
|
||||
AdvSceneSwitcher.tempVar.twitch.to_broadcaster_user_login.raid="Raid receiver user login"
|
||||
AdvSceneSwitcher.tempVar.twitch.to_broadcaster_user_login.raid.description="The broadcaster login that created the raid."
|
||||
AdvSceneSwitcher.tempVar.twitch.to_broadcaster_user_name.raid="Raid receiver user name"
|
||||
AdvSceneSwitcher.tempVar.twitch.to_broadcaster_user_name.raid.description="The broadcaster display name that created the raid."
|
||||
AdvSceneSwitcher.tempVar.twitch.viewers.raid="Raid participants"
|
||||
AdvSceneSwitcher.tempVar.twitch.viewers.raid.description="The number of viewers in the raid."
|
||||
|
||||
AdvSceneSwitcher.tempVar.audio.output_volume="Output volume"
|
||||
AdvSceneSwitcher.tempVar.audio.output_volume.description="The volume the audio source is outputting."
|
||||
@@ -1443,6 +1462,12 @@ AdvSceneSwitcher.tempVar.date.minute="Minute"
|
||||
AdvSceneSwitcher.tempVar.date.second="Second"
|
||||
AdvSceneSwitcher.tempVar.date.dayOfWeek="Day of week"
|
||||
|
||||
AdvSceneSwitcher.tempVar.midi.type="Message type"
|
||||
AdvSceneSwitcher.tempVar.midi.channel="Channel"
|
||||
AdvSceneSwitcher.tempVar.midi.note="Note"
|
||||
AdvSceneSwitcher.tempVar.midi.value1="Value 1"
|
||||
AdvSceneSwitcher.tempVar.midi.value2="Value 2"
|
||||
|
||||
AdvSceneSwitcher.selectScene="--select scene--"
|
||||
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
|
||||
AdvSceneSwitcher.selectCurrentScene="Current Scene"
|
||||
|
||||
@@ -736,9 +736,9 @@ AdvSceneSwitcher.action.sceneLock.type.unlock="déverrouiller"
|
||||
AdvSceneSwitcher.action.sceneLock.type.toggle="basculer le verrouillage de"
|
||||
AdvSceneSwitcher.action.sceneLock.entry="Sur{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.twitch="Twitch"
|
||||
AdvSceneSwitcher.action.twitch.type.title="Définir le titre du flux"
|
||||
AdvSceneSwitcher.action.twitch.type.category="Définir la catégorie du flux"
|
||||
AdvSceneSwitcher.action.twitch.type.commercial="Démarrer une publicité d'une durée de"
|
||||
AdvSceneSwitcher.action.twitch.type.channel.info.title.set="Définir le titre du flux"
|
||||
AdvSceneSwitcher.action.twitch.type.channel.info.category.set="Définir la catégorie du flux"
|
||||
AdvSceneSwitcher.action.twitch.type.commercial.start="Démarrer une publicité d'une durée de"
|
||||
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Impossible de sélectionner une catégorie sans avoir d'abord sélectionné un compte Twitch !"
|
||||
AdvSceneSwitcher.action.twitch.entry.line1="Sur{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}"
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ void MacroActionWebsocketEdit::CheckForSettingsConflict()
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionWebsocketEdit::SetupWidgetVisibility()
|
||||
void MacroActionWebsocketEdit::SetWidgetVisibility()
|
||||
{
|
||||
_messageType->setVisible(_entryData->_api ==
|
||||
MacroActionWebsocket::API::SCENE_SWITCHER);
|
||||
@@ -283,7 +283,7 @@ void MacroActionWebsocketEdit::UpdateEntryData()
|
||||
_message->setPlainText(_entryData->_message);
|
||||
_connection->SetConnection(_entryData->_connection);
|
||||
|
||||
SetupWidgetVisibility();
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionWebsocketEdit::APITypeChanged(int index)
|
||||
@@ -294,7 +294,7 @@ void MacroActionWebsocketEdit::APITypeChanged(int index)
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_api = static_cast<MacroActionWebsocket::API>(index);
|
||||
SetupWidgetVisibility();
|
||||
SetWidgetVisibility();
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
@@ -308,7 +308,7 @@ void MacroActionWebsocketEdit::MessageTypeChanged(int index)
|
||||
auto lock = LockContext();
|
||||
_entryData->_type =
|
||||
static_cast<MacroActionWebsocket::MessageType>(index);
|
||||
SetupWidgetVisibility();
|
||||
SetWidgetVisibility();
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ protected:
|
||||
|
||||
private:
|
||||
void CheckForSettingsConflict();
|
||||
void SetupWidgetVisibility();
|
||||
void SetWidgetVisibility();
|
||||
void SetupRequestEdit();
|
||||
void SetupEventEdit();
|
||||
void SetupGenericEdit();
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "macro-condition-recording.hpp"
|
||||
#include "macro.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
namespace advss {
|
||||
@@ -11,91 +10,45 @@ bool MacroConditionRecord::_registered = MacroConditionFactory::Register(
|
||||
{MacroConditionRecord::Create, MacroConditionRecordEdit::Create,
|
||||
"AdvSceneSwitcher.condition.record"});
|
||||
|
||||
const static std::map<MacroConditionRecord::Condition, std::string>
|
||||
recordStates = {
|
||||
{MacroConditionRecord::Condition::STOP,
|
||||
"AdvSceneSwitcher.condition.record.state.stop"},
|
||||
{MacroConditionRecord::Condition::PAUSE,
|
||||
"AdvSceneSwitcher.condition.record.state.pause"},
|
||||
{MacroConditionRecord::Condition::START,
|
||||
"AdvSceneSwitcher.condition.record.state.start"},
|
||||
{MacroConditionRecord::Condition::SAVE_DONE,
|
||||
"AdvSceneSwitcher.condition.record.state.saveDone"},
|
||||
const static std::map<RecordState, std::string> recordStates = {
|
||||
{RecordState::STOP, "AdvSceneSwitcher.condition.record.state.stop"},
|
||||
{RecordState::PAUSE, "AdvSceneSwitcher.condition.record.state.pause"},
|
||||
{RecordState::START, "AdvSceneSwitcher.condition.record.state.start"},
|
||||
};
|
||||
|
||||
MacroConditionRecord::MacroConditionRecord(Macro *m) : MacroCondition(m)
|
||||
{
|
||||
OBSOutputAutoRelease output = obs_frontend_get_recording_output();
|
||||
if (!output) {
|
||||
return;
|
||||
}
|
||||
auto sh = obs_output_get_signal_handler(output);
|
||||
signal_handler_connect(sh, "stop", StopSignal, this);
|
||||
}
|
||||
|
||||
MacroConditionRecord::~MacroConditionRecord()
|
||||
{
|
||||
OBSOutputAutoRelease output = obs_frontend_get_recording_output();
|
||||
if (!output) {
|
||||
return;
|
||||
}
|
||||
auto sh = obs_output_get_signal_handler(output);
|
||||
signal_handler_disconnect(sh, "stop", StopSignal, this);
|
||||
}
|
||||
|
||||
bool MacroConditionRecord::CheckCondition()
|
||||
{
|
||||
switch (_condition) {
|
||||
case Condition::STOP:
|
||||
return !obs_frontend_recording_active();
|
||||
case Condition::PAUSE:
|
||||
return obs_frontend_recording_paused();
|
||||
case Condition::START:
|
||||
return obs_frontend_recording_active();
|
||||
case Condition::SAVE_DONE:
|
||||
if (_recordingSaveDone) {
|
||||
_recordingSaveDone = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
bool stateMatch = false;
|
||||
switch (_recordState) {
|
||||
case RecordState::STOP:
|
||||
stateMatch = !obs_frontend_recording_active();
|
||||
break;
|
||||
case RecordState::PAUSE:
|
||||
stateMatch = obs_frontend_recording_paused();
|
||||
break;
|
||||
case RecordState::START:
|
||||
stateMatch = obs_frontend_recording_active();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
return stateMatch;
|
||||
}
|
||||
|
||||
bool MacroConditionRecord::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
obs_data_set_int(obj, "state", static_cast<int>(_condition));
|
||||
obs_data_set_int(obj, "state", static_cast<int>(_recordState));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroConditionRecord::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_condition = static_cast<Condition>(obs_data_get_int(obj, "state"));
|
||||
_recordState = static_cast<RecordState>(obs_data_get_int(obj, "state"));
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacroConditionRecord::StopSignal(void *c, calldata_t *data)
|
||||
{
|
||||
auto condition = static_cast<MacroConditionRecord *>(c);
|
||||
const auto macro = condition->GetMacro();
|
||||
if (macro && macro->Paused()) {
|
||||
return;
|
||||
}
|
||||
|
||||
long long code = 0;
|
||||
if (!calldata_get_int(data, "code", &code)) {
|
||||
condition->_recordingSaveDone = false;
|
||||
}
|
||||
|
||||
if (code == OBS_OUTPUT_SUCCESS) {
|
||||
condition->_recordingSaveDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void populateStateSelection(QComboBox *list)
|
||||
{
|
||||
for (auto entry : recordStates) {
|
||||
@@ -136,8 +89,7 @@ void MacroConditionRecordEdit::StateChanged(int value)
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_condition =
|
||||
static_cast<MacroConditionRecord::Condition>(value);
|
||||
_entryData->_recordState = static_cast<RecordState>(value);
|
||||
}
|
||||
|
||||
void MacroConditionRecordEdit::UpdateEntryData()
|
||||
@@ -146,7 +98,8 @@ void MacroConditionRecordEdit::UpdateEntryData()
|
||||
return;
|
||||
}
|
||||
|
||||
_recordState->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
||||
_recordState->setCurrentIndex(
|
||||
static_cast<int>(_entryData->_recordState));
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -6,10 +6,15 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
enum class RecordState {
|
||||
STOP,
|
||||
PAUSE,
|
||||
START,
|
||||
};
|
||||
|
||||
class MacroConditionRecord : public MacroCondition {
|
||||
public:
|
||||
MacroConditionRecord(Macro *m);
|
||||
~MacroConditionRecord();
|
||||
MacroConditionRecord(Macro *m) : MacroCondition(m) {}
|
||||
bool CheckCondition();
|
||||
bool Save(obs_data_t *obj) const;
|
||||
bool Load(obs_data_t *obj);
|
||||
@@ -19,18 +24,9 @@ public:
|
||||
return std::make_shared<MacroConditionRecord>(m);
|
||||
}
|
||||
|
||||
enum class Condition {
|
||||
STOP,
|
||||
PAUSE,
|
||||
START,
|
||||
SAVE_DONE,
|
||||
};
|
||||
Condition _condition = Condition::STOP;
|
||||
RecordState _recordState = RecordState::STOP;
|
||||
|
||||
private:
|
||||
static void StopSignal(void *condition, calldata_t *);
|
||||
bool _recordingSaveDone = false;
|
||||
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
|
||||
@@ -19,8 +19,7 @@ bool MacroConditionMidi::CheckCondition()
|
||||
|
||||
for (const auto &m : *messages) {
|
||||
if (m.Matches(_message)) {
|
||||
SetVariableValue(std::to_string(m.Note()) + " " +
|
||||
std::to_string(m.Value()));
|
||||
SetVariableValues(m);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -49,6 +48,36 @@ std::string MacroConditionMidi::GetShortDesc() const
|
||||
return _device.Name();
|
||||
}
|
||||
|
||||
void MacroConditionMidi::SetupTempVars()
|
||||
{
|
||||
MacroCondition::SetupTempVars();
|
||||
AddTempvar("type",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.midi.type"));
|
||||
AddTempvar("channel",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.midi.channel"));
|
||||
AddTempvar("note",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.midi.note"));
|
||||
AddTempvar("value1",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.midi.value1"));
|
||||
AddTempvar("value2",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.midi.value2"));
|
||||
}
|
||||
|
||||
void MacroConditionMidi::SetVariableValues(const MidiMessage &m)
|
||||
{
|
||||
SetVariableValue(std::to_string(m.Note()) + " " +
|
||||
std::to_string(m.Value()));
|
||||
SetTempVarValue("type", m.MidiTypeToString(m.Type()));
|
||||
SetTempVarValue("channel", std::to_string(m.Channel()));
|
||||
try {
|
||||
SetTempVarValue("note",
|
||||
GetAllNotes().at(m.Note()).toStdString());
|
||||
} catch (...) {
|
||||
}
|
||||
SetTempVarValue("value1", std::to_string(m.Note()));
|
||||
SetTempVarValue("value2", std::to_string(m.Value()));
|
||||
}
|
||||
|
||||
MacroConditionMidiEdit::MacroConditionMidiEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionMidi> entryData)
|
||||
: QWidget(parent),
|
||||
|
||||
@@ -24,6 +24,9 @@ public:
|
||||
MidiMessage _message;
|
||||
|
||||
private:
|
||||
void SetupTempVars();
|
||||
void SetVariableValues(const MidiMessage &);
|
||||
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
|
||||
@@ -190,7 +190,7 @@ void CategoryGrabber::Search(const std::string &)
|
||||
std::string cursor;
|
||||
httplib::Params params = {
|
||||
{"first", "100"}, {"after", cursor}, {"query", _searchString}};
|
||||
auto response = SendGetRequest(uri, path, *_token, params);
|
||||
auto response = SendGetRequest(*_token, uri, path, params);
|
||||
|
||||
while (response.status == 200 && !_stop) {
|
||||
cursor = ParseReply(response.data);
|
||||
@@ -200,7 +200,7 @@ void CategoryGrabber::Search(const std::string &)
|
||||
params = {{"first", "100"},
|
||||
{"after", cursor},
|
||||
{"query", _searchString}};
|
||||
response = SendGetRequest(uri, path, *_token, params);
|
||||
response = SendGetRequest(*_token, uri, path, params);
|
||||
emit CategoryCountUpdated(_categoryMap.size() - startCount);
|
||||
}
|
||||
}
|
||||
@@ -214,7 +214,7 @@ void CategoryGrabber::GetAll()
|
||||
static std::string cursor;
|
||||
|
||||
httplib::Params params = {{"first", "100"}, {"after", cursor}};
|
||||
auto response = SendGetRequest(uri, path, *_token, params);
|
||||
auto response = SendGetRequest(*_token, uri, path, params);
|
||||
|
||||
while (response.status == 200 && !_stop) {
|
||||
cursor = ParseReply(response.data);
|
||||
@@ -222,7 +222,7 @@ void CategoryGrabber::GetAll()
|
||||
break; // End of category list
|
||||
}
|
||||
params = {{"first", "100"}, {"after", cursor}};
|
||||
response = SendGetRequest(uri, path, *_token, params);
|
||||
response = SendGetRequest(*_token, uri, path, params);
|
||||
emit CategoryCountUpdated(_categoryMap.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ std::string TwitchChannel::GetUserID(const TwitchToken &token) const
|
||||
return it->second;
|
||||
}
|
||||
|
||||
auto res = SendGetRequest("https://api.twitch.tv", "/helix/users",
|
||||
token, {{"login", _name}});
|
||||
auto res = SendGetRequest(token, "https://api.twitch.tv",
|
||||
"/helix/users", {{"login", _name}});
|
||||
|
||||
if (res.status == 400) {
|
||||
userIDCache[_name] = "invalid";
|
||||
@@ -112,8 +112,8 @@ TwitchChannel::GetLiveInfo(const TwitchToken &token)
|
||||
|
||||
httplib::Params params = {
|
||||
{"first", "1"}, {"after", ""}, {"user_id", id}};
|
||||
auto result = SendGetRequest("https://api.twitch.tv", "/helix/streams",
|
||||
token, params, true);
|
||||
auto result = SendGetRequest(token, "https://api.twitch.tv",
|
||||
"/helix/streams", params, true);
|
||||
if (result.status != 200) {
|
||||
return {};
|
||||
}
|
||||
@@ -153,8 +153,8 @@ std::optional<ChannelInfo> TwitchChannel::GetInfo(const TwitchToken &token)
|
||||
|
||||
httplib::Params params = {
|
||||
{"first", "1"}, {"after", ""}, {"broadcaster_id", id}};
|
||||
auto result = SendGetRequest("https://api.twitch.tv", "/helix/channels",
|
||||
token, params, true);
|
||||
auto result = SendGetRequest(token, "https://api.twitch.tv",
|
||||
"/helix/channels", params, true);
|
||||
if (result.status != 200) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -432,8 +432,8 @@ void TwitchChatConnection::ConnectThread()
|
||||
_client.reset();
|
||||
_connected = true;
|
||||
websocketpp::lib::error_code ec;
|
||||
EventSubWSClient::connection_ptr con =
|
||||
_client.get_connection(_url, ec);
|
||||
websocketpp::client<websocketpp::config::asio_tls_client>::
|
||||
connection_ptr con = _client.get_connection(_url, ec);
|
||||
if (ec) {
|
||||
blog(LOG_INFO, "Twitch TwitchChatConnection failed: %s",
|
||||
ec.message().c_str());
|
||||
@@ -634,8 +634,10 @@ void TwitchChatConnection::OnOpen(connection_hdl)
|
||||
Authenticate();
|
||||
}
|
||||
|
||||
void TwitchChatConnection::OnMessage(connection_hdl,
|
||||
EventSubWSClient::message_ptr message)
|
||||
void TwitchChatConnection::OnMessage(
|
||||
connection_hdl,
|
||||
websocketpp::client<websocketpp::config::asio_tls_client>::message_ptr
|
||||
message)
|
||||
{
|
||||
constexpr std::string_view authOKCommand = "001";
|
||||
constexpr std::string_view pingCommand = "PING";
|
||||
@@ -679,7 +681,8 @@ void TwitchChatConnection::OnMessage(connection_hdl,
|
||||
|
||||
void TwitchChatConnection::OnClose(connection_hdl hdl)
|
||||
{
|
||||
EventSubWSClient::connection_ptr con = _client.get_con_from_hdl(hdl);
|
||||
websocketpp::client<websocketpp::config::asio_tls_client>::connection_ptr
|
||||
con = _client.get_con_from_hdl(hdl);
|
||||
auto msg = con->get_ec().message();
|
||||
blog(LOG_INFO, "Twitch chat connection closed: %s", msg.c_str());
|
||||
_connected = false;
|
||||
@@ -687,7 +690,8 @@ void TwitchChatConnection::OnClose(connection_hdl hdl)
|
||||
|
||||
void TwitchChatConnection::OnFail(connection_hdl hdl)
|
||||
{
|
||||
EventSubWSClient::connection_ptr con = _client.get_con_from_hdl(hdl);
|
||||
websocketpp::client<websocketpp::config::asio_tls_client>::connection_ptr
|
||||
con = _client.get_con_from_hdl(hdl);
|
||||
auto msg = con->get_ec().message();
|
||||
blog(LOG_INFO, "Twitch chat connection failed: %s", msg.c_str());
|
||||
_connected = false;
|
||||
|
||||
@@ -230,14 +230,16 @@ std::string EventSub::AddEventSubscribtion(std::shared_ptr<TwitchToken> token,
|
||||
|
||||
OBSDataAutoRelease postData = copyData(subscription.data);
|
||||
setTransportData(postData.Get(), eventSub->_sessionID);
|
||||
auto result = SendPostRequest(registerSubscriptionURL.data(),
|
||||
registerSubscriptionPath.data(), *token,
|
||||
auto result = SendPostRequest(*token, registerSubscriptionURL.data(),
|
||||
registerSubscriptionPath.data(), {},
|
||||
postData.Get());
|
||||
|
||||
if (result.status != 202) {
|
||||
vblog(LOG_INFO, "failed to register Twitch EventSub (%d)",
|
||||
result.status);
|
||||
return "";
|
||||
}
|
||||
|
||||
OBSDataArrayAutoRelease replyArray =
|
||||
obs_data_get_array(result.data, "data");
|
||||
OBSDataAutoRelease replyData = obs_data_array_item(replyArray, 0);
|
||||
|
||||
@@ -19,24 +19,24 @@ std::string MacroActionTwitch::GetShortDesc() const
|
||||
}
|
||||
|
||||
const static std::map<MacroActionTwitch::Action, std::string> actionTypes = {
|
||||
{MacroActionTwitch::Action::TITLE,
|
||||
"AdvSceneSwitcher.action.twitch.type.title"},
|
||||
{MacroActionTwitch::Action::CATEGORY,
|
||||
"AdvSceneSwitcher.action.twitch.type.category"},
|
||||
{MacroActionTwitch::Action::MARKER,
|
||||
"AdvSceneSwitcher.action.twitch.type.marker"},
|
||||
{MacroActionTwitch::Action::CLIP,
|
||||
"AdvSceneSwitcher.action.twitch.type.clip"},
|
||||
{MacroActionTwitch::Action::COMMERCIAL,
|
||||
"AdvSceneSwitcher.action.twitch.type.commercial"},
|
||||
{MacroActionTwitch::Action::ANNOUNCEMENT,
|
||||
"AdvSceneSwitcher.action.twitch.type.announcement"},
|
||||
{MacroActionTwitch::Action::ENABLE_EMOTE_ONLY,
|
||||
"AdvSceneSwitcher.action.twitch.type.emoteOnlyEnable"},
|
||||
{MacroActionTwitch::Action::DISABLE_EMOTE_ONLY,
|
||||
"AdvSceneSwitcher.action.twitch.type.emoteOnlyDisable"},
|
||||
{MacroActionTwitch::Action::RAID,
|
||||
"AdvSceneSwitcher.action.twitch.type.raid"},
|
||||
{MacroActionTwitch::Action::CHANNEL_INFO_TITLE_SET,
|
||||
"AdvSceneSwitcher.action.twitch.type.channel.info.title.set"},
|
||||
{MacroActionTwitch::Action::CHANNEL_INFO_CATEGORY_SET,
|
||||
"AdvSceneSwitcher.action.twitch.type.channel.info.category.set"},
|
||||
{MacroActionTwitch::Action::RAID_START,
|
||||
"AdvSceneSwitcher.action.twitch.type.raid.start"},
|
||||
{MacroActionTwitch::Action::COMMERCIAL_START,
|
||||
"AdvSceneSwitcher.action.twitch.type.commercial.start"},
|
||||
{MacroActionTwitch::Action::MARKER_CREATE,
|
||||
"AdvSceneSwitcher.action.twitch.type.marker.create"},
|
||||
{MacroActionTwitch::Action::CLIP_CREATE,
|
||||
"AdvSceneSwitcher.action.twitch.type.clip.create"},
|
||||
{MacroActionTwitch::Action::CHAT_ANNOUNCEMENT_SEND,
|
||||
"AdvSceneSwitcher.action.twitch.type.chat.announcement.send"},
|
||||
{MacroActionTwitch::Action::CHAT_EMOTE_ONLY_ENABLE,
|
||||
"AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.enable"},
|
||||
{MacroActionTwitch::Action::CHAT_EMOTE_ONLY_DISABLE,
|
||||
"AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.disable"},
|
||||
{MacroActionTwitch::Action::SEND_CHAT_MESSAGE,
|
||||
"AdvSceneSwitcher.action.twitch.type.sendChatMessage"},
|
||||
};
|
||||
@@ -64,6 +64,12 @@ const static std::map<MacroActionTwitch::AnnouncementColor, std::string>
|
||||
{MacroActionTwitch::AnnouncementColor::PURPLE, "purple"},
|
||||
};
|
||||
|
||||
const static std::map<MacroActionTwitch::RedemptionStatus, std::string>
|
||||
redemptionStatusesTwitch = {
|
||||
{MacroActionTwitch::RedemptionStatus::CANCELED, "CANCELED"},
|
||||
{MacroActionTwitch::RedemptionStatus::FULFILLED, "FULFILLED"},
|
||||
};
|
||||
|
||||
void MacroActionTwitch::SetStreamTitle(
|
||||
const std::shared_ptr<TwitchToken> &token) const
|
||||
{
|
||||
@@ -73,11 +79,10 @@ void MacroActionTwitch::SetStreamTitle(
|
||||
|
||||
OBSDataAutoRelease data = obs_data_create();
|
||||
obs_data_set_string(data, "title", _streamTitle.c_str());
|
||||
auto result = SendPatchRequest(
|
||||
"https://api.twitch.tv",
|
||||
std::string("/helix/channels?broadcaster_id=") +
|
||||
token->GetUserID(),
|
||||
*token, data.Get());
|
||||
auto result = SendPatchRequest(*token, "https://api.twitch.tv",
|
||||
"/helix/channels",
|
||||
{{"broadcaster_id", token->GetUserID()}},
|
||||
data.Get());
|
||||
|
||||
if (result.status != 204) {
|
||||
blog(LOG_INFO, "Failed to set stream title! (%d)",
|
||||
@@ -95,11 +100,11 @@ void MacroActionTwitch::SetStreamCategory(
|
||||
OBSDataAutoRelease data = obs_data_create();
|
||||
obs_data_set_string(data, "game_id",
|
||||
std::to_string(_category.id).c_str());
|
||||
auto result = SendPatchRequest(
|
||||
"https://api.twitch.tv",
|
||||
std::string("/helix/channels?broadcaster_id=") +
|
||||
token->GetUserID(),
|
||||
*token, data.Get());
|
||||
auto result = SendPatchRequest(*token, "https://api.twitch.tv",
|
||||
"/helix/channels",
|
||||
{{"broadcaster_id", token->GetUserID()}},
|
||||
data.Get());
|
||||
|
||||
if (result.status != 204) {
|
||||
blog(LOG_INFO, "Failed to set stream category! (%d)",
|
||||
result.status);
|
||||
@@ -117,9 +122,8 @@ void MacroActionTwitch::CreateStreamMarker(
|
||||
_markerDescription.c_str());
|
||||
}
|
||||
|
||||
auto result = SendPostRequest("https://api.twitch.tv",
|
||||
"/helix/streams/markers", *token,
|
||||
data.Get());
|
||||
auto result = SendPostRequest(*token, "https://api.twitch.tv",
|
||||
"/helix/streams/markers", {}, data.Get());
|
||||
|
||||
if (result.status != 200) {
|
||||
blog(LOG_INFO, "Failed to create marker! (%d)", result.status);
|
||||
@@ -129,14 +133,12 @@ void MacroActionTwitch::CreateStreamMarker(
|
||||
void MacroActionTwitch::CreateStreamClip(
|
||||
const std::shared_ptr<TwitchToken> &token) const
|
||||
{
|
||||
OBSDataAutoRelease data = obs_data_create();
|
||||
auto hasDelay = _clipHasDelay ? "true" : "false";
|
||||
|
||||
auto result = SendPostRequest(
|
||||
"https://api.twitch.tv",
|
||||
"/helix/clips?broadcaster_id=" + token->GetUserID() +
|
||||
"&has_delay=" + hasDelay,
|
||||
*token, data.Get());
|
||||
auto result = SendPostRequest(*token, "https://api.twitch.tv",
|
||||
"/helix/clips",
|
||||
{{"broadcaster_id", token->GetUserID()},
|
||||
{"has_delay", hasDelay}});
|
||||
|
||||
if (result.status != 202) {
|
||||
blog(LOG_INFO, "Failed to create clip! (%d)", result.status);
|
||||
@@ -149,9 +151,10 @@ void MacroActionTwitch::StartCommercial(
|
||||
OBSDataAutoRelease data = obs_data_create();
|
||||
obs_data_set_string(data, "broadcaster_id", token->GetUserID().c_str());
|
||||
obs_data_set_int(data, "length", _duration.Seconds());
|
||||
auto result = SendPostRequest("https://api.twitch.tv",
|
||||
"/helix/channels/commercial", *token,
|
||||
auto result = SendPostRequest(*token, "https://api.twitch.tv",
|
||||
"/helix/channels/commercial", {},
|
||||
data.Get());
|
||||
|
||||
if (result.status != 200) {
|
||||
OBSDataArrayAutoRelease replyArray =
|
||||
obs_data_get_array(result.data, "data");
|
||||
@@ -178,11 +181,10 @@ void MacroActionTwitch::SendChatAnnouncement(
|
||||
announcementColorsTwitch.at(_announcementColor).c_str());
|
||||
auto userId = token->GetUserID();
|
||||
|
||||
auto result =
|
||||
SendPostRequest("https://api.twitch.tv",
|
||||
"/helix/chat/announcements?broadcaster_id=" +
|
||||
userId + "&moderator_id=" + userId,
|
||||
*token, data.Get());
|
||||
auto result = SendPostRequest(
|
||||
*token, "https://api.twitch.tv", "/helix/chat/announcements",
|
||||
{{"broadcaster_id", userId}, {"moderator_id", userId}},
|
||||
data.Get());
|
||||
|
||||
if (result.status != 204) {
|
||||
blog(LOG_INFO, "Failed to send chat announcement! (%d)",
|
||||
@@ -197,11 +199,10 @@ void MacroActionTwitch::SetChatEmoteOnlyMode(
|
||||
obs_data_set_bool(data, "emote_mode", enable);
|
||||
auto userId = token->GetUserID();
|
||||
|
||||
auto result =
|
||||
SendPatchRequest("https://api.twitch.tv",
|
||||
"/helix/chat/settings?broadcaster_id=" +
|
||||
userId + "&moderator_id=" + userId,
|
||||
*token, data.Get());
|
||||
auto result = SendPatchRequest(
|
||||
*token, "https://api.twitch.tv", "/helix/chat/settings",
|
||||
{{"broadcaster_id", userId}, {"moderator_id", userId}},
|
||||
data.Get());
|
||||
|
||||
if (result.status != 200) {
|
||||
blog(LOG_INFO, "Failed to %s chat's emote-only mode! (%d)",
|
||||
@@ -216,8 +217,9 @@ void MacroActionTwitch::StartRaid(const std::shared_ptr<TwitchToken> &token)
|
||||
token->GetUserID().c_str());
|
||||
obs_data_set_string(data, "to_broadcaster_id",
|
||||
_channel.GetUserID(*token).c_str());
|
||||
auto result = SendPostRequest("https://api.twitch.tv", "/helix/raids",
|
||||
*token, data.Get());
|
||||
auto result = SendPostRequest(*token, "https://api.twitch.tv",
|
||||
"/helix/raids", {}, data.Get());
|
||||
|
||||
if (result.status != 200) {
|
||||
blog(LOG_INFO, "Failed to start raid! (%d)\n", result.status);
|
||||
}
|
||||
@@ -243,33 +245,32 @@ bool MacroActionTwitch::PerformAction()
|
||||
}
|
||||
|
||||
switch (_action) {
|
||||
case MacroActionTwitch::Action::TITLE:
|
||||
case Action::CHANNEL_INFO_TITLE_SET:
|
||||
SetStreamTitle(token);
|
||||
break;
|
||||
case MacroActionTwitch::Action::CATEGORY:
|
||||
case Action::CHANNEL_INFO_CATEGORY_SET:
|
||||
SetStreamCategory(token);
|
||||
break;
|
||||
case MacroActionTwitch::Action::MARKER:
|
||||
CreateStreamMarker(token);
|
||||
break;
|
||||
case MacroActionTwitch::Action::CLIP:
|
||||
CreateStreamClip(token);
|
||||
break;
|
||||
case MacroActionTwitch::Action::COMMERCIAL:
|
||||
StartCommercial(token);
|
||||
break;
|
||||
case MacroActionTwitch::Action::ANNOUNCEMENT:
|
||||
SendChatAnnouncement(token);
|
||||
break;
|
||||
case MacroActionTwitch::Action::ENABLE_EMOTE_ONLY:
|
||||
SetChatEmoteOnlyMode(token, true);
|
||||
break;
|
||||
case MacroActionTwitch::Action::DISABLE_EMOTE_ONLY:
|
||||
SetChatEmoteOnlyMode(token, false);
|
||||
break;
|
||||
case MacroActionTwitch::Action::RAID:
|
||||
case Action::RAID_START:
|
||||
StartRaid(token);
|
||||
break;
|
||||
case Action::COMMERCIAL_START:
|
||||
StartCommercial(token);
|
||||
break;
|
||||
case Action::MARKER_CREATE:
|
||||
CreateStreamMarker(token);
|
||||
break;
|
||||
case Action::CLIP_CREATE:
|
||||
CreateStreamClip(token);
|
||||
break;
|
||||
case Action::CHAT_ANNOUNCEMENT_SEND:
|
||||
SendChatAnnouncement(token);
|
||||
break;
|
||||
case Action::CHAT_EMOTE_ONLY_ENABLE:
|
||||
SetChatEmoteOnlyMode(token, true);
|
||||
break;
|
||||
case Action::CHAT_EMOTE_ONLY_DISABLE:
|
||||
SetChatEmoteOnlyMode(token, false);
|
||||
case MacroActionTwitch::Action::SEND_CHAT_MESSAGE:
|
||||
SendChatMessage(token);
|
||||
break;
|
||||
@@ -338,27 +339,111 @@ bool MacroActionTwitch::Load(obs_data_t *obj)
|
||||
bool MacroActionTwitch::ActionIsSupportedByToken()
|
||||
{
|
||||
static const std::unordered_map<Action, TokenOption> requiredOption = {
|
||||
{Action::TITLE, {"channel:manage:broadcast"}},
|
||||
{Action::CATEGORY, {"channel:manage:broadcast"}},
|
||||
{Action::MARKER, {"channel:manage:broadcast"}},
|
||||
{Action::CLIP, {"clips:edit"}},
|
||||
{Action::COMMERCIAL, {"channel:edit:commercial"}},
|
||||
{Action::ANNOUNCEMENT, {"moderator:manage:announcements"}},
|
||||
{Action::ENABLE_EMOTE_ONLY, {"moderator:manage:chat_settings"}},
|
||||
{Action::DISABLE_EMOTE_ONLY,
|
||||
{Action::CHANNEL_INFO_TITLE_SET, {"channel:manage:broadcast"}},
|
||||
{Action::CHANNEL_INFO_CATEGORY_SET,
|
||||
{"channel:manage:broadcast"}},
|
||||
{Action::CHANNEL_INFO_LANGUAGE_SET,
|
||||
{"channel:manage:broadcast"}},
|
||||
{Action::CHANNEL_INFO_DELAY_SET, {"channel:manage:broadcast"}},
|
||||
{Action::CHANNEL_INFO_BRANDED_CONTENT_ENABLE,
|
||||
{"channel:manage:broadcast"}},
|
||||
{Action::CHANNEL_INFO_BRANDED_CONTENT_DISABLE,
|
||||
{"channel:manage:broadcast"}},
|
||||
{Action::RAID_START, {"channel:manage:raids"}},
|
||||
{Action::RAID_END, {"channel:manage:raids"}},
|
||||
{Action::SHOUTOUT_SEND, {"moderator:manage:shoutouts"}},
|
||||
{Action::POLL_END, {"channel:manage:polls"}},
|
||||
{Action::PREDICTION_END, {"channel:manage:predictions"}},
|
||||
{Action::SHIELD_MODE_START, {"moderator:manage:shield_mode"}},
|
||||
{Action::SHIELD_MODE_END, {"moderator:manage:shield_mode"}},
|
||||
{Action::POINTS_REWARD_ENABLE, {"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_DISABLE, {"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_PAUSE, {"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_UNPAUSE, {"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_TITLE_SET,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_PROMPT_SET,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_COST_SET,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_USER_INPUT_REQUIRE,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_USER_INPUT_UNREQUIRE,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_COOLDOWN_ENABLE,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_COOLDOWN_DISABLE,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_QUEUE_SKIP_ENABLE,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_QUEUE_SKIP_DISABLE,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_MAX_PER_STREAM_ENABLE,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_MAX_PER_STREAM_DISABLE,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_MAX_PER_USER_ENABLE,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_MAX_PER_USER_DISABLE,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_DELETE, {"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_REDEMPTION_CANCEL,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::POINTS_REWARD_REDEMPTION_FULFILL,
|
||||
{"channel:manage:redemptions"}},
|
||||
{Action::USER_BAN, {"moderator:manage:banned_users"}},
|
||||
{Action::USER_UNBAN, {"moderator:manage:banned_users"}},
|
||||
{Action::USER_BLOCK, {"user:manage:blocked_users"}},
|
||||
{Action::USER_UNBLOCK, {"user:manage:blocked_users"}},
|
||||
{Action::USER_MODERATOR_ADD, {"channel:manage:moderators"}},
|
||||
{Action::USER_MODERATOR_DELETE, {"channel:manage:moderators"}},
|
||||
{Action::USER_VIP_ADD, {"channel:manage:vips"}},
|
||||
{Action::USER_VIP_DELETE, {"channel:manage:vips"}},
|
||||
{Action::COMMERCIAL_START, {"channel:edit:commercial"}},
|
||||
{Action::COMMERCIAL_SNOOZE, {"channel:manage:ads"}},
|
||||
{Action::MARKER_CREATE, {"channel:manage:broadcast"}},
|
||||
{Action::CLIP_CREATE, {"clips:edit"}},
|
||||
{Action::CHAT_ANNOUNCEMENT_SEND,
|
||||
{"moderator:manage:announcements"}},
|
||||
{Action::CHAT_EMOTE_ONLY_ENABLE,
|
||||
{"moderator:manage:chat_settings"}},
|
||||
{Action::RAID, {"channel:manage:raids"}},
|
||||
{Action::CHAT_EMOTE_ONLY_DISABLE,
|
||||
{"moderator:manage:chat_settings"}},
|
||||
{Action::CHAT_FOLLOWER_ONLY_ENABLE,
|
||||
{"moderator:manage:chat_settings"}},
|
||||
{Action::CHAT_FOLLOWER_ONLY_DISABLE,
|
||||
{"moderator:manage:chat_settings"}},
|
||||
{Action::CHAT_SUBSCRIBER_ONLY_ENABLE,
|
||||
{"moderator:manage:chat_settings"}},
|
||||
{Action::CHAT_SUBSCRIBER_ONLY_DISABLE,
|
||||
{"moderator:manage:chat_settings"}},
|
||||
{Action::CHAT_SLOW_MODE_ENABLE,
|
||||
{"moderator:manage:chat_settings"}},
|
||||
{Action::CHAT_SLOW_MODE_DISABLE,
|
||||
{"moderator:manage:chat_settings"}},
|
||||
{Action::CHAT_NON_MODERATOR_DELAY_ENABLE,
|
||||
{"moderator:manage:chat_settings"}},
|
||||
{Action::CHAT_NON_MODERATOR_DELAY_DISABLE,
|
||||
{"moderator:manage:chat_settings"}},
|
||||
{Action::CHAT_UNIQUE_MODE_ENABLE,
|
||||
{"moderator:manage:chat_settings"}},
|
||||
{Action::CHAT_UNIQUE_MODE_DISABLE,
|
||||
{"moderator:manage:chat_settings"}},
|
||||
{Action::WHISPER_SEND, {"user:manage:whispers"}},
|
||||
{Action::SEND_CHAT_MESSAGE, {"chat:edit"}},
|
||||
};
|
||||
|
||||
auto token = _token.lock();
|
||||
if (!token) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto option = requiredOption.find(_action);
|
||||
assert(option != requiredOption.end());
|
||||
if (option == requiredOption.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return token->OptionIsEnabled(option->second);
|
||||
}
|
||||
|
||||
@@ -401,49 +486,8 @@ MacroActionTwitchEdit::MacroActionTwitchEdit(
|
||||
_channel(new TwitchChannelSelection(this)),
|
||||
_chatMessage(new VariableTextEdit(this))
|
||||
{
|
||||
_streamTitle->setSizePolicy(QSizePolicy::MinimumExpanding,
|
||||
QSizePolicy::Preferred);
|
||||
_streamTitle->setMaxLength(140);
|
||||
_markerDescription->setSizePolicy(QSizePolicy::MinimumExpanding,
|
||||
QSizePolicy::Preferred);
|
||||
_markerDescription->setMaxLength(140);
|
||||
_announcementMessage->setSizePolicy(QSizePolicy::MinimumExpanding,
|
||||
QSizePolicy::Preferred);
|
||||
_announcementMessage->setMaxLength(500);
|
||||
|
||||
auto spinBox = _duration->SpinBox();
|
||||
spinBox->setSuffix("s");
|
||||
spinBox->setMaximum(180);
|
||||
|
||||
populateActionSelection(_actions);
|
||||
populateAnnouncementColorSelection(_announcementColor);
|
||||
|
||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionChanged(int)));
|
||||
QWidget::connect(_tokens, SIGNAL(SelectionChanged(const QString &)),
|
||||
this, SLOT(TwitchTokenChanged(const QString &)));
|
||||
QWidget::connect(&_tokenPermissionCheckTimer, SIGNAL(timeout()), this,
|
||||
SLOT(CheckTokenPermissions()));
|
||||
QWidget::connect(_streamTitle, SIGNAL(editingFinished()), this,
|
||||
SLOT(StreamTitleChanged()));
|
||||
QWidget::connect(_category,
|
||||
SIGNAL(CategoreyChanged(const TwitchCategory &)), this,
|
||||
SLOT(CategoreyChanged(const TwitchCategory &)));
|
||||
QWidget::connect(_markerDescription, SIGNAL(editingFinished()), this,
|
||||
SLOT(MarkerDescriptionChanged()));
|
||||
QObject::connect(_clipHasDelay, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(ClipHasDelayChanged(int)));
|
||||
QObject::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(_announcementMessage, SIGNAL(textChanged()), this,
|
||||
SLOT(AnnouncementMessageChanged()));
|
||||
QWidget::connect(_announcementColor, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(AnnouncementColorChanged(int)));
|
||||
QWidget::connect(_channel,
|
||||
SIGNAL(ChannelChanged(const TwitchChannel &)), this,
|
||||
SLOT(ChannelChanged(const TwitchChannel &)));
|
||||
QWidget::connect(_chatMessage, SIGNAL(textChanged()), this,
|
||||
SLOT(ChatMessageChanged()));
|
||||
SetWidgetProperties();
|
||||
SetWidgetSignalConnections();
|
||||
|
||||
_entryData = entryData;
|
||||
SetWidgetLayout();
|
||||
@@ -477,8 +521,8 @@ void MacroActionTwitchEdit::ActionChanged(int idx)
|
||||
auto lock = LockContext();
|
||||
_entryData->_action = static_cast<MacroActionTwitch::Action>(
|
||||
_actions->itemData(idx).toInt());
|
||||
SetupWidgetVisibility();
|
||||
SetWidgetLayout();
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionTwitchEdit::TwitchTokenChanged(const QString &token)
|
||||
@@ -492,7 +536,7 @@ void MacroActionTwitchEdit::TwitchTokenChanged(const QString &token)
|
||||
_category->SetToken(_entryData->_token);
|
||||
_channel->SetToken(_entryData->_token);
|
||||
|
||||
SetupWidgetVisibility();
|
||||
SetWidgetVisibility();
|
||||
emit(HeaderInfoChanged(token));
|
||||
}
|
||||
|
||||
@@ -580,30 +624,86 @@ void MacroActionTwitchEdit::AnnouncementColorChanged(int index)
|
||||
static_cast<MacroActionTwitch::AnnouncementColor>(index);
|
||||
}
|
||||
|
||||
void MacroActionTwitchEdit::SetupWidgetVisibility()
|
||||
void MacroActionTwitchEdit::SetWidgetProperties()
|
||||
{
|
||||
_streamTitle->setVisible(_entryData->_action ==
|
||||
MacroActionTwitch::Action::TITLE);
|
||||
_category->setVisible(_entryData->_action ==
|
||||
MacroActionTwitch::Action::CATEGORY);
|
||||
_markerDescription->setVisible(_entryData->_action ==
|
||||
MacroActionTwitch::Action::MARKER);
|
||||
_clipHasDelay->setVisible(_entryData->_action ==
|
||||
MacroActionTwitch::Action::CLIP);
|
||||
_duration->setVisible(_entryData->_action ==
|
||||
MacroActionTwitch::Action::COMMERCIAL);
|
||||
_announcementMessage->setVisible(
|
||||
_entryData->_action == MacroActionTwitch::Action::ANNOUNCEMENT);
|
||||
_announcementColor->setVisible(_entryData->_action ==
|
||||
MacroActionTwitch::Action::ANNOUNCEMENT);
|
||||
_streamTitle->setSizePolicy(QSizePolicy::MinimumExpanding,
|
||||
QSizePolicy::Preferred);
|
||||
_streamTitle->setMaxLength(140);
|
||||
_markerDescription->setSizePolicy(QSizePolicy::MinimumExpanding,
|
||||
QSizePolicy::Preferred);
|
||||
_markerDescription->setMaxLength(140);
|
||||
_announcementMessage->setMaxLength(500);
|
||||
|
||||
auto durationSpinBox = _duration->SpinBox();
|
||||
durationSpinBox->setMaximum(180);
|
||||
durationSpinBox->setSuffix("s");
|
||||
|
||||
populateActionSelection(_actions);
|
||||
populateAnnouncementColorSelection(_announcementColor);
|
||||
}
|
||||
|
||||
void MacroActionTwitchEdit::SetWidgetSignalConnections()
|
||||
{
|
||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionChanged(int)));
|
||||
QWidget::connect(_tokens, SIGNAL(SelectionChanged(const QString &)),
|
||||
this, SLOT(TwitchTokenChanged(const QString &)));
|
||||
QWidget::connect(&_tokenPermissionCheckTimer, SIGNAL(timeout()), this,
|
||||
SLOT(CheckTokenPermissions()));
|
||||
QWidget::connect(_streamTitle, SIGNAL(editingFinished()), this,
|
||||
SLOT(StreamTitleChanged()));
|
||||
QWidget::connect(_category,
|
||||
SIGNAL(CategoreyChanged(const TwitchCategory &)), this,
|
||||
SLOT(CategoreyChanged(const TwitchCategory &)));
|
||||
QWidget::connect(_markerDescription, SIGNAL(editingFinished()), this,
|
||||
SLOT(MarkerDescriptionChanged()));
|
||||
QObject::connect(_clipHasDelay, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(ClipHasDelayChanged(int)));
|
||||
QObject::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(_announcementMessage, SIGNAL(textChanged()), this,
|
||||
SLOT(AnnouncementMessageChanged()));
|
||||
QWidget::connect(_announcementColor, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(AnnouncementColorChanged(int)));
|
||||
QWidget::connect(_channel,
|
||||
SIGNAL(ChannelChanged(const TwitchChannel &)), this,
|
||||
SLOT(ChannelChanged(const TwitchChannel &)));
|
||||
QWidget::connect(_chatMessage, SIGNAL(textChanged()), this,
|
||||
SLOT(ChatMessageChanged()));
|
||||
}
|
||||
|
||||
void MacroActionTwitchEdit::SetWidgetVisibility()
|
||||
{
|
||||
_streamTitle->setVisible(
|
||||
_entryData->_action ==
|
||||
MacroActionTwitch::Action::CHANNEL_INFO_TITLE_SET);
|
||||
_category->setVisible(
|
||||
_entryData->_action ==
|
||||
MacroActionTwitch::Action::CHANNEL_INFO_CATEGORY_SET);
|
||||
_channel->setVisible(
|
||||
_entryData->_action == MacroActionTwitch::Action::RAID ||
|
||||
_entryData->_action == MacroActionTwitch::Action::RAID_START ||
|
||||
_entryData->_action == MacroActionTwitch::Action::RAID_END ||
|
||||
_entryData->_action ==
|
||||
MacroActionTwitch::Action::SEND_CHAT_MESSAGE);
|
||||
_duration->setVisible(_entryData->_action ==
|
||||
MacroActionTwitch::Action::COMMERCIAL_START);
|
||||
_markerDescription->setVisible(
|
||||
_entryData->_action ==
|
||||
MacroActionTwitch::Action::MARKER_CREATE);
|
||||
_clipHasDelay->setVisible(_entryData->_action ==
|
||||
MacroActionTwitch::Action::CLIP_CREATE);
|
||||
_announcementMessage->setVisible(
|
||||
_entryData->_action ==
|
||||
MacroActionTwitch::Action::CHAT_ANNOUNCEMENT_SEND);
|
||||
_announcementColor->setVisible(
|
||||
_entryData->_action ==
|
||||
MacroActionTwitch::Action::CHAT_ANNOUNCEMENT_SEND);
|
||||
_chatMessage->setVisible(_entryData->_action ==
|
||||
MacroActionTwitch::Action::SEND_CHAT_MESSAGE);
|
||||
if (_entryData->_action == MacroActionTwitch::Action::TITLE ||
|
||||
_entryData->_action == MacroActionTwitch::Action::MARKER) {
|
||||
|
||||
if (_entryData->_action ==
|
||||
MacroActionTwitch::Action::CHANNEL_INFO_TITLE_SET ||
|
||||
_entryData->_action == MacroActionTwitch::Action::MARKER_CREATE) {
|
||||
RemoveStretchIfPresent(_layout);
|
||||
} else {
|
||||
AddStretchIfNecessary(_layout);
|
||||
@@ -641,7 +741,7 @@ void MacroActionTwitchEdit::ChatMessageChanged()
|
||||
|
||||
void MacroActionTwitchEdit::SetWidgetLayout()
|
||||
{
|
||||
static const std::vector<QWidget *> widgets{
|
||||
const std::vector<QWidget *> widgets{
|
||||
_tokens, _actions, _streamTitle,
|
||||
_category, _markerDescription, _clipHasDelay,
|
||||
_duration, _announcementColor, _channel};
|
||||
@@ -692,7 +792,7 @@ void MacroActionTwitchEdit::UpdateEntryData()
|
||||
_channel->SetChannel(_entryData->_channel);
|
||||
_chatMessage->setPlainText(_entryData->_chatMessage);
|
||||
|
||||
SetupWidgetVisibility();
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "category-selection.hpp"
|
||||
#include "channel-selection.hpp"
|
||||
#include "chat-connection.hpp"
|
||||
#include "points-reward-selection.hpp"
|
||||
|
||||
#include <variable-line-edit.hpp>
|
||||
#include <variable-text-edit.hpp>
|
||||
@@ -22,16 +23,118 @@ public:
|
||||
std::string GetShortDesc() const;
|
||||
|
||||
enum class Action {
|
||||
TITLE,
|
||||
CATEGORY = 10,
|
||||
MARKER = 20,
|
||||
CLIP = 30,
|
||||
COMMERCIAL = 40,
|
||||
ANNOUNCEMENT = 50,
|
||||
ENABLE_EMOTE_ONLY = 60,
|
||||
DISABLE_EMOTE_ONLY = 70,
|
||||
RAID = 80,
|
||||
SEND_CHAT_MESSAGE = 90,
|
||||
// Channel info update
|
||||
CHANNEL_INFO_TITLE_SET = 10,
|
||||
CHANNEL_INFO_CATEGORY_SET = 20,
|
||||
CHANNEL_INFO_LANGUAGE_SET = 30,
|
||||
CHANNEL_INFO_DELAY_SET = 40,
|
||||
CHANNEL_INFO_TAGS_SET = 50, // TODO
|
||||
CHANNEL_INFO_CONTENT_LABELS_SET = 60, // TODO
|
||||
CHANNEL_INFO_BRANDED_CONTENT_ENABLE = 70,
|
||||
CHANNEL_INFO_BRANDED_CONTENT_DISABLE = 71,
|
||||
|
||||
// Raid
|
||||
RAID_START = 110,
|
||||
RAID_END = 120,
|
||||
|
||||
// Shoutout
|
||||
SHOUTOUT_SEND = 200,
|
||||
|
||||
// Poll
|
||||
POLL_START = 300, // TODO
|
||||
POLL_END = 310,
|
||||
|
||||
// Prediction
|
||||
PREDICTION_START = 400, // TODO
|
||||
PREDICTION_END = 410,
|
||||
|
||||
// Shield mode
|
||||
SHIELD_MODE_START = 500,
|
||||
SHIELD_MODE_END = 501,
|
||||
|
||||
// Reward add
|
||||
POINTS_REWARD_ADD = 600, // TODO
|
||||
|
||||
// Reward update
|
||||
POINTS_REWARD_ENABLE = 710,
|
||||
POINTS_REWARD_DISABLE = 711,
|
||||
POINTS_REWARD_PAUSE = 712,
|
||||
POINTS_REWARD_UNPAUSE = 713,
|
||||
POINTS_REWARD_TITLE_SET = 720,
|
||||
POINTS_REWARD_PROMPT_SET = 730,
|
||||
POINTS_REWARD_COST_SET = 740,
|
||||
POINTS_REWARD_BACKGROUND_COLOR_SET = 750, // TODO
|
||||
POINTS_REWARD_USER_INPUT_REQUIRE = 760,
|
||||
POINTS_REWARD_USER_INPUT_UNREQUIRE = 761,
|
||||
POINTS_REWARD_COOLDOWN_ENABLE = 770,
|
||||
POINTS_REWARD_COOLDOWN_DISABLE = 771,
|
||||
POINTS_REWARD_QUEUE_SKIP_ENABLE = 780,
|
||||
POINTS_REWARD_QUEUE_SKIP_DISABLE = 781,
|
||||
POINTS_REWARD_MAX_PER_STREAM_ENABLE = 790,
|
||||
POINTS_REWARD_MAX_PER_STREAM_DISABLE = 791,
|
||||
POINTS_REWARD_MAX_PER_USER_ENABLE = 792,
|
||||
POINTS_REWARD_MAX_PER_USER_DISABLE = 793,
|
||||
|
||||
// Reward delete
|
||||
POINTS_REWARD_DELETE = 800,
|
||||
|
||||
// Reward redemption update
|
||||
POINTS_REWARD_REDEMPTION_FULFILL = 900,
|
||||
POINTS_REWARD_REDEMPTION_CANCEL = 910,
|
||||
|
||||
// User state
|
||||
USER_BAN = 1000,
|
||||
USER_UNBAN = 1100,
|
||||
USER_BLOCK = 1200,
|
||||
USER_UNBLOCK = 1300,
|
||||
USER_MODERATOR_ADD = 1400,
|
||||
USER_MODERATOR_DELETE = 1500,
|
||||
USER_VIP_ADD = 1600,
|
||||
USER_VIP_DELETE = 1700,
|
||||
USER_CHAT_COLOR_UPDATE = 1800, // TODO
|
||||
|
||||
// Commercial
|
||||
COMMERCIAL_START = 1900,
|
||||
COMMERCIAL_SNOOZE = 2000,
|
||||
|
||||
// Marker
|
||||
MARKER_CREATE = 2100,
|
||||
|
||||
// Clips
|
||||
CLIP_CREATE = 2200,
|
||||
|
||||
// Videos
|
||||
VIDEOS_DELETE = 2300, // TODO
|
||||
|
||||
// Chat
|
||||
CHAT_MESSAGES_DELETE = 2400, // TODO
|
||||
CHAT_ANNOUNCEMENT_SEND = 2500,
|
||||
CHAT_EMOTE_ONLY_ENABLE = 2600,
|
||||
CHAT_EMOTE_ONLY_DISABLE = 2601,
|
||||
CHAT_FOLLOWER_ONLY_ENABLE = 2602,
|
||||
CHAT_FOLLOWER_ONLY_DISABLE = 2603,
|
||||
CHAT_SUBSCRIBER_ONLY_ENABLE = 2604,
|
||||
CHAT_SUBSCRIBER_ONLY_DISABLE = 2605,
|
||||
CHAT_SLOW_MODE_ENABLE = 2640,
|
||||
CHAT_SLOW_MODE_DISABLE = 2641,
|
||||
CHAT_NON_MODERATOR_DELAY_ENABLE = 2650,
|
||||
CHAT_NON_MODERATOR_DELAY_DISABLE = 2651,
|
||||
CHAT_UNIQUE_MODE_ENABLE = 2960,
|
||||
CHAT_UNIQUE_MODE_DISABLE = 2661,
|
||||
CHAT_AUTOMOD_UPDATE = 2700, // TODO
|
||||
CHAT_AUTOMOD_MESSAGE_ALLOW = 2800, // TODO
|
||||
CHAT_AUTOMOD_MESSAGE_DENY = 2801, // TODO
|
||||
CHAT_BLOCKED_TERM_ADD = 2900, // TODO
|
||||
CHAT_BLOCKED_TERM_DELETE = 3000, // TODO
|
||||
WHISPER_SEND = 3100,
|
||||
|
||||
// Schedule
|
||||
CHANNEL_SCHEDULE_UPDATE = 3200, // TODO
|
||||
CHANNEL_SCHEDULE_SEGMENT_ADD = 3300, // TODO
|
||||
CHANNEL_SCHEDULE_SEGMENT_UPDATE = 3400, // TODO
|
||||
CHANNEL_SCHEDULE_SEGMENT_DELETE = 3500, // TODO
|
||||
|
||||
SEND_CHAT_MESSAGE = 5000,
|
||||
};
|
||||
|
||||
enum class AnnouncementColor {
|
||||
@@ -42,6 +145,8 @@ public:
|
||||
PURPLE,
|
||||
};
|
||||
|
||||
enum class RedemptionStatus { CANCELED, FULFILLED };
|
||||
|
||||
bool PerformAction();
|
||||
void LogAction() const;
|
||||
bool Save(obs_data_t *obj) const;
|
||||
@@ -49,7 +154,7 @@ public:
|
||||
bool ActionIsSupportedByToken();
|
||||
void ResetChatConnection();
|
||||
|
||||
Action _action = Action::TITLE;
|
||||
Action _action = Action::CHANNEL_INFO_TITLE_SET;
|
||||
std::weak_ptr<TwitchToken> _token;
|
||||
StringVariable _streamTitle =
|
||||
obs_module_text("AdvSceneSwitcher.action.twitch.title.title");
|
||||
@@ -119,8 +224,10 @@ protected:
|
||||
std::shared_ptr<MacroActionTwitch> _entryData;
|
||||
|
||||
private:
|
||||
void SetupWidgetVisibility();
|
||||
void SetWidgetProperties();
|
||||
void SetWidgetSignalConnections();
|
||||
void SetWidgetLayout();
|
||||
void SetWidgetVisibility();
|
||||
|
||||
QHBoxLayout *_layout;
|
||||
FilterComboBox *_actions;
|
||||
|
||||
@@ -866,7 +866,9 @@ void MacroConditionTwitch::SetupTempVars()
|
||||
AddTempvar(id, name.empty() ? id : name, description);
|
||||
};
|
||||
|
||||
if (_condition != Condition::CHAT_MESSAGE_RECEIVED) {
|
||||
if (_condition != Condition::CHAT_MESSAGE_RECEIVED &&
|
||||
_condition != Condition::RAID_INBOUND_EVENT &&
|
||||
_condition != Condition::RAID_OUTBOUND_EVENT) {
|
||||
setupTempVarHelper("broadcaster_user_id");
|
||||
setupTempVarHelper("broadcaster_user_login");
|
||||
setupTempVarHelper("broadcaster_user_name");
|
||||
@@ -1141,7 +1143,16 @@ void MacroConditionTwitch::SetupTempVars()
|
||||
setupTempVarHelper("user_name", ".follow");
|
||||
setupTempVarHelper("followed_at");
|
||||
break;
|
||||
case Condition::RAID_INBOUND_EVENT:
|
||||
case Condition::RAID_OUTBOUND_EVENT:
|
||||
setupTempVarHelper("from_broadcaster_user_id", ".raid");
|
||||
setupTempVarHelper("from_broadcaster_user_login", ".raid");
|
||||
setupTempVarHelper("from_broadcaster_user_name", ".raid");
|
||||
setupTempVarHelper("to_broadcaster_user_id", ".raid");
|
||||
setupTempVarHelper("to_broadcaster_user_login", ".raid");
|
||||
setupTempVarHelper("to_broadcaster_user_name", ".raid");
|
||||
setupTempVarHelper("viewers", ".raid");
|
||||
break;
|
||||
case Condition::LIVE_POLLING:
|
||||
setupTempVarHelper("id", ".stream.online");
|
||||
setupTempVarHelper("game_id");
|
||||
@@ -1280,7 +1291,7 @@ void MacroConditionTwitchEdit::ConditionChanged(int idx)
|
||||
auto lock = LockContext();
|
||||
_entryData->SetCondition(static_cast<MacroConditionTwitch::Condition>(
|
||||
_conditions->itemData(idx).toInt()));
|
||||
SetupWidgetVisibility();
|
||||
SetWidgetVisibility();
|
||||
emit TempVarsChanged();
|
||||
}
|
||||
|
||||
@@ -1297,7 +1308,7 @@ void MacroConditionTwitchEdit::TwitchTokenChanged(const QString &token)
|
||||
_pointsReward->SetToken(_entryData->_token);
|
||||
_entryData->ResetChatConnection();
|
||||
|
||||
SetupWidgetVisibility();
|
||||
SetWidgetVisibility();
|
||||
emit(HeaderInfoChanged(token));
|
||||
}
|
||||
|
||||
@@ -1388,7 +1399,7 @@ void MacroConditionTwitchEdit::CategoreyChanged(const TwitchCategory &category)
|
||||
_entryData->_category = category;
|
||||
}
|
||||
|
||||
void MacroConditionTwitchEdit::SetupWidgetVisibility()
|
||||
void MacroConditionTwitchEdit::SetWidgetVisibility()
|
||||
{
|
||||
auto condition = _entryData->GetCondition();
|
||||
|
||||
@@ -1448,7 +1459,7 @@ void MacroConditionTwitchEdit::UpdateEntryData()
|
||||
_category->SetToken(_entryData->_token);
|
||||
_category->SetCategory(_entryData->_category);
|
||||
|
||||
SetupWidgetVisibility();
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -23,8 +23,13 @@ public:
|
||||
std::string GetShortDesc() const;
|
||||
|
||||
enum class Condition {
|
||||
// Generic event based
|
||||
// Event based
|
||||
STREAM_ONLINE_EVENT = 0,
|
||||
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,
|
||||
STREAM_OFFLINE_EVENT = 100,
|
||||
CHANNEL_INFO_UPDATE_EVENT = 200,
|
||||
FOLLOW_EVENT = 300,
|
||||
@@ -66,13 +71,6 @@ public:
|
||||
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,
|
||||
|
||||
// Chat
|
||||
CHAT_MESSAGE_RECEIVED = 500000,
|
||||
|
||||
@@ -170,7 +168,7 @@ protected:
|
||||
std::shared_ptr<MacroConditionTwitch> _entryData;
|
||||
|
||||
private:
|
||||
void SetupWidgetVisibility();
|
||||
void SetWidgetVisibility();
|
||||
|
||||
QHBoxLayout *_layout;
|
||||
FilterComboBox *_conditions;
|
||||
|
||||
@@ -134,9 +134,9 @@ TwitchPointsRewardSelection::GetPointsRewards(
|
||||
httplib::Params params = {
|
||||
{"broadcaster_id", channel.GetUserID(*token)}};
|
||||
|
||||
auto response = SendGetRequest("https://api.twitch.tv",
|
||||
auto response = SendGetRequest(*token, "https://api.twitch.tv",
|
||||
"/helix/channel_points/custom_rewards",
|
||||
*token, params);
|
||||
params);
|
||||
|
||||
if (response.status != 200) {
|
||||
blog(LOG_WARNING,
|
||||
|
||||
@@ -13,14 +13,6 @@ static std::deque<std::shared_ptr<Item>> twitchTokens;
|
||||
const std::unordered_map<std::string, std::string> TokenOption::_apiIdToLocale{
|
||||
{"channel:manage:broadcast",
|
||||
"AdvSceneSwitcher.twitchToken.channel.broadcast.manage"},
|
||||
{"clips:edit", "AdvSceneSwitcher.twitchToken.clips.edit"},
|
||||
{"channel:edit:commercial",
|
||||
"AdvSceneSwitcher.twitchToken.channel.commercial.edit"},
|
||||
{"moderator:manage:announcements",
|
||||
"AdvSceneSwitcher.twitchToken.moderator.announcements.manage"},
|
||||
{"moderator:manage:chat_settings",
|
||||
"AdvSceneSwitcher.twitchToken.moderator.chat.settings.manage"},
|
||||
{"channel:manage:raids", "AdvSceneSwitcher.twitchToken.channel.raid"},
|
||||
{"moderator:read:followers",
|
||||
"AdvSceneSwitcher.twitchToken.moderator.followers.read"},
|
||||
{"channel:read:subscriptions",
|
||||
@@ -28,6 +20,8 @@ const std::unordered_map<std::string, std::string> TokenOption::_apiIdToLocale{
|
||||
{"bits:read", "AdvSceneSwitcher.twitchToken.bits.read"},
|
||||
{"moderator:read:shoutouts",
|
||||
"AdvSceneSwitcher.twitchToken.moderator.shoutouts.read"},
|
||||
{"channel:manage:raids",
|
||||
"AdvSceneSwitcher.twitchToken.channel.raids.manage"},
|
||||
{"moderator:manage:shoutouts",
|
||||
"AdvSceneSwitcher.twitchToken.moderator.shoutouts.manage"},
|
||||
{"channel:read:polls",
|
||||
@@ -53,8 +47,26 @@ const std::unordered_map<std::string, std::string> TokenOption::_apiIdToLocale{
|
||||
{"channel:manage:redemptions",
|
||||
"AdvSceneSwitcher.twitchToken.channel.redemptions.manage"},
|
||||
{"channel:moderate", "AdvSceneSwitcher.twitchToken.channel.moderate"},
|
||||
{"moderation:read",
|
||||
"AdvSceneSwitcher.twitchToken.channel.moderation.read"},
|
||||
{"moderator:manage:banned_users",
|
||||
"AdvSceneSwitcher.twitchToken.moderator.bannedUsers.manage"},
|
||||
{"user:manage:blocked_users",
|
||||
"AdvSceneSwitcher.twitchToken.user.blockedUsers.manage"},
|
||||
{"moderation:read", "AdvSceneSwitcher.twitchToken.moderation.read"},
|
||||
{"channel:manage:moderators",
|
||||
"AdvSceneSwitcher.twitchToken.channel.moderators.manage"},
|
||||
{"channel:manage:vips",
|
||||
"AdvSceneSwitcher.twitchToken.channel.vips.manage"},
|
||||
{"channel:edit:commercial",
|
||||
"AdvSceneSwitcher.twitchToken.channel.commercial.edit"},
|
||||
{"channel:manage:ads",
|
||||
"AdvSceneSwitcher.twitchToken.channel.ads.manage"},
|
||||
{"clips:edit", "AdvSceneSwitcher.twitchToken.clips.edit"},
|
||||
{"moderator:manage:announcements",
|
||||
"AdvSceneSwitcher.twitchToken.moderator.announcements.manage"},
|
||||
{"moderator:manage:chat_settings",
|
||||
"AdvSceneSwitcher.twitchToken.moderator.chat.settings.manage"},
|
||||
{"user:manage:whispers",
|
||||
"AdvSceneSwitcher.twitchToken.user.whispers.manage"},
|
||||
{"chat:read", "AdvSceneSwitcher.twitchToken.chat.read"},
|
||||
{"chat:edit", "AdvSceneSwitcher.twitchToken.chat.edit"},
|
||||
};
|
||||
@@ -194,7 +206,7 @@ void TwitchToken::SetToken(const std::string &value)
|
||||
{
|
||||
_token = value;
|
||||
auto res =
|
||||
SendGetRequest("https://api.twitch.tv", "/helix/users", *this);
|
||||
SendGetRequest(*this, "https://api.twitch.tv", "/helix/users");
|
||||
if (res.status != 200) {
|
||||
blog(LOG_WARNING, "failed to get Twitch user id from token!");
|
||||
_userID = -1;
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
#include "twitch-helpers.hpp"
|
||||
#include "token.hpp"
|
||||
|
||||
#include <log-helper.hpp>
|
||||
|
||||
namespace advss {
|
||||
|
||||
static constexpr std::string_view clientID = "ds5tt4ogliifsqc04mz3d3etnck3e5";
|
||||
static const int cacheTimeoutSeconds = 10;
|
||||
|
||||
const char *GetClientID()
|
||||
{
|
||||
return clientID.data();
|
||||
}
|
||||
|
||||
class Args {
|
||||
public:
|
||||
Args(const std::string &uri, const std::string &path,
|
||||
@@ -43,7 +50,7 @@ struct CacheEntry {
|
||||
std::chrono::system_clock::now();
|
||||
};
|
||||
|
||||
static bool chacheIsTooOld(const CacheEntry &cache)
|
||||
static bool cacheIsTooOld(const CacheEntry &cache)
|
||||
{
|
||||
auto currentTime = std::chrono::system_clock::now();
|
||||
auto diff = currentTime - cache.cacheTime;
|
||||
@@ -54,7 +61,7 @@ static bool cacheIsValid(const std::map<Args, CacheEntry> &cache,
|
||||
const Args &args)
|
||||
{
|
||||
auto it = cache.find(args);
|
||||
return it != cache.end() && !chacheIsTooOld(it->second);
|
||||
return it != cache.end() && !cacheIsTooOld(it->second);
|
||||
}
|
||||
|
||||
static httplib::Headers getTokenRequestHeaders(const std::string &token)
|
||||
@@ -65,166 +72,262 @@ static httplib::Headers getTokenRequestHeaders(const std::string &token)
|
||||
};
|
||||
}
|
||||
|
||||
RequestResult SendGetRequest(const std::string &uri, const std::string &path,
|
||||
const TwitchToken &token,
|
||||
static std::string getRequestBody(const OBSData &data)
|
||||
{
|
||||
auto json = obs_data_get_json(data);
|
||||
return json ? json : "";
|
||||
}
|
||||
|
||||
static RequestResult processResult(const httplib::Result &response,
|
||||
const char *funcName)
|
||||
{
|
||||
if (!response) {
|
||||
auto err = response.error();
|
||||
blog(LOG_WARNING, "Twitch request failed in %s with error: %s",
|
||||
funcName, httplib::to_string(err).c_str());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
RequestResult result;
|
||||
result.status = response->status;
|
||||
|
||||
if (response->body.empty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
OBSDataAutoRelease replyData =
|
||||
obs_data_create_from_json(response->body.c_str());
|
||||
result.data = replyData;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
RequestResult SendGetRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms)
|
||||
{
|
||||
httplib::Client cli(uri);
|
||||
auto tokenStr = token.GetToken();
|
||||
|
||||
if (!tokenStr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto url = httplib::append_query_params(uri + path, params);
|
||||
vblog(LOG_INFO, "Twitch GET request to %s began", url.c_str());
|
||||
|
||||
auto headers = getTokenRequestHeaders(*tokenStr);
|
||||
auto response = cli.Get(path, params, headers);
|
||||
if (!response) {
|
||||
auto err = response.error();
|
||||
blog(LOG_INFO, "%s failed - %s", __func__,
|
||||
httplib::to_string(err).c_str());
|
||||
return {};
|
||||
}
|
||||
RequestResult result;
|
||||
result.status = response->status;
|
||||
if (response->body.empty()) {
|
||||
return result;
|
||||
}
|
||||
OBSDataAutoRelease replyData =
|
||||
obs_data_create_from_json(response->body.c_str());
|
||||
result.data = replyData;
|
||||
return result;
|
||||
|
||||
return processResult(response, __func__);
|
||||
}
|
||||
|
||||
RequestResult SendGetRequest(const std::string &uri, const std::string &path,
|
||||
const TwitchToken &token,
|
||||
RequestResult SendGetRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms, bool useCache)
|
||||
{
|
||||
static std::map<Args, CacheEntry> cache;
|
||||
static std::mutex mtx;
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
auto tokenStr = token.GetToken();
|
||||
|
||||
if (!tokenStr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto headers = getTokenRequestHeaders(*tokenStr);
|
||||
Args args(uri, path, "", params, headers);
|
||||
|
||||
if (useCache && cacheIsValid(cache, args)) {
|
||||
auto it = cache.find(args);
|
||||
return it->second.result;
|
||||
}
|
||||
|
||||
auto result = SendGetRequest(uri, path, token, params);
|
||||
auto result = SendGetRequest(token, uri, path, params);
|
||||
cache[args] = {result};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
RequestResult SendPostRequest(const std::string &uri, const std::string &path,
|
||||
const TwitchToken &token, const OBSData &data)
|
||||
RequestResult SendPostRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms,
|
||||
const OBSData &data)
|
||||
{
|
||||
httplib::Client cli(uri);
|
||||
auto tokenStr = token.GetToken();
|
||||
|
||||
if (!tokenStr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto pathWithParams = httplib::append_query_params(path, params);
|
||||
auto url = uri + pathWithParams;
|
||||
vblog(LOG_INFO, "Twitch POST request to %s began", url.c_str());
|
||||
|
||||
auto headers = getTokenRequestHeaders(*tokenStr);
|
||||
auto json = obs_data_get_json(data);
|
||||
std::string body = json ? json : "";
|
||||
auto response = cli.Post(path, headers, body, "application/json");
|
||||
if (!response) {
|
||||
auto err = response.error();
|
||||
blog(LOG_INFO, "%s failed - %s", __func__,
|
||||
httplib::to_string(err).c_str());
|
||||
return {};
|
||||
}
|
||||
RequestResult result;
|
||||
result.status = response->status;
|
||||
if (response->body.empty()) {
|
||||
return result;
|
||||
}
|
||||
OBSDataAutoRelease replyData =
|
||||
obs_data_create_from_json(response->body.c_str());
|
||||
result.data = replyData;
|
||||
return result;
|
||||
auto body = getRequestBody(data);
|
||||
auto response =
|
||||
cli.Post(pathWithParams, headers, body, "application/json");
|
||||
|
||||
return processResult(response, __func__);
|
||||
}
|
||||
|
||||
RequestResult SendPostRequest(const std::string &uri, const std::string &path,
|
||||
const TwitchToken &token, const OBSData &data,
|
||||
bool useCache)
|
||||
RequestResult SendPostRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms,
|
||||
const OBSData &data, bool useCache)
|
||||
{
|
||||
static std::map<Args, CacheEntry> cache;
|
||||
static std::mutex mtx;
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
auto tokenStr = token.GetToken();
|
||||
|
||||
if (!tokenStr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto headers = getTokenRequestHeaders(*tokenStr);
|
||||
auto jsonCstr = obs_data_get_json(data);
|
||||
Args args(uri, path, jsonCstr ? jsonCstr : "", {}, headers);
|
||||
auto body = getRequestBody(data);
|
||||
Args args(uri, path, body, params, headers);
|
||||
|
||||
if (useCache && cacheIsValid(cache, args)) {
|
||||
auto it = cache.find(args);
|
||||
return it->second.result;
|
||||
}
|
||||
|
||||
auto result = SendPostRequest(uri, path, token, data);
|
||||
auto result = SendPostRequest(token, uri, path, params, data);
|
||||
cache[args] = {result};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
RequestResult SendPatchRequest(const std::string &uri, const std::string &path,
|
||||
const TwitchToken &token, const OBSData &data)
|
||||
RequestResult SendPutRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms, const OBSData &data)
|
||||
{
|
||||
httplib::Client cli(uri);
|
||||
auto tokenStr = token.GetToken();
|
||||
|
||||
if (!tokenStr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto pathWithParams = httplib::append_query_params(path, params);
|
||||
auto url = uri + pathWithParams;
|
||||
vblog(LOG_INFO, "Twitch PUT request to %s began", url.c_str());
|
||||
|
||||
auto headers = getTokenRequestHeaders(*tokenStr);
|
||||
auto json = obs_data_get_json(data);
|
||||
std::string body = json ? json : "";
|
||||
auto response = cli.Patch(path, headers, body, "application/json");
|
||||
if (!response) {
|
||||
auto err = response.error();
|
||||
blog(LOG_INFO, "%s failed - %s", __func__,
|
||||
httplib::to_string(err).c_str());
|
||||
return {};
|
||||
}
|
||||
RequestResult result;
|
||||
result.status = response->status;
|
||||
if (response->body.empty()) {
|
||||
return result;
|
||||
}
|
||||
OBSDataAutoRelease replyData =
|
||||
obs_data_create_from_json(response->body.c_str());
|
||||
result.data = replyData;
|
||||
return result;
|
||||
auto body = getRequestBody(data);
|
||||
auto response =
|
||||
cli.Put(pathWithParams, headers, body, "application/json");
|
||||
|
||||
return processResult(response, __func__);
|
||||
}
|
||||
|
||||
RequestResult SendPatchRequest(const std::string &uri, const std::string &path,
|
||||
const TwitchToken &token, const OBSData &data,
|
||||
bool useCache)
|
||||
RequestResult SendPutRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms, const OBSData &data,
|
||||
bool useCache)
|
||||
{
|
||||
static std::map<Args, CacheEntry> cache;
|
||||
static std::mutex mtx;
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
auto tokenStr = token.GetToken();
|
||||
|
||||
if (!tokenStr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto headers = getTokenRequestHeaders(*tokenStr);
|
||||
auto jsonCstr = obs_data_get_json(data);
|
||||
Args args(uri, path, jsonCstr ? jsonCstr : "", {}, headers);
|
||||
auto body = getRequestBody(data);
|
||||
Args args(uri, path, body, params, headers);
|
||||
|
||||
if (useCache && cacheIsValid(cache, args)) {
|
||||
auto it = cache.find(args);
|
||||
return it->second.result;
|
||||
}
|
||||
|
||||
auto result = SendPatchRequest(uri, path, token, data);
|
||||
auto result = SendPutRequest(token, uri, path, params, data);
|
||||
cache[args] = {result};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const char *GetClientID()
|
||||
RequestResult SendPatchRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms,
|
||||
const OBSData &data)
|
||||
{
|
||||
return clientID.data();
|
||||
httplib::Client cli(uri);
|
||||
auto tokenStr = token.GetToken();
|
||||
|
||||
if (!tokenStr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto pathWithParams = httplib::append_query_params(path, params);
|
||||
auto url = uri + pathWithParams;
|
||||
vblog(LOG_INFO, "Twitch PATCH request to %s began", url.c_str());
|
||||
|
||||
auto headers = getTokenRequestHeaders(*tokenStr);
|
||||
auto body = getRequestBody(data);
|
||||
auto response =
|
||||
cli.Patch(pathWithParams, headers, body, "application/json");
|
||||
|
||||
return processResult(response, __func__);
|
||||
}
|
||||
|
||||
RequestResult SendPatchRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms,
|
||||
const OBSData &data, bool useCache)
|
||||
{
|
||||
static std::map<Args, CacheEntry> cache;
|
||||
static std::mutex mtx;
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
auto tokenStr = token.GetToken();
|
||||
|
||||
if (!tokenStr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto headers = getTokenRequestHeaders(*tokenStr);
|
||||
auto body = getRequestBody(data);
|
||||
Args args(uri, path, body, params, headers);
|
||||
|
||||
if (useCache && cacheIsValid(cache, args)) {
|
||||
auto it = cache.find(args);
|
||||
return it->second.result;
|
||||
}
|
||||
|
||||
auto result = SendPatchRequest(token, uri, path, params, data);
|
||||
cache[args] = {result};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
RequestResult SendDeleteRequest(const TwitchToken &token,
|
||||
const std::string &uri, const std::string &path,
|
||||
const httplib::Params ¶ms)
|
||||
{
|
||||
httplib::Client cli(uri);
|
||||
auto tokenStr = token.GetToken();
|
||||
|
||||
if (!tokenStr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto pathWithParams = httplib::append_query_params(path, params);
|
||||
auto url = uri + pathWithParams;
|
||||
vblog(LOG_INFO, "Twitch DELETE request to %s began", url.c_str());
|
||||
|
||||
auto headers = getTokenRequestHeaders(*tokenStr);
|
||||
auto response =
|
||||
cli.Delete(pathWithParams, headers, "", "application/json");
|
||||
|
||||
return processResult(response, __func__);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -13,29 +13,44 @@ struct RequestResult {
|
||||
OBSData data = nullptr;
|
||||
};
|
||||
|
||||
// These functions do *not* use or create RequestResult cache entries
|
||||
const char *GetClientID();
|
||||
|
||||
RequestResult SendGetRequest(const std::string &uri, const std::string &path,
|
||||
const TwitchToken &token,
|
||||
const httplib::Params & = {});
|
||||
RequestResult SendPostRequest(const std::string &uri, const std::string &path,
|
||||
const TwitchToken &token, const OBSData &data);
|
||||
RequestResult SendPatchRequest(const std::string &uri, const std::string &path,
|
||||
const TwitchToken &token, const OBSData &data);
|
||||
// These functions do *not* use or create RequestResult cache entries
|
||||
RequestResult SendGetRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms = {});
|
||||
RequestResult SendPostRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms = {},
|
||||
const OBSData &data = nullptr);
|
||||
RequestResult SendPutRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms = {},
|
||||
const OBSData &data = nullptr);
|
||||
RequestResult SendPatchRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms = {},
|
||||
const OBSData &data = nullptr);
|
||||
RequestResult SendDeleteRequest(const TwitchToken &token,
|
||||
const std::string &uri, const std::string &path,
|
||||
const httplib::Params ¶ms = {});
|
||||
|
||||
// These functions will cache the RequestResult for 10s
|
||||
// Note that the cache will be reported as a "memory leak" on OBS shutdown
|
||||
|
||||
RequestResult SendGetRequest(const std::string &uri, const std::string &path,
|
||||
const TwitchToken &token, const httplib::Params &,
|
||||
RequestResult SendGetRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms, bool useCache);
|
||||
RequestResult SendPostRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms,
|
||||
const OBSData &data, bool useCache);
|
||||
RequestResult SendPutRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms, const OBSData &data,
|
||||
bool useCache);
|
||||
RequestResult SendPostRequest(const std::string &uri, const std::string &path,
|
||||
const TwitchToken &token, const OBSData &data,
|
||||
bool useCache);
|
||||
RequestResult SendPatchRequest(const std::string &uri, const std::string &path,
|
||||
const TwitchToken &token, const OBSData &data,
|
||||
bool useCache);
|
||||
|
||||
const char *GetClientID();
|
||||
RequestResult SendPatchRequest(const TwitchToken &token, const std::string &uri,
|
||||
const std::string &path,
|
||||
const httplib::Params ¶ms,
|
||||
const OBSData &data, bool useCache);
|
||||
|
||||
} // namespace advss
|
||||
|
||||
Reference in New Issue
Block a user