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:
commit
f46ca1c341
40
.gitignore
vendored
40
.gitignore
vendored
@ -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
16
CMakeLists.txt
Normal 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)
|
35
README.md
35
README.md
@ -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
1
config.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
47
src/main.cpp
Normal file
47
src/main.cpp
Normal 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
84
src/mongoStub.cpp
Normal 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
41
src/mongoStub.hpp
Normal 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
83
src/rtcPeerHandler.cpp
Normal 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
32
src/rtcPeerHandler.hpp
Normal 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
0
src/rtcServer.hpp
Normal file
Loading…
Reference in New Issue
Block a user