101 lines
3.5 KiB
C++
101 lines
3.5 KiB
C++
/*
|
|
* session/session.h: client-side mirror of the server's channel/user state.
|
|
*
|
|
* Populated from ServerStateSnapshot (full snapshot) and incremental UserEvent /
|
|
* ChannelEvent messages. Not thread-safe — always called from io_thread_.
|
|
*/
|
|
#ifndef VOICECAT_SESSION_SESSION_H
|
|
#define VOICECAT_SESSION_SESSION_H
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "proto/voicecat.pb.h"
|
|
|
|
namespace voicecat::session {
|
|
|
|
struct Channel {
|
|
uint32_t id{0};
|
|
uint32_t parent_id{0};
|
|
std::string name;
|
|
std::string topic;
|
|
bool password_protected{false};
|
|
uint32_t max_users{0};
|
|
uint32_t sort_order{0};
|
|
// Authoritative channel AudioConfig mirrors
|
|
// voicecat::v1::AudioConfig field-for-field, same flat shape as Stream below. Populated
|
|
// from ServerStateSnapshot / ChannelEvent so the channel-edit dialog can read back the
|
|
// current config (the vc_channel read struct now carries these too).
|
|
uint32_t audio_sample_rate{48000};
|
|
uint32_t audio_frame_ms{20};
|
|
uint32_t audio_mode{0}; // 0 = mono, 1 = stereo
|
|
uint32_t audio_bitrate_bps{0};
|
|
uint32_t audio_application{0}; // 0=VOIP, 1=AUDIO, 2=LOWDELAY
|
|
bool audio_fec{false};
|
|
uint32_t audio_expected_packet_loss{0};
|
|
bool audio_dtx{false};
|
|
uint32_t audio_complexity{0};
|
|
bool audio_dred{false};
|
|
};
|
|
|
|
struct Stream {
|
|
uint32_t stream_id{0};
|
|
uint32_t ssrc{0};
|
|
int kind{0};
|
|
std::string label;
|
|
// Full effective AudioConfig as broadcast by the server in
|
|
// StreamInfo.audio — mirrors voicecat::v1::AudioConfig field-for-field so per-channel
|
|
// tuning (mono/stereo, bitrate, FEC/DTX, application) is observable client-side, not just
|
|
// sample_rate/frame_ms.
|
|
uint32_t sample_rate{48000};
|
|
uint32_t frame_ms{20};
|
|
uint32_t mode{0}; // 0 = mono, 1 = stereo (ChannelMode)
|
|
uint32_t bitrate_bps{0};
|
|
uint32_t application{0}; // 0=VOIP, 1=AUDIO, 2=LOWDELAY (OpusApplication)
|
|
bool fec{false};
|
|
uint32_t expected_packet_loss{0};
|
|
bool dtx{false};
|
|
uint32_t complexity{0};
|
|
bool dred{false};
|
|
};
|
|
|
|
struct User {
|
|
uint32_t id{0};
|
|
std::string nickname;
|
|
bool is_guest{true};
|
|
uint32_t channel_id{0};
|
|
bool self_mic_muted{false};
|
|
bool self_deafened{false};
|
|
bool server_muted{false};
|
|
bool server_deafened{false};
|
|
bool voice_subscribed{false};
|
|
std::vector<Stream> streams;
|
|
};
|
|
|
|
class SessionModel {
|
|
public:
|
|
const std::vector<Channel>& channels() const { return channels_; }
|
|
const std::vector<User>& users() const { return users_; }
|
|
|
|
const Channel* find_channel(uint32_t id) const;
|
|
const User* find_user(uint32_t id) const;
|
|
|
|
// Find the user that owns a given media ssrc, and the matching Stream entry.
|
|
// Returns {nullptr, nullptr} if not found.
|
|
std::pair<const User*, const Stream*> find_user_by_ssrc(uint32_t ssrc) const;
|
|
|
|
void apply_snapshot(const voicecat::v1::ServerStateSnapshot& snap);
|
|
void apply_user_event(const voicecat::v1::UserEvent& ev);
|
|
void apply_channel_event(const voicecat::v1::ChannelEvent& ev);
|
|
|
|
private:
|
|
std::vector<Channel> channels_;
|
|
std::vector<User> users_;
|
|
};
|
|
|
|
} // namespace voicecat::session
|
|
|
|
#endif // VOICECAT_SESSION_SESSION_H
|