1
0
mirror of https://github.com/spacebarchat/server.git synced 2024-11-10 20:52:42 +01:00

Merge branch 'rtc'

This commit is contained in:
Flam3rboy 2021-08-12 20:32:55 +02:00
commit f46ca1c341
10 changed files with 355 additions and 24 deletions

40
.gitignore vendored
View File

@ -104,4 +104,42 @@ typings/
.DS_Store
# Compiled TypeScript code
dist/
dist/
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.o
# Protobuffer builds
*.pb.cc
*.pb.h
# Directories
build/
.vscode/

16
CMakeLists.txt Normal file
View File

@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.2)
project(fosscord-media)
set(CMAKE_CXX_STANDARD 17)
find_package(Threads REQUIRED)
find_package(mongocxx REQUIRED)
find_package(Boost REQUIRED)
file(GLOB SourceFiles ${PROJECT_SOURCE_DIR}/src/*.cpp)
#include_directories("bsoncxx/v_noabi/bsoncxx/")
add_executable(${CMAKE_PROJECT_NAME} ${SourceFiles})
target_link_libraries(${CMAKE_PROJECT_NAME} datachannel mongo::mongocxx_shared Boost::boost)

View File

@ -1,29 +1,18 @@
<p align="center">
<img width="100" src="https://raw.githubusercontent.com/fosscord/fosscord/master/assets/logo_big_transparent.png" />
</p>
<h1 align="center">Fosscord server util</h1>
# Fosscord-media
<p>
<a href="https://discord.gg/ZrnGQP6p3d">
<img src="https://img.shields.io/discord/806142446094385153?color=7489d5&logo=discord&logoColor=ffffff" />
</a>
<img src="https://img.shields.io/static/v1?label=Status&message=Development&color=blue">
<a title="Crowdin" target="_blank" href="https://translate.fosscord.com/"><img src="https://badges.crowdin.net/fosscord/localized.svg"></a>
<a href="https://opencollective.com/fosscord">
<img src="https://opencollective.com/fosscord/tiers/badge.svg">
</a>
</p>
## [About](https://fosscord.com)
Fosscord is a free open source selfhostable chat, voice and video discord-compatible platform.
Fosscord server util contains all necessary logic that is shared between the [api](https://github.com/fosscord/fosscord-api), [gateway](https://github.com/fosscord/fosscord-gateway) and [cdn](https://github.com/fosscord/fosscord-cdn).
It contains all mongoose database models and utility functions.
A Fosscord media (voice and video) server
## Installation
### Prerequisites
- Install the [libdatachannel](https://github.com/paullouisageneau/libdatachannel) library
- Install the [libmongocxx](http://mongocxx.org/mongocxx-v3/installation/) driver and its requirements
### Building
```bash
npm install @fosscord/server-util
$ cmake
$ cd build
$ make
```

1
config.json Normal file
View File

@ -0,0 +1 @@
{}

47
src/main.cpp Normal file
View File

@ -0,0 +1,47 @@
// $$$$$$\ $$\
// $$ __$$\ $$ |
// $$ / \__|$$$$$$\ $$$$$$$\ $$$$$$$\ $$$$$$$\ $$$$$$\ $$$$$$\ $$$$$$$ |
// $$$$\ $$ __$$\ $$ _____|$$ _____|$$ _____|$$ __$$\ $$ __$$\ $$ __$$ |
// $$ _| $$ / $$ |\$$$$$$\ \$$$$$$\ $$ / $$ / $$ |$$ | \__|$$ / $$ |
// $$ | $$ | $$ | \____$$\ \____$$\ $$ | $$ | $$ |$$ | $$ | $$ |
// $$ | \$$$$$$ |$$$$$$$ |$$$$$$$ |\$$$$$$$\ \$$$$$$ |$$ | \$$$$$$$ |
// \__| \______/ \_______/ \_______/ \_______| \______/ \__| \_______|
//
//
//
// $$\ $$$$$$\
// \__| $$ __$$\
// $$\ $$\ $$$$$$\ $$\ $$$$$$$\ $$$$$$\ $$ / \__| $$$$$$\ $$$$$$\ $$\ $$\ $$$$$$\ $$$$$$\
// \$$\ $$ |$$ __$$\ $$ |$$ _____|$$ __$$\ \$$$$$$\ $$ __$$\ $$ __$$\\$$\ $$ |$$ __$$\ $$ __$$\
// \$$\$$ / $$ / $$ |$$ |$$ / $$$$$$$$ | \____$$\ $$$$$$$$ |$$ | \__|\$$\$$ / $$$$$$$$ |$$ | \__|
// \$$$ / $$ | $$ |$$ |$$ | $$ ____|$$\ $$ |$$ ____|$$ | \$$$ / $$ ____|$$ |
// \$ / \$$$$$$ |$$ |\$$$$$$$\ \$$$$$$$\ \$$$$$$ |\$$$$$$$\ $$ | \$ / \$$$$$$$\ $$ |
// \_/ \______/ \__| \_______| \_______| \______/ \_______|\__| \_/ \_______|\__|
//
//
//
#include "rtcPeerHandler.hpp" //Handle peer connection requests
#include "mongoStub.hpp" //Handle communication with the MongoDB server
int main(int argc, char **argv){
auto commsHandler = std::make_shared<rtcPeerHandler>();
auto mongoHandler = std::make_unique<mongoStub>();
mongocxx::options::change_stream options;
//voiceEvents collection watcher
mongocxx::change_stream colCs = mongoHandler->getCol().watch(options);
std::cout << "Server created and listening for events" << std::endl;
//Check for new messages in the collection
for (;;){
std::vector<mongoStub::mongoMessage> t = mongoHandler->getNewMessages(&colCs);
for(auto &i : t){
std::cout << "[" << i.eventName << "] " << std::endl;
}
}
return 0;
}

84
src/mongoStub.cpp Normal file
View File

@ -0,0 +1,84 @@
#include "mongoStub.hpp"
mongoStub::mongoStub() {
if (this->client) {
this->db = client["fosscord"];
if (this->db) {
this->col = db["events"];
} else {
std::cout << "db not found";
exit(-1);
}
} else {
std::cout << "Client couldn't be initialized";
exit(-1);
}
}
// Too slow for my liking
std::vector<mongoStub::mongoMessage> mongoStub::getNewMessages(
mongocxx::change_stream* colCs) {
std::vector<mongoStub::mongoMessage> retVec;
for (auto&& event : *colCs) {
mongoStub::mongoMessage returnValue;
std::cout << bsoncxx::to_json(event) << std::endl;
// Only listen to insert events (to avoid "precondition failed: data"
// exception)
if (event["operationType"].get_utf8().value.to_string() != "insert") {
continue;
}
std::string evName = event["fullDocument"]["event"].get_utf8().value.to_string();
if(evName.substr(0, 7)=="VSERVER"){ continue; } //Ignore the event if it's been emited by a voice server
if (evName == "UDP_CONNECTION") {
handleUdpRequest(
event["fullDocument"]["data"]["d"]["address"].get_utf8().value.to_string(),
event["fullDocument"]["data"]["d"]["port"].get_int32().value,
event["fullDocument"]["data"]["d"]["mode"].get_utf8().value.to_string()
);
} else if (evName == "VOICE_REQUEST") {
//TODO
continue;
}
returnValue.eventName = evName;
retVec.push_back(returnValue);
}
return retVec;
}
void mongoStub::handleUdpRequest(std::string address, int port, std::string mode) {
using bsoncxx::builder::basic::kvp;
using bsoncxx::builder::basic::sub_array;
using bsoncxx::builder::basic::sub_document;
auto builder = bsoncxx::builder::basic::document{};
//Handle UDP socket stuff (later tho)
builder.append(kvp("event", "VSERVER_UDP_RESPONSE"));
builder.append(kvp("op", "4"));
builder.append(kvp("d", [](sub_document subdoc) {
subdoc.append(kvp("mode", "CRYPT_MODE")),
subdoc.append(kvp("secret_key", [](sub_array subarr) {
subarr.append(1, 2, 3, 5); // HOW DO I GEN A SKEY?
}));
}));
bsoncxx::stdx::optional<mongocxx::result::insert_one> r= col.insert_one(builder.view());
}
void mongoStub::handleVoiceRequest() {
//Is this really needed? idk
}

41
src/mongoStub.hpp Normal file
View File

@ -0,0 +1,41 @@
#ifndef MONGOSTUB_HPP
#define MONGOSTUB_HPP
#include <boost/utility.hpp>
#include <cstdint>
#include <iostream>
#include <vector>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/change_stream.hpp>
#include <bsoncxx/json.hpp>
#include <bsoncxx/document/element.hpp>
class mongoStub{
public:
mongoStub();
struct mongoMessage{
std::string eventName;
std::vector<std::string> data;
};
std::vector<mongoMessage> getNewMessages(mongocxx::change_stream* colCs);
mongocxx::collection getCol() const { return col; }
private:
mongocxx::instance instance;
mongocxx::client client{mongocxx::uri{}};
mongocxx::database db;
mongocxx::collection col;
mongocxx::change_stream* colCs = nullptr;
void handleUdpRequest(std::string address, int port, std::string mode);
void handleVoiceRequest();
};
#endif

83
src/rtcPeerHandler.cpp Normal file
View File

@ -0,0 +1,83 @@
#include "rtcPeerHandler.hpp"
rtcPeerHandler::rtcPeerHandler() {
rtc::InitLogger(rtc::LogLevel::Verbose, NULL);
}
void rtcPeerHandler::initiateConnection(std::string peerIP, int peerPort) {
// Socket connection between client and server
SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
sockaddr_in addr;
addr.sin_addr.s_addr = inet_addr(peerIP.c_str());
addr.sin_port = htons(peerPort);
addr.sin_family = AF_INET;
rtc::Configuration conf;
conf.enableIceTcp = false;
conf.disableAutoNegotiation = false;
auto pc = std::make_shared<rtc::PeerConnection>(conf);
rtc::Description::Audio media("audio",
rtc::Description::Direction::SendRecv);
media.addOpusCodec(96);
media.setBitrate(64);
auto track = pc->addTrack(media);
// auto session = std::make_shared<rtc::MediaHandler>();
// track->setMediaHandler(session);
rtc::Reliability rtcRel;
rtcRel.unordered = true;
rtcRel.type = rtc::Reliability::Type::Timed;
rtcRel.rexmit = 500;
rtc::DataChannelInit rtcConf;
rtcConf.reliability = rtcRel;
rtcConf.negotiated = false;
pc->onStateChange([](rtc::PeerConnection::State state) {
std::cout << "State: " << state << std::endl;
if (state == rtc::PeerConnection::State::Disconnected ||
state == rtc::PeerConnection::State::Failed ||
state == rtc::PeerConnection::State::Closed) {
// remove disconnected client
}
});
pc->onGatheringStateChange([](rtc::PeerConnection::GatheringState state) {
std::cout << "Gathering State: " << state << std::endl;
});
/*std::tuple<rtc::Track*, rtc::RtcpSrReporter*> addAudio(
const std::shared_ptr<rtc::PeerConnection> pc,
const uint8_t payloadType, const uint32_t ssrc, const std::string cname,
const std::string msid, const std::function<void(void)> onOpen) {
auto audio = Description::Audio(cname);
audio.addOpusCodec(payloadType);
audio.addSSRC(ssrc, cname, msid, cname);
auto track = pc->addTrack(audio);
// create RTP configuration
auto rtpConfig = make_shared<RtpPacketizationConfig>(
ssrc, cname, payloadType, OpusRtpPacketizer::defaultClockRate);
// create packetizer
auto packetizer = make_shared<OpusRtpPacketizer>(rtpConfig);
// create opus handler
auto opusHandler = make_shared<OpusPacketizationHandler>(packetizer);
// add RTCP SR handler
auto srReporter = make_shared<RtcpSrReporter>(rtpConfig);
opusHandler->addToChain(srReporter);
// set handler
track->setMediaHandler(opusHandler);
track->onOpen(onOpen);
auto trackData = make_shared<ClientTrackData>(track, srReporter);
return trackData;
}*/
pc->createDataChannel("Fosscord voice connection", rtcConf);
}

32
src/rtcPeerHandler.hpp Normal file
View File

@ -0,0 +1,32 @@
#include "libdatachannel/rtc.hpp"
#include <iostream>
#include <memory>
#include "nlohmann/json.hpp"
#include <array>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <arpa/inet.h>
typedef int SOCKET;
#endif
using json = nlohmann::json;
#ifndef RTCPEERHANDLER
#define RTCPEERHANDLER
class rtcPeerHandler{
public:
rtcPeerHandler();
void initiateConnection(std::string peerIP, int peerPort);
struct client
{
std::shared_ptr<rtc::PeerConnection> pc;
std::shared_ptr<rtc::DataChannel> dc;
};
private:
std::map<SOCKET, client> clients;
};
#endif

0
src/rtcServer.hpp Normal file
View File