diff --git a/.gitmodules b/.gitmodules index ecd47ac0..ce13f339 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "deps/json"] path = deps/json url = https://github.com/nlohmann/json.git +[submodule "deps/qr"] + path = deps/qr + url = https://github.com/nayuki/QR-Code-generator.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 81f0645b..2a0f15cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,10 +79,12 @@ set(obs-websocket_SOURCES src/requesthandler/rpc/Request.cpp src/requesthandler/rpc/RequestResult.cpp src/forms/SettingsDialog.cpp + src/forms/ConnectInfo.cpp src/utils/Json.cpp src/utils/Crypto.cpp src/utils/Platform.cpp - src/utils/Obs.cpp) + src/utils/Obs.cpp + deps/qr/cpp/QrCode.cpp) set(obs-websocket_HEADERS src/obs-websocket.h @@ -95,7 +97,9 @@ set(obs-websocket_HEADERS src/requesthandler/rpc/RequestResult.h src/requesthandler/rpc/RequestStatus.h src/forms/SettingsDialog.h - src/utils/Utils.h) + src/forms/ConnectInfo.h + src/utils/Utils.h + deps/qr/cpp/QrCode.hpp) # Platform-independent build settings diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 817d434b..f4df6ea3 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -2,12 +2,13 @@ OBSWebSocket.Settings.DialogTitle="WebSocket Server Settings" OBSWebSocket.Settings.ServerEnable="Enable WebSocket server" OBSWebSocket.Settings.AlertsEnable="Enable System Tray Alerts" OBSWebSocket.Settings.DebugEnable="Enable Debug Logging" +OBSWebSocket.Settings.DebugEnableHoverText="Changing this requires the WebSocket server to restart. However, changing this will not automatically restart the obs-websocket server." OBSWebSocket.Settings.AuthRequired="Enable Authentication" OBSWebSocket.Settings.Password="Server Password" -OBSWebSocket.Settings.CopyPassword="Copy Password to Clipboard" +OBSWebSocket.Settings.GeneratePassword="Generate Password" +OBSWebSocket.Settings.ShowConnectInfo="Show Connect Info" OBSWebSocket.Settings.ServerPort="Server Port" OBSWebSocket.Settings.ConnectedSessionsTitle="Connected WebSocket Sessions" -OBSWebSocket.Settings.DebugEnableHoverText="Changing this requires the WebSocket server to restart. However, changing this will not automatically restart the obs-websocket server." OBSWebSocket.SessionTable.RemoteAddressColumnTitle="Remote Address" OBSWebSocket.SessionTable.SessionDurationColumnTitle="Session Duration" @@ -16,6 +17,14 @@ OBSWebSocket.SessionTable.IdentifiedTitle="Identified" OBSWebSocket.SessionTable.KickButtonColumnTitle="Kick?" OBSWebSocket.SessionTable.KickButtonText="Kick" +OBSWebSocket.ConnectInfo.DialogTitle="WebSocket Connect Info" +OBSWebSocket.ConnectInfo.CopyText="Copy" +OBSWebSocket.ConnectInfo.ServerIp="Server IP" +OBSWebSocket.ConnectInfo.ServerPort="Server Port" +OBSWebSocket.ConnectInfo.ServerPassword="Server Password" +OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Auth Disabled]" +OBSWebSocket.ConnectInfo.QrTitle="Connect QR" + OBSWebSocket.NotifyConnect.Title="New WebSocket connection." OBSWebSocket.NotifyConnect.Message="Client %1 connected." OBSWebSocket.NotifyDisconnect.Title="WebSocket client disconnected." diff --git a/deps/qr b/deps/qr new file mode 160000 index 00000000..8518684c --- /dev/null +++ b/deps/qr @@ -0,0 +1 @@ +Subproject commit 8518684c0f33d004fa93971be2c6a8eca3167d1e diff --git a/src/Config.cpp b/src/Config.cpp index 986421ee..058bb782 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -7,6 +7,7 @@ #define CONFIG_SECTION_NAME "OBSWebSocket" +#define PARAM_FIRSTLOAD "FirstLoad" #define PARAM_ENABLED "ServerEnabled" #define PARAM_PORT "ServerPort" #define PARAM_DEBUG "DebugEnabled" @@ -17,14 +18,8 @@ #define CMDLINE_WEBSOCKET_PORT "websocket_port" #define CMDLINE_WEBSOCKET_PASSWORD "websocket_password" -std::vector GetCmdlineArgs() -{ - struct obs_cmdline_args args = obs_get_cmdline_args(); - std::vector ret(args.argv + 1, args.argv + args.argc); - return ret; -} - Config::Config() : + FirstLoad(true), PortOverridden(false), PasswordOverridden(false), ServerEnabled(true), @@ -45,6 +40,7 @@ void Config::Load() return; } + FirstLoad = config_get_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_FIRSTLOAD); ServerEnabled = config_get_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ENABLED); DebugEnabled = config_get_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_DEBUG); AlertsEnabled = config_get_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ALERTS); @@ -72,7 +68,11 @@ void Config::Load() ServerPassword = passwordArgument; } else { AuthRequired = config_get_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_AUTHREQUIRED); - ServerPassword = config_get_string(obsConfig, CONFIG_SECTION_NAME, PARAM_PASSWORD); + if (FirstLoad) { + ServerPassword = Utils::Crypto::GeneratePassword(); + } else { + ServerPassword = config_get_string(obsConfig, CONFIG_SECTION_NAME, PARAM_PASSWORD); + } } } @@ -84,6 +84,7 @@ void Config::Save() return; } + config_set_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_FIRSTLOAD, FirstLoad); config_set_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ENABLED, ServerEnabled); if (!PortOverridden) { config_set_uint(obsConfig, CONFIG_SECTION_NAME, PARAM_PORT, ServerPort); @@ -106,6 +107,7 @@ void Config::SetDefaultsToGlobalStore() return; } + config_set_default_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_FIRSTLOAD, FirstLoad); config_set_default_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ENABLED, ServerEnabled); config_set_default_uint(obsConfig, CONFIG_SECTION_NAME, PARAM_PORT, ServerPort); config_set_default_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_DEBUG, DebugEnabled); diff --git a/src/Config.h b/src/Config.h index 2f197b64..f194d623 100644 --- a/src/Config.h +++ b/src/Config.h @@ -14,6 +14,7 @@ class Config { bool PortOverridden; bool PasswordOverridden; + bool FirstLoad; bool ServerEnabled; uint16_t ServerPort; bool DebugEnabled; diff --git a/src/WebSocketServer.cpp b/src/WebSocketServer.cpp index 2a4d6dfc..bf26dfdb 100644 --- a/src/WebSocketServer.cpp +++ b/src/WebSocketServer.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include "obs-websocket.h" @@ -16,9 +15,6 @@ WebSocketServer::WebSocketServer() : QObject(nullptr), _sessions() { - // Randomize the random number generator - qsrand(QTime::currentTime().msec()); - _server.get_alog().clear_channels(websocketpp::log::alevel::all); _server.get_elog().clear_channels(websocketpp::log::elevel::all); _server.init_asio(); @@ -189,16 +185,6 @@ std::vector WebSocketServer::GetWebSocke return webSocketSessions; } -QString WebSocketServer::GetConnectString() -{ - QString ret; - if (AuthenticationRequired) - ret = QString("obswebsocket|%1:%2|%3").arg(QString::fromStdString(Utils::Platform::GetLocalAddress())).arg(_serverPort).arg(_serverPassword); - else - ret = QString("obswebsocket|%1:%2").arg(QString::fromStdString(Utils::Platform::GetLocalAddress())).arg(_serverPort); - return ret; -} - // It isn't consistent to directly call the WebSocketServer from the events system, but it would also be dumb to make it unnecessarily complicated. void WebSocketServer::BroadcastEvent(uint64_t requiredIntent, std::string eventType, json eventData) { diff --git a/src/WebSocketServer.h b/src/WebSocketServer.h index da25a484..af3278d3 100644 --- a/src/WebSocketServer.h +++ b/src/WebSocketServer.h @@ -74,8 +74,6 @@ class WebSocketServer : QObject return &_threadPool; } - QString GetConnectString(); - bool AuthenticationRequired; std::string AuthenticationSecret; std::string AuthenticationSalt; diff --git a/src/forms/ConnectInfo.cpp b/src/forms/ConnectInfo.cpp new file mode 100644 index 00000000..99da7d60 --- /dev/null +++ b/src/forms/ConnectInfo.cpp @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include "../../deps/qr/cpp/QrCode.hpp" + +#include "ConnectInfo.h" +#include "../obs-websocket.h" +#include "../Config.h" +#include "../utils/Utils.h" + +#include "../plugin-macros.generated.h" + +ConnectInfo::ConnectInfo(QWidget* parent) : + QDialog(parent, Qt::Dialog), + ui(new Ui::ConnectInfo) +{ + ui->setupUi(this); + + connect(ui->copyServerIpButton, &QPushButton::clicked, + this, &ConnectInfo::CopyServerIpButtonClicked); + connect(ui->copyServerPortButton, &QPushButton::clicked, + this, &ConnectInfo::CopyServerPortButtonClicked); + connect(ui->copyServerPasswordButton, &QPushButton::clicked, + this, &ConnectInfo::CopyServerPasswordButtonClicked); +} + +ConnectInfo::~ConnectInfo() +{ + delete ui; +} + +void ConnectInfo::showEvent(QShowEvent *event) +{ + auto conf = GetConfig(); + if (!conf) { + blog(LOG_ERROR, "[ConnectInfo::showEvent] Unable to retreive config!"); + return; + } + + QString serverIp = QString::fromStdString(Utils::Platform::GetLocalAddress()); + ui->serverIpLineEdit->setText(serverIp); + + QString serverPort = QString::number(conf->ServerPort); + ui->serverPortLineEdit->setText(serverPort); + + QString serverPassword; + if (conf->AuthRequired) { + ui->copyServerPasswordButton->setEnabled(true); + serverPassword = conf->ServerPassword; + } else { + ui->copyServerPasswordButton->setEnabled(false); + obs_frontend_push_ui_translation(obs_module_get_string); + serverPassword = QObject::tr("OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText"); + obs_frontend_pop_ui_translation(); + } + ui->serverPasswordLineEdit->setText(serverPassword); + + QString connectString; + if (conf->AuthRequired) + connectString = QString("obswebsocket|%1:%2|%3").arg(serverIp).arg(serverPort).arg(serverPassword); + else + connectString = QString("obswebsocket|%1:%2").arg(serverIp).arg(serverPort); + DrawQr(connectString); +} + +void ConnectInfo::CopyServerIpButtonClicked() +{ + SetClipboardText(ui->serverIpLineEdit->text()); + ui->serverIpLineEdit->selectAll(); +} + +void ConnectInfo::CopyServerPortButtonClicked() +{ + SetClipboardText(ui->serverPortLineEdit->text()); + ui->serverPortLineEdit->selectAll(); +} + +void ConnectInfo::CopyServerPasswordButtonClicked() +{ + SetClipboardText(ui->serverPasswordLineEdit->text()); + ui->serverPasswordLineEdit->selectAll(); +} + +void ConnectInfo::SetClipboardText(QString text) +{ + QClipboard *clipboard = QGuiApplication::clipboard(); + clipboard->setText(text); +} + +void ConnectInfo::DrawQr(QString qrText) +{ + QPixmap map(230, 230); + map.fill(Qt::white); + QPainter painter(&map); + + qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(QT_TO_UTF8(qrText), qrcodegen::QrCode::Ecc::MEDIUM); + const int s = qr.getSize() > 0 ? qr.getSize() : 1; + const double w = map.width(); + const double h = map.height(); + const double aspect = w/h; + const double size = ((aspect > 1.0) ? h : w); + const double scale = size / (s+2); + painter.setPen(Qt::NoPen); + painter.setBrush(Qt::black); + + for (int y = 0; y < s; y++) { + for (int x = 0; x < s; x++) { + const int color = qr.getModule(x, y); + if (0x0 != color) { + const double ry1 = (y + 1) * scale; + const double rx1 = (x + 1) * scale; + QRectF r(rx1, ry1, scale, scale); + painter.drawRects(&r, 1); + } + } + } + + ui->qrCodeLabel->setPixmap(map); +} diff --git a/src/forms/ConnectInfo.h b/src/forms/ConnectInfo.h new file mode 100644 index 00000000..a65656d4 --- /dev/null +++ b/src/forms/ConnectInfo.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include "ui_ConnectInfo.h" + +class ConnectInfo : public QDialog +{ + Q_OBJECT + +public: + explicit ConnectInfo(QWidget* parent = 0); + ~ConnectInfo(); + void showEvent(QShowEvent *event); + +private Q_SLOTS: + void CopyServerIpButtonClicked(); + void CopyServerPortButtonClicked(); + void CopyServerPasswordButtonClicked(); + +private: + void DrawQr(QString qrText); + void SetClipboardText(QString text); + + Ui::ConnectInfo *ui; +}; diff --git a/src/forms/ConnectInfo.ui b/src/forms/ConnectInfo.ui new file mode 100644 index 00000000..32b6b771 --- /dev/null +++ b/src/forms/ConnectInfo.ui @@ -0,0 +1,147 @@ + + + ConnectInfo + + + + 0 + 0 + 451 + 412 + + + + + 451 + 412 + + + + + 451 + 412 + + + + OBSWebSocket.ConnectInfo.DialogTitle + + + + + 10 + 10 + 431 + 101 + + + + + + + OBSWebSocket.ConnectInfo.ServerIp + + + + + + + + + true + + + + + + + OBSWebSocket.ConnectInfo.CopyText + + + + + + + + + OBSWebSocket.ConnectInfo.ServerPort + + + + + + + + + true + + + + + + + OBSWebSocket.ConnectInfo.CopyText + + + + + + + + + OBSWebSocket.ConnectInfo.ServerPassword + + + + + + + + + OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText + + + true + + + + + + + OBSWebSocket.ConnectInfo.CopyText + + + + + + + + + + + 10 + 120 + 431 + 281 + + + + OBSWebSocket.ConnectInfo.QrTitle + + + + + 100 + 40 + 230 + 230 + + + + + + + + + + + diff --git a/src/forms/SettingsDialog.cpp b/src/forms/SettingsDialog.cpp index fa1c72c6..5a1da870 100644 --- a/src/forms/SettingsDialog.cpp +++ b/src/forms/SettingsDialog.cpp @@ -1,11 +1,8 @@ #include #include #include -#include #include #include -#include -#include #include "SettingsDialog.h" #include "../obs-websocket.h" @@ -17,25 +14,29 @@ SettingsDialog::SettingsDialog(QWidget* parent) : QDialog(parent, Qt::Dialog), ui(new Ui::SettingsDialog), + connectInfo(new ConnectInfo), sessionTableTimer(new QTimer) { ui->setupUi(this); ui->websocketSessionTable->horizontalHeader()->resizeSection(3, 100); ui->websocketSessionTable->horizontalHeader()->resizeSection(4, 100); - connect(ui->buttonBox, &QDialogButtonBox::accepted, - this, &SettingsDialog::FormAccepted); - connect(ui->enableAuthenticationCheckBox, &QCheckBox::stateChanged, - this, &SettingsDialog::EnableAuthenticationCheckBoxChanged); - connect(ui->copyPasswordButton, &QPushButton::clicked, - this, &SettingsDialog::CopyPasswordButtonClicked); connect(sessionTableTimer, &QTimer::timeout, this, &SettingsDialog::FillSessionTable); + connect(ui->buttonBox, &QDialogButtonBox::clicked, + this, &SettingsDialog::DialogButtonClicked); + connect(ui->enableAuthenticationCheckBox, &QCheckBox::stateChanged, + this, &SettingsDialog::EnableAuthenticationCheckBoxChanged); + connect(ui->generatePasswordButton, &QPushButton::clicked, + this, &SettingsDialog::GeneratePasswordButtonClicked); + connect(ui->showConnectInfoButton, &QPushButton::clicked, + this, &SettingsDialog::ShowConnectInfoButtonClicked); } SettingsDialog::~SettingsDialog() { delete ui; + delete connectInfo; delete sessionTableTimer; } @@ -43,7 +44,7 @@ void SettingsDialog::showEvent(QShowEvent *event) { auto conf = GetConfig(); if (!conf) { - blog(LOG_ERROR, "[showEvent] Unable to retreive config!"); + blog(LOG_ERROR, "[SettingsDialog::showEvent] Unable to retreive config!"); return; } @@ -73,6 +74,8 @@ void SettingsDialog::closeEvent(QCloseEvent *event) { if (sessionTableTimer->isActive()) sessionTableTimer->stop(); + + connectInfo->hide(); } void SettingsDialog::ToggleShowHide() @@ -83,11 +86,61 @@ void SettingsDialog::ToggleShowHide() setVisible(false); } +void SettingsDialog::DialogButtonClicked(QAbstractButton *button) +{ + if (button == ui->buttonBox->button(QDialogButtonBox::Ok)) { + SaveFormData(); + } else if (button == ui->buttonBox->button(QDialogButtonBox::Apply)) { + SaveFormData(); + } +} + +void SettingsDialog::SaveFormData() +{ + connectInfo->hide(); + + auto conf = GetConfig(); + if (!conf) { + blog(LOG_ERROR, "[SettingsDialog::SaveFormData] Unable to retreive config!"); + return; + } + + bool needsRestart = false; + + // I decided not to restart the server if debug is changed. Might mess with peoples' scripts + if (conf->ServerEnabled != ui->enableWebSocketServerCheckBox->isChecked()) { + needsRestart = true; + } else if (conf->AuthRequired != ui->enableAuthenticationCheckBox->isChecked()) { + needsRestart = true; + } else if (conf->ServerPassword != ui->serverPasswordLineEdit->text()) { + needsRestart = true; + } else if (conf->ServerPort != ui->serverPortSpinBox->value()) { + needsRestart = true; + } + + conf->ServerEnabled = ui->enableWebSocketServerCheckBox->isChecked(); + conf->AlertsEnabled = ui->enableSystemTrayAlertsCheckBox->isChecked(); + conf->DebugEnabled = ui->enableDebugLoggingCheckBox->isChecked(); + conf->AuthRequired = ui->enableAuthenticationCheckBox->isChecked(); + conf->ServerPassword = ui->serverPasswordLineEdit->text(); + conf->ServerPort = ui->serverPortSpinBox->value(); + + conf->Save(); + + if (needsRestart) { + auto server = GetWebSocketServer(); + server->Stop(); + if (conf->ServerEnabled) { + server->Start(); + } + } +} + void SettingsDialog::FillSessionTable() { auto webSocketServer = GetWebSocketServer(); if (!webSocketServer) { - blog(LOG_ERROR, "[FillSessionTable] Unable to fetch websocket server instance!"); + blog(LOG_ERROR, "[SettingsDialog::FillSessionTable] Unable to fetch websocket server instance!"); return; } @@ -142,59 +195,28 @@ void SettingsDialog::FillSessionTable() } } -void SettingsDialog::FormAccepted() -{ - auto conf = GetConfig(); - if (!conf) { - blog(LOG_ERROR, "[FormAccepted] Unable to retreive config!"); - return; - } - - bool needsRestart = false; - - // I decided not to restart the server if debug is changed. Might mess with peoples' scripts - if (conf->ServerEnabled != ui->enableWebSocketServerCheckBox->isChecked()) { - needsRestart = true; - } else if (conf->AuthRequired != ui->enableAuthenticationCheckBox->isChecked()) { - needsRestart = true; - } else if (conf->ServerPassword != ui->serverPasswordLineEdit->text()) { - needsRestart = true; - } else if (conf->ServerPort != ui->serverPortSpinBox->value()) { - needsRestart = true; - } - - conf->ServerEnabled = ui->enableWebSocketServerCheckBox->isChecked(); - conf->AlertsEnabled = ui->enableSystemTrayAlertsCheckBox->isChecked(); - conf->DebugEnabled = ui->enableDebugLoggingCheckBox->isChecked(); - conf->AuthRequired = ui->enableAuthenticationCheckBox->isChecked(); - conf->ServerPassword = ui->serverPasswordLineEdit->text(); - conf->ServerPort = ui->serverPortSpinBox->value(); - - conf->Save(); - - if (needsRestart) { - auto server = GetWebSocketServer(); - server->Stop(); - if (conf->ServerEnabled) { - server->Start(); - } - } -} - void SettingsDialog::EnableAuthenticationCheckBoxChanged() { if (ui->enableAuthenticationCheckBox->isChecked()) { ui->serverPasswordLineEdit->setEnabled(true); - ui->copyPasswordButton->setEnabled(true); + ui->generatePasswordButton->setEnabled(true); } else { ui->serverPasswordLineEdit->setEnabled(false); - ui->copyPasswordButton->setEnabled(false); + ui->generatePasswordButton->setEnabled(false); } } -void SettingsDialog::CopyPasswordButtonClicked() +void SettingsDialog::GeneratePasswordButtonClicked() { - QClipboard *clipboard = QGuiApplication::clipboard(); - clipboard->setText(ui->serverPasswordLineEdit->text()); + QString newPassword = Utils::Crypto::GeneratePassword(); + ui->serverPasswordLineEdit->setText(newPassword); ui->serverPasswordLineEdit->selectAll(); } + +void SettingsDialog::ShowConnectInfoButtonClicked() +{ + connectInfo->show(); + connectInfo->activateWindow(); + connectInfo->raise(); + connectInfo->setFocus(); +} diff --git a/src/forms/SettingsDialog.h b/src/forms/SettingsDialog.h index d98254d2..66328df9 100644 --- a/src/forms/SettingsDialog.h +++ b/src/forms/SettingsDialog.h @@ -3,6 +3,7 @@ #include #include +#include "ConnectInfo.h" #include "ui_SettingsDialog.h" class SettingsDialog : public QDialog @@ -17,12 +18,15 @@ public: void ToggleShowHide(); private Q_SLOTS: - void FormAccepted(); - void EnableAuthenticationCheckBoxChanged(); - void CopyPasswordButtonClicked(); + void DialogButtonClicked(QAbstractButton *button); + void SaveFormData(); void FillSessionTable(); + void EnableAuthenticationCheckBoxChanged(); + void GeneratePasswordButtonClicked(); + void ShowConnectInfoButtonClicked(); private: Ui::SettingsDialog *ui; + ConnectInfo *connectInfo; QTimer *sessionTableTimer; }; diff --git a/src/forms/SettingsDialog.ui b/src/forms/SettingsDialog.ui index ba271c49..59a0b544 100644 --- a/src/forms/SettingsDialog.ui +++ b/src/forms/SettingsDialog.ui @@ -32,7 +32,7 @@ Qt::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -97,27 +97,31 @@ - - - QLineEdit::PasswordEchoOnEdit - - + + + + + QLineEdit::Password + + + + + + + OBSWebSocket.Settings.GeneratePassword + + + + - - - - OBSWebSocket.Settings.CopyPassword - - - - + OBSWebSocket.Settings.ServerPort - + 1 @@ -130,6 +134,13 @@ + + + + OBSWebSocket.Settings.ShowConnectInfo + + + diff --git a/src/obs-websocket.cpp b/src/obs-websocket.cpp index f7d112d8..a07f2112 100644 --- a/src/obs-websocket.cpp +++ b/src/obs-websocket.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "obs-websocket.h" #include "Config.h" @@ -40,6 +41,10 @@ bool obs_module_load(void) blog(LOG_INFO, "[obs_module_load] Qt version (compile-time): %s | Qt version (run-time): %s", QT_VERSION_STR, qVersion()); + // Randomize the random number generator + qsrand(QTime::currentTime().msec()); + + // Create the config object then load the parameters from storage _config = ConfigPtr(new Config()); _config->Load(); @@ -67,6 +72,7 @@ void obs_module_unload() { blog(LOG_INFO, "[obs_module_unload] Shutting down..."); + _config->FirstLoad = false; _config->Save(); if (_webSocketServer->IsListening()) { diff --git a/src/utils/Crypto.cpp b/src/utils/Crypto.cpp index 6454bb41..3a7f3e73 100644 --- a/src/utils/Crypto.cpp +++ b/src/utils/Crypto.cpp @@ -53,3 +53,25 @@ bool Utils::Crypto::CheckAuthenticationString(std::string secret, std::string ch return (authenticationString == expectedAuthenticationString); } + +QString Utils::Crypto::GeneratePassword(size_t length) +{ + QString ret; + int rand; + + for (size_t i = 0; i < length; i++) { + while (true) { + rand = qrand() % ((0x7a + 1) - 0x30) + 0x30; + if ( + (rand >= 0x30 && rand <= 0x39) || + (rand >= 0x41 && rand <= 0x5A) || + (rand >= 0x61 && rand <= 0x7A) + ) + break; + } + + ret += QString(rand); + } + + return ret; +} diff --git a/src/utils/Utils.h b/src/utils/Utils.h index d199746b..a87e436a 100644 --- a/src/utils/Utils.h +++ b/src/utils/Utils.h @@ -18,6 +18,7 @@ namespace Utils { std::string GenerateSalt(); std::string GenerateSecret(std::string password, std::string salt); bool CheckAuthenticationString(std::string secret, std::string challenge, std::string authenticationString); + QString GeneratePassword(size_t length = 16); } namespace Platform {