SettingsDialog: Mild refactor and add Connect Info dialog

Among lots of stuff:

- Generate a random password on first load

- Add `ConnectInfo` dialog including QR code display

- Add `Generate Password` button to generate a new random
password

- Delete `Copy Password to Clipboard` button

- Delete `GetConnectString` or whatever from WebSocketServer
(reimplemented the functionality directly into ConnectInfo)

- Added `GeneratePassword()` to Utils

Todo: Show warning when users specify their own passwords
This commit is contained in:
tt2468 2021-05-08 01:42:06 -07:00
parent 600505b60a
commit ee751edf54
17 changed files with 464 additions and 101 deletions

3
.gitmodules vendored
View File

@ -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

View File

@ -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

View File

@ -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."

1
deps/qr vendored Submodule

@ -0,0 +1 @@
Subproject commit 8518684c0f33d004fa93971be2c6a8eca3167d1e

View File

@ -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<std::string> GetCmdlineArgs()
{
struct obs_cmdline_args args = obs_get_cmdline_args();
std::vector<std::string> 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);

View File

@ -14,6 +14,7 @@ class Config {
bool PortOverridden;
bool PasswordOverridden;
bool FirstLoad;
bool ServerEnabled;
uint16_t ServerPort;
bool DebugEnabled;

View File

@ -2,7 +2,6 @@
#include <thread>
#include <QtConcurrent>
#include <QDateTime>
#include <QTime>
#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::WebSocketSessionState> 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)
{

View File

@ -74,8 +74,6 @@ class WebSocketServer : QObject
return &_threadPool;
}
QString GetConnectString();
bool AuthenticationRequired;
std::string AuthenticationSecret;
std::string AuthenticationSalt;

120
src/forms/ConnectInfo.cpp Normal file
View File

@ -0,0 +1,120 @@
#include <obs-module.h>
#include <obs-frontend-api.h>
#include <QClipboard>
#include <QPainter>
#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);
}

26
src/forms/ConnectInfo.h Normal file
View File

@ -0,0 +1,26 @@
#pragma once
#include <QtWidgets/QDialog>
#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;
};

147
src/forms/ConnectInfo.ui Normal file
View File

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConnectInfo</class>
<widget class="QDialog" name="ConnectInfo">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>451</width>
<height>412</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>451</width>
<height>412</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>451</width>
<height>412</height>
</size>
</property>
<property name="windowTitle">
<string>OBSWebSocket.ConnectInfo.DialogTitle</string>
</property>
<widget class="QWidget" name="formLayoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>431</width>
<height>101</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="serverIpLabel">
<property name="text">
<string>OBSWebSocket.ConnectInfo.ServerIp</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="serverIpLineEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="copyServerIpButton">
<property name="text">
<string>OBSWebSocket.ConnectInfo.CopyText</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="serverPortLabel">
<property name="text">
<string>OBSWebSocket.ConnectInfo.ServerPort</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="serverPortLineEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="copyServerPortButton">
<property name="text">
<string>OBSWebSocket.ConnectInfo.CopyText</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="serverPasswordLabel">
<property name="text">
<string>OBSWebSocket.ConnectInfo.ServerPassword</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLineEdit" name="serverPasswordLineEdit">
<property name="text">
<string>OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="copyServerPasswordButton">
<property name="text">
<string>OBSWebSocket.ConnectInfo.CopyText</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>120</y>
<width>431</width>
<height>281</height>
</rect>
</property>
<property name="title">
<string>OBSWebSocket.ConnectInfo.QrTitle</string>
</property>
<widget class="QLabel" name="qrCodeLabel">
<property name="geometry">
<rect>
<x>100</x>
<y>40</y>
<width>230</width>
<height>230</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,11 +1,8 @@
#include <obs-module.h>
#include <obs-frontend-api.h>
#include <QtWidgets/QMessageBox>
#include <QClipboard>
#include <QDateTime>
#include <QTime>
#include <QPixmap>
#include <QIcon>
#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();
}

View File

@ -3,6 +3,7 @@
#include <QtWidgets/QDialog>
#include <QTimer>
#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;
};

View File

@ -32,7 +32,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
@ -97,27 +97,31 @@
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="serverPasswordLineEdit">
<property name="echoMode">
<enum>QLineEdit::PasswordEchoOnEdit</enum>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="serverPasswordLineEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="generatePasswordButton">
<property name="text">
<string>OBSWebSocket.Settings.GeneratePassword</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="1">
<widget class="QPushButton" name="copyPasswordButton">
<property name="text">
<string>OBSWebSocket.Settings.CopyPassword</string>
</property>
</widget>
</item>
<item row="6" column="0">
<item row="5" column="0">
<widget class="QLabel" name="serverPortLabel">
<property name="text">
<string>OBSWebSocket.Settings.ServerPort</string>
</property>
</widget>
</item>
<item row="6" column="1">
<item row="5" column="1">
<widget class="QSpinBox" name="serverPortSpinBox">
<property name="minimum">
<number>1</number>
@ -130,6 +134,13 @@
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QPushButton" name="showConnectInfoButton">
<property name="text">
<string>OBSWebSocket.Settings.ShowConnectInfo</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">

View File

@ -5,6 +5,7 @@
#include <QtCore/QTimer>
#include <QtWidgets/QAction>
#include <QtWidgets/QMainWindow>
#include <QTime>
#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()) {

View File

@ -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;
}

View File

@ -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 {