From 5cf2b50b633851f54e26b3a34c0ada9c14ed22c0 Mon Sep 17 00:00:00 2001 From: tt2468 Date: Mon, 21 Jun 2021 15:27:17 -0700 Subject: [PATCH] RequestHandler: Add some more requests --- src/requesthandler/RequestHandler.cpp | 2 + src/requesthandler/RequestHandler.h | 2 + src/requesthandler/RequestHandler_Inputs.cpp | 76 ++++++++++++++++++++ src/requesthandler/rpc/Request.cpp | 32 +++++++++ src/requesthandler/rpc/Request.h | 1 + 5 files changed, 113 insertions(+) diff --git a/src/requesthandler/RequestHandler.cpp b/src/requesthandler/RequestHandler.cpp index cc35629a..123959bf 100644 --- a/src/requesthandler/RequestHandler.cpp +++ b/src/requesthandler/RequestHandler.cpp @@ -48,6 +48,8 @@ const std::map RequestHandler::_handlerMap {"ToggleInputMute", &RequestHandler::ToggleInputMute}, {"GetInputVolume", &RequestHandler::GetInputVolume}, {"SetInputVolume", &RequestHandler::SetInputVolume}, + {"SetInputName", &RequestHandler::SetInputName}, + {"CreateInput", &RequestHandler::CreateInput}, }; RequestResult RequestHandler::ProcessRequest(const Request& request) diff --git a/src/requesthandler/RequestHandler.h b/src/requesthandler/RequestHandler.h index 9d9baae8..0aac251f 100644 --- a/src/requesthandler/RequestHandler.h +++ b/src/requesthandler/RequestHandler.h @@ -62,6 +62,8 @@ class RequestHandler { RequestResult ToggleInputMute(const Request&); RequestResult GetInputVolume(const Request&); RequestResult SetInputVolume(const Request&); + RequestResult SetInputName(const Request&); + RequestResult CreateInput(const Request&); static const std::map _handlerMap; }; diff --git a/src/requesthandler/RequestHandler_Inputs.cpp b/src/requesthandler/RequestHandler_Inputs.cpp index 98bd6bcd..1544ecfd 100644 --- a/src/requesthandler/RequestHandler_Inputs.cpp +++ b/src/requesthandler/RequestHandler_Inputs.cpp @@ -203,3 +203,79 @@ RequestResult RequestHandler::SetInputVolume(const Request& request) return RequestResult::Success(); } + +RequestResult RequestHandler::SetInputName(const Request& request) +{ + RequestStatus::RequestStatus statusCode; + std::string comment; + OBSSourceAutoRelease input = request.ValidateInput("inputName", statusCode, comment); + if (!input || !request.ValidateString("newInputName", statusCode, comment)) + return RequestResult::Error(statusCode, comment); + + std::string newInputName = request.RequestData["newInputName"]; + + OBSSourceAutoRelease existingSource = obs_get_source_by_name(newInputName.c_str()); + if (existingSource) + return RequestResult::Error(RequestStatus::SourceAlreadyExists, "A source already exists by that new input name."); + + obs_source_set_name(input, newInputName.c_str()); + + return RequestResult::Success(); +} + +RequestResult RequestHandler::CreateInput(const Request& request) +{ + // Initial validation + RequestStatus::RequestStatus statusCode; + std::string comment; + OBSSourceAutoRelease sceneSource = request.ValidateScene("sceneName", statusCode, comment); + if (!request.ValidateString("inputName", statusCode, comment) || + !request.ValidateString("inputKind", statusCode, comment) || + !sceneSource) + { + return RequestResult::Error(statusCode, comment); + } + + // Verify that no other inputs share the name + std::string inputName = request.RequestData["inputName"]; + OBSSourceAutoRelease existingInput = obs_get_source_by_name(inputName.c_str()); + if (existingInput) + return RequestResult::Error(RequestStatus::SourceAlreadyExists, "A source already exists by that input name."); + + // Verify that the input kind is valid + std::string inputKind = request.RequestData["inputKind"]; + auto kinds = Utils::Obs::ListHelper::GetInputKindList(); + if (std::find(kinds.begin(), kinds.end(), inputKind) == kinds.end()) + return RequestResult::Error(RequestStatus::InvalidInputKind, "Your specified input kind is not supported by OBS. Check that your specified kind is properly versioned and that any necessary plugins are loaded."); + + // Get input settings if they exist + OBSDataAutoRelease inputSettings = nullptr; + if (request.RequestData.contains("inputSettings") && !request.RequestData["inputSettings"].is_null()) { + if (!request.ValidateObject("inputSettings", statusCode, comment, true)) + return RequestResult::Error(statusCode, comment); + + inputSettings = Utils::Json::JsonToObsData(request.RequestData["inputSettings"]); + } + + // Get the destination scene + OBSScene scene = obs_scene_from_source(sceneSource); + + // Get scene item enable state if it exists + bool sceneItemEnabled = true; + if (request.RequestData.contains("sceneItemEnabled") && !request.RequestData["sceneItemEnabled"].is_null()) { + if (!request.ValidateBoolean("sceneItemEnabled", statusCode, comment)) + return RequestResult::Error(statusCode, comment); + + sceneItemEnabled = request.RequestData["sceneItemEnabled"]; + } + + // Create the input and add it as a scene item to the destination scene + obs_sceneitem_t *sceneItem = Utils::Obs::ActionHelper::CreateInput(inputName, inputKind, inputSettings, scene, sceneItemEnabled); + + if (!sceneItem) + return RequestResult::Error(RequestStatus::RequestProcessingFailed, "Creation of the input or scene item failed."); + + json responseData; + responseData["sceneItemId"] = obs_sceneitem_get_id(sceneItem); + return RequestResult::Success(responseData); +} diff --git a/src/requesthandler/rpc/Request.cpp b/src/requesthandler/rpc/Request.cpp index c5b705b9..b12703f0 100644 --- a/src/requesthandler/rpc/Request.cpp +++ b/src/requesthandler/rpc/Request.cpp @@ -136,6 +136,38 @@ const bool Request::ValidateArray(const std::string keyName, RequestStatus::Requ return true; } +obs_source_t *Request::ValidateScene(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const +{ + if (!ValidateString(keyName, statusCode, comment)) + return nullptr; + + std::string sceneName = RequestData[keyName]; + + obs_source_t *ret = obs_get_source_by_name(sceneName.c_str()); + if (!ret) { + statusCode = RequestStatus::SceneNotFound; + comment = std::string("No scene was found by the name of `") + sceneName + "`."; + return nullptr; + } + + if (obs_source_get_type(ret) != OBS_SOURCE_TYPE_SCENE) { + obs_source_release(ret); + statusCode = RequestStatus::InvalidSourceType; + comment = "The specified source is not a scene."; + return nullptr; + } + + OBSScene scene = obs_scene_from_source(ret); + if (obs_scene_is_group(scene)) { + obs_source_release(ret); + statusCode = RequestStatus::InvalidSourceType; + comment = "The specified source is not a scene."; + return nullptr; + } + + return ret; +} + obs_source_t *Request::ValidateInput(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const { if (!ValidateString(keyName, statusCode, comment)) diff --git a/src/requesthandler/rpc/Request.h b/src/requesthandler/rpc/Request.h index 7a35bbe7..1b327782 100644 --- a/src/requesthandler/rpc/Request.h +++ b/src/requesthandler/rpc/Request.h @@ -21,6 +21,7 @@ struct Request const bool ValidateObject(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment, const bool allowEmpty = false) const; const bool ValidateArray(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment, const bool allowEmpty = false) const; + obs_source_t *ValidateScene(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const; obs_source_t *ValidateInput(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const; const uint8_t RpcVersion;