mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
base: Refactor request stuff and finish more logic
This commit is contained in:
parent
687f53bc6d
commit
807a1501b7
@ -75,7 +75,9 @@ set(obs-websocket_SOURCES
|
|||||||
src/WebSocketProtocol.cpp
|
src/WebSocketProtocol.cpp
|
||||||
src/WebSocketSession.cpp
|
src/WebSocketSession.cpp
|
||||||
src/requesthandler/RequestHandler.cpp
|
src/requesthandler/RequestHandler.cpp
|
||||||
|
src/requesthandler/RequestHandler_General.cpp
|
||||||
src/requesthandler/rpc/Request.cpp
|
src/requesthandler/rpc/Request.cpp
|
||||||
|
src/requesthandler/rpc/RequestResult.cpp
|
||||||
src/forms/SettingsDialog.cpp
|
src/forms/SettingsDialog.cpp
|
||||||
src/utils/Json.cpp
|
src/utils/Json.cpp
|
||||||
src/utils/Crypto.cpp
|
src/utils/Crypto.cpp
|
||||||
@ -89,6 +91,8 @@ set(obs-websocket_HEADERS
|
|||||||
src/WebSocketSession.h
|
src/WebSocketSession.h
|
||||||
src/requesthandler/RequestHandler.h
|
src/requesthandler/RequestHandler.h
|
||||||
src/requesthandler/rpc/Request.h
|
src/requesthandler/rpc/Request.h
|
||||||
|
src/requesthandler/rpc/RequestResult.h
|
||||||
|
src/requesthandler/rpc/RequestStatus.h
|
||||||
src/forms/SettingsDialog.h
|
src/forms/SettingsDialog.h
|
||||||
src/utils/Utils.h)
|
src/utils/Utils.h)
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#include "WebSocketProtocol.h"
|
#include "WebSocketProtocol.h"
|
||||||
#include "obs-websocket.h"
|
#include "requesthandler/RequestHandler.h"
|
||||||
#include "utils/Utils.h"
|
#include "requesthandler/rpc/RequestStatus.h"
|
||||||
|
|
||||||
|
#include "utils/Utils.h"
|
||||||
#include "plugin-macros.generated.h"
|
#include "plugin-macros.generated.h"
|
||||||
|
|
||||||
bool IsSupportedRpcVersion(uint8_t requestedVersion)
|
bool IsSupportedRpcVersion(uint8_t requestedVersion)
|
||||||
@ -98,25 +99,22 @@ WebSocketProtocol::ProcessResult WebSocketProtocol::ProcessMessage(SessionPtr se
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto requestHandler = RequestHandler(session);
|
RequestHandler requestHandler;
|
||||||
RequestHandler::RequestResult result;
|
Request request(session->RpcVersion(), session->IgnoreNonFatalRequestChecks(), incomingMessage["requestType"], incomingMessage["requestData"]);
|
||||||
if (incomingMessage.contains("requestData")) {
|
|
||||||
result = requestHandler.ProcessRequest(incomingMessage["requestType"], incomingMessage["requestData"]);
|
RequestResult requestResult = requestHandler.ProcessRequest(request);
|
||||||
} else {
|
|
||||||
result = requestHandler.ProcessRequest(incomingMessage["requestType"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.result["messageType"] = "RequestResponse";
|
ret.result["messageType"] = "RequestResponse";
|
||||||
ret.result["requestType"] = incomingMessage["requestType"];
|
ret.result["requestType"] = incomingMessage["requestType"];
|
||||||
ret.result["requestId"] = incomingMessage["requestId"];
|
ret.result["requestId"] = incomingMessage["requestId"];
|
||||||
ret.result["requestStatus"] = {
|
ret.result["requestStatus"] = {
|
||||||
{"result", result.statusCode == RequestHandler::RequestStatus::Success},
|
{"result", requestResult.StatusCode == RequestStatus::Success},
|
||||||
{"code", result.statusCode}
|
{"code", requestResult.StatusCode}
|
||||||
};
|
};
|
||||||
if (result.comment != "")
|
if (!requestResult.Comment.empty())
|
||||||
ret.result["requestStatus"]["comment"] = result.comment;
|
ret.result["requestStatus"]["comment"] = requestResult.Comment;
|
||||||
if (!result.responseData.is_null())
|
if (requestResult.ResponseData.is_object())
|
||||||
ret.result["responseData"] = result.responseData;
|
ret.result["responseData"] = requestResult.ResponseData;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
} else if (messageType == "RequestBatch") {
|
} else if (messageType == "RequestBatch") {
|
||||||
@ -131,19 +129,13 @@ WebSocketProtocol::ProcessResult WebSocketProtocol::ProcessMessage(SessionPtr se
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto webSocketServer = GetWebSocketServer();
|
if (session->AuthenticationRequired()) {
|
||||||
if (!webSocketServer) {
|
|
||||||
blog(LOG_ERROR, "[WebSocketProtocol::ProcessMessage] Unable to fetch websocket server instance!");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (webSocketServer->AuthenticationRequired) {
|
|
||||||
if (!incomingMessage.contains("authentication")) {
|
if (!incomingMessage.contains("authentication")) {
|
||||||
ret.closeCode = WebSocketServer::WebSocketCloseCode::InvalidIdentifyParameter;
|
ret.closeCode = WebSocketServer::WebSocketCloseCode::InvalidIdentifyParameter;
|
||||||
ret.closeReason = "Your `Identify` payload is missing an `authentication` string, however authentication is required.";
|
ret.closeReason = "Your `Identify` payload is missing an `authentication` string, however authentication is required.";
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (!Utils::Crypto::CheckAuthenticationString(webSocketServer->AuthenticationSecret, session->Challenge(), incomingMessage["authentication"])) {
|
if (!Utils::Crypto::CheckAuthenticationString(session->Secret(), session->Challenge(), incomingMessage["authentication"])) {
|
||||||
ret.closeCode = WebSocketServer::WebSocketCloseCode::AuthenticationFailed;
|
ret.closeCode = WebSocketServer::WebSocketCloseCode::AuthenticationFailed;
|
||||||
ret.closeReason = "Authentication failed.";
|
ret.closeReason = "Authentication failed.";
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include "WebSocketServer.h"
|
#include "WebSocketServer.h"
|
||||||
#include "WebSocketSession.h"
|
#include "WebSocketSession.h"
|
||||||
#include "requesthandler/RequestHandler.h"
|
|
||||||
|
|
||||||
namespace WebSocketProtocol {
|
namespace WebSocketProtocol {
|
||||||
const std::vector<uint8_t> SupportedRpcVersions{
|
const std::vector<uint8_t> SupportedRpcVersions{
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
||||||
|
#include "obs-websocket.h"
|
||||||
|
|
||||||
#include "WebSocketServer.h"
|
#include "WebSocketServer.h"
|
||||||
#include "WebSocketProtocol.h"
|
#include "WebSocketProtocol.h"
|
||||||
#include "obs-websocket.h"
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "utils/Utils.h"
|
|
||||||
|
|
||||||
#include "plugin-macros.generated.h"
|
#include "plugin-macros.generated.h"
|
||||||
|
|
||||||
@ -260,6 +260,7 @@ void WebSocketServer::onOpen(websocketpp::connection_hdl hdl)
|
|||||||
// Configure session details
|
// Configure session details
|
||||||
session->SetRemoteAddress(conn->get_remote_endpoint());
|
session->SetRemoteAddress(conn->get_remote_endpoint());
|
||||||
session->SetConnectedAt(QDateTime::currentSecsSinceEpoch());
|
session->SetConnectedAt(QDateTime::currentSecsSinceEpoch());
|
||||||
|
session->SetAuthenticationRequired(AuthenticationRequired);
|
||||||
std::string contentType = conn->get_request_header("Content-Type");
|
std::string contentType = conn->get_request_header("Content-Type");
|
||||||
if (contentType == "") {
|
if (contentType == "") {
|
||||||
;
|
;
|
||||||
@ -280,6 +281,7 @@ void WebSocketServer::onOpen(websocketpp::connection_hdl hdl)
|
|||||||
helloMessage["availableRequests"] = WebSocketProtocol::GetRequestList();
|
helloMessage["availableRequests"] = WebSocketProtocol::GetRequestList();
|
||||||
helloMessage["availableEvents"] = WebSocketProtocol::GetEventList();
|
helloMessage["availableEvents"] = WebSocketProtocol::GetEventList();
|
||||||
if (AuthenticationRequired) {
|
if (AuthenticationRequired) {
|
||||||
|
session->SetSecret(AuthenticationSecret);
|
||||||
std::string sessionChallenge = Utils::Crypto::GenerateSalt();
|
std::string sessionChallenge = Utils::Crypto::GenerateSalt();
|
||||||
session->SetChallenge(sessionChallenge);
|
session->SetChallenge(sessionChallenge);
|
||||||
helloMessage["authentication"] = {};
|
helloMessage["authentication"] = {};
|
||||||
|
@ -5,20 +5,18 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include "utils/Utils.h"
|
||||||
#include <websocketpp/config/asio_no_tls.hpp>
|
#include <websocketpp/config/asio_no_tls.hpp>
|
||||||
#include <websocketpp/server.hpp>
|
#include <websocketpp/server.hpp>
|
||||||
|
|
||||||
#include "WebSocketSession.h"
|
#include "WebSocketSession.h"
|
||||||
|
|
||||||
using json = nlohmann::json;
|
|
||||||
|
|
||||||
class WebSocketServer : QObject
|
class WebSocketServer : QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum WebSocketCloseCode: uint16_t {
|
enum WebSocketCloseCode {
|
||||||
// Internal only
|
// Internal only
|
||||||
DontClose = 0,
|
DontClose = 0,
|
||||||
// Reserved
|
// Reserved
|
||||||
@ -45,7 +43,7 @@ class WebSocketServer : QObject
|
|||||||
InvalidContentType = 4010,
|
InvalidContentType = 4010,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum WebSocketEncoding: uint8_t {
|
enum WebSocketEncoding {
|
||||||
Json,
|
Json,
|
||||||
MsgPack
|
MsgPack
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#include <obs-module.h>
|
|
||||||
|
|
||||||
#include "WebSocketSession.h"
|
#include "WebSocketSession.h"
|
||||||
|
|
||||||
#include "plugin-macros.generated.h"
|
#include "plugin-macros.generated.h"
|
||||||
@ -72,6 +70,29 @@ void WebSocketSession::SetEncoding(uint8_t encoding)
|
|||||||
_encoding.store(encoding);
|
_encoding.store(encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WebSocketSession::AuthenticationRequired()
|
||||||
|
{
|
||||||
|
return _authenticationRequired.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebSocketSession::SetAuthenticationRequired(bool required)
|
||||||
|
{
|
||||||
|
_authenticationRequired.store(required);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string WebSocketSession::Secret()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_secretMutex);
|
||||||
|
std::string ret(_secret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebSocketSession::SetSecret(std::string secret)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_secretMutex);
|
||||||
|
_secret = secret;
|
||||||
|
}
|
||||||
|
|
||||||
std::string WebSocketSession::Challenge()
|
std::string WebSocketSession::Challenge()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_challengeMutex);
|
std::lock_guard<std::mutex> lock(_challengeMutex);
|
||||||
|
@ -28,6 +28,12 @@ class WebSocketSession
|
|||||||
uint8_t Encoding();
|
uint8_t Encoding();
|
||||||
void SetEncoding(uint8_t encoding);
|
void SetEncoding(uint8_t encoding);
|
||||||
|
|
||||||
|
bool AuthenticationRequired();
|
||||||
|
void SetAuthenticationRequired(bool required);
|
||||||
|
|
||||||
|
std::string Secret();
|
||||||
|
void SetSecret(std::string secret);
|
||||||
|
|
||||||
std::string Challenge();
|
std::string Challenge();
|
||||||
void SetChallenge(std::string challenge);
|
void SetChallenge(std::string challenge);
|
||||||
|
|
||||||
@ -55,6 +61,9 @@ class WebSocketSession
|
|||||||
std::atomic<uint64_t> _incomingMessages;
|
std::atomic<uint64_t> _incomingMessages;
|
||||||
std::atomic<uint64_t> _outgoingMessages;
|
std::atomic<uint64_t> _outgoingMessages;
|
||||||
std::atomic<uint8_t> _encoding;
|
std::atomic<uint8_t> _encoding;
|
||||||
|
std::atomic<bool> _authenticationRequired;
|
||||||
|
std::mutex _secretMutex;
|
||||||
|
std::string _secret;
|
||||||
std::mutex _challengeMutex;
|
std::mutex _challengeMutex;
|
||||||
std::string _challenge;
|
std::string _challenge;
|
||||||
std::atomic<uint8_t> _rpcVersion;
|
std::atomic<uint8_t> _rpcVersion;
|
||||||
|
@ -18,10 +18,11 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <util/base.h>
|
||||||
|
#define blog(level, msg, ...) blog(level, "[obs-websocket] " msg, ##__VA_ARGS__)
|
||||||
|
|
||||||
#define OBS_WEBSOCKET_VERSION "5.0.0"
|
#define OBS_WEBSOCKET_VERSION "5.0.0"
|
||||||
|
|
||||||
#define OBS_WEBSOCKET_RPC_VERSION 1
|
#define OBS_WEBSOCKET_RPC_VERSION 1
|
||||||
|
|
||||||
#define QT_TO_UTF8(str) str.toUtf8().constData()
|
#define QT_TO_UTF8(str) str.toUtf8().constData()
|
||||||
|
|
||||||
#define blog(level, msg, ...) blog(level, "[obs-websocket] " msg, ##__VA_ARGS__)
|
|
||||||
|
@ -1,27 +1,23 @@
|
|||||||
#include <obs.hpp>
|
|
||||||
#include <obs-frontend-api.h>
|
|
||||||
|
|
||||||
#include "RequestHandler.h"
|
#include "RequestHandler.h"
|
||||||
|
|
||||||
#include "../plugin-macros.generated.h"
|
#include "../plugin-macros.generated.h"
|
||||||
|
|
||||||
RequestHandler::RequestHandler(bool ignoreNonFatalRequestChecks, uint8_t rpcVersion) :
|
const std::map<std::string, RequestMethodHandler> RequestHandler::_handlerMap
|
||||||
_ignoreNonFatalRequestChecks(ignoreNonFatalRequestChecks),
|
|
||||||
_rpcVersion(rpcVersion)
|
|
||||||
{
|
{
|
||||||
|
{"GetVersion", &RequestHandler::GetVersion},
|
||||||
|
};
|
||||||
|
|
||||||
|
RequestResult RequestHandler::ProcessRequest(const Request& request)
|
||||||
|
{
|
||||||
|
if (!request.RequestData.is_null() && !request.RequestData.is_object())
|
||||||
|
return RequestResult::Error(RequestStatus::InvalidRequestParameterDataType, "Your request data is not an object.");
|
||||||
|
|
||||||
|
RequestMethodHandler handler;
|
||||||
|
try {
|
||||||
|
handler = _handlerMap.at(request.RequestType);
|
||||||
|
} catch (const std::out_of_range& oor) {
|
||||||
|
return RequestResult::Error(RequestStatus::UnknownRequestType, "Your request type is not valid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestHandler::RequestHandler(SessionPtr session) :
|
return std::bind(handler, this, std::placeholders::_1)(request);
|
||||||
_ignoreNonFatalRequestChecks(session->IgnoreNonFatalRequestChecks()),
|
|
||||||
_rpcVersion(session->RpcVersion())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
RequestHandler::RequestResult RequestHandler::ProcessRequest(std::string requestType, json requestData)
|
|
||||||
{
|
|
||||||
RequestHandler::RequestResult ret;
|
|
||||||
|
|
||||||
ret.statusCode = RequestHandler::RequestStatus::Success;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
@ -1,139 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <map>
|
||||||
|
|
||||||
#include "rpc/Request.h"
|
#include "rpc/Request.h"
|
||||||
#include "../WebSocketSession.h"
|
#include "rpc/RequestResult.h"
|
||||||
|
#include "../utils/Utils.h"
|
||||||
|
|
||||||
using json = nlohmann::json;
|
class RequestHandler;
|
||||||
|
typedef RequestResult(RequestHandler::*RequestMethodHandler)(const Request&);
|
||||||
|
|
||||||
class RequestHandler {
|
class RequestHandler {
|
||||||
public:
|
public:
|
||||||
enum RequestStatus: uint16_t {
|
RequestResult ProcessRequest(const Request& request);
|
||||||
Unknown = 0,
|
|
||||||
|
|
||||||
// For internal use to signify a successful parameter check
|
|
||||||
NoError = 10,
|
|
||||||
|
|
||||||
Success = 100,
|
|
||||||
|
|
||||||
// The request is denied because the client is not authenticated
|
|
||||||
AuthenticationMissing = 200,
|
|
||||||
// Connection has already been authenticated (for modules utilizing a request to provide authentication)
|
|
||||||
AlreadyAuthenticated = 201,
|
|
||||||
// Authentication request was denied (for modules utilizing a request to provide authentication)
|
|
||||||
AuthenticationDenied = 202,
|
|
||||||
// The `requestType` field is missing from the request data
|
|
||||||
RequestTypeMissing = 203,
|
|
||||||
// The request type is invalid (does not exist)
|
|
||||||
InvalidRequestType = 204,
|
|
||||||
// Generic error code (comment is expected to be provided)
|
|
||||||
GenericError = 205,
|
|
||||||
|
|
||||||
// A required request parameter is missing
|
|
||||||
MissingRequestParameter = 300,
|
|
||||||
|
|
||||||
// Generic invalid request parameter message
|
|
||||||
InvalidRequestParameter = 400,
|
|
||||||
// A request parameter has the wrong data type
|
|
||||||
InvalidRequestParameterDataType = 401,
|
|
||||||
// A request parameter (float or int) is out of valid range
|
|
||||||
RequestParameterOutOfRange = 402,
|
|
||||||
// A request parameter (string or array) is empty and cannot be
|
|
||||||
RequestParameterEmpty = 403,
|
|
||||||
|
|
||||||
// An output is running and cannot be in order to perform the request (generic)
|
|
||||||
OutputRunning = 500,
|
|
||||||
// An output is not running and should be
|
|
||||||
OutputNotRunning = 501,
|
|
||||||
// Stream is running and cannot be
|
|
||||||
StreamRunning = 502,
|
|
||||||
// Stream is not running and should be
|
|
||||||
StreamNotRunning = 503,
|
|
||||||
// Record is running and cannot be
|
|
||||||
RecordRunning = 504,
|
|
||||||
// Record is not running and should be
|
|
||||||
RecordNotRunning = 505,
|
|
||||||
// Record is paused and cannot be
|
|
||||||
RecordPaused = 506,
|
|
||||||
// Replay buffer is running and cannot be
|
|
||||||
ReplayBufferRunning = 507,
|
|
||||||
// Replay buffer is not running and should be
|
|
||||||
ReplayBufferNotRunning = 508,
|
|
||||||
// Replay buffer is disabled and cannot be
|
|
||||||
ReplayBufferDisabled = 509,
|
|
||||||
// Studio mode is active and cannot be
|
|
||||||
StudioModeActive = 510,
|
|
||||||
// Studio mode is not active and should be
|
|
||||||
StudioModeNotActive = 511,
|
|
||||||
|
|
||||||
// The specified source (obs_source_t) was of the invalid type (Eg. input instead of scene)
|
|
||||||
InvalidSourceType = 600,
|
|
||||||
// The specified source (obs_source_t) was not found (generic for input, filter, transition, scene)
|
|
||||||
SourceNotFound = 601,
|
|
||||||
// The specified source (obs_source_t) already exists. Applicable to inputs, filters, transitions, scenes
|
|
||||||
SourceAlreadyExists = 602,
|
|
||||||
// The specified input (obs_source_t-OBS_SOURCE_TYPE_FILTER) was not found
|
|
||||||
InputNotFound = 603,
|
|
||||||
// The specified input (obs_source_t-OBS_SOURCE_TYPE_INPUT) had the wrong kind
|
|
||||||
InvalidInputKind = 604,
|
|
||||||
// The specified filter (obs_source_t-OBS_SOURCE_TYPE_FILTER) was not found
|
|
||||||
FilterNotFound = 605,
|
|
||||||
// The specified transition (obs_source_t-OBS_SOURCE_TYPE_TRANSITION) was not found
|
|
||||||
TransitionNotFound = 606,
|
|
||||||
// The specified transition (obs_source_t-OBS_SOURCE_TYPE_TRANSITION) does not support setting its position (transition is of fixed type)
|
|
||||||
TransitionDurationFixed = 607,
|
|
||||||
// The specified scene (obs_source_t-OBS_SOURCE_TYPE_SCENE), (obs_scene_t) was not found
|
|
||||||
SceneNotFound = 608,
|
|
||||||
// The specified scene item (obs_sceneitem_t) was not found
|
|
||||||
SceneItemNotFound = 609,
|
|
||||||
// The specified scene collection was not found
|
|
||||||
SceneCollectionNotFound = 610,
|
|
||||||
// The specified profile was not found
|
|
||||||
ProfileNotFound = 611,
|
|
||||||
// The specified output (obs_output_t) was not found
|
|
||||||
OutputNotFound = 612,
|
|
||||||
// The specified encoder (obs_encoder_t) was not found
|
|
||||||
EncoderNotFound = 613,
|
|
||||||
// The specified service (obs_service_t) was not found
|
|
||||||
ServiceNotFound = 614,
|
|
||||||
// The specified hotkey was not found
|
|
||||||
HotkeyNotFound = 615,
|
|
||||||
// The specified directory was not found
|
|
||||||
DirectoryNotFound = 616,
|
|
||||||
// The specified config item (obs_config_t) was not found. Could be section or parameter name.
|
|
||||||
ConfigParameterNotFound = 617,
|
|
||||||
// The specified property (obs_properties_t) was not found
|
|
||||||
PropertyNotFound = 618,
|
|
||||||
|
|
||||||
// Processing the request failed unexpectedly
|
|
||||||
RequestProcessingFailed = 700,
|
|
||||||
// Starting the Output failed
|
|
||||||
OutputStartFailed = 701,
|
|
||||||
// Duplicating the scene item failed
|
|
||||||
SceneItemDuplicationFailed = 702,
|
|
||||||
// Rendering the screenshot failed
|
|
||||||
ScreenshotRenderFailed = 703,
|
|
||||||
// Encoding the screenshot failed
|
|
||||||
ScreenshotEncodeFailed = 704,
|
|
||||||
// Saving the screenshot failed
|
|
||||||
ScreenshotSaveFailed = 705,
|
|
||||||
// Creating the directory failed
|
|
||||||
DirectoryCreationFailed = 706,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RequestResult {
|
|
||||||
RequestStatus statusCode;
|
|
||||||
json responseData = nullptr;
|
|
||||||
std::string comment;
|
|
||||||
};
|
|
||||||
|
|
||||||
RequestHandler(bool ignoreNonFatalRequestChecks, uint8_t rpcVersion);
|
|
||||||
RequestHandler(SessionPtr session);
|
|
||||||
|
|
||||||
RequestResult ProcessRequest(std::string requestType, json requestData = json::object());
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _ignoreNonFatalRequestChecks;
|
RequestResult GetVersion(const Request&);
|
||||||
uint8_t _rpcVersion;
|
|
||||||
|
static const std::map<std::string, RequestMethodHandler> _handlerMap;
|
||||||
};
|
};
|
9
src/requesthandler/RequestHandler_General.cpp
Normal file
9
src/requesthandler/RequestHandler_General.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include "RequestHandler.h"
|
||||||
|
|
||||||
|
#include "../plugin-macros.generated.h"
|
||||||
|
|
||||||
|
RequestResult RequestHandler::GetVersion(const Request& request)
|
||||||
|
{
|
||||||
|
json ret{{"test", "pp"}};
|
||||||
|
return RequestResult::Success(ret);
|
||||||
|
}
|
@ -1,3 +1,14 @@
|
|||||||
#include "Request.h"
|
#include "Request.h"
|
||||||
|
|
||||||
#include "../../plugin-macros.generated.h"
|
#include "../../plugin-macros.generated.h"
|
||||||
|
|
||||||
|
Request::Request(uint8_t rpcVersion, bool ignoreNonFatalRequestChecks, std::string requestType, json requestData) :
|
||||||
|
RpcVersion(rpcVersion),
|
||||||
|
IgnoreNonFatalRequestChecks(ignoreNonFatalRequestChecks),
|
||||||
|
RequestType(requestType)
|
||||||
|
{
|
||||||
|
if (!requestData.is_object())
|
||||||
|
RequestData = json::object();
|
||||||
|
else
|
||||||
|
RequestData = requestData;
|
||||||
|
}
|
@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include "../../utils/Utils.h"
|
||||||
|
|
||||||
#include "../RequestHandler.h"
|
struct Request
|
||||||
|
|
||||||
class Request
|
|
||||||
{
|
{
|
||||||
public:
|
Request(uint8_t rpcVersion, bool ignoreNonFatalRequestChecks, std::string requestType, json requestData = nullptr);
|
||||||
;
|
|
||||||
private:
|
uint8_t RpcVersion;
|
||||||
;
|
bool IgnoreNonFatalRequestChecks;
|
||||||
|
std::string RequestType;
|
||||||
|
json RequestData;
|
||||||
};
|
};
|
18
src/requesthandler/rpc/RequestResult.cpp
Normal file
18
src/requesthandler/rpc/RequestResult.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#include "RequestResult.h"
|
||||||
|
|
||||||
|
RequestResult::RequestResult(RequestStatus statusCode, json responseData, std::string comment) :
|
||||||
|
StatusCode(statusCode),
|
||||||
|
ResponseData(responseData),
|
||||||
|
Comment(comment)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestResult RequestResult::Success(json responseData)
|
||||||
|
{
|
||||||
|
return RequestResult(RequestStatus::Success, responseData, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestResult RequestResult::Error(RequestStatus statusCode, std::string comment)
|
||||||
|
{
|
||||||
|
return RequestResult(statusCode, nullptr, comment);
|
||||||
|
}
|
14
src/requesthandler/rpc/RequestResult.h
Normal file
14
src/requesthandler/rpc/RequestResult.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "RequestStatus.h"
|
||||||
|
#include "../../utils/Utils.h"
|
||||||
|
|
||||||
|
struct RequestResult
|
||||||
|
{
|
||||||
|
RequestResult(RequestStatus statusCode = RequestStatus::Success, json responseData = nullptr, std::string comment = "");
|
||||||
|
static RequestResult Success(json responseData = nullptr);
|
||||||
|
static RequestResult Error(RequestStatus statusCode, std::string comment = "");
|
||||||
|
RequestStatus StatusCode;
|
||||||
|
json ResponseData;
|
||||||
|
std::string Comment;
|
||||||
|
};
|
106
src/requesthandler/rpc/RequestStatus.h
Normal file
106
src/requesthandler/rpc/RequestStatus.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum RequestStatus {
|
||||||
|
Unknown = 0,
|
||||||
|
|
||||||
|
// For internal use to signify a successful parameter check
|
||||||
|
NoError = 10,
|
||||||
|
|
||||||
|
Success = 100,
|
||||||
|
|
||||||
|
// The request type is invalid (does not exist)
|
||||||
|
UnknownRequestType = 204,
|
||||||
|
// Generic error code (comment is expected to be provided)
|
||||||
|
GenericError = 205,
|
||||||
|
|
||||||
|
// A required request parameter is missing
|
||||||
|
MissingRequestParameter = 300,
|
||||||
|
|
||||||
|
// Generic invalid request parameter message
|
||||||
|
InvalidRequestParameter = 400,
|
||||||
|
// A request parameter has the wrong data type
|
||||||
|
InvalidRequestParameterDataType = 401,
|
||||||
|
// A request parameter (float or int) is out of valid range
|
||||||
|
RequestParameterOutOfRange = 402,
|
||||||
|
// A request parameter (string or array) is empty and cannot be
|
||||||
|
RequestParameterEmpty = 403,
|
||||||
|
|
||||||
|
// An output is running and cannot be in order to perform the request (generic)
|
||||||
|
OutputRunning = 500,
|
||||||
|
// An output is not running and should be
|
||||||
|
OutputNotRunning = 501,
|
||||||
|
// Stream is running and cannot be
|
||||||
|
StreamRunning = 502,
|
||||||
|
// Stream is not running and should be
|
||||||
|
StreamNotRunning = 503,
|
||||||
|
// Record is running and cannot be
|
||||||
|
RecordRunning = 504,
|
||||||
|
// Record is not running and should be
|
||||||
|
RecordNotRunning = 505,
|
||||||
|
// Record is paused and cannot be
|
||||||
|
RecordPaused = 506,
|
||||||
|
// Replay buffer is running and cannot be
|
||||||
|
ReplayBufferRunning = 507,
|
||||||
|
// Replay buffer is not running and should be
|
||||||
|
ReplayBufferNotRunning = 508,
|
||||||
|
// Replay buffer is disabled and cannot be
|
||||||
|
ReplayBufferDisabled = 509,
|
||||||
|
// Studio mode is active and cannot be
|
||||||
|
StudioModeActive = 510,
|
||||||
|
// Studio mode is not active and should be
|
||||||
|
StudioModeNotActive = 511,
|
||||||
|
|
||||||
|
// The specified source (obs_source_t) was of the invalid type (Eg. input instead of scene)
|
||||||
|
InvalidSourceType = 600,
|
||||||
|
// The specified source (obs_source_t) was not found (generic for input, filter, transition, scene)
|
||||||
|
SourceNotFound = 601,
|
||||||
|
// The specified source (obs_source_t) already exists. Applicable to inputs, filters, transitions, scenes
|
||||||
|
SourceAlreadyExists = 602,
|
||||||
|
// The specified input (obs_source_t-OBS_SOURCE_TYPE_FILTER) was not found
|
||||||
|
InputNotFound = 603,
|
||||||
|
// The specified input (obs_source_t-OBS_SOURCE_TYPE_INPUT) had the wrong kind
|
||||||
|
InvalidInputKind = 604,
|
||||||
|
// The specified filter (obs_source_t-OBS_SOURCE_TYPE_FILTER) was not found
|
||||||
|
FilterNotFound = 605,
|
||||||
|
// The specified transition (obs_source_t-OBS_SOURCE_TYPE_TRANSITION) was not found
|
||||||
|
TransitionNotFound = 606,
|
||||||
|
// The specified transition (obs_source_t-OBS_SOURCE_TYPE_TRANSITION) does not support setting its position (transition is of fixed type)
|
||||||
|
TransitionDurationFixed = 607,
|
||||||
|
// The specified scene (obs_source_t-OBS_SOURCE_TYPE_SCENE), (obs_scene_t) was not found
|
||||||
|
SceneNotFound = 608,
|
||||||
|
// The specified scene item (obs_sceneitem_t) was not found
|
||||||
|
SceneItemNotFound = 609,
|
||||||
|
// The specified scene collection was not found
|
||||||
|
SceneCollectionNotFound = 610,
|
||||||
|
// The specified profile was not found
|
||||||
|
ProfileNotFound = 611,
|
||||||
|
// The specified output (obs_output_t) was not found
|
||||||
|
OutputNotFound = 612,
|
||||||
|
// The specified encoder (obs_encoder_t) was not found
|
||||||
|
EncoderNotFound = 613,
|
||||||
|
// The specified service (obs_service_t) was not found
|
||||||
|
ServiceNotFound = 614,
|
||||||
|
// The specified hotkey was not found
|
||||||
|
HotkeyNotFound = 615,
|
||||||
|
// The specified directory was not found
|
||||||
|
DirectoryNotFound = 616,
|
||||||
|
// The specified config item (obs_config_t) was not found. Could be section or parameter name.
|
||||||
|
ConfigParameterNotFound = 617,
|
||||||
|
// The specified property (obs_properties_t) was not found
|
||||||
|
PropertyNotFound = 618,
|
||||||
|
|
||||||
|
// Processing the request failed unexpectedly
|
||||||
|
RequestProcessingFailed = 700,
|
||||||
|
// Starting the Output failed
|
||||||
|
OutputStartFailed = 701,
|
||||||
|
// Duplicating the scene item failed
|
||||||
|
SceneItemDuplicationFailed = 702,
|
||||||
|
// Rendering the screenshot failed
|
||||||
|
ScreenshotRenderFailed = 703,
|
||||||
|
// Encoding the screenshot failed
|
||||||
|
ScreenshotEncodeFailed = 704,
|
||||||
|
// Saving the screenshot failed
|
||||||
|
ScreenshotSaveFailed = 705,
|
||||||
|
// Creating the directory failed
|
||||||
|
DirectoryCreationFailed = 706,
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user