Base: More code cleanup and fixes

This commit is contained in:
tt2468 2021-09-04 10:47:51 -07:00
parent 7e1e1bc33c
commit e89c0c2b05
26 changed files with 338 additions and 346 deletions

View File

@ -1,7 +1,6 @@
#include <obs-frontend-api.h> #include <obs-frontend-api.h>
#include "Config.h" #include "Config.h"
#include "plugin-macros.generated.h"
#include "utils/Crypto.h" #include "utils/Crypto.h"
#include "utils/Platform.h" #include "utils/Platform.h"

View File

@ -3,6 +3,8 @@
#include <QString> #include <QString>
#include <util/config-file.h> #include <util/config-file.h>
#include "plugin-macros.generated.h"
class Config { class Config {
public: public:
Config(); Config();

View File

@ -11,7 +11,6 @@
#include "Config.h" #include "Config.h"
#include "utils/Crypto.h" #include "utils/Crypto.h"
#include "utils/Platform.h" #include "utils/Platform.h"
#include "plugin-macros.generated.h"
WebSocketServer::WebSocketServer() : WebSocketServer::WebSocketServer() :
QObject(nullptr), QObject(nullptr),

View File

@ -9,6 +9,7 @@
#include "utils/Json.h" #include "utils/Json.h"
#include "WebSocketSession.h" #include "WebSocketSession.h"
#include "plugin-macros.generated.h"
class WebSocketServer : QObject class WebSocketServer : QObject
{ {

View File

@ -1,324 +1,322 @@
#include <QtConcurrent> #include <QtConcurrent>
#include <obs-module.h> #include <obs-module.h>
#include "WebSocketServer.h" #include "WebSocketServer.h"
#include "requesthandler/RequestHandler.h" #include "requesthandler/RequestHandler.h"
#include "eventhandler/EventHandler.h" #include "eventhandler/EventHandler.h"
#include "obs-websocket.h" #include "obs-websocket.h"
#include "Config.h" #include "Config.h"
#include "plugin-macros.generated.h" #include "utils/Crypto.h"
#include "utils/Crypto.h" #include "utils/Platform.h"
#include "utils/Json.h"
#include "utils/Platform.h" namespace WebSocketOpCode {
enum WebSocketOpCode: uint8_t {
namespace WebSocketOpCode { Hello = 0,
enum WebSocketOpCode: uint8_t { Identify = 1,
Hello = 0, Identified = 2,
Identify = 1, Reidentify = 3,
Identified = 2, Event = 5,
Reidentify = 3, Request = 6,
Event = 5, RequestResponse = 7,
Request = 6, RequestBatch = 8,
RequestResponse = 7, RequestBatchResponse = 9,
RequestBatch = 8, };
RequestBatchResponse = 9, };
};
}; bool IsSupportedRpcVersion(uint8_t requestedVersion)
{
bool IsSupportedRpcVersion(uint8_t requestedVersion) return (requestedVersion == 1);
{ }
return (requestedVersion == 1);
} void WebSocketServer::SetSessionParameters(SessionPtr session, ProcessResult &ret, json payloadData)
{
void WebSocketServer::SetSessionParameters(SessionPtr session, ProcessResult &ret, json payloadData) if (payloadData.contains("ignoreInvalidMessages")) {
{ if (!payloadData["ignoreInvalidMessages"].is_boolean()) {
if (payloadData.contains("ignoreInvalidMessages")) { ret.closeCode = WebSocketCloseCode::InvalidDataKeyType;
if (!payloadData["ignoreInvalidMessages"].is_boolean()) { ret.closeReason = "Your `ignoreInvalidMessages` is not a boolean.";
ret.closeCode = WebSocketCloseCode::InvalidDataKeyType; return;
ret.closeReason = "Your `ignoreInvalidMessages` is not a boolean."; }
return; session->SetIgnoreInvalidMessages(payloadData["ignoreInvalidMessages"]);
} }
session->SetIgnoreInvalidMessages(payloadData["ignoreInvalidMessages"]);
} if (payloadData.contains("ignoreNonFatalRequestChecks")) {
if (!payloadData["ignoreNonFatalRequestChecks"].is_boolean()) {
if (payloadData.contains("ignoreNonFatalRequestChecks")) { ret.closeCode = WebSocketCloseCode::InvalidDataKeyType;
if (!payloadData["ignoreNonFatalRequestChecks"].is_boolean()) { ret.closeReason = "Your `ignoreNonFatalRequestChecks` is not a boolean.";
ret.closeCode = WebSocketCloseCode::InvalidDataKeyType; return;
ret.closeReason = "Your `ignoreNonFatalRequestChecks` is not a boolean."; }
return; session->SetIgnoreNonFatalRequestChecks(payloadData["ignoreNonFatalRequestChecks"]);
} }
session->SetIgnoreNonFatalRequestChecks(payloadData["ignoreNonFatalRequestChecks"]);
} if (payloadData.contains("eventSubscriptions")) {
if (!payloadData["eventSubscriptions"].is_number_unsigned()) {
if (payloadData.contains("eventSubscriptions")) { ret.closeCode = WebSocketCloseCode::InvalidDataKeyType;
if (!payloadData["eventSubscriptions"].is_number_unsigned()) { ret.closeReason = "Your `eventSubscriptions` is not an unsigned number.";
ret.closeCode = WebSocketCloseCode::InvalidDataKeyType; return;
ret.closeReason = "Your `eventSubscriptions` is not an unsigned number."; }
return; session->SetEventSubscriptions(payloadData["eventSubscriptions"]);
} }
session->SetEventSubscriptions(payloadData["eventSubscriptions"]); }
}
} void WebSocketServer::ProcessMessage(SessionPtr session, WebSocketServer::ProcessResult &ret, uint8_t opCode, json payloadData)
{
void WebSocketServer::ProcessMessage(SessionPtr session, WebSocketServer::ProcessResult &ret, uint8_t opCode, json payloadData) if (!payloadData.is_object()) {
{ if (payloadData.is_null()) {
if (!payloadData.is_object()) { ret.closeCode = WebSocketCloseCode::MissingDataKey;
if (payloadData.is_null()) { ret.closeReason = "Your payload is missing data (`d`).";
ret.closeCode = WebSocketCloseCode::MissingDataKey; } else {
ret.closeReason = "Your payload is missing data (`d`)."; ret.closeCode = WebSocketCloseCode::InvalidDataKeyType;
} else { ret.closeReason = "Your payload's data (`d`) is not an object.";
ret.closeCode = WebSocketCloseCode::InvalidDataKeyType; }
ret.closeReason = "Your payload's data (`d`) is not an object."; return;
} }
return;
} // Only `Identify` is allowed when not identified
if (!session->IsIdentified() && opCode != 1) {
// Only `Identify` is allowed when not identified ret.closeCode = WebSocketCloseCode::NotIdentified;
if (!session->IsIdentified() && opCode != 1) { ret.closeReason = "You attempted to send a non-Identify message while not identified.";
ret.closeCode = WebSocketCloseCode::NotIdentified; return;
ret.closeReason = "You attempted to send a non-Identify message while not identified."; }
return;
} switch (opCode) {
case WebSocketOpCode::Identify: { // Identify
switch (opCode) { std::unique_lock<std::mutex> sessionLock(session->OperationMutex);
case WebSocketOpCode::Identify: { // Identify if (session->IsIdentified()) {
std::unique_lock<std::mutex> sessionLock(session->OperationMutex); if (!session->IgnoreInvalidMessages()) {
if (session->IsIdentified()) { ret.closeCode = WebSocketCloseCode::AlreadyIdentified;
if (!session->IgnoreInvalidMessages()) { ret.closeReason = "You are already Identified with the obs-websocket server.";
ret.closeCode = WebSocketCloseCode::AlreadyIdentified; }
ret.closeReason = "You are already Identified with the obs-websocket server."; return;
} }
return;
} if (session->AuthenticationRequired()) {
if (!payloadData.contains("authentication")) {
if (session->AuthenticationRequired()) { ret.closeCode = WebSocketCloseCode::AuthenticationFailed;
if (!payloadData.contains("authentication")) { ret.closeReason = "Your payload's data is missing an `authentication` string, however authentication is required.";
ret.closeCode = WebSocketCloseCode::AuthenticationFailed; return;
ret.closeReason = "Your payload's data is missing an `authentication` string, however authentication is required."; }
return; if (!Utils::Crypto::CheckAuthenticationString(session->Secret(), session->Challenge(), payloadData["authentication"])) {
} auto conf = GetConfig();
if (!Utils::Crypto::CheckAuthenticationString(session->Secret(), session->Challenge(), payloadData["authentication"])) { if (conf && conf->AlertsEnabled) {
auto conf = GetConfig(); QString title = obs_module_text("OBSWebSocket.TrayNotification.AuthenticationFailed.Title");
if (conf && conf->AlertsEnabled) { QString body = QString(obs_module_text("OBSWebSocket.TrayNotification.AuthenticationFailed.Body")).arg(QString::fromStdString(session->RemoteAddress()));
QString title = obs_module_text("OBSWebSocket.TrayNotification.AuthenticationFailed.Title"); Utils::Platform::SendTrayNotification(QSystemTrayIcon::Warning, title, body);
QString body = QString(obs_module_text("OBSWebSocket.TrayNotification.AuthenticationFailed.Body")).arg(QString::fromStdString(session->RemoteAddress())); }
Utils::Platform::SendTrayNotification(QSystemTrayIcon::Warning, title, body); ret.closeCode = WebSocketCloseCode::AuthenticationFailed;
} ret.closeReason = "Authentication failed.";
ret.closeCode = WebSocketCloseCode::AuthenticationFailed; return;
ret.closeReason = "Authentication failed."; }
return; }
}
} if (!payloadData.contains("rpcVersion")) {
ret.closeCode = WebSocketCloseCode::MissingDataKey;
if (!payloadData.contains("rpcVersion")) { ret.closeReason = "Your payload's data is missing an `rpcVersion`.";
ret.closeCode = WebSocketCloseCode::MissingDataKey; return;
ret.closeReason = "Your payload's data is missing an `rpcVersion`."; }
return;
} if (!payloadData["rpcVersion"].is_number_unsigned()) {
ret.closeCode = WebSocketCloseCode::InvalidDataKeyType;
if (!payloadData["rpcVersion"].is_number_unsigned()) { ret.closeReason = "Your `rpcVersion` is not an unsigned number.";
ret.closeCode = WebSocketCloseCode::InvalidDataKeyType; }
ret.closeReason = "Your `rpcVersion` is not an unsigned number.";
} uint8_t requestedRpcVersion = payloadData["rpcVersion"];
if (!IsSupportedRpcVersion(requestedRpcVersion)) {
uint8_t requestedRpcVersion = payloadData["rpcVersion"]; ret.closeCode = WebSocketCloseCode::UnsupportedRpcVersion;
if (!IsSupportedRpcVersion(requestedRpcVersion)) { ret.closeReason = "Your requested RPC version is not supported by this server.";
ret.closeCode = WebSocketCloseCode::UnsupportedRpcVersion; return;
ret.closeReason = "Your requested RPC version is not supported by this server."; }
return; session->SetRpcVersion(requestedRpcVersion);
}
session->SetRpcVersion(requestedRpcVersion); SetSessionParameters(session, ret, payloadData);
if (ret.closeCode != WebSocketCloseCode::DontClose) {
SetSessionParameters(session, ret, payloadData); return;
if (ret.closeCode != WebSocketCloseCode::DontClose) { }
return;
} // Increment refs for event subscriptions
auto eventHandler = GetEventHandler();
// Increment refs for event subscriptions eventHandler->ProcessSubscription(session->EventSubscriptions());
auto eventHandler = GetEventHandler();
eventHandler->ProcessSubscription(session->EventSubscriptions()); // Mark session as identified
session->SetIsIdentified(true);
// Mark session as identified
session->SetIsIdentified(true); // Send desktop notification. TODO: Move to UI code
auto conf = GetConfig();
// Send desktop notification. TODO: Move to UI code if (conf && conf->AlertsEnabled) {
auto conf = GetConfig(); QString title = obs_module_text("OBSWebSocket.TrayNotification.Identified.Title");
if (conf && conf->AlertsEnabled) { QString body = QString(obs_module_text("OBSWebSocket.TrayNotification.Identified.Body")).arg(QString::fromStdString(session->RemoteAddress()));
QString title = obs_module_text("OBSWebSocket.TrayNotification.Identified.Title"); Utils::Platform::SendTrayNotification(QSystemTrayIcon::Information, title, body);
QString body = QString(obs_module_text("OBSWebSocket.TrayNotification.Identified.Body")).arg(QString::fromStdString(session->RemoteAddress())); }
Utils::Platform::SendTrayNotification(QSystemTrayIcon::Information, title, body);
} ret.result["op"] = WebSocketOpCode::Identified;
ret.result["d"]["negotiatedRpcVersion"] = session->RpcVersion();
ret.result["op"] = WebSocketOpCode::Identified; } return;
ret.result["d"]["negotiatedRpcVersion"] = session->RpcVersion(); case WebSocketOpCode::Reidentify: { // Reidentify
} return; std::unique_lock<std::mutex> sessionLock(session->OperationMutex);
case WebSocketOpCode::Reidentify: { // Reidentify
std::unique_lock<std::mutex> sessionLock(session->OperationMutex); // Decrement refs for current subscriptions
auto eventHandler = GetEventHandler();
// Decrement refs for current subscriptions eventHandler->ProcessUnsubscription(session->EventSubscriptions());
auto eventHandler = GetEventHandler();
eventHandler->ProcessUnsubscription(session->EventSubscriptions()); SetSessionParameters(session, ret, payloadData);
if (ret.closeCode != WebSocketCloseCode::DontClose) {
SetSessionParameters(session, ret, payloadData); return;
if (ret.closeCode != WebSocketCloseCode::DontClose) { }
return;
} // Increment refs for new subscriptions
eventHandler->ProcessSubscription(session->EventSubscriptions());
// Increment refs for new subscriptions
eventHandler->ProcessSubscription(session->EventSubscriptions()); ret.result["op"] = WebSocketOpCode::Identified;
ret.result["d"]["negotiatedRpcVersion"] = session->RpcVersion();
ret.result["op"] = WebSocketOpCode::Identified; } return;
ret.result["d"]["negotiatedRpcVersion"] = session->RpcVersion(); case WebSocketOpCode::Request: { // Request
} return; // RequestID checking has to be done here where we are able to close the connection.
case WebSocketOpCode::Request: { // Request if (!payloadData.contains("requestId")) {
// RequestID checking has to be done here where we are able to close the connection. if (!session->IgnoreInvalidMessages()) {
if (!payloadData.contains("requestId")) { ret.closeCode = WebSocketCloseCode::MissingDataKey;
if (!session->IgnoreInvalidMessages()) { ret.closeReason = "Your payload data is missing a `requestId`.";
ret.closeCode = WebSocketCloseCode::MissingDataKey; }
ret.closeReason = "Your payload data is missing a `requestId`."; return;
} }
return;
} RequestHandler requestHandler(session);
Request request(payloadData["requestType"], payloadData["requestData"]);
RequestHandler requestHandler(session);
Request request(payloadData["requestType"], payloadData["requestData"]); RequestResult requestResult = requestHandler.ProcessRequest(request);
RequestResult requestResult = requestHandler.ProcessRequest(request); json resultPayloadData;
resultPayloadData["requestType"] = payloadData["requestType"];
json resultPayloadData; resultPayloadData["requestId"] = payloadData["requestId"];
resultPayloadData["requestType"] = payloadData["requestType"]; resultPayloadData["requestStatus"] = {
resultPayloadData["requestId"] = payloadData["requestId"]; {"result", requestResult.StatusCode == RequestStatus::Success},
resultPayloadData["requestStatus"] = { {"code", requestResult.StatusCode}
{"result", requestResult.StatusCode == RequestStatus::Success}, };
{"code", requestResult.StatusCode} if (!requestResult.Comment.empty())
}; resultPayloadData["requestStatus"]["comment"] = requestResult.Comment;
if (!requestResult.Comment.empty()) if (requestResult.ResponseData.is_object())
resultPayloadData["requestStatus"]["comment"] = requestResult.Comment; resultPayloadData["responseData"] = requestResult.ResponseData;
if (requestResult.ResponseData.is_object()) ret.result["op"] = WebSocketOpCode::RequestResponse;
resultPayloadData["responseData"] = requestResult.ResponseData; ret.result["d"] = resultPayloadData;
ret.result["op"] = WebSocketOpCode::RequestResponse; } return;
ret.result["d"] = resultPayloadData; case WebSocketOpCode::RequestBatch: { // RequestBatch
} return; // RequestID checking has to be done here where we are able to close the connection.
case WebSocketOpCode::RequestBatch: { // RequestBatch if (!payloadData.contains("requestId")) {
// RequestID checking has to be done here where we are able to close the connection. if (!session->IgnoreInvalidMessages()) {
if (!payloadData.contains("requestId")) { ret.closeCode = WebSocketCloseCode::MissingDataKey;
if (!session->IgnoreInvalidMessages()) { ret.closeReason = "Your payload data is missing a `requestId`.";
ret.closeCode = WebSocketCloseCode::MissingDataKey; }
ret.closeReason = "Your payload data is missing a `requestId`."; return;
} }
return;
} if (!payloadData.contains("requests")) {
if (!session->IgnoreInvalidMessages()) {
if (!payloadData.contains("requests")) { ret.closeCode = WebSocketCloseCode::MissingDataKey;
if (!session->IgnoreInvalidMessages()) { ret.closeReason = "Your payload data is missing a `requests`.";
ret.closeCode = WebSocketCloseCode::MissingDataKey; }
ret.closeReason = "Your payload data is missing a `requests`."; return;
} }
return;
} if (!payloadData["requests"].is_array()) {
if (!session->IgnoreInvalidMessages()) {
if (!payloadData["requests"].is_array()) { ret.closeCode = WebSocketCloseCode::InvalidDataKeyType;
if (!session->IgnoreInvalidMessages()) { ret.closeReason = "Your `requests` is not an array.";
ret.closeCode = WebSocketCloseCode::InvalidDataKeyType; }
ret.closeReason = "Your `requests` is not an array."; return;
} }
return;
} std::vector<json> requests = payloadData["requests"];
json results = json::array();
std::vector<json> requests = payloadData["requests"];
json results = json::array(); RequestHandler requestHandler(session);
for (auto requestJson : requests) {
RequestHandler requestHandler(session); Request request(requestJson["requestType"], requestJson["requestData"]);
for (auto requestJson : requests) {
Request request(requestJson["requestType"], requestJson["requestData"]); RequestResult requestResult = requestHandler.ProcessRequest(request);
RequestResult requestResult = requestHandler.ProcessRequest(request); json result;
result["requestType"] = requestJson["requestType"];
json result;
result["requestType"] = requestJson["requestType"]; if (requestJson.contains("requestId"))
result["requestId"] = requestJson["requestId"];
if (requestJson.contains("requestId"))
result["requestId"] = requestJson["requestId"]; result["requestStatus"] = {
{"result", requestResult.StatusCode == RequestStatus::Success},
result["requestStatus"] = { {"code", requestResult.StatusCode}
{"result", requestResult.StatusCode == RequestStatus::Success}, };
{"code", requestResult.StatusCode}
}; if (!requestResult.Comment.empty())
result["requestStatus"]["comment"] = requestResult.Comment;
if (!requestResult.Comment.empty())
result["requestStatus"]["comment"] = requestResult.Comment; if (requestResult.ResponseData.is_object())
result["responseData"] = requestResult.ResponseData;
if (requestResult.ResponseData.is_object())
result["responseData"] = requestResult.ResponseData; results.push_back(result);
}
results.push_back(result);
} ret.result["op"] = WebSocketOpCode::RequestBatchResponse;
ret.result["d"]["requestId"] = payloadData["requestId"];
ret.result["op"] = WebSocketOpCode::RequestBatchResponse; ret.result["d"]["results"] = results;
ret.result["d"]["requestId"] = payloadData["requestId"]; } return;
ret.result["d"]["results"] = results; default:
} return; if (!session->IgnoreInvalidMessages()) {
default: ret.closeCode = WebSocketCloseCode::UnknownOpCode;
if (!session->IgnoreInvalidMessages()) { ret.closeReason = std::string("Unknown OpCode: %s") + std::to_string(opCode);
ret.closeCode = WebSocketCloseCode::UnknownOpCode; }
ret.closeReason = std::string("Unknown OpCode: %s") + std::to_string(opCode); return;
} }
return; }
}
} void WebSocketServer::BroadcastEvent(uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion)
{
void WebSocketServer::BroadcastEvent(uint64_t requiredIntent, std::string eventType, json eventData, uint8_t rpcVersion) if (!_server.is_listening())
{ return;
if (!_server.is_listening())
return; QtConcurrent::run(&_threadPool, [=]() {
// Populate message object
QtConcurrent::run(&_threadPool, [=]() { json eventMessage;
// Populate message object eventMessage["op"] = 5;
json eventMessage; eventMessage["d"]["eventType"] = eventType;
eventMessage["op"] = 5; eventMessage["d"]["eventIntent"] = requiredIntent;
eventMessage["d"]["eventType"] = eventType; if (eventData.is_object())
eventMessage["d"]["eventIntent"] = requiredIntent; eventMessage["d"]["eventData"] = eventData;
if (eventData.is_object())
eventMessage["d"]["eventData"] = eventData; // Initialize objects. The broadcast process only dumps the data when its needed.
std::string messageJson;
// Initialize objects. The broadcast process only dumps the data when its needed. std::string messageMsgPack;
std::string messageJson;
std::string messageMsgPack; // Recurse connected sessions and send the event to suitable sessions.
std::unique_lock<std::mutex> lock(_sessionMutex);
// Recurse connected sessions and send the event to suitable sessions. for (auto & it : _sessions) {
std::unique_lock<std::mutex> lock(_sessionMutex); if (!it.second->IsIdentified()) {
for (auto & it : _sessions) { continue;
if (!it.second->IsIdentified()) { }
continue; if (rpcVersion && it.second->RpcVersion() != rpcVersion) {
} continue;
if (rpcVersion && it.second->RpcVersion() != rpcVersion) { }
continue; if ((it.second->EventSubscriptions() & requiredIntent) != 0) {
} websocketpp::lib::error_code errorCode;
if ((it.second->EventSubscriptions() & requiredIntent) != 0) { switch (it.second->Encoding()) {
websocketpp::lib::error_code errorCode; case WebSocketEncoding::Json:
switch (it.second->Encoding()) { if (messageJson.empty()) {
case WebSocketEncoding::Json: messageJson = eventMessage.dump();
if (messageJson.empty()) { }
messageJson = eventMessage.dump(); _server.send((websocketpp::connection_hdl)it.first, messageJson, websocketpp::frame::opcode::text, errorCode);
} it.second->IncrementOutgoingMessages();
_server.send((websocketpp::connection_hdl)it.first, messageJson, websocketpp::frame::opcode::text, errorCode); break;
it.second->IncrementOutgoingMessages(); case WebSocketEncoding::MsgPack:
break; if (messageMsgPack.empty()) {
case WebSocketEncoding::MsgPack: auto msgPackData = json::to_msgpack(eventMessage);
if (messageMsgPack.empty()) { messageMsgPack = std::string(msgPackData.begin(), msgPackData.end());
auto msgPackData = json::to_msgpack(eventMessage); }
messageMsgPack = std::string(msgPackData.begin(), msgPackData.end()); _server.send((websocketpp::connection_hdl)it.first, messageMsgPack, websocketpp::frame::opcode::binary, errorCode);
} it.second->IncrementOutgoingMessages();
_server.send((websocketpp::connection_hdl)it.first, messageMsgPack, websocketpp::frame::opcode::binary, errorCode); break;
it.second->IncrementOutgoingMessages(); }
break; if (errorCode)
} blog(LOG_ERROR, "[WebSocketServer::BroadcastEvent] Error sending event message: %s", errorCode.message().c_str());
if (errorCode) }
blog(LOG_ERROR, "[WebSocketServer::BroadcastEvent] Error sending event message: %s", errorCode.message().c_str()); }
} lock.unlock();
} if (_debugEnabled && (EventSubscription::All & requiredIntent) != 0) // Don't log high volume events
lock.unlock(); blog(LOG_INFO, "[WebSocketServer::BroadcastEvent] Outgoing event:\n%s", eventMessage.dump(2).c_str());
if (_debugEnabled && (EventSubscription::All & requiredIntent) != 0) // Don't log high volume events });
blog(LOG_INFO, "[WebSocketServer::BroadcastEvent] Outgoing event:\n%s", eventMessage.dump(2).c_str()); }
});
}

View File

@ -1,6 +1,5 @@
#include "WebSocketSession.h" #include "WebSocketSession.h"
#include "eventhandler/types/EventSubscription.h" #include "eventhandler/types/EventSubscription.h"
#include "plugin-macros.generated.h"
WebSocketSession::WebSocketSession() : WebSocketSession::WebSocketSession() :
_remoteAddress(""), _remoteAddress(""),

View File

@ -5,6 +5,8 @@
#include <atomic> #include <atomic>
#include <memory> #include <memory>
#include "plugin-macros.generated.h"
class WebSocketSession; class WebSocketSession;
typedef std::shared_ptr<WebSocketSession> SessionPtr; typedef std::shared_ptr<WebSocketSession> SessionPtr;

View File

@ -1,5 +1,4 @@
#include "EventHandler.h" #include "EventHandler.h"
#include "../plugin-macros.generated.h"
EventHandler::EventHandler() : EventHandler::EventHandler() :
_obsLoaded(false), _obsLoaded(false),

View File

@ -8,6 +8,7 @@
#include "types/EventSubscription.h" #include "types/EventSubscription.h"
#include "../obs-websocket.h" #include "../obs-websocket.h"
#include "../utils/Obs.h" #include "../utils/Obs.h"
#include "../plugin-macros.generated.h"
template <typename T> T* GetCalldataPointer(const calldata_t *data, const char* name) { template <typename T> T* GetCalldataPointer(const calldata_t *data, const char* name) {
void *ptr = nullptr; void *ptr = nullptr;
@ -40,7 +41,7 @@ class EventHandler
void ConnectSourceSignals(obs_source_t *source); void ConnectSourceSignals(obs_source_t *source);
void DisconnectSourceSignals(obs_source_t *source); void DisconnectSourceSignals(obs_source_t *source);
void BroadcastEvent(uint64_t requiredIntent, std::string eventType, json eventData = nullptr, uint8_t rpcVersion = 1); void BroadcastEvent(uint64_t requiredIntent, std::string eventType, json eventData = nullptr, uint8_t rpcVersion = 0);
// Signal handler: frontend // Signal handler: frontend
static void OnFrontendEvent(enum obs_frontend_event event, void *private_data); static void OnFrontendEvent(enum obs_frontend_event event, void *private_data);

View File

@ -1,5 +1,4 @@
#include "EventHandler.h" #include "EventHandler.h"
#include "../plugin-macros.generated.h"
void EventHandler::HandleCurrentSceneCollectionChanged() void EventHandler::HandleCurrentSceneCollectionChanged()
{ {

View File

@ -1,2 +1 @@
#include "EventHandler.h" #include "EventHandler.h"
#include "../plugin-macros.generated.h"

View File

@ -1,5 +1,4 @@
#include "EventHandler.h" #include "EventHandler.h"
#include "../plugin-macros.generated.h"
void EventHandler::HandleExitStarted() void EventHandler::HandleExitStarted()
{ {

View File

@ -1,5 +1,4 @@
#include "EventHandler.h" #include "EventHandler.h"
#include "../plugin-macros.generated.h"
void EventHandler::HandleInputCreated(obs_source_t *source) void EventHandler::HandleInputCreated(obs_source_t *source)
{ {

View File

@ -1,5 +1,4 @@
#include "EventHandler.h" #include "EventHandler.h"
#include "../plugin-macros.generated.h"
#define CASE(x) case x: return #x; #define CASE(x) case x: return #x;

View File

@ -1,5 +1,4 @@
#include "EventHandler.h" #include "EventHandler.h"
#include "../plugin-macros.generated.h"
#define CASE(x) case x: return #x; #define CASE(x) case x: return #x;

View File

@ -1,5 +1,4 @@
#include "EventHandler.h" #include "EventHandler.h"
#include "../plugin-macros.generated.h"
void EventHandler::HandleSceneItemCreated(void *param, calldata_t *data) void EventHandler::HandleSceneItemCreated(void *param, calldata_t *data)
{ {

View File

@ -1,5 +1,4 @@
#include "EventHandler.h" #include "EventHandler.h"
#include "../plugin-macros.generated.h"
void EventHandler::HandleSceneCreated(obs_source_t *source) void EventHandler::HandleSceneCreated(obs_source_t *source)
{ {

View File

@ -1,5 +1,4 @@
#include "EventHandler.h" #include "EventHandler.h"
#include "../plugin-macros.generated.h"
void EventHandler::HandleTransitionCreated(obs_source_t *source) void EventHandler::HandleTransitionCreated(obs_source_t *source)
{ {

View File

@ -8,7 +8,6 @@
#include "../obs-websocket.h" #include "../obs-websocket.h"
#include "../Config.h" #include "../Config.h"
#include "../utils/Platform.h" #include "../utils/Platform.h"
#include "../plugin-macros.generated.h"
ConnectInfo::ConnectInfo(QWidget* parent) : ConnectInfo::ConnectInfo(QWidget* parent) :
QDialog(parent, Qt::Dialog), QDialog(parent, Qt::Dialog),

View File

@ -2,6 +2,8 @@
#include <QtWidgets/QDialog> #include <QtWidgets/QDialog>
#include "../plugin-macros.generated.h"
#include "ui_ConnectInfo.h" #include "ui_ConnectInfo.h"
class ConnectInfo : public QDialog class ConnectInfo : public QDialog

View File

@ -9,7 +9,6 @@
#include "../Config.h" #include "../Config.h"
#include "../WebSocketServer.h" #include "../WebSocketServer.h"
#include "../utils/Crypto.h" #include "../utils/Crypto.h"
#include "../plugin-macros.generated.h"
QString GetToolTipIconHtml() QString GetToolTipIconHtml()
{ {

View File

@ -3,8 +3,10 @@
#include <QDialog> #include <QDialog>
#include <QTimer> #include <QTimer>
#include "ui_SettingsDialog.h"
#include "ConnectInfo.h" #include "ConnectInfo.h"
#include "../plugin-macros.generated.h"
#include "ui_SettingsDialog.h"
class SettingsDialog : public QDialog class SettingsDialog : public QDialog
{ {

View File

@ -6,7 +6,6 @@
#include <obs-data.h> #include <obs-data.h>
#include <obs-frontend-api.h> #include <obs-frontend-api.h>
#include "plugin-macros.generated.h"
#include "obs-websocket.h" #include "obs-websocket.h"
#include "Config.h" #include "Config.h"
#include "WebSocketServer.h" #include "WebSocketServer.h"
@ -34,8 +33,7 @@ void ___properties_dummy_addref(obs_properties_t*) {};
bool obs_module_load(void) bool obs_module_load(void)
{ {
blog(LOG_INFO, "[obs_module_load] you can haz websockets (Version: %s | RPC Version: %d)", OBS_WEBSOCKET_VERSION, OBS_WEBSOCKET_RPC_VERSION); blog(LOG_INFO, "[obs_module_load] you can haz websockets (Version: %s | RPC Version: %d)", OBS_WEBSOCKET_VERSION, OBS_WEBSOCKET_RPC_VERSION);
blog(LOG_INFO, "[obs_module_load] Qt version (compile-time): %s | Qt version (run-time): %s", blog(LOG_INFO, "[obs_module_load] Qt version (compile-time): %s | Qt version (run-time): %s", QT_VERSION_STR, qVersion());
QT_VERSION_STR, qVersion());
// Randomize the random number generator // Randomize the random number generator
qsrand(QTime::currentTime().msec()); qsrand(QTime::currentTime().msec());

View File

@ -10,6 +10,8 @@
#pragma pop_macro("strtoll") #pragma pop_macro("strtoll")
#endif #endif
#include "plugin-macros.generated.h"
// Autorelease object definitions // Autorelease object definitions
void ___source_dummy_addref(obs_source_t*); void ___source_dummy_addref(obs_source_t*);
void ___sceneitem_dummy_addref(obs_sceneitem_t*); void ___sceneitem_dummy_addref(obs_sceneitem_t*);

View File

@ -1,5 +1,4 @@
#include "RequestHandler.h" #include "RequestHandler.h"
#include "../plugin-macros.generated.h"
const std::map<std::string, RequestMethodHandler> RequestHandler::_handlerMap const std::map<std::string, RequestMethodHandler> RequestHandler::_handlerMap
{ {

View File

@ -1,9 +1,9 @@
#include <QImageWriter> #include <QImageWriter>
#include "RequestHandler.h" #include "RequestHandler.h"
#include "../WebSocketServer.h"
#include "../eventhandler/types/EventSubscription.h" #include "../eventhandler/types/EventSubscription.h"
#include "../obs-websocket.h" #include "../obs-websocket.h"
#include "../WebSocketServer.h"
RequestResult RequestHandler::GetVersion(const Request& request) RequestResult RequestHandler::GetVersion(const Request& request)
{ {