diff --git a/.gitignore b/.gitignore index 896be89..2f706c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # CMake builds [Bb]uild*/ -cmake-build-debug/ +cmake-build*/ # clangd .cache/ diff --git a/Source/config.cppm b/Source/config.cppm index 4e73707..f24412b 100644 --- a/Source/config.cppm +++ b/Source/config.cppm @@ -36,7 +36,9 @@ export struct Config { std::vector approvedUsers = {}; std::string twitchChannel = "", refreshToken = ""; CommandCooldownType enabledCooldowns = CommandCooldownType::eGlobal; - ConfigOption cooldownTime{5, 1, 60}; + ConfigOption cooldownGlobal{5, 1, 600}; + ConfigOption cooldownPerUser{5, 1, 600}; + ConfigOption cooldownPerCommand{5, 1, 600}; ConfigOption maxAudioTriggers{ 3, 0, 10}; //< How many audio triggers can a message cause ConfigOption audioSequenceOffset{ @@ -57,17 +59,24 @@ export struct Config { json["notifEffectIntensity"] = notifEffectIntensity.value; json["notifFontScale"] = notifFontScale.value; json["globalAudioVolume"] = globalAudioVolume.value; - json["approvedUsers"] = approvedUsers; json["twitchChannel"] = twitchChannel; json["refreshToken"] = refreshToken; json["enabledCooldowns"] = static_cast(enabledCooldowns); - json["cooldownTime"] = cooldownTime.value; + json["cooldownGlobal"] = cooldownGlobal.value; + json["cooldownPerUser"] = cooldownPerUser.value; + json["cooldownPerCommand"] = cooldownPerCommand.value; json["maxAudioTriggers"] = maxAudioTriggers.value; json["audioSequenceOffset"] = audioSequenceOffset.value; json["ttsVoiceSpeed"] = ttsVoiceSpeed.value; json["ttsVoiceVolume"] = ttsVoiceVolume.value; json["ttsVoicePitch"] = ttsVoicePitch.value; + // Approved users has to be made into comma separated string + std::string approvedUsersStr; + for (const auto &user : approvedUsers) approvedUsersStr += user + ","; + + json["approvedUsers"] = approvedUsersStr; + std::ofstream file(get_config_path()); file << json.dump(4); file.close(); @@ -95,18 +104,27 @@ export struct Config { notifEffectIntensity.value = json["notifEffectIntensity"].get(); notifFontScale.value = json["notifFontScale"].get(); globalAudioVolume.value = json["globalAudioVolume"].get(); - //approvedUsers = json["approvedUsers"].get>(); twitchChannel = json["twitchChannel"].get(); refreshToken = json["refreshToken"].get(); enabledCooldowns = static_cast(json["enabledCooldowns"].get()); - cooldownTime.value = json["cooldownTime"].get(); + cooldownGlobal.value = json["cooldownGlobal"].get(); + cooldownPerUser.value = json["cooldownPerUser"].get(); + cooldownPerCommand.value = json["cooldownPerCommand"].get(); maxAudioTriggers.value = json["maxAudioTriggers"].get(); audioSequenceOffset.value = json["audioSequenceOffset"].get(); ttsVoiceSpeed.value = json["ttsVoiceSpeed"].get(); ttsVoiceVolume.value = json["ttsVoiceVolume"].get(); ttsVoicePitch.value = json["ttsVoicePitch"].get(); + // Approved users has to be made into vector from comma separated string + const auto approvedUsersStr = json["approvedUsers"].get(); + const auto splitted = split_string(approvedUsersStr, ","); + approvedUsers.clear(); + for (const auto &user : splitted) { + if (!user.empty()) approvedUsers.push_back(user); + } + return Result(); } diff --git a/Source/gui.cppm b/Source/gui.cppm index 6d9762e..2743194 100644 --- a/Source/gui.cppm +++ b/Source/gui.cppm @@ -280,20 +280,32 @@ public: reinterpret_cast(&global_config.enabledCooldowns), static_cast(CommandCooldownType::eGlobal)); ImGui::SameLine(); + ImGui::BeginDisabled(~global_config.enabledCooldowns & CommandCooldownType::eGlobal); + { + ImGui::InputScalar("##cooldownGlobal", ImGuiDataType_U32, + &global_config.cooldownGlobal.value); + } + ImGui::EndDisabled(); + ImGui::CheckboxFlags("Per User", reinterpret_cast(&global_config.enabledCooldowns), static_cast(CommandCooldownType::ePerUser)); ImGui::SameLine(); + ImGui::BeginDisabled(~global_config.enabledCooldowns & CommandCooldownType::ePerUser); + { + ImGui::InputScalar("##cooldownPerUser", ImGuiDataType_U32, + &global_config.cooldownPerUser.value); + } + ImGui::EndDisabled(); + ImGui::CheckboxFlags("Per Command", reinterpret_cast(&global_config.enabledCooldowns), static_cast(CommandCooldownType::ePerCommand)); - - // Input box for cooldown time - ImGui::BeginDisabled(global_config.enabledCooldowns == CommandCooldownType::eNone); + ImGui::SameLine(); + ImGui::BeginDisabled(~global_config.enabledCooldowns & CommandCooldownType::ePerCommand); { - ImGui::Text("Cooldown time:"); - ImGui::InputScalar("##cooldownTime", ImGuiDataType_U32, - &global_config.cooldownTime.value); + ImGui::InputScalar("##cooldownPerCommand", ImGuiDataType_U32, + &global_config.cooldownPerCommand.value); } ImGui::EndDisabled(); @@ -302,17 +314,17 @@ public: // Modifiable list of approved users ImGui::Text("Approved users:"); - static std::array user_buf = {""}; + static std::string user_buf = ""; if (ImGui::Button("Add")) { - if (user_buf[0] != '\0') { + if (!user_buf.empty()) { // Add the user to the list - global_config.approvedUsers.emplace_back(user_buf.data()); + global_config.approvedUsers.emplace_back(user_buf.c_str()); // Clear the input buffer std::ranges::fill(user_buf, '\0'); } } ImGui::SameLine(); - ImGui::InputText("##approvedUsers", user_buf.data(), user_buf.size()); + ImGui::InputText("##approvedUsers", &user_buf); // List of approved users, if empty, show warning text if (global_config.approvedUsers.empty()) diff --git a/Source/twitch.cppm b/Source/twitch.cppm index 1050cb1..c48a227 100644 --- a/Source/twitch.cppm +++ b/Source/twitch.cppm @@ -166,7 +166,7 @@ private: // Handlers if (global_config.enabledCooldowns & CommandCooldownType::eGlobal) { const auto now = std::chrono::steady_clock::now(); if (now - m_lastCommandTime < - std::chrono::seconds(global_config.cooldownTime.value)) + std::chrono::seconds(global_config.cooldownGlobal.value)) return Result(); m_lastCommandTime = now; @@ -175,7 +175,7 @@ private: // Handlers if (global_users.contains(user)) { if (const auto now = std::chrono::steady_clock::now(); now - global_users[user]->lastMessage.time < - std::chrono::seconds(global_config.cooldownTime.value) && + std::chrono::seconds(global_config.cooldownPerUser.value) && !global_users[user]->bypassCooldown) return Result(); } @@ -187,7 +187,8 @@ private: // Handlers const auto cmdLastExec = CommandHandler::get_last_executed_time( CommandHandler::get_command_key(extractedCommand)); if (const auto now = std::chrono::steady_clock::now(); - now - cmdLastExec < std::chrono::seconds(global_config.cooldownTime.value)) + now - cmdLastExec < + std::chrono::seconds(global_config.cooldownPerCommand.value)) return Result(); } diff --git a/cmake/modules/FetchDeps.cmake b/cmake/modules/FetchDeps.cmake index 05a7c7e..3998130 100644 --- a/cmake/modules/FetchDeps.cmake +++ b/cmake/modules/FetchDeps.cmake @@ -90,6 +90,7 @@ FetchContent_Declare( GIT_TAG "v1.90.4-docking" PATCH_COMMAND ${IMGUI_PATCH} UPDATE_DISCONNECTED 1 + OVERRIDE_FIND_PACKAGE ) # Fetch glfw