General: code style refactor

This commit is contained in:
Stéphane L 2017-08-05 03:14:07 +02:00
parent add39cfc5f
commit 586f9076f0
10 changed files with 408 additions and 555 deletions

View File

@ -22,8 +22,6 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include <util/config-file.h>
#include <string>
#include "Config.h"
#define SECTION_NAME "WebsocketAPI"
#define PARAM_ENABLE "ServerEnabled"
#define PARAM_PORT "ServerPort"
@ -32,25 +30,21 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#define PARAM_SECRET "AuthSecret"
#define PARAM_SALT "AuthSalt"
Config *Config::_instance = new Config();
#include "Config.h"
Config::Config()
{
// Default settings
ServerEnabled = true;
ServerPort = 4444;
DebugEnabled = false;
AuthRequired = false;
Secret = "";
Salt = "";
SettingsLoaded = false;
Config* Config::_instance = new Config();
Config::Config() :
ServerEnabled(true),
ServerPort(4444),
DebugEnabled(false),
AuthRequired(false),
Secret(""),
Salt(""),
SettingsLoaded(false) {
// OBS Config defaults
config_t* obs_config = obs_frontend_get_global_config();
if (obs_config)
{
if (obs_config) {
config_set_default_bool(obs_config,
SECTION_NAME, PARAM_ENABLE, ServerEnabled);
config_set_default_uint(obs_config,
@ -70,19 +64,16 @@ Config::Config()
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&rng);
mbedtls_ctr_drbg_seed(&rng, mbedtls_entropy_func, &entropy, nullptr, 0);
//mbedtls_ctr_drbg_set_prediction_resistance(&rng, MBEDTLS_CTR_DRBG_PR_ON);
SessionChallenge = GenerateSalt();
}
Config::~Config()
{
Config::~Config() {
mbedtls_ctr_drbg_free(&rng);
mbedtls_entropy_free(&entropy);
}
void Config::Load()
{
void Config::Load() {
config_t* obs_config = obs_frontend_get_global_config();
ServerEnabled = config_get_bool(obs_config, SECTION_NAME, PARAM_ENABLE);
@ -95,8 +86,7 @@ void Config::Load()
Salt = config_get_string(obs_config, SECTION_NAME, PARAM_SALT);
}
void Config::Save()
{
void Config::Save() {
config_t* obs_config = obs_frontend_get_global_config();
config_set_bool(obs_config, SECTION_NAME, PARAM_ENABLE, ServerEnabled);
@ -111,8 +101,7 @@ void Config::Save()
config_save(obs_config);
}
const char* Config::GenerateSalt()
{
const char* Config::GenerateSalt() {
// Generate 32 random chars
unsigned char* random_chars = (unsigned char*)bzalloc(32);
mbedtls_ctr_drbg_random(&rng, random_chars, 32);
@ -128,8 +117,7 @@ const char* Config::GenerateSalt()
return salt;
}
const char* Config::GenerateSecret(const char *password, const char *salt)
{
const char* Config::GenerateSecret(const char* password, const char* salt) {
// Concatenate the password and the salt
std::string passAndSalt = "";
passAndSalt += password;
@ -152,17 +140,15 @@ const char* Config::GenerateSecret(const char *password, const char *salt)
return challenge;
}
void Config::SetPassword(const char *password)
{
const char *new_salt = GenerateSalt();
const char *new_challenge = GenerateSecret(password, new_salt);
void Config::SetPassword(const char* password) {
const char* new_salt = GenerateSalt();
const char* new_challenge = GenerateSecret(password, new_salt);
this->Salt = new_salt;
this->Secret = new_challenge;
}
bool Config::CheckAuth(const char *response)
{
bool Config::CheckAuth(const char* response) {
// Concatenate auth secret with the challenge sent to the user
std::string challengeAndResponse = "";
challengeAndResponse += this->Secret;
@ -193,7 +179,6 @@ bool Config::CheckAuth(const char *response)
return authSuccess;
}
Config* Config::Current()
{
Config* Config::Current() {
return _instance;
}

View File

@ -22,37 +22,36 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
class Config
{
public:
Config();
~Config();
void Load();
void Save();
class Config {
public:
Config();
~Config();
void Load();
void Save();
void SetPassword(const char *password);
bool CheckAuth(const char *userChallenge);
const char* GenerateSalt();
static const char* GenerateSecret(
const char *password, const char *salt);
void SetPassword(const char* password);
bool CheckAuth(const char* userChallenge);
const char* GenerateSalt();
static const char* GenerateSecret(
const char* password, const char* salt);
bool ServerEnabled;
uint64_t ServerPort;
bool ServerEnabled;
uint64_t ServerPort;
bool DebugEnabled;
bool DebugEnabled;
bool AuthRequired;
const char *Secret;
const char *Salt;
const char *SessionChallenge;
bool SettingsLoaded;
bool AuthRequired;
const char* Secret;
const char* Salt;
const char* SessionChallenge;
bool SettingsLoaded;
static Config* Current();
static Config* Current();
private:
static Config *_instance;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context rng;
private:
static Config* _instance;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context rng;
};
#endif // CONFIG_H

193
Utils.cpp
View File

@ -16,26 +16,25 @@ You should have received a copy of the GNU General Public License along
with this program. If not, see <https://www.gnu.org/licenses/>
*/
#include <obs-frontend-api.h>
#include <obs.hpp>
#include <QMainWindow>
#include <QDir>
#include <QUrl>
#include "Utils.h"
#include <obs-frontend-api.h>
#include <obs.hpp>
#include "obs-websocket.h"
#include "Utils.h"
Q_DECLARE_METATYPE(OBSScene);
obs_data_array_t* string_list_to_array(char** strings, char* key)
{
obs_data_array_t* string_list_to_array(char** strings, char* key) {
if (!strings)
return obs_data_array_create();
obs_data_array_t* list = obs_data_array_create();
char* value = "";
for (int i = 0; value != nullptr; i++)
{
for (int i = 0; value != nullptr; i++) {
value = strings[i];
obs_data_t* item = obs_data_create();
@ -50,17 +49,18 @@ obs_data_array_t* string_list_to_array(char** strings, char* key)
return list;
}
obs_data_array_t* Utils::GetSceneItems(obs_source_t* source)
{
obs_data_array_t* Utils::GetSceneItems(obs_source_t* source) {
obs_data_array_t* items = obs_data_array_create();
obs_scene_t* scene = obs_scene_from_source(source);
if (!scene)
return nullptr;
obs_scene_enum_items(scene, [](obs_scene_t* scene, obs_sceneitem_t* currentItem, void* param)
{
obs_data_array_t* data = static_cast<obs_data_array_t* >(param);
obs_scene_enum_items(scene, [](
obs_scene_t* scene,
obs_sceneitem_t* currentItem,
void* param) {
obs_data_array_t* data = static_cast<obs_data_array_t*>(param);
obs_data_t* item_data = GetSceneItemData(currentItem);
obs_data_array_insert(data, 0, item_data);
@ -72,8 +72,7 @@ obs_data_array_t* Utils::GetSceneItems(obs_source_t* source)
return items;
}
obs_data_t* Utils::GetSceneItemData(obs_sceneitem_t* item)
{
obs_data_t* Utils::GetSceneItemData(obs_sceneitem_t* item) {
if (!item)
return nullptr;
@ -105,8 +104,7 @@ obs_data_t* Utils::GetSceneItemData(obs_sceneitem_t* item)
return data;
}
obs_sceneitem_t* Utils::GetSceneItemFromName(obs_source_t* source, const char* name)
{
obs_sceneitem_t* Utils::GetSceneItemFromName(obs_source_t* source, const char* name) {
struct current_search {
const char* query;
obs_sceneitem_t* result;
@ -120,15 +118,16 @@ obs_sceneitem_t* Utils::GetSceneItemFromName(obs_source_t* source, const char* n
if (scene == nullptr)
return nullptr;
obs_scene_enum_items(scene, [](obs_scene_t* scene, obs_sceneitem_t* currentItem, void* param)
{
current_search* search = static_cast<current_search* >(param);
obs_scene_enum_items(scene, [](
obs_scene_t* scene,
obs_sceneitem_t* currentItem,
void* param) {
current_search* search = static_cast<current_search*>(param);
const char* currentItemName =
obs_source_get_name(obs_sceneitem_get_source(currentItem));
if (strcmp(currentItemName, search->query) == 0)
{
if (strcmp(currentItemName, search->query) == 0) {
search->result = currentItem;
obs_sceneitem_addref(search->result);
return false;
@ -140,15 +139,13 @@ obs_sceneitem_t* Utils::GetSceneItemFromName(obs_source_t* source, const char* n
return search.result;
}
obs_source_t* Utils::GetTransitionFromName(const char* search_name)
{
obs_source_t* Utils::GetTransitionFromName(const char* search_name) {
obs_source_t* found_transition = NULL;
obs_frontend_source_list transition_list = {};
obs_frontend_get_transitions(&transition_list);
for (size_t i = 0; i < transition_list.sources.num; i++)
{
for (size_t i = 0; i < transition_list.sources.num; i++) {
obs_source_t* transition = transition_list.sources.array[i];
const char* transition_name = obs_source_get_name(transition);
@ -165,8 +162,7 @@ obs_source_t* Utils::GetTransitionFromName(const char* search_name)
return found_transition;
}
obs_source_t* Utils::GetSceneFromNameOrCurrent(const char* scene_name)
{
obs_source_t* Utils::GetSceneFromNameOrCurrent(const char* scene_name) {
obs_source_t* scene = nullptr;
if (!scene_name || !strlen(scene_name))
@ -177,14 +173,12 @@ obs_source_t* Utils::GetSceneFromNameOrCurrent(const char* scene_name)
return scene;
}
obs_data_array_t* Utils::GetScenes()
{
obs_data_array_t* Utils::GetScenes() {
obs_frontend_source_list sceneList = {};
obs_frontend_get_scenes(&sceneList);
obs_data_array_t* scenes = obs_data_array_create();
for (size_t i = 0; i < sceneList.sources.num; i++)
{
for (size_t i = 0; i < sceneList.sources.num; i++) {
obs_source_t* scene = sceneList.sources.array[i];
obs_data_t* scene_data = GetSceneData(scene);
@ -198,8 +192,7 @@ obs_data_array_t* Utils::GetScenes()
return scenes;
}
obs_data_t* Utils::GetSceneData(obs_source* source)
{
obs_data_t* Utils::GetSceneData(obs_source* source) {
obs_data_array_t* scene_items = GetSceneItems(source);
obs_data_t* sceneData = obs_data_create();
@ -210,8 +203,7 @@ obs_data_t* Utils::GetSceneData(obs_source* source)
return sceneData;
}
obs_data_array_t* Utils::GetSceneCollections()
{
obs_data_array_t* Utils::GetSceneCollections() {
char** scene_collections = obs_frontend_get_scene_collections();
obs_data_array_t* list = string_list_to_array(scene_collections, "sc-name");
@ -219,8 +211,7 @@ obs_data_array_t* Utils::GetSceneCollections()
return list;
}
obs_data_array_t* Utils::GetProfiles()
{
obs_data_array_t* Utils::GetProfiles() {
char** profiles = obs_frontend_get_profiles();
obs_data_array_t* list = string_list_to_array(profiles, "profile-name");
@ -228,14 +219,12 @@ obs_data_array_t* Utils::GetProfiles()
return list;
}
QSpinBox* Utils::GetTransitionDurationControl()
{
QSpinBox* Utils::GetTransitionDurationControl() {
QMainWindow* window = (QMainWindow*)obs_frontend_get_main_window();
return window->findChild<QSpinBox*>("transitionDuration");
}
int Utils::GetTransitionDuration()
{
int Utils::GetTransitionDuration() {
QSpinBox* control = GetTransitionDurationControl();
if (control)
return control->value();
@ -243,45 +232,35 @@ int Utils::GetTransitionDuration()
return -1;
}
void Utils::SetTransitionDuration(int ms)
{
void Utils::SetTransitionDuration(int ms) {
QSpinBox* control = GetTransitionDurationControl();
if (control && ms >= 0)
control->setValue(ms);
}
bool Utils::SetTransitionByName(const char* transition_name)
{
bool Utils::SetTransitionByName(const char* transition_name) {
obs_source_t* transition = GetTransitionFromName(transition_name);
if (transition)
{
if (transition) {
obs_frontend_set_current_transition(transition);
obs_source_release(transition);
return true;
}
else
{
} else {
return false;
}
}
QPushButton* Utils::GetPreviewModeButtonControl()
{
QPushButton* Utils::GetPreviewModeButtonControl() {
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
return main->findChild<QPushButton*>("modeSwitch");
}
QListWidget* Utils::GetSceneListControl()
{
QListWidget* Utils::GetSceneListControl() {
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
return main->findChild<QListWidget*>("scenes");
}
obs_scene_t* Utils::SceneListItemToScene(QListWidgetItem* item)
{
obs_scene_t* Utils::SceneListItemToScene(QListWidgetItem* item) {
if (!item)
return nullptr;
@ -289,14 +268,12 @@ obs_scene_t* Utils::SceneListItemToScene(QListWidgetItem* item)
return item_data.value<OBSScene>();
}
QLayout* Utils::GetPreviewLayout()
{
QLayout* Utils::GetPreviewLayout() {
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
return main->findChild<QLayout*>("previewLayout");
}
bool Utils::IsPreviewModeActive()
{
bool Utils::IsPreviewModeActive() {
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
// Clue 1 : "Studio Mode" button is toggled on
@ -309,29 +286,23 @@ bool Utils::IsPreviewModeActive()
return buttonToggledOn || (previewChildCount >= 2);
}
void Utils::EnablePreviewMode()
{
void Utils::EnablePreviewMode() {
if (!IsPreviewModeActive())
GetPreviewModeButtonControl()->click();
}
void Utils::DisablePreviewMode()
{
void Utils::DisablePreviewMode() {
if (IsPreviewModeActive())
GetPreviewModeButtonControl()->click();
}
void Utils::TogglePreviewMode()
{
void Utils::TogglePreviewMode() {
GetPreviewModeButtonControl()->click();
}
obs_scene_t* Utils::GetPreviewScene()
{
if (IsPreviewModeActive())
{
obs_scene_t* Utils::GetPreviewScene() {
if (IsPreviewModeActive()) {
QListWidget* sceneList = GetSceneListControl();
QList<QListWidgetItem*> selected = sceneList->selectedItems();
// Qt::UserRole == QtUserRole::OBSRef
@ -344,21 +315,16 @@ obs_scene_t* Utils::GetPreviewScene()
return nullptr;
}
bool Utils::SetPreviewScene(const char* name)
{
if (IsPreviewModeActive())
{
bool Utils::SetPreviewScene(const char* name) {
if (IsPreviewModeActive()) {
QListWidget* sceneList = GetSceneListControl();
QList<QListWidgetItem*> matchingItems =
sceneList->findItems(name, Qt::MatchExactly);
if (matchingItems.count() > 0)
{
if (matchingItems.count() > 0) {
sceneList->setCurrentItem(matchingItems.first());
return true;
}
else
{
} else {
return false;
}
}
@ -366,8 +332,7 @@ bool Utils::SetPreviewScene(const char* name)
return false;
}
void Utils::TransitionToProgram()
{
void Utils::TransitionToProgram() {
if (!IsPreviewModeActive())
return;
@ -405,14 +370,13 @@ const char* Utils::OBSVersionString() {
return result;
}
QSystemTrayIcon* Utils::GetTrayIcon()
{
QSystemTrayIcon* Utils::GetTrayIcon() {
QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window();
return main->findChildren<QSystemTrayIcon*>().first();
}
void Utils::SysTrayNotify(QString &text, QSystemTrayIcon::MessageIcon icon, QString title)
{
void Utils::SysTrayNotify(QString &text,
QSystemTrayIcon::MessageIcon icon, QString title) {
if (!QSystemTrayIcon::supportsMessages())
return;
@ -421,45 +385,36 @@ void Utils::SysTrayNotify(QString &text, QSystemTrayIcon::MessageIcon icon, QStr
trayIcon->showMessage(title, text, icon);
}
QString Utils::FormatIPAddress(QHostAddress &addr)
{
QString Utils::FormatIPAddress(QHostAddress &addr) {
if (addr.protocol() == QAbstractSocket::IPv4Protocol)
QString v4addr = addr.toString().replace("::fff:", "");
return addr.toString();
}
const char* Utils::GetRecordingFolder()
{
const char* Utils::GetRecordingFolder() {
config_t* profile = obs_frontend_get_profile_config();
const char* outputMode = config_get_string(profile, "Output", "Mode");
if (strcmp(outputMode, "Advanced") == 0)
{
if (strcmp(outputMode, "Advanced") == 0) {
// Advanced mode
return config_get_string(profile, "AdvOut", "RecFilePath");
}
else
{
} else {
// Simple mode
return config_get_string(profile, "SimpleOutput", "FilePath");
}
}
bool Utils::SetRecordingFolder(const char* path)
{
bool Utils::SetRecordingFolder(const char* path) {
if (!QDir(path).exists())
return false;
config_t* profile = obs_frontend_get_profile_config();
const char* outputMode = config_get_string(profile, "Output", "Mode");
if (strcmp(outputMode, "Advanced") == 0)
{
if (strcmp(outputMode, "Advanced") == 0) {
config_set_string(profile, "AdvOut", "RecFilePath", path);
}
else
{
} else {
config_set_string(profile, "SimpleOutput", "FilePath", path);
}
@ -467,18 +422,14 @@ bool Utils::SetRecordingFolder(const char* path)
return true;
}
QString* Utils::ParseDataToQueryString(obs_data_t * data)
{
QString* Utils::ParseDataToQueryString(obs_data_t* data) {
QString* query = nullptr;
if (data)
{
obs_data_item_t* item = obs_data_first(data);
if (item)
{
if (data) {
obs_data_item_t* item = obs_data_first(data);
if (item) {
query = new QString();
bool isFirst = true;
do
{
do {
if (!obs_data_item_has_user_value(item))
continue;
@ -489,8 +440,8 @@ QString* Utils::ParseDataToQueryString(obs_data_t * data)
const char* attrName = obs_data_item_get_name(item);
query->append(attrName).append("=");
switch (obs_data_item_gettype(item))
{
switch (obs_data_item_gettype(item)) {
case OBS_DATA_BOOLEAN:
query->append(obs_data_item_get_bool(item)?"true":"false");
break;
@ -498,25 +449,27 @@ QString* Utils::ParseDataToQueryString(obs_data_t * data)
switch (obs_data_item_numtype(item))
{
case OBS_DATA_NUM_DOUBLE:
query->append(QString::number(obs_data_item_get_double(item)));
query->append(
QString::number(obs_data_item_get_double(item)));
break;
case OBS_DATA_NUM_INT:
query->append(QString::number(obs_data_item_get_int(item)));
query->append(
QString::number(obs_data_item_get_int(item)));
break;
case OBS_DATA_NUM_INVALID:
break;
}
break;
case OBS_DATA_STRING:
query->append(QUrl::toPercentEncoding(QString(obs_data_item_get_string(item))));
query->append(QUrl::toPercentEncoding(
QString(obs_data_item_get_string(item))));
break;
default:
//other types are not supported
break;
}
} while ( obs_data_item_next( &item ) );
} while (obs_data_item_next(&item));
}
}
return query;
}

78
Utils.h
View File

@ -25,59 +25,59 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include <QListWidget>
#include <QSystemTrayIcon>
#include <QHostAddress>
#include <stdio.h>
#include <obs-module.h>
#include <util/config-file.h>
class Utils
{
public:
static obs_data_array_t* GetSceneItems(obs_source_t* source);
static obs_data_t* GetSceneItemData(obs_scene_item* item);
static obs_sceneitem_t* GetSceneItemFromName(
obs_source_t* source, const char* name);
static obs_source_t* GetTransitionFromName(const char* search_name);
static obs_source_t* GetSceneFromNameOrCurrent(const char* scene_name);
class Utils {
public:
static obs_data_array_t* GetSceneItems(obs_source_t* source);
static obs_data_t* GetSceneItemData(obs_scene_item* item);
static obs_sceneitem_t* GetSceneItemFromName(
obs_source_t* source, const char* name);
static obs_source_t* GetTransitionFromName(const char* search_name);
static obs_source_t* GetSceneFromNameOrCurrent(const char* scene_name);
static obs_data_array_t* GetScenes();
static obs_data_t* GetSceneData(obs_source* source);
static obs_data_array_t* GetScenes();
static obs_data_t* GetSceneData(obs_source* source);
static obs_data_array_t* GetSceneCollections();
static obs_data_array_t* GetProfiles();
static obs_data_array_t* GetSceneCollections();
static obs_data_array_t* GetProfiles();
static QSpinBox* GetTransitionDurationControl();
static int GetTransitionDuration();
static void SetTransitionDuration(int ms);
static QSpinBox* GetTransitionDurationControl();
static int GetTransitionDuration();
static void SetTransitionDuration(int ms);
static bool SetTransitionByName(const char* transition_name);
static bool SetTransitionByName(const char* transition_name);
static QPushButton* GetPreviewModeButtonControl();
static QLayout* GetPreviewLayout();
static QListWidget* GetSceneListControl();
static obs_scene_t* SceneListItemToScene(QListWidgetItem* item);
static QPushButton* GetPreviewModeButtonControl();
static QLayout* GetPreviewLayout();
static QListWidget* GetSceneListControl();
static obs_scene_t* SceneListItemToScene(QListWidgetItem* item);
static bool IsPreviewModeActive();
static void EnablePreviewMode();
static void DisablePreviewMode();
static void TogglePreviewMode();
static bool IsPreviewModeActive();
static void EnablePreviewMode();
static void DisablePreviewMode();
static void TogglePreviewMode();
static obs_scene_t* GetPreviewScene();
static bool SetPreviewScene(const char* name);
static void TransitionToProgram();
static obs_scene_t* GetPreviewScene();
static bool SetPreviewScene(const char* name);
static void TransitionToProgram();
static const char* OBSVersionString();
static const char* OBSVersionString();
static QSystemTrayIcon* GetTrayIcon();
static void SysTrayNotify(
QString &text,
QSystemTrayIcon::MessageIcon n,
QString title = QString("obs-websocket"));
static QSystemTrayIcon* GetTrayIcon();
static void SysTrayNotify(
QString &text,
QSystemTrayIcon::MessageIcon n,
QString title = QString("obs-websocket"));
static QString FormatIPAddress(QHostAddress &addr);
static const char* GetRecordingFolder();
static bool SetRecordingFolder(const char* path);
static QString FormatIPAddress(QHostAddress &addr);
static const char* GetRecordingFolder();
static bool SetRecordingFolder(const char* path);
static QString* ParseDataToQueryString(obs_data_t * data);
static QString* ParseDataToQueryString(obs_data_t * data);
};
#endif // UTILS_H

View File

@ -18,29 +18,28 @@ with this program. If not, see <https://www.gnu.org/licenses/>
*/
#include <util/platform.h>
#include <QTimer>
#include <QPushButton>
#include "Config.h"
#include "Utils.h"
#include "WSEvents.h"
#include "obs-websocket.h"
bool transition_is_cut(obs_source_t* transition)
{
bool transition_is_cut(obs_source_t* transition) {
if (!transition)
return false;
if (obs_source_get_type(transition) == OBS_SOURCE_TYPE_TRANSITION
&& strcmp(obs_source_get_id(transition), "cut_transition") == 0)
{
&& strcmp(obs_source_get_id(transition), "cut_transition") == 0) {
return true;
}
return false;
}
const char* ns_to_timestamp(uint64_t ns)
{
const char* ns_to_timestamp(uint64_t ns) {
uint64_t ms = ns / (1000 * 1000);
uint64_t secs = ms / 1000;
uint64_t minutes = secs / 60;
@ -59,8 +58,7 @@ const char* ns_to_timestamp(uint64_t ns)
WSEvents* WSEvents::Instance = nullptr;
WSEvents::WSEvents(WSServer* srv)
{
WSEvents::WSEvents(WSServer* srv) {
_srv = srv;
obs_frontend_add_event_callback(WSEvents::FrontendEventHandler, this);
@ -92,13 +90,11 @@ WSEvents::WSEvents(WSServer* srv)
_rec_starttime = 0;
}
WSEvents::~WSEvents()
{
WSEvents::~WSEvents() {
obs_frontend_remove_event_callback(WSEvents::FrontendEventHandler, this);
}
void WSEvents::deferredInitOperations()
{
void WSEvents::deferredInitOperations() {
obs_source_t* transition = obs_frontend_get_current_transition();
connectTransitionSignals(transition);
obs_source_release(transition);
@ -108,8 +104,7 @@ void WSEvents::deferredInitOperations()
obs_source_release(scene);
}
void WSEvents::FrontendEventHandler(enum obs_frontend_event event, void* private_data)
{
void WSEvents::FrontendEventHandler(enum obs_frontend_event event, void* private_data) {
WSEvents* owner = static_cast<WSEvents*>(private_data);
if (!owner->_srv)
@ -117,95 +112,76 @@ void WSEvents::FrontendEventHandler(enum obs_frontend_event event, void* private
// TODO : implement SourceOrderChanged and RepopulateSources
if (event == OBS_FRONTEND_EVENT_SCENE_CHANGED)
{
if (event == OBS_FRONTEND_EVENT_SCENE_CHANGED) {
owner->OnSceneChange();
}
else if (event == OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED)
{
else if (event == OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED) {
owner->OnSceneListChange();
}
else if (event == OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGED)
{
else if (event == OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGED) {
owner->OnSceneCollectionChange();
}
else if (event == OBS_FRONTEND_EVENT_SCENE_COLLECTION_LIST_CHANGED)
{
else if (event == OBS_FRONTEND_EVENT_SCENE_COLLECTION_LIST_CHANGED) {
owner->OnSceneCollectionListChange();
}
else if (event == OBS_FRONTEND_EVENT_TRANSITION_CHANGED)
{
else if (event == OBS_FRONTEND_EVENT_TRANSITION_CHANGED) {
owner->OnTransitionChange();
}
else if (event == OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED)
{
else if (event == OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED) {
owner->OnTransitionListChange();
}
else if (event == OBS_FRONTEND_EVENT_PROFILE_CHANGED)
{
else if (event == OBS_FRONTEND_EVENT_PROFILE_CHANGED) {
owner->OnProfileChange();
}
else if (event == OBS_FRONTEND_EVENT_PROFILE_LIST_CHANGED)
{
else if (event == OBS_FRONTEND_EVENT_PROFILE_LIST_CHANGED) {
owner->OnProfileListChange();
}
else if (event == OBS_FRONTEND_EVENT_STREAMING_STARTING)
{
else if (event == OBS_FRONTEND_EVENT_STREAMING_STARTING) {
owner->OnStreamStarting();
}
else if (event == OBS_FRONTEND_EVENT_STREAMING_STARTED)
{
else if (event == OBS_FRONTEND_EVENT_STREAMING_STARTED) {
owner->_streaming_active = true;
owner->OnStreamStarted();
}
else if (event == OBS_FRONTEND_EVENT_STREAMING_STOPPING)
{
else if (event == OBS_FRONTEND_EVENT_STREAMING_STOPPING) {
owner->OnStreamStopping();
}
else if (event == OBS_FRONTEND_EVENT_STREAMING_STOPPED)
{
else if (event == OBS_FRONTEND_EVENT_STREAMING_STOPPED) {
owner->_streaming_active = false;
owner->OnStreamStopped();
}
else if (event == OBS_FRONTEND_EVENT_RECORDING_STARTING)
{
else if (event == OBS_FRONTEND_EVENT_RECORDING_STARTING) {
owner->OnRecordingStarting();
}
else if (event == OBS_FRONTEND_EVENT_RECORDING_STARTED)
{
else if (event == OBS_FRONTEND_EVENT_RECORDING_STARTED) {
owner->_recording_active = true;
owner->OnRecordingStarted();
}
else if (event == OBS_FRONTEND_EVENT_RECORDING_STOPPING)
{
else if (event == OBS_FRONTEND_EVENT_RECORDING_STOPPING) {
owner->OnRecordingStopping();
}
else if (event == OBS_FRONTEND_EVENT_RECORDING_STOPPED)
{
else if (event == OBS_FRONTEND_EVENT_RECORDING_STOPPED) {
owner->_recording_active = false;
owner->OnRecordingStopped();
}
else if (event == OBS_FRONTEND_EVENT_EXIT)
{
else if (event == OBS_FRONTEND_EVENT_EXIT) {
owner->OnExit();
}
}
void WSEvents::broadcastUpdate(const char* updateType, obs_data_t* additionalFields = NULL)
{
void WSEvents::broadcastUpdate(const char* updateType,
obs_data_t* additionalFields = NULL) {
obs_data_t* update = obs_data_create();
obs_data_set_string(update, "update-type", updateType);
const char* ts = nullptr;
if (_streaming_active)
{
if (_streaming_active) {
ts = ns_to_timestamp(os_gettime_ns() - _stream_starttime);
obs_data_set_string(update, "stream-timecode", ts);
bfree((void*)ts);
}
if (_recording_active)
{
if (_recording_active) {
ts = ns_to_timestamp(os_gettime_ns() - _rec_starttime);
obs_data_set_string(update, "rec-timecode", ts);
bfree((void*)ts);
@ -222,30 +198,23 @@ void WSEvents::broadcastUpdate(const char* updateType, obs_data_t* additionalFie
obs_data_release(update);
}
void WSEvents::connectTransitionSignals(obs_source_t* transition)
{
if (transition_handler)
{
void WSEvents::connectTransitionSignals(obs_source_t* transition) {
if (transition_handler) {
signal_handler_disconnect(transition_handler,
"transition_start", OnTransitionBegin, this);
}
if (!transition_is_cut(transition))
{
if (!transition_is_cut(transition)) {
transition_handler = obs_source_get_signal_handler(transition);
signal_handler_connect(transition_handler,
"transition_start", OnTransitionBegin, this);
}
else
{
} else {
transition_handler = nullptr;
}
}
void WSEvents::connectSceneSignals(obs_source_t* scene)
{
if (scene_handler)
{
void WSEvents::connectSceneSignals(obs_source_t* scene) {
if (scene_handler) {
signal_handler_disconnect(scene_handler,
"reorder", OnSceneReordered, this);
signal_handler_disconnect(scene_handler,
@ -268,34 +237,29 @@ void WSEvents::connectSceneSignals(obs_source_t* scene)
"item_visible", OnSceneItemVisibilityChanged, this);
}
uint64_t WSEvents::GetStreamingTime()
{
uint64_t WSEvents::GetStreamingTime() {
if (_streaming_active)
return (os_gettime_ns() - _stream_starttime);
else
return 0;
}
const char* WSEvents::GetStreamingTimecode()
{
const char* WSEvents::GetStreamingTimecode() {
return ns_to_timestamp(GetStreamingTime());
}
uint64_t WSEvents::GetRecordingTime()
{
uint64_t WSEvents::GetRecordingTime() {
if (_recording_active)
return (os_gettime_ns() - _rec_starttime);
else
return 0;
}
const char* WSEvents::GetRecordingTimecode()
{
const char* WSEvents::GetRecordingTimecode() {
return ns_to_timestamp(GetRecordingTime());
}
void WSEvents::OnSceneChange()
{
void WSEvents::OnSceneChange() {
// Implements an existing update type from bilhamil's OBS Remote
obs_data_t* data = obs_data_create();
@ -314,20 +278,17 @@ void WSEvents::OnSceneChange()
// Dirty fix : OBS blocks signals when swapping scenes in Studio Mode
// after transition end, so SelectedSceneChanged is never called...
if (Utils::IsPreviewModeActive())
{
if (Utils::IsPreviewModeActive()) {
QListWidget* list = Utils::GetSceneListControl();
SelectedSceneChanged(list->currentItem(), nullptr);
}
}
void WSEvents::OnSceneListChange()
{
void WSEvents::OnSceneListChange() {
broadcastUpdate("ScenesChanged");
}
void WSEvents::OnSceneCollectionChange()
{
void WSEvents::OnSceneCollectionChange() {
broadcastUpdate("SceneCollectionChanged");
scene_handler = nullptr;
@ -340,13 +301,11 @@ void WSEvents::OnSceneCollectionChange()
OnSceneChange();
}
void WSEvents::OnSceneCollectionListChange()
{
void WSEvents::OnSceneCollectionListChange() {
broadcastUpdate("SceneCollectionListChanged");
}
void WSEvents::OnTransitionChange()
{
void WSEvents::OnTransitionChange() {
obs_source_t* current_transition = obs_frontend_get_current_transition();
connectTransitionSignals(current_transition);
@ -360,23 +319,19 @@ void WSEvents::OnTransitionChange()
obs_source_release(current_transition);
}
void WSEvents::OnTransitionListChange()
{
void WSEvents::OnTransitionListChange() {
broadcastUpdate("TransitionListChanged");
}
void WSEvents::OnProfileChange()
{
void WSEvents::OnProfileChange() {
broadcastUpdate("ProfileChanged");
}
void WSEvents::OnProfileListChange()
{
void WSEvents::OnProfileListChange() {
broadcastUpdate("ProfileListChanged");
}
void WSEvents::OnStreamStarting()
{
void WSEvents::OnStreamStarting() {
// Implements an existing update type from bilhamil's OBS Remote
obs_data_t* data = obs_data_create();
obs_data_set_bool(data, "preview-only", false);
@ -386,16 +341,14 @@ void WSEvents::OnStreamStarting()
obs_data_release(data);
}
void WSEvents::OnStreamStarted()
{
void WSEvents::OnStreamStarted() {
// New update type specific to OBS Studio
_stream_starttime = os_gettime_ns();
_lastBytesSent = 0;
broadcastUpdate("StreamStarted");
}
void WSEvents::OnStreamStopping()
{
void WSEvents::OnStreamStopping() {
// Implements an existing update type from bilhamil's OBS Remote
obs_data_t* data = obs_data_create();
obs_data_set_bool(data, "preview-only", false);
@ -405,57 +358,49 @@ void WSEvents::OnStreamStopping()
obs_data_release(data);
}
void WSEvents::OnStreamStopped()
{
void WSEvents::OnStreamStopped() {
// New update type specific to OBS Studio
_stream_starttime = 0;
broadcastUpdate("StreamStopped");
}
void WSEvents::OnRecordingStarting()
{
void WSEvents::OnRecordingStarting() {
// New update type specific to OBS Studio
broadcastUpdate("RecordingStarting");
}
void WSEvents::OnRecordingStarted()
{
void WSEvents::OnRecordingStarted() {
// New update type specific to OBS Studio
_rec_starttime = os_gettime_ns();
broadcastUpdate("RecordingStarted");
}
void WSEvents::OnRecordingStopping()
{
void WSEvents::OnRecordingStopping() {
// New update type specific to OBS Studio
broadcastUpdate("RecordingStopping");
}
void WSEvents::OnRecordingStopped()
{
void WSEvents::OnRecordingStopped() {
// New update type specific to OBS Studio
_rec_starttime = 0;
broadcastUpdate("RecordingStopped");
}
void WSEvents::OnExit()
{
void WSEvents::OnExit() {
// New update type specific to OBS Studio
broadcastUpdate("Exiting");
}
void WSEvents::StreamStatus()
{
void WSEvents::StreamStatus() {
bool streaming_active = obs_frontend_streaming_active();
bool recording_active = obs_frontend_recording_active();
obs_output_t* stream_output = obs_frontend_get_streaming_output();
if (!stream_output || !streaming_active)
{
if (stream_output)
obs_output_release(stream_output);
if (!stream_output || !streaming_active) {
if (stream_output) {
obs_output_release(stream_output);
}
return;
}
@ -503,8 +448,7 @@ void WSEvents::StreamStatus()
obs_output_release(stream_output);
}
void WSEvents::TransitionDurationChanged(int ms)
{
void WSEvents::TransitionDurationChanged(int ms) {
obs_data_t* fields = obs_data_create();
obs_data_set_int(fields, "new-duration", ms);
@ -513,8 +457,7 @@ void WSEvents::TransitionDurationChanged(int ms)
obs_data_release(fields);
}
void WSEvents::OnTransitionBegin(void* param, calldata_t* data)
{
void WSEvents::OnTransitionBegin(void* param, calldata_t* data) {
UNUSED_PARAMETER(data);
WSEvents* instance = static_cast<WSEvents*>(param);
@ -523,8 +466,7 @@ void WSEvents::OnTransitionBegin(void* param, calldata_t* data)
blog(LOG_INFO, "transition begin");
}
void WSEvents::OnSceneReordered(void* param, calldata_t* data)
{
void WSEvents::OnSceneReordered(void* param, calldata_t* data) {
WSEvents* instance = static_cast<WSEvents*>(param);
obs_scene_t* scene = nullptr;
@ -539,8 +481,7 @@ void WSEvents::OnSceneReordered(void* param, calldata_t* data)
obs_data_release(fields);
}
void WSEvents::OnSceneItemAdd(void* param, calldata_t* data)
{
void WSEvents::OnSceneItemAdd(void* param, calldata_t* data) {
WSEvents* instance = static_cast<WSEvents*>(param);
obs_scene_t* scene = nullptr;
@ -563,8 +504,7 @@ void WSEvents::OnSceneItemAdd(void* param, calldata_t* data)
obs_data_release(fields);
}
void WSEvents::OnSceneItemDelete(void* param, calldata_t* data)
{
void WSEvents::OnSceneItemDelete(void* param, calldata_t* data) {
WSEvents* instance = static_cast<WSEvents*>(param);
obs_scene_t* scene = nullptr;
@ -587,8 +527,7 @@ void WSEvents::OnSceneItemDelete(void* param, calldata_t* data)
obs_data_release(fields);
}
void WSEvents::OnSceneItemVisibilityChanged(void* param, calldata_t* data)
{
void WSEvents::OnSceneItemVisibilityChanged(void* param, calldata_t* data) {
WSEvents* instance = static_cast<WSEvents*>(param);
obs_scene_t* scene = nullptr;
@ -615,10 +554,8 @@ void WSEvents::OnSceneItemVisibilityChanged(void* param, calldata_t* data)
obs_data_release(fields);
}
void WSEvents::SelectedSceneChanged(QListWidgetItem* current, QListWidgetItem* prev)
{
if (Utils::IsPreviewModeActive())
{
void WSEvents::SelectedSceneChanged(QListWidgetItem* current, QListWidgetItem* prev) {
if (Utils::IsPreviewModeActive()) {
obs_scene_t* scene = Utils::SceneListItemToScene(current);
if (!scene) return;
@ -636,8 +573,7 @@ void WSEvents::SelectedSceneChanged(QListWidgetItem* current, QListWidgetItem* p
}
}
void WSEvents::ModeSwitchClicked(bool checked)
{
void WSEvents::ModeSwitchClicked(bool checked) {
obs_data_t* data = obs_data_create();
obs_data_set_bool(data, "new-state", checked);

View File

@ -22,80 +22,79 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include <obs-frontend-api.h>
#include <QListWidgetItem>
#include "WSServer.h"
class WSEvents : public QObject
{
Q_OBJECT
class WSEvents : public QObject {
Q_OBJECT
public:
explicit WSEvents(WSServer* srv);
~WSEvents();
static void FrontendEventHandler(
enum obs_frontend_event event, void* private_data);
void connectTransitionSignals(obs_source_t* transition);
void connectSceneSignals(obs_source_t* scene);
static WSEvents* Instance;
public:
explicit WSEvents(WSServer* srv);
~WSEvents();
static void FrontendEventHandler(
enum obs_frontend_event event, void* private_data);
void connectTransitionSignals(obs_source_t* transition);
void connectSceneSignals(obs_source_t* scene);
static WSEvents* Instance;
uint64_t GetStreamingTime();
const char* GetStreamingTimecode();
uint64_t GetRecordingTime();
const char* GetRecordingTimecode();
uint64_t GetStreamingTime();
const char* GetStreamingTimecode();
uint64_t GetRecordingTime();
const char* GetRecordingTimecode();
private slots:
void deferredInitOperations();
void StreamStatus();
void TransitionDurationChanged(int ms);
void SelectedSceneChanged(
QListWidgetItem* current, QListWidgetItem* prev);
void ModeSwitchClicked(bool checked);
private Q_SLOTS:
void deferredInitOperations();
void StreamStatus();
void TransitionDurationChanged(int ms);
void SelectedSceneChanged(
QListWidgetItem* current, QListWidgetItem* prev);
void ModeSwitchClicked(bool checked);
private:
WSServer* _srv;
signal_handler_t* transition_handler;
signal_handler_t* scene_handler;
private:
WSServer* _srv;
signal_handler_t* transition_handler;
signal_handler_t* scene_handler;
bool _streaming_active;
bool _recording_active;
bool _streaming_active;
bool _recording_active;
uint64_t _stream_starttime;
uint64_t _rec_starttime;
uint64_t _stream_starttime;
uint64_t _rec_starttime;
uint64_t _lastBytesSent;
uint64_t _lastBytesSentTime;
uint64_t _lastBytesSent;
uint64_t _lastBytesSentTime;
void broadcastUpdate(const char* updateType,
obs_data_t* additionalFields);
void broadcastUpdate(const char* updateType,
obs_data_t* additionalFields);
void OnSceneChange();
void OnSceneListChange();
void OnSceneCollectionChange();
void OnSceneCollectionListChange();
void OnSceneChange();
void OnSceneListChange();
void OnSceneCollectionChange();
void OnSceneCollectionListChange();
void OnTransitionChange();
void OnTransitionListChange();
void OnTransitionChange();
void OnTransitionListChange();
void OnProfileChange();
void OnProfileListChange();
void OnProfileChange();
void OnProfileListChange();
void OnStreamStarting();
void OnStreamStarted();
void OnStreamStopping();
void OnStreamStopped();
void OnStreamStarting();
void OnStreamStarted();
void OnStreamStopping();
void OnStreamStopped();
void OnRecordingStarting();
void OnRecordingStarted();
void OnRecordingStopping();
void OnRecordingStopped();
void OnRecordingStarting();
void OnRecordingStarted();
void OnRecordingStopping();
void OnRecordingStopped();
void OnExit();
void OnExit();
static void OnTransitionBegin(void* param, calldata_t* data);
static void OnTransitionBegin(void* param, calldata_t* data);
static void OnSceneReordered(void* param, calldata_t* data);
static void OnSceneItemAdd(void* param, calldata_t* data);
static void OnSceneItemDelete(void* param, calldata_t* data);
static void OnSceneItemVisibilityChanged(void* param, calldata_t* data);
static void OnSceneReordered(void* param, calldata_t* data);
static void OnSceneItemAdd(void* param, calldata_t* data);
static void OnSceneItemDelete(void* param, calldata_t* data);
static void OnSceneItemVisibilityChanged(void* param, calldata_t* data);
};
#endif // WSEVENTS_H

View File

@ -20,97 +20,96 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#ifndef WSREQUESTHANDLER_H
#define WSREQUESTHANDLER_H
#include <QWebSocket>
#include <QWebSocketServer>
#include <obs-frontend-api.h>
#include <QtWebSockets/QWebSocket>
#include <QtWebSockets/QWebSocketServer>
class WSRequestHandler : public QObject {
Q_OBJECT
class WSRequestHandler : public QObject
{
Q_OBJECT
public:
explicit WSRequestHandler(QWebSocket* client);
~WSRequestHandler();
void processIncomingMessage(QString textMessage);
bool hasField(const char* name);
public:
explicit WSRequestHandler(QWebSocket* client);
~WSRequestHandler();
void processIncomingMessage(QString textMessage);
bool hasField(const char* name);
private:
static obs_service_t* _service;
QWebSocket* _client;
const char* _messageId;
const char* _requestType;
obs_data_t* data;
private:
static obs_service_t* _service;
QWebSocket* _client;
const char* _messageId;
const char* _requestType;
obs_data_t* data;
QMap<QString, void(*)(WSRequestHandler*)> messageMap;
QSet<QString> authNotRequired;
QMap<QString, void(*)(WSRequestHandler*)> messageMap;
QSet<QString> authNotRequired;
void SendOKResponse(obs_data_t* additionalFields = NULL);
void SendErrorResponse(const char* errorMessage);
void SendResponse(obs_data_t* response);
void SendOKResponse(obs_data_t* additionalFields = NULL);
void SendErrorResponse(const char* errorMessage);
void SendResponse(obs_data_t* response);
static void HandleGetVersion(WSRequestHandler* req);
static void HandleGetAuthRequired(WSRequestHandler* req);
static void HandleAuthenticate(WSRequestHandler* req);
static void HandleGetVersion(WSRequestHandler* req);
static void HandleGetAuthRequired(WSRequestHandler* req);
static void HandleAuthenticate(WSRequestHandler* req);
static void HandleSetCurrentScene(WSRequestHandler* req);
static void HandleGetCurrentScene(WSRequestHandler* req);
static void HandleGetSceneList(WSRequestHandler* req);
static void HandleSetCurrentScene(WSRequestHandler* req);
static void HandleGetCurrentScene(WSRequestHandler* req);
static void HandleGetSceneList(WSRequestHandler* req);
static void HandleSetSceneItemRender(WSRequestHandler* req);
static void HandleSetSceneItemPosition(WSRequestHandler* req);
static void HandleSetSceneItemTransform(WSRequestHandler* req);
static void HandleSetSceneItemCrop(WSRequestHandler* req);
static void HandleSetSceneItemRender(WSRequestHandler* req);
static void HandleSetSceneItemPosition(WSRequestHandler* req);
static void HandleSetSceneItemTransform(WSRequestHandler* req);
static void HandleSetSceneItemCrop(WSRequestHandler* req);
static void HandleGetStreamingStatus(WSRequestHandler* req);
static void HandleStartStopStreaming(WSRequestHandler* req);
static void HandleStartStopRecording(WSRequestHandler* req);
static void HandleStartStreaming(WSRequestHandler* req);
static void HandleStopStreaming(WSRequestHandler* req);
static void HandleStartRecording(WSRequestHandler* req);
static void HandleStopRecording(WSRequestHandler* req);
static void HandleGetStreamingStatus(WSRequestHandler* req);
static void HandleStartStopStreaming(WSRequestHandler* req);
static void HandleStartStopRecording(WSRequestHandler* req);
static void HandleStartStreaming(WSRequestHandler* req);
static void HandleStopStreaming(WSRequestHandler* req);
static void HandleStartRecording(WSRequestHandler* req);
static void HandleStopRecording(WSRequestHandler* req);
static void HandleSetRecordingFolder(WSRequestHandler* req);
static void HandleGetRecordingFolder(WSRequestHandler* req);
static void HandleSetRecordingFolder(WSRequestHandler* req);
static void HandleGetRecordingFolder(WSRequestHandler* req);
static void HandleGetTransitionList(WSRequestHandler* req);
static void HandleGetCurrentTransition(WSRequestHandler* req);
static void HandleSetCurrentTransition(WSRequestHandler* req);
static void HandleGetTransitionList(WSRequestHandler* req);
static void HandleGetCurrentTransition(WSRequestHandler* req);
static void HandleSetCurrentTransition(WSRequestHandler* req);
static void HandleSetVolume(WSRequestHandler* req);
static void HandleGetVolume(WSRequestHandler* req);
static void HandleToggleMute(WSRequestHandler* req);
static void HandleSetMute(WSRequestHandler* req);
static void HandleGetMute(WSRequestHandler* req);
static void HandleGetSpecialSources(WSRequestHandler* req);
static void HandleSetVolume(WSRequestHandler* req);
static void HandleGetVolume(WSRequestHandler* req);
static void HandleToggleMute(WSRequestHandler* req);
static void HandleSetMute(WSRequestHandler* req);
static void HandleGetMute(WSRequestHandler* req);
static void HandleGetSpecialSources(WSRequestHandler* req);
static void HandleSetCurrentSceneCollection(WSRequestHandler* req);
static void HandleGetCurrentSceneCollection(WSRequestHandler* req);
static void HandleListSceneCollections(WSRequestHandler* req);
static void HandleSetCurrentSceneCollection(WSRequestHandler* req);
static void HandleGetCurrentSceneCollection(WSRequestHandler* req);
static void HandleListSceneCollections(WSRequestHandler* req);
static void HandleSetCurrentProfile(WSRequestHandler* req);
static void HandleGetCurrentProfile(WSRequestHandler* req);
static void HandleListProfiles(WSRequestHandler* req);
static void HandleSetCurrentProfile(WSRequestHandler* req);
static void HandleGetCurrentProfile(WSRequestHandler* req);
static void HandleListProfiles(WSRequestHandler* req);
static void HandleSetStreamSettings(WSRequestHandler* req);
static void HandleGetStreamSettings(WSRequestHandler* req);
static void HandleSaveStreamSettings(WSRequestHandler* req);
static void HandleSetStreamSettings(WSRequestHandler* req);
static void HandleGetStreamSettings(WSRequestHandler* req);
static void HandleSaveStreamSettings(WSRequestHandler* req);
static void HandleSetTransitionDuration(WSRequestHandler* req);
static void HandleGetTransitionDuration(WSRequestHandler* req);
static void HandleSetTransitionDuration(WSRequestHandler* req);
static void HandleGetTransitionDuration(WSRequestHandler* req);
static void HandleGetStudioModeStatus(WSRequestHandler* req);
static void HandleGetPreviewScene(WSRequestHandler* req);
static void HandleSetPreviewScene(WSRequestHandler* req);
static void HandleTransitionToProgram(WSRequestHandler* req);
static void HandleEnableStudioMode(WSRequestHandler* req);
static void HandleDisableStudioMode(WSRequestHandler* req);
static void HandleToggleStudioMode(WSRequestHandler* req);
static void HandleGetStudioModeStatus(WSRequestHandler* req);
static void HandleGetPreviewScene(WSRequestHandler* req);
static void HandleSetPreviewScene(WSRequestHandler* req);
static void HandleTransitionToProgram(WSRequestHandler* req);
static void HandleEnableStudioMode(WSRequestHandler* req);
static void HandleDisableStudioMode(WSRequestHandler* req);
static void HandleToggleStudioMode(WSRequestHandler* req);
static void HandleSetTextGDIPlusProperties(WSRequestHandler* req);
static void HandleGetTextGDIPlusProperties(WSRequestHandler* req);
static void HandleSetBrowserSourceProperties(WSRequestHandler* req);
static void HandleGetBrowserSourceProperties(WSRequestHandler* req);
static void HandleSetTextGDIPlusProperties(WSRequestHandler* req);
static void HandleGetTextGDIPlusProperties(WSRequestHandler* req);
static void HandleSetBrowserSourceProperties(WSRequestHandler* req);
static void HandleGetBrowserSourceProperties(WSRequestHandler* req);
};
#endif // WSPROTOCOL_H

View File

@ -34,26 +34,21 @@ WSServer::WSServer(QObject* parent) :
QObject(parent),
_wsServer(Q_NULLPTR),
_clients(),
_clMutex(QMutex::Recursive)
{
_clMutex(QMutex::Recursive) {
_serverThread = new QThread();
_wsServer = new QWebSocketServer(
QStringLiteral("obs-websocket"),
QWebSocketServer::NonSecureMode,
_serverThread);
_serverThread->start();
}
WSServer::~WSServer()
{
WSServer::~WSServer() {
Stop();
delete _serverThread;
}
void WSServer::Start(quint16 port)
{
void WSServer::Start(quint16 port) {
if (port == _wsServer->serverPort())
return;
@ -61,15 +56,13 @@ void WSServer::Start(quint16 port)
Stop();
bool serverStarted = _wsServer->listen(QHostAddress::Any, port);
if (serverStarted)
{
connect(_wsServer, &QWebSocketServer::newConnection,
this, &WSServer::onNewConnection);
if (serverStarted) {
connect(_wsServer, SIGNAL(newConnection()),
this, SLOT(onNewConnection()));
}
}
void WSServer::Stop()
{
void WSServer::Stop() {
_clMutex.lock();
for(QWebSocket* pClient : _clients) {
pClient->close();
@ -79,35 +72,34 @@ void WSServer::Stop()
_wsServer->close();
}
void WSServer::broadcast(QString message)
{
void WSServer::broadcast(QString message) {
_clMutex.lock();
for(QWebSocket* pClient : _clients) {
if (Config::Current()->AuthRequired
&& (pClient->property(PROP_AUTHENTICATED).toBool() == false))
{
&& (pClient->property(PROP_AUTHENTICATED).toBool() == false)) {
// Skip this client if unauthenticated
continue;
}
pClient->sendTextMessage(message);
}
_clMutex.unlock();
}
void WSServer::onNewConnection()
{
void WSServer::onNewConnection() {
QWebSocket* pSocket = _wsServer->nextPendingConnection();
if (pSocket)
{
if (pSocket) {
connect(pSocket, &QWebSocket::textMessageReceived,
this, &WSServer::textMessageReceived);
this, &WSServer::onTextMessageReceived);
connect(pSocket, &QWebSocket::disconnected,
this, &WSServer::socketDisconnected);
pSocket->setProperty(PROP_AUTHENTICATED, false);
this, &WSServer::onSocketDisconnected);
connect(pSocket, SIGNAL(textMessageReceived(const QString&)),
this, SLOT(onTextMessageReceived(QString)));
connect(pSocket, SIGNAL(disconnected()),
this, SLOT(onSocketDisconnected()));
pSocket->setProperty(PROP_AUTHENTICATED, false);
_clMutex.lock();
_clients << pSocket;
@ -129,23 +121,17 @@ void WSServer::onNewConnection()
}
}
void WSServer::textMessageReceived(QString message)
{
void WSServer::onTextMessageReceived(QString message) {
QWebSocket* pSocket = qobject_cast<QWebSocket*>(sender());
if (pSocket)
{
if (pSocket) {
WSRequestHandler handler(pSocket);
handler.processIncomingMessage(message);
}
}
void WSServer::socketDisconnected()
{
void WSServer::onSocketDisconnected() {
QWebSocket* pSocket = qobject_cast<QWebSocket*>(sender());
if (pSocket)
{
if (pSocket) {
pSocket->setProperty(PROP_AUTHENTICATED, false);
_clMutex.lock();

View File

@ -19,37 +19,35 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#ifndef WSSERVER_H
#define WSSERVER_H
#include <QtCore/QObject>
#include <QtCore/QList>
#include <QtCore/QMutex>
#include <QObject>
#include <QList>
#include <QMutex>
#include "WSRequestHandler.h"
QT_FORWARD_DECLARE_CLASS(QWebSocketServer)
QT_FORWARD_DECLARE_CLASS(QWebSocket)
#include "WSRequestHandler.h"
class WSServer : public QObject {
Q_OBJECT
public:
explicit WSServer(QObject* parent = Q_NULLPTR);
virtual ~WSServer();
void Start(quint16 port);
void Stop();
void broadcast(QString message);
static WSServer* Instance;
class WSServer : public QObject
{
Q_OBJECT
private slots:
void onNewConnection();
void onTextMessageReceived(QString message);
void onSocketDisconnected();
public:
explicit WSServer(QObject* parent = Q_NULLPTR);
virtual ~WSServer();
void Start(quint16 port);
void Stop();
void broadcast(QString message);
static WSServer* Instance;
private Q_SLOTS:
void onNewConnection();
void textMessageReceived(QString message);
void socketDisconnected();
private:
QWebSocketServer* _wsServer;
QList<QWebSocket*> _clients;
QMutex _clMutex;
QThread* _serverThread;
private:
QWebSocketServer* _wsServer;
QList<QWebSocket*> _clients;
QMutex _clMutex;
QThread* _serverThread;
};
#endif // WSSERVER_H

View File

@ -31,10 +31,9 @@ with this program. If not, see <https://www.gnu.org/licenses/>
OBS_DECLARE_MODULE()
OBS_MODULE_USE_DEFAULT_LOCALE("obs-websocket", "en-US")
SettingsDialog *settings_dialog;
SettingsDialog* settings_dialog;
bool obs_module_load(void)
{
bool obs_module_load(void) {
blog(LOG_INFO, "you can haz websockets (version %s)", OBS_WEBSOCKET_VERSION);
// Core setup
@ -48,7 +47,7 @@ bool obs_module_load(void)
WSServer::Instance->Start(config->ServerPort);
// UI setup
QAction *menu_action = (QAction*)obs_frontend_add_tools_menu_qaction(
QAction* menu_action = (QAction*)obs_frontend_add_tools_menu_qaction(
obs_module_text("OBSWebsocket.Menu.SettingsItem"));
obs_frontend_push_ui_translation(obs_module_get_string);
@ -67,8 +66,7 @@ bool obs_module_load(void)
return true;
}
void obs_module_unload()
{
void obs_module_unload() {
blog(LOG_INFO, "goodbye!");
}