mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
Updated locale variables names + WIP Dynamic Server Settings
This commit is contained in:
parent
f8b1cae0c9
commit
3d68b7c9e5
96
Config.cpp
96
Config.cpp
@ -19,22 +19,41 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
#include <mbedtls/base64.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <obs-frontend-api.h>
|
||||
#include <util/config-file.h>
|
||||
#include "Config.h"
|
||||
|
||||
#define CONFIG_SECTION_NAME "obs-websocket"
|
||||
#define CONFIG_PARAM_SECRET "auth_hash"
|
||||
#define CONFIG_PARAM_SALT "auth_salt"
|
||||
#define CONFIG_PARAM_AUTHREQUIRED "auth_required"
|
||||
#define SECTION_NAME "obs-websocket"
|
||||
#define PARAM_ENABLE "server_enabled"
|
||||
#define PARAM_PORT "server_port"
|
||||
#define PARAM_SECRET "auth_hash"
|
||||
#define PARAM_SALT "auth_salt"
|
||||
#define PARAM_AUTHREQUIRED "auth_required"
|
||||
|
||||
Config *Config::_instance = new Config();
|
||||
|
||||
Config::Config() {
|
||||
Config::Config()
|
||||
{
|
||||
// Default settings
|
||||
ServerEnabled = true;
|
||||
ServerPort = 4444;
|
||||
|
||||
AuthRequired = false;
|
||||
Secret = "";
|
||||
Salt = "";
|
||||
SettingsLoaded = false;
|
||||
|
||||
// OBS Config defaults
|
||||
config_t* obs_config = obs_frontend_get_global_config();
|
||||
if (obs_config)
|
||||
{
|
||||
config_set_default_bool(obs_config, SECTION_NAME, PARAM_ENABLE, ServerEnabled);
|
||||
config_set_default_uint(obs_config, SECTION_NAME, PARAM_PORT, ServerPort);
|
||||
|
||||
config_set_default_bool(obs_config, SECTION_NAME, PARAM_AUTHREQUIRED, AuthRequired);
|
||||
config_set_default_string(obs_config, SECTION_NAME, PARAM_SECRET, Secret);
|
||||
config_set_default_string(obs_config, SECTION_NAME, PARAM_SALT, Salt);
|
||||
}
|
||||
|
||||
mbedtls_entropy_init(&entropy);
|
||||
mbedtls_ctr_drbg_init(&rng);
|
||||
mbedtls_ctr_drbg_seed(&rng, mbedtls_entropy_func, &entropy, nullptr, 0);
|
||||
@ -43,12 +62,40 @@ Config::Config() {
|
||||
SessionChallenge = GenerateSalt();
|
||||
}
|
||||
|
||||
Config::~Config() {
|
||||
Config::~Config()
|
||||
{
|
||||
mbedtls_ctr_drbg_free(&rng);
|
||||
mbedtls_entropy_free(&entropy);
|
||||
}
|
||||
|
||||
const char* Config::GenerateSalt() {
|
||||
void Config::Load()
|
||||
{
|
||||
config_t* obs_config = obs_frontend_get_global_config();
|
||||
|
||||
ServerEnabled = config_get_bool(obs_config, SECTION_NAME, PARAM_ENABLE);
|
||||
ServerPort = config_get_uint(obs_config, SECTION_NAME, PARAM_PORT);
|
||||
|
||||
AuthRequired = config_get_bool(obs_config, SECTION_NAME, PARAM_AUTHREQUIRED);
|
||||
Secret = config_get_string(obs_config, SECTION_NAME, PARAM_SECRET);
|
||||
Salt = config_get_string(obs_config, SECTION_NAME, PARAM_SALT);
|
||||
}
|
||||
|
||||
void Config::Save()
|
||||
{
|
||||
config_t* obs_config = obs_frontend_get_global_config();
|
||||
|
||||
config_set_bool(obs_config, SECTION_NAME, PARAM_ENABLE, ServerEnabled);
|
||||
config_set_uint(obs_config, SECTION_NAME, PARAM_PORT, ServerPort);
|
||||
|
||||
config_set_bool(obs_config, SECTION_NAME, PARAM_AUTHREQUIRED, AuthRequired);
|
||||
config_set_string(obs_config, SECTION_NAME, PARAM_SECRET, Secret);
|
||||
config_set_string(obs_config, SECTION_NAME, PARAM_SALT, Salt);
|
||||
|
||||
config_save(obs_config);
|
||||
}
|
||||
|
||||
const char* Config::GenerateSalt()
|
||||
{
|
||||
// Generate 32 random chars
|
||||
unsigned char *random_chars = (unsigned char *)bzalloc(32);
|
||||
mbedtls_ctr_drbg_random(&rng, random_chars, 32);
|
||||
@ -63,7 +110,8 @@ const char* Config::GenerateSalt() {
|
||||
return (char *)salt;
|
||||
}
|
||||
|
||||
const char* Config::GenerateSecret(const char *password, const char *salt) {
|
||||
const char* Config::GenerateSecret(const char *password, const char *salt)
|
||||
{
|
||||
size_t passwordLength = strlen(password);
|
||||
size_t saltLength = strlen(salt);
|
||||
|
||||
@ -88,7 +136,8 @@ const char* Config::GenerateSecret(const char *password, const char *salt) {
|
||||
return (char*)challenge;
|
||||
}
|
||||
|
||||
void Config::SetPassword(const char *password) {
|
||||
void Config::SetPassword(const char *password)
|
||||
{
|
||||
const char *new_salt = GenerateSalt();
|
||||
const char *new_challenge = GenerateSecret(password, new_salt);
|
||||
|
||||
@ -96,7 +145,8 @@ void Config::SetPassword(const char *password) {
|
||||
this->Secret = new_challenge;
|
||||
}
|
||||
|
||||
bool Config::CheckAuth(const char *response) {
|
||||
bool Config::CheckAuth(const char *response)
|
||||
{
|
||||
size_t secretLength = strlen(this->Secret);
|
||||
size_t sessChallengeLength = strlen(this->SessionChallenge);
|
||||
|
||||
@ -125,29 +175,7 @@ bool Config::CheckAuth(const char *response) {
|
||||
}
|
||||
}
|
||||
|
||||
void Config::OBSSaveCallback(obs_data_t *save_data, bool saving, void *private_data) {
|
||||
Config *conf = static_cast<Config *>(private_data);
|
||||
|
||||
if (saving) {
|
||||
obs_data_t *settings = obs_data_create();
|
||||
obs_data_set_bool(settings, CONFIG_PARAM_AUTHREQUIRED, conf->AuthRequired);
|
||||
obs_data_set_string(settings, CONFIG_PARAM_SECRET, conf->Secret);
|
||||
obs_data_set_string(settings, CONFIG_PARAM_SALT, conf->Salt);
|
||||
|
||||
obs_data_set_obj(save_data, CONFIG_SECTION_NAME, settings);
|
||||
}
|
||||
else {
|
||||
obs_data_t *settings = obs_data_get_obj(save_data, CONFIG_SECTION_NAME);
|
||||
if (settings) {
|
||||
conf->AuthRequired = obs_data_get_bool(settings, CONFIG_PARAM_AUTHREQUIRED);
|
||||
conf->Secret = obs_data_get_string(settings, CONFIG_PARAM_SECRET);
|
||||
conf->Salt = obs_data_get_string(settings, CONFIG_PARAM_SALT);
|
||||
|
||||
conf->SettingsLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Config* Config::Current() {
|
||||
Config* Config::Current()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
10
Config.h
10
Config.h
@ -23,15 +23,21 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
|
||||
class Config {
|
||||
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);
|
||||
static void OBSSaveCallback(obs_data_t *save_data, bool saving, void *);
|
||||
|
||||
bool ServerEnabled;
|
||||
uint64_t ServerPort;
|
||||
|
||||
bool AuthRequired;
|
||||
const char *Secret;
|
||||
|
@ -19,8 +19,8 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
|
||||
#include "WSEvents.h"
|
||||
|
||||
WSEvents::WSEvents(WSServer *server) {
|
||||
_srv = server;
|
||||
WSEvents::WSEvents(WSServer *srv) {
|
||||
_srv = srv;
|
||||
obs_frontend_add_event_callback(WSEvents::FrontendEventHandler, this);
|
||||
|
||||
QTimer *statusTimer = new QTimer();
|
||||
@ -39,6 +39,9 @@ void WSEvents::FrontendEventHandler(enum obs_frontend_event event, void *private
|
||||
{
|
||||
WSEvents *owner = static_cast<WSEvents *>(private_data);
|
||||
|
||||
if (!owner->_srv)
|
||||
return;
|
||||
|
||||
// TODO : implement SourceChanged, SourceOrderChanged and RepopulateSources
|
||||
|
||||
if (event == OBS_FRONTEND_EVENT_SCENE_CHANGED) {
|
||||
|
@ -31,7 +31,7 @@ class WSEvents : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WSEvents(WSServer *server);
|
||||
explicit WSEvents(WSServer *srv);
|
||||
~WSEvents();
|
||||
static void FrontendEventHandler(enum obs_frontend_event event, void *private_data);
|
||||
|
||||
|
31
WSServer.cpp
31
WSServer.cpp
@ -29,7 +29,9 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
WSServer::WSServer(quint16 port, QObject *parent) :
|
||||
WSServer* WSServer::Instance = new WSServer();
|
||||
|
||||
WSServer::WSServer(QObject *parent) :
|
||||
QObject(parent),
|
||||
_wsServer(Q_NULLPTR),
|
||||
_clients(),
|
||||
@ -44,6 +46,22 @@ WSServer::WSServer(quint16 port, QObject *parent) :
|
||||
|
||||
_wsServer->moveToThread(_serverThread);
|
||||
_serverThread->start();
|
||||
}
|
||||
|
||||
WSServer::~WSServer()
|
||||
{
|
||||
Stop();
|
||||
|
||||
delete _serverThread;
|
||||
}
|
||||
|
||||
void WSServer::Start(quint16 port)
|
||||
{
|
||||
if (port == _wsServer->serverPort())
|
||||
return;
|
||||
|
||||
if(_wsServer->isListening())
|
||||
Stop();
|
||||
|
||||
bool serverStarted = _wsServer->listen(QHostAddress::Any, port);
|
||||
if (serverStarted)
|
||||
@ -52,15 +70,18 @@ WSServer::WSServer(quint16 port, QObject *parent) :
|
||||
}
|
||||
}
|
||||
|
||||
WSServer::~WSServer()
|
||||
void WSServer::Stop()
|
||||
{
|
||||
_wsServer->close();
|
||||
|
||||
_clMutex.lock();
|
||||
Q_FOREACH(QWebSocket *pClient, _clients)
|
||||
{
|
||||
pClient->close();
|
||||
}
|
||||
|
||||
qDeleteAll(_clients.begin(), _clients.end());
|
||||
_clMutex.unlock();
|
||||
|
||||
delete _serverThread;
|
||||
_wsServer->close();
|
||||
}
|
||||
|
||||
void WSServer::broadcast(QString message)
|
||||
|
@ -34,9 +34,12 @@ class WSServer : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WSServer(quint16 port, QObject *parent = Q_NULLPTR);
|
||||
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();
|
||||
|
@ -1,4 +1,4 @@
|
||||
Menu.SettingsItem="Websocket-Server Einstellungen"
|
||||
Settings.DialogTitle="Websocket-Server Einstellungen"
|
||||
Settings.AuthRequired="Authentifizierung erforderlich"
|
||||
Settings.Password="Passwort"
|
||||
OBSWebsocket.Menu.SettingsItem="Websocket-Server Einstellungen"
|
||||
OBSWebsocket.Settings.DialogTitle="Websocket-Server Einstellungen"
|
||||
OBSWebsocket.Settings.AuthRequired="Authentifizierung erforderlich"
|
||||
OBSWebsocket.Settings.Password="Passwort"
|
@ -1,4 +1,6 @@
|
||||
Menu.SettingsItem="Websocket server settings"
|
||||
Settings.DialogTitle="obs-websocket"
|
||||
Settings.AuthRequired="Enable authentication"
|
||||
Settings.Password="Password"
|
||||
OBSWebsocket.Menu.SettingsItem="Websocket server settings"
|
||||
OBSWebsocket.Settings.DialogTitle="obs-websocket"
|
||||
OBSWebsocket.Settings.ServerEnable="Enable Websocket server"
|
||||
OBSWebsocket.Settings.ServerPort="Server Port"
|
||||
OBSWebsocket.Settings.AuthRequired="Enable authentication"
|
||||
OBSWebsocket.Settings.Password="Password"
|
@ -1,4 +1,6 @@
|
||||
Menu.SettingsItem="Paramètres du serveur Websocket"
|
||||
Settings.DialogTitle="obs-websocket"
|
||||
Settings.AuthRequired="Activer l'authentification"
|
||||
Settings.Password="Mot de passe"
|
||||
OBSWebsocket.Menu.SettingsItem="Paramètres du serveur Websocket"
|
||||
OBSWebsocket.Settings.DialogTitle="obs-websocket"
|
||||
OBSWebsocket.Settings.ServerEnable="Activer le serveur Websockets"
|
||||
OBSWebsocket.Settings.ServerPort="Port du serveur"
|
||||
OBSWebsocket.Settings.AuthRequired="Activer l'authentification"
|
||||
OBSWebsocket.Settings.Password="Mot de passe"
|
@ -17,9 +17,12 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
#include "obs-websocket.h"
|
||||
#include "Config.h"
|
||||
#include "WSServer.h"
|
||||
#include "settings-dialog.h"
|
||||
#include "ui_settings-dialog.h"
|
||||
#include "Config.h"
|
||||
|
||||
#define CHANGE_ME "changeme"
|
||||
|
||||
@ -35,12 +38,19 @@ SettingsDialog::SettingsDialog(QWidget *parent) :
|
||||
AuthCheckboxChanged();
|
||||
}
|
||||
|
||||
void SettingsDialog::showEvent(QShowEvent *event) {
|
||||
ui->authRequired->setChecked(Config::Current()->AuthRequired);
|
||||
void SettingsDialog::showEvent(QShowEvent *event)
|
||||
{
|
||||
Config* conf = Config::Current();
|
||||
|
||||
ui->serverEnabled->setChecked(conf->ServerEnabled);
|
||||
ui->serverPort->setValue(conf->ServerPort);
|
||||
|
||||
ui->authRequired->setChecked(conf->AuthRequired);
|
||||
ui->password->setText(CHANGE_ME);
|
||||
}
|
||||
|
||||
void SettingsDialog::ToggleShowHide() {
|
||||
void SettingsDialog::ToggleShowHide()
|
||||
{
|
||||
if (!isVisible()) {
|
||||
setVisible(true);
|
||||
}
|
||||
@ -49,7 +59,8 @@ void SettingsDialog::ToggleShowHide() {
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::AuthCheckboxChanged() {
|
||||
void SettingsDialog::AuthCheckboxChanged()
|
||||
{
|
||||
if (ui->authRequired->isChecked()) {
|
||||
ui->password->setEnabled(true);
|
||||
}
|
||||
@ -58,28 +69,48 @@ void SettingsDialog::AuthCheckboxChanged() {
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::FormAccepted() {
|
||||
if (ui->authRequired->isChecked()) {
|
||||
if (ui->password->text() != CHANGE_ME) {
|
||||
void SettingsDialog::FormAccepted()
|
||||
{
|
||||
Config* conf = Config::Current();
|
||||
|
||||
conf->ServerEnabled = ui->serverEnabled->isChecked();
|
||||
conf->ServerPort = ui->serverPort->value();
|
||||
|
||||
if (ui->authRequired->isChecked())
|
||||
{
|
||||
if (ui->password->text() != CHANGE_ME)
|
||||
{
|
||||
QByteArray pwd = ui->password->text().toLocal8Bit();
|
||||
const char *new_password = pwd;
|
||||
|
||||
blog(LOG_INFO, "new password : %s", new_password);
|
||||
Config::Current()->SetPassword(new_password);
|
||||
conf->SetPassword(new_password);
|
||||
}
|
||||
|
||||
if (strcmp(Config::Current()->Secret, "") != 0) {
|
||||
Config::Current()->AuthRequired = true;
|
||||
if (strcmp(Config::Current()->Secret, "") != 0)
|
||||
{
|
||||
conf->AuthRequired = true;
|
||||
}
|
||||
else {
|
||||
Config::Current()->AuthRequired = false;
|
||||
else
|
||||
{
|
||||
conf->AuthRequired = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Config::Current()->AuthRequired = false;
|
||||
else
|
||||
{
|
||||
conf->AuthRequired = false;
|
||||
}
|
||||
|
||||
conf->Save();
|
||||
|
||||
if (conf->ServerEnabled)
|
||||
{
|
||||
WSServer::Instance->Start(conf->ServerPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
WSServer::Instance->Stop();
|
||||
}
|
||||
|
||||
obs_frontend_save();
|
||||
}
|
||||
|
||||
SettingsDialog::~SettingsDialog()
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>354</width>
|
||||
<height>110</height>
|
||||
<width>407</width>
|
||||
<height>155</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -17,7 +17,7 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Settings.DialogTitle</string>
|
||||
<string>OBSWebsocket.Settings.DialogTitle</string>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>false</bool>
|
||||
@ -28,24 +28,54 @@
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lbl_password">
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="authRequired">
|
||||
<property name="text">
|
||||
<string>Settings.Password</string>
|
||||
<string>OBSWebsocket.Settings.AuthRequired</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="lbl_password">
|
||||
<property name="text">
|
||||
<string>OBSWebsocket.Settings.Password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="password">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="authRequired">
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="serverEnabled">
|
||||
<property name="text">
|
||||
<string>Settings.AuthRequired</string>
|
||||
<string>OBSWebsocket.Settings.ServerEnable</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbl_serverPort">
|
||||
<property name="text">
|
||||
<string>OBSWebsocket.Settings.ServerPort</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="serverPort">
|
||||
<property name="minimum">
|
||||
<number>1024</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>4444</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -21,8 +21,8 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
#include <QAction>
|
||||
|
||||
#include "obs-websocket.h"
|
||||
#include "WSEvents.h"
|
||||
#include "WSServer.h"
|
||||
#include "WSEvents.h"
|
||||
#include "Config.h"
|
||||
#include "forms/settings-dialog.h"
|
||||
|
||||
@ -30,19 +30,21 @@ OBS_DECLARE_MODULE()
|
||||
OBS_MODULE_USE_DEFAULT_LOCALE("obs-websocket", "en-US")
|
||||
|
||||
WSEvents *eventHandler;
|
||||
WSServer *server;
|
||||
SettingsDialog *settings_dialog;
|
||||
|
||||
bool obs_module_load(void)
|
||||
{
|
||||
blog(LOG_INFO, "[obs-websockets] you can haz websockets (version %s)", OBS_WEBSOCKET_VERSION);
|
||||
|
||||
server = new WSServer(4444);
|
||||
eventHandler = new WSEvents(server);
|
||||
|
||||
obs_frontend_add_save_callback(Config::OBSSaveCallback, Config::Current());
|
||||
// Core setup
|
||||
Config* config = Config::Current();
|
||||
config->Load();
|
||||
|
||||
QAction *menu_action = (QAction*)obs_frontend_add_tools_menu_qaction(obs_module_text("Menu.SettingsItem"));
|
||||
if (config->ServerEnabled)
|
||||
WSServer::Instance->Start(config->ServerPort);
|
||||
|
||||
eventHandler = new WSEvents(WSServer::Instance);
|
||||
|
||||
// UI setup
|
||||
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);
|
||||
settings_dialog = new SettingsDialog();
|
||||
@ -53,6 +55,9 @@ bool obs_module_load(void)
|
||||
};
|
||||
menu_action->connect(menu_action, &QAction::triggered, menu_cb);
|
||||
|
||||
// Loading finished
|
||||
blog(LOG_INFO, "[obs-websockets] you can haz websockets (version %s)", OBS_WEBSOCKET_VERSION);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user