Skip to content

Commit

Permalink
include cleanup + only pragma once + improved command handler
Browse files Browse the repository at this point in the history
  • Loading branch information
99oblivius committed Oct 28, 2024
1 parent 58631ca commit 18f34fe
Show file tree
Hide file tree
Showing 19 changed files with 332 additions and 273 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ target_sources(${CMAKE_PROJECT_NAME} PRIVATE
src/vrbro.cpp
src/network/network.cpp
src/config.cpp
src/handler/command-handler.cpp
src/forms/server-settings.cpp
src/handler/handler.cpp
src/handler/events/request-handlers.cpp
src/handler/events/event-handlers.cpp
src/handler/errors/handle-errors.cpp
Expand Down
129 changes: 69 additions & 60 deletions src/config.cpp
Original file line number Diff line number Diff line change
@@ -1,50 +1,51 @@
#include <obs-frontend-api.h>
#include <util/config-file.h>
#include <QString>
#include "config.hpp"

#include <fstream>

#include <QMessageBox>
#include <QRegularExpression>
#include <QString>
#include <obs-frontend-api.h>
#include <obs-module.h>
#include <plugin-support.h>
#include <fstream>
#include <util/config-file.h>

#include "config.hpp"
#include <nlohmann/json.hpp>
#include "plugin-support.h"
#include "vrbro.hpp"

using json = nlohmann::json;

#define TITLE "VRBroServerPlugin"
#define LISTEN_ADDR_STRING "ListenAddrString"
#define LISTEN_PORT_NUMBER "ListenPortNumber"
#define AUTO_BUFFER "AutoBufferBool"
namespace {
constexpr const char* TITLE = "VRBroServerPlugin";
constexpr const char* LISTEN_ADDR_STRING = "ListenAddrString";
constexpr const char* LISTEN_PORT_NUMBER = "ListenPortNumber";
constexpr const char* AUTO_BUFFER = "AutoBufferBool";

bool isValidAddr(const QString &str_ip) {
QRegularExpression addrRegex(R"(^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$)");
QRegularExpressionMatch match = addrRegex.match(str_ip);
return match.hasMatch();
}
bool isValidAddr(const QString& str_ip) {
static const QRegularExpression addrRegex(
R"(^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$)"
);
return addrRegex.match(str_ip).hasMatch();
}

bool isValidRange(const QString &str_port) {
bool ok;
qulonglong value = str_port.toULongLong(&ok);
return ok && value >= 1024 && value <= 65353;
bool isValidPort(const QString& str_port) {
bool ok;
qulonglong value = str_port.toULongLong(&ok);
return ok && value >= 1024 && value <= 65535;
}
}


Config::Config() {
config_t *obs_config = GetConfigStore();
if (obs_config) {
config_set_default_string(obs_config, TITLE, LISTEN_ADDR_STRING,
config_t* obs_config = GetConfigStore();
if (obs_config) {
config_set_default_string(obs_config, TITLE, LISTEN_ADDR_STRING,
ListenAddrString.toUtf8().constData());
config_set_default_uint(obs_config, TITLE, LISTEN_PORT_NUMBER,
config_set_default_uint(obs_config, TITLE, LISTEN_PORT_NUMBER,
ListenPortNumber.toULongLong());
config_set_default_bool(obs_config, TITLE, AUTO_BUFFER,
config_set_default_bool(obs_config, TITLE, AUTO_BUFFER,
AutoBufferBool);
}
}
}

void Config::Load() {
config_t *obs_config = GetConfigStore();
config_t* obs_config = GetConfigStore();
if (obs_config) {
ListenAddrString = config_get_string(obs_config, TITLE, LISTEN_ADDR_STRING);
ListenPortNumber = QString::number(config_get_uint(obs_config, TITLE, LISTEN_PORT_NUMBER));
Expand All @@ -53,37 +54,45 @@ void Config::Load() {
}

void Config::Save() {
config_t *obs_config = GetConfigStore();
if (obs_config) {

ListenAddrString.remove(QRegularExpression("\\s+"));
if (!isValidAddr(ListenAddrString)) {
QMessageBox alertbox;
alertbox.setWindowTitle("VRBro.Address.Error");
alertbox.setText("x.x.x.x\n\nChoose a valid listening address\ne.g 0.0.0.0");
alertbox.exec();
return;
}
config_set_string(obs_config, TITLE, LISTEN_ADDR_STRING, ListenAddrString.toUtf8().constData());

if (!isValidRange(ListenPortNumber)) {
QMessageBox alertbox;
alertbox.setWindowTitle("VRBro.Port.Error");
alertbox.setText("1024 <-> 65535]\n\nChoose a valid port number\ne.g 33390");
alertbox.exec();
return;
}
config_set_uint(obs_config, TITLE, LISTEN_PORT_NUMBER, ListenPortNumber.toULongLong());

config_set_bool(obs_config, TITLE, AUTO_BUFFER, AutoBufferBool);

obs_log(LOG_WARNING, "[VRBro::Config] listen: %s port: %d", ListenAddrString.toUtf8().constData(), ListenPortNumber.toULongLong());
config_save(obs_config);
config_t* obs_config = GetConfigStore();
if (!obs_config) {
return;
}

vrbro_restart_server();
// Validate and save address
ListenAddrString.remove(QRegularExpression("\\s+"));
if (!isValidAddr(ListenAddrString)) {
QMessageBox alertbox;
alertbox.setWindowTitle("VRBro.Address.Error");
alertbox.setText("x.x.x.x\n\nChoose a valid listening address\ne.g 0.0.0.0");
alertbox.exec();
return;
}
}
config_set_string(obs_config, TITLE, LISTEN_ADDR_STRING,
ListenAddrString.toUtf8().constData());

// Validate and save port
if (!isValidPort(ListenPortNumber)) {
QMessageBox alertbox;
alertbox.setWindowTitle("VRBro.Port.Error");
alertbox.setText("1024 <-> 65535\n\nChoose a valid port number\ne.g 33390");
alertbox.exec();
return;
}
config_set_uint(obs_config, TITLE, LISTEN_PORT_NUMBER,
ListenPortNumber.toULongLong());

config_t *Config::GetConfigStore() {
return obs_frontend_get_global_config();
// Save auto buffer setting
config_set_bool(obs_config, TITLE, AUTO_BUFFER, AutoBufferBool);

obs_log(LOG_WARNING, "[VRBro::Config] listen: %s port: %d",
ListenAddrString.toUtf8().constData(),
ListenPortNumber.toULongLong());

config_save(obs_config);
vrbro_restart_server();
}

config_t* Config::GetConfigStore() {
return obs_frontend_get_global_config();
}
26 changes: 16 additions & 10 deletions src/config.hpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
#ifndef CONFIG_HPP
#define CONFIG_HPP
#pragma once

#include <atomic>

#include <QString>
#include <obs-module.h>
#include <util/config-file.h>

struct Config {
// Configuration constants
namespace ConfigConstants {
constexpr const char* DEFAULT_ADDRESS = "127.0.0.1";
constexpr int DEFAULT_PORT = 33390;
}

class Config {
public:
Config();

void Load();
void Save();
static config_t *GetConfigStore();
static void OBSSaveCallback(obs_data_t *config_data, bool save, void *data);
static config_t* GetConfigStore();
static void OBSSaveCallback(obs_data_t* config_data, bool save, void* data);

QString ListenAddrString = "127.0.0.1";
QString ListenPortNumber = QString::number(33390);
std::atomic<bool> AutoBufferBool = false;
QString ListenAddrString{ConfigConstants::DEFAULT_ADDRESS};
QString ListenPortNumber{QString::number(ConfigConstants::DEFAULT_PORT)};
std::atomic<bool> AutoBufferBool{false};
};

#endif
5 changes: 1 addition & 4 deletions src/forms/server-settings.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#ifndef SERVERSETTINGS_H
#define SERVERSETTINGS_H
#pragma once

#include <QDialog>

Expand All @@ -21,5 +20,3 @@ private slots:
private:
Ui::ServerSettings *ui;
};

#endif
112 changes: 112 additions & 0 deletions src/handler/command-handler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#include "command-handler.hpp"

#include "errors/handle-errors.hpp"
#include "events/action-type.hpp"
#include "events/event-handlers.hpp"
#include "events/request-handlers.hpp"

namespace {
void ping(std::string& msg, std::error_code& ec) {
ec.clear();
msg = "pong";
}

void unknown_command(std::string& msg, std::error_code& ec) {
msg.clear();
ec = make_error_code(HandleError::UnknownCommand);
}

void handle_request(std::string_view& packet, ActionType& action, std::string& msg, std::error_code& ec) {
action = static_cast<uint8_t>(packet[0]) & 0x3F;
switch (static_cast<ActionTypeRequest>(action)) {
case ActionTypeRequest::PING:
ping(msg, ec);
break;
case ActionTypeRequest::REPLAY_BUFFER_ACTIVE:
RequestHandler::is_replay_buffer(msg, ec);
break;
case ActionTypeRequest::RECORDING_ACTIVE:
RequestHandler::is_recording(msg, ec);
break;
case ActionTypeRequest::STREAMING_ACTIVE:
RequestHandler::is_streaming(msg, ec);
break;
default:
unknown_command(msg, ec);
break;
}
}

void handle_event(std::string_view& packet, ActionType& action, std::string& msg, std::error_code& ec) {
action = static_cast<uint8_t>(packet[0]) & 0x3F;
switch (static_cast<ActionTypeEvent>(action)) {
case ActionTypeEvent::PING:
ping(msg, ec);
break;
case ActionTypeEvent::START_REPLAY_BUFFER:
EventHandler::start_replay_buffer(msg, ec);
break;
case ActionTypeEvent::STOP_REPLAY_BUFFER:
EventHandler::stop_replay_buffer(msg, ec);
break;
case ActionTypeEvent::SAVE_REPLAY_BUFFER:
EventHandler::save_replay_buffer(msg, ec);
break;
case ActionTypeEvent::START_RECORDING:
EventHandler::start_recording(msg, ec);
break;
case ActionTypeEvent::STOP_RECORDING:
EventHandler::stop_recording(msg, ec);
break;
case ActionTypeEvent::START_STREAMING:
EventHandler::start_streaming(msg, ec);
break;
case ActionTypeEvent::STOP_STREAMING:
EventHandler::stop_streaming(msg, ec);
break;
case ActionTypeEvent::RECORDING_SPLIT_FILE:
EventHandler::recording_split_file(msg, ec);
break;
default:
unknown_command(msg, ec);
break;
}
}
}

namespace CommandHandler {
void Handler(std::string_view packet, std::vector<uint8_t>& response, std::error_code& ec) {
ActionType action = 0xFF;
std::string msg;

uint8_t header = 0;
uint8_t success_flag = 0;

if (packet.empty()) {
action = 0xFF;
ec = make_error_code(HandleError::EmptyMessage);
} else {
std::string payload;
if (packet.size() > 1) {
payload.assign(packet.begin() + 1, packet.end());
}
action = packet[0] & 0x3F;
if (static_cast<uint8_t>(packet[0]) & 0x80) {
handle_event(packet, action, msg, ec);
header |= 1 << 7;
success_flag = ec ? 0 : 1;
} else {
handle_request(packet, action, msg, ec);
success_flag = msg.empty() ? 0 : 1;
}
}

header |= success_flag << 6;
header |= static_cast<uint8_t>(action) & 0x3F;
response.push_back(header);

if (!msg.empty()) {
response.insert(response.end(), msg.begin(), msg.end());
}
}
}
10 changes: 10 additions & 0 deletions src/handler/command-handler.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include <cstdint>
#include <string_view>
#include <system_error>
#include <vector>

namespace CommandHandler {
void Handler(std::string_view packet, std::vector<uint8_t>& response, std::error_code& ec);
}
9 changes: 9 additions & 0 deletions src/handler/errors/handle-errors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,12 @@ namespace std {
template <>
struct is_error_code_enum<HandleError> : true_type {};
}

const std::error_category& getHandleErrorCategory() {
static HandleErrorCategory instance;
return instance;
}

std::error_code make_error_code(HandleError e) {
return {static_cast<int>(e), getHandleErrorCategory()};
}
Loading

0 comments on commit 18f34fe

Please sign in to comment.