intelij hack

This commit is contained in:
Auzan 2018-03-28 10:37:59 +07:00
parent 993ea209c7
commit 7d64b05e3c
10 changed files with 110 additions and 76 deletions

View File

@ -11,6 +11,7 @@
namespace mumlib { namespace mumlib {
constexpr int DEFAULT_OPUS_ENCODER_BITRATE = 16000; constexpr int DEFAULT_OPUS_ENCODER_BITRATE = 16000;
constexpr int DEFAULT_OPUS_SAMPLE_RATE = 48000;
using namespace std; using namespace std;
using namespace boost::asio; using namespace boost::asio;
@ -22,6 +23,7 @@ namespace mumlib {
struct MumlibConfiguration { struct MumlibConfiguration {
int opusEncoderBitrate = DEFAULT_OPUS_ENCODER_BITRATE; int opusEncoderBitrate = DEFAULT_OPUS_ENCODER_BITRATE;
int opusSampleRate = DEFAULT_OPUS_SAMPLE_RATE;
// additional fields will be added in the future // additional fields will be added in the future
}; };
@ -30,7 +32,7 @@ namespace mumlib {
class Mumlib : boost::noncopyable { class Mumlib : boost::noncopyable {
public: public:
Mumlib(Callback &callback); explicit Mumlib(Callback &callback);
Mumlib(Callback &callback, io_service &ioService); Mumlib(Callback &callback, io_service &ioService);
@ -44,10 +46,14 @@ namespace mumlib {
void disconnect(); void disconnect();
void reconnect();
void run(); void run();
ConnectionState getConnectionState(); ConnectionState getConnectionState();
int getChannelId();
void sendAudioData(int16_t *pcmData, int pcmLength); void sendAudioData(int16_t *pcmData, int pcmLength);
void sendAudioDataTarget(int targetId, int16_t *pcmData, int pcmLength); void sendAudioDataTarget(int targetId, int16_t *pcmData, int pcmLength);

View File

@ -2,19 +2,17 @@
#include "Transport.hpp" #include "Transport.hpp"
#include <opus.h> #include <opus/opus.h>
#include <chrono> #include <chrono>
namespace mumlib { namespace mumlib {
constexpr int SAMPLE_RATE = 48000;
class MumlibException; class MumlibException;
class AudioException : public MumlibException { class AudioException : public MumlibException {
public: public:
AudioException(string message) : MumlibException(message) { } explicit AudioException(string message) : MumlibException(message) { }
}; };
struct IncomingAudioPacket { struct IncomingAudioPacket {
@ -27,8 +25,8 @@ namespace mumlib {
}; };
class Audio : boost::noncopyable { class Audio : boost::noncopyable {
public: public:
Audio(int opusEncoderBitrate = DEFAULT_OPUS_ENCODER_BITRATE); Audio(int opusSampleRate, int opusEncoderBitrate);
virtual ~Audio(); virtual ~Audio();
@ -59,6 +57,7 @@ namespace mumlib {
OpusEncoder *opusEncoder; OpusEncoder *opusEncoder;
int64_t outgoingSequenceNumber; int64_t outgoingSequenceNumber;
int sampleRate;
std::chrono::time_point<std::chrono::system_clock> lastEncodedAudioPacketTimestamp; std::chrono::time_point<std::chrono::system_clock> lastEncodedAudioPacketTimestamp;
}; };

View File

@ -153,7 +153,7 @@ namespace mumlib {
~BasicCallback(); ~BasicCallback();
virtual void version( void version(
uint16_t major, uint16_t major,
uint8_t minor, uint8_t minor,
uint8_t patch, uint8_t patch,
@ -161,29 +161,29 @@ namespace mumlib {
string os, string os,
string os_version) override; string os_version) override;
virtual void audio( void audio(
int target, int target,
int sessionId, int sessionId,
int sequenceNumber, int sequenceNumber,
int16_t *pcm_data, int16_t *pcm_data,
uint32_t pcm_data_size) override; uint32_t pcm_data_size) override;
virtual void unsupportedAudio( void unsupportedAudio(
int target, int target,
int sessionId, int sessionId,
int sequenceNumber, int sequenceNumber,
uint8_t *encoded_audio_data, uint8_t *encoded_audio_data,
uint32_t encoded_audio_data_size) override; uint32_t encoded_audio_data_size) override;
virtual void serverSync( void serverSync(
string welcome_text, string welcome_text,
int32_t session, int32_t session,
int32_t max_bandwidth, int32_t max_bandwidth,
int64_t permissions) override; int64_t permissions) override;
virtual void channelRemove(uint32_t channel_id) override; void channelRemove(uint32_t channel_id) override;
virtual void channelState( void channelState(
string name, string name,
int32_t channel_id, int32_t channel_id,
int32_t parent, int32_t parent,
@ -194,13 +194,13 @@ namespace mumlib {
bool temporary, bool temporary,
int32_t position) override; int32_t position) override;
virtual void userRemove( void userRemove(
uint32_t session, uint32_t session,
int32_t actor, int32_t actor,
string reason, string reason,
bool ban) override; bool ban) override;
virtual void userState( void userState(
int32_t session, int32_t session,
int32_t actor, int32_t actor,
string name, string name,
@ -215,7 +215,7 @@ namespace mumlib {
int32_t priority_speaker, int32_t priority_speaker,
int32_t recording) override; int32_t recording) override;
virtual void banList( void banList(
const uint8_t *ip_data, const uint8_t *ip_data,
uint32_t ip_data_size, uint32_t ip_data_size,
uint32_t mask, uint32_t mask,
@ -225,14 +225,14 @@ namespace mumlib {
string start, string start,
int32_t duration) override; int32_t duration) override;
virtual void textMessage( void textMessage(
uint32_t actor, uint32_t actor,
std::vector<uint32_t> session, std::vector<uint32_t> session,
std::vector<uint32_t> channel_id, std::vector<uint32_t> channel_id,
std::vector<uint32_t> tree_id, std::vector<uint32_t> tree_id,
string message) override; string message) override;
virtual void permissionDenied( void permissionDenied(
int32_t permission, int32_t permission,
int32_t channel_id, int32_t channel_id,
int32_t session, int32_t session,
@ -240,48 +240,48 @@ namespace mumlib {
int32_t deny_type, int32_t deny_type,
string name) override; string name) override;
virtual void queryUsers( void queryUsers(
uint32_t n_ids, uint32_t n_ids,
uint32_t *ids, uint32_t *ids,
uint32_t n_names, uint32_t n_names,
string *names) override; string *names) override;
virtual void contextActionModify( void contextActionModify(
string action, string action,
string text, string text,
uint32_t m_context, uint32_t m_context,
uint32_t operation) override; uint32_t operation) override;
virtual void contextAction( void contextAction(
int32_t session, int32_t session,
int32_t channel_id, int32_t channel_id,
string action) override; string action) override;
virtual void userList( void userList(
uint32_t user_id, uint32_t user_id,
string name, string name,
string last_seen, string last_seen,
int32_t last_channel) override; int32_t last_channel) override;
virtual void permissionQuery( void permissionQuery(
int32_t channel_id, int32_t channel_id,
uint32_t permissions, uint32_t permissions,
int32_t flush) override; int32_t flush) override;
virtual void codecVersion( void codecVersion(
int32_t alpha, int32_t alpha,
int32_t beta, int32_t beta,
uint32_t prefer_alpha, uint32_t prefer_alpha,
int32_t opus) override; int32_t opus) override;
virtual void serverConfig( void serverConfig(
uint32_t max_bandwidth, uint32_t max_bandwidth,
string welcome_text, string welcome_text,
uint32_t allow_html, uint32_t allow_html,
uint32_t message_length, uint32_t message_length,
uint32_t image_message_length) override; uint32_t image_message_length) override;
virtual void suggestConfig( void suggestConfig(
uint32_t version, uint32_t version,
uint32_t positional, uint32_t positional,
uint32_t push_to_talk) override; uint32_t push_to_talk) override;

View File

@ -14,6 +14,7 @@
#include <google/protobuf/message.h> #include <google/protobuf/message.h>
#include <chrono> #include <chrono>
#include <utility>
namespace mumlib { namespace mumlib {
@ -30,7 +31,7 @@ namespace mumlib {
class TransportException : public MumlibException { class TransportException : public MumlibException {
public: public:
TransportException(string message) : MumlibException(message) { } TransportException(string message) : MumlibException(std::move(message)) { }
}; };
class Transport : boost::noncopyable { class Transport : boost::noncopyable {
@ -49,6 +50,8 @@ namespace mumlib {
void disconnect(); void disconnect();
void reconnect();
ConnectionState getConnectionState() { ConnectionState getConnectionState() {
return state; return state;
} }

View File

@ -29,6 +29,6 @@ namespace mumlib {
private: private:
const int64_t value; const int64_t value;
int64_t parseVariant(uint8_t *buffer); long parseVariant(const uint8_t *buffer);
}; };
} }

View File

@ -4,20 +4,21 @@
static boost::posix_time::seconds RESET_SEQUENCE_NUMBER_INTERVAL(5); static boost::posix_time::seconds RESET_SEQUENCE_NUMBER_INTERVAL(5);
mumlib::Audio::Audio(int opusEncoderBitrate) mumlib::Audio::Audio(int opusSampleRate, int opusEncoderBitrate)
: logger(log4cpp::Category::getInstance("mumlib.Audio")), : logger(log4cpp::Category::getInstance("mumlib.Audio")),
opusDecoder(nullptr), opusDecoder(nullptr),
opusEncoder(nullptr), opusEncoder(nullptr),
outgoingSequenceNumber(0) { outgoingSequenceNumber(0) {
int error; int error;
this->sampleRate = opusSampleRate;
opusDecoder = opus_decoder_create(SAMPLE_RATE, 1, &error); opusDecoder = opus_decoder_create(opusSampleRate, 1, &error);
if (error != OPUS_OK) { if (error != OPUS_OK) {
throw AudioException((boost::format("failed to initialize OPUS decoder: %s") % opus_strerror(error)).str()); throw AudioException((boost::format("failed to initialize OPUS decoder: %s") % opus_strerror(error)).str());
} }
opusEncoder = opus_encoder_create(SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP, &error); opusEncoder = opus_encoder_create(opusSampleRate, 1, OPUS_APPLICATION_VOIP, &error);
if (error != OPUS_OK) { if (error != OPUS_OK) {
throw AudioException((boost::format("failed to initialize OPUS encoder: %s") % opus_strerror(error)).str()); throw AudioException((boost::format("failed to initialize OPUS encoder: %s") % opus_strerror(error)).str());
} }
@ -108,7 +109,7 @@ int mumlib::Audio::encodeAudioPacket(int target, int16_t *inputPcmBuffer, int in
std::vector<uint8_t> header; std::vector<uint8_t> header;
header.push_back(0x80 | target); header.push_back(static_cast<unsigned char &&>(0x80 | target));
auto sequenceNumberEnc = VarInt(outgoingSequenceNumber).getEncoded(); auto sequenceNumberEnc = VarInt(outgoingSequenceNumber).getEncoded();
header.insert(header.end(), sequenceNumberEnc.begin(), sequenceNumberEnc.end()); header.insert(header.end(), sequenceNumberEnc.begin(), sequenceNumberEnc.end());
@ -130,15 +131,15 @@ int mumlib::Audio::encodeAudioPacket(int target, int16_t *inputPcmBuffer, int in
header.insert(header.end(), outputSizeEnc.begin(), outputSizeEnc.end()); header.insert(header.end(), outputSizeEnc.begin(), outputSizeEnc.end());
memcpy(outputBuffer, &header[0], header.size()); memcpy(outputBuffer, &header[0], header.size());
memcpy(outputBuffer + header.size(), tmpOpusBuffer, outputSize); memcpy(outputBuffer + header.size(), tmpOpusBuffer, (size_t) outputSize);
int incrementNumber = 100 * inputLength / SAMPLE_RATE; int incrementNumber = 100 * inputLength / this->sampleRate;
outgoingSequenceNumber += incrementNumber; outgoingSequenceNumber += incrementNumber;
lastEncodedAudioPacketTimestamp = std::chrono::system_clock::now(); lastEncodedAudioPacketTimestamp = std::chrono::system_clock::now();
return outputSize + header.size(); return static_cast<int>(outputSize + header.size());
} }
void mumlib::Audio::resetEncoder() { void mumlib::Audio::resetEncoder() {
@ -152,7 +153,7 @@ void mumlib::Audio::resetEncoder() {
} }
mumlib::IncomingAudioPacket mumlib::Audio::decodeIncomingAudioPacket(uint8_t *inputBuffer, int inputBufferLength) { mumlib::IncomingAudioPacket mumlib::Audio::decodeIncomingAudioPacket(uint8_t *inputBuffer, int inputBufferLength) {
mumlib::IncomingAudioPacket incomingAudioPacket; mumlib::IncomingAudioPacket incomingAudioPacket{};
incomingAudioPacket.type = static_cast<AudioPacketType >((inputBuffer[0] & 0xE0) >> 5); incomingAudioPacket.type = static_cast<AudioPacketType >((inputBuffer[0] & 0xE0) >> 5);
incomingAudioPacket.target = inputBuffer[0] & 0x1F; incomingAudioPacket.target = inputBuffer[0] & 0x1F;

View File

@ -35,7 +35,7 @@ void mumlib::BasicCallback::version(
os_version.c_str()); os_version.c_str());
} }
void mumlib::BasicCallback::audio( void BasicCallback::audio(
int target, int target,
int sessionId, int sessionId,
int sequenceNumber, int sequenceNumber,

View File

@ -3,6 +3,7 @@
#include "Mumble.pb.h" #include "Mumble.pb.h"
#include <boost/format.hpp> #include <boost/format.hpp>
#include <utility>
using namespace std; using namespace std;
@ -32,15 +33,15 @@ mumlib::Transport::Transport(
bool noUdp) : bool noUdp) :
logger(log4cpp::Category::getInstance("mumlib.Transport")), logger(log4cpp::Category::getInstance("mumlib.Transport")),
ioService(ioService), ioService(ioService),
processMessageFunction(processMessageFunc), processMessageFunction(std::move(processMessageFunc)),
processEncodedAudioPacketFunction(processEncodedAudioPacketFunction), processEncodedAudioPacketFunction(std::move(processEncodedAudioPacketFunction)),
noUdp(noUdp), noUdp(noUdp),
state(ConnectionState::NOT_CONNECTED), state(ConnectionState::NOT_CONNECTED),
udpSocket(ioService), udpSocket(ioService),
sslContext(ssl::context::sslv23), sslContext(ssl::context::sslv23),
sslSocket(ioService, sslContext), sslSocket(ioService, sslContext),
pingTimer(ioService, PING_INTERVAL), pingTimer(ioService, PING_INTERVAL),
asyncBufferPool(max(MAX_UDP_LENGTH, MAX_TCP_LENGTH)) { asyncBufferPool(static_cast<const unsigned long>(max(MAX_UDP_LENGTH, MAX_TCP_LENGTH))) {
sslIncomingBuffer = new uint8_t[MAX_TCP_LENGTH]; sslIncomingBuffer = new uint8_t[MAX_TCP_LENGTH];
@ -118,6 +119,15 @@ void mumlib::Transport::disconnect() {
} }
} }
void mumlib::Transport::reconnect() {
boost::system::error_code errorCode;
udpSocket.close(errorCode);
if (errorCode) {
logger.warn("SSL socket close return an error: %s.", errorCode.message().c_str());
}
}
void mumlib::Transport::sendVersion() { void mumlib::Transport::sendVersion() {
MumbleProto::Version version; MumbleProto::Version version;
@ -185,10 +195,10 @@ void mumlib::Transport::doReceiveUdp() {
} }
uint8_t plainBuffer[1024]; uint8_t plainBuffer[1024];
const int plainBufferLength = bytesTransferred - 4; const int plainBufferLength = static_cast<const int>(bytesTransferred - 4);
bool success = cryptState.decrypt( bool success = cryptState.decrypt(
udpIncomingBuffer, plainBuffer, bytesTransferred); udpIncomingBuffer, plainBuffer, static_cast<unsigned int>(bytesTransferred));
if (not success) { if (not success) {
throwTransportException("UDP packet decryption failed"); throwTransportException("UDP packet decryption failed");
@ -263,12 +273,12 @@ void mumlib::Transport::sendUdpAsync(uint8_t *buff, int length) {
auto *encryptedMsgBuff = asyncBufferPool.malloc(); auto *encryptedMsgBuff = asyncBufferPool.malloc();
const int encryptedMsgLength = length + 4; const int encryptedMsgLength = length + 4;
cryptState.encrypt(buff, reinterpret_cast<uint8_t *>(encryptedMsgBuff), length); cryptState.encrypt(buff, reinterpret_cast<uint8_t *>(encryptedMsgBuff), static_cast<unsigned int>(length));
logger.debug("Sending %d B of data UDP asynchronously.", encryptedMsgLength); logger.debug("Sending %d B of data UDP asynchronously.", encryptedMsgLength);
udpSocket.async_send_to( udpSocket.async_send_to(
boost::asio::buffer(encryptedMsgBuff, length + 4), boost::asio::buffer(encryptedMsgBuff, static_cast<size_t>(length + 4)),
udpReceiverEndpoint, udpReceiverEndpoint,
[this, encryptedMsgBuff](const boost::system::error_code &ec, size_t bytesTransferred) { [this, encryptedMsgBuff](const boost::system::error_code &ec, size_t bytesTransferred) {
asyncBufferPool.free(encryptedMsgBuff); asyncBufferPool.free(encryptedMsgBuff);
@ -318,7 +328,7 @@ void mumlib::Transport::doReceiveSsl() {
processMessageInternal( processMessageInternal(
static_cast<MessageType>(messageType), static_cast<MessageType>(messageType),
&sslIncomingBuffer[6], &sslIncomingBuffer[6],
bytesTransferred - 6); static_cast<int>(bytesTransferred - 6));
doReceiveSsl(); doReceiveSsl();
} else { } else {
@ -438,10 +448,10 @@ void mumlib::Transport::sendUdpPing() {
vector<uint8_t> message; vector<uint8_t> message;
message.push_back(0x20); message.push_back(0x20);
auto timestampVarint = VarInt(time(nullptr)).getEncoded(); auto timestampVarint = VarInt(static_cast<int64_t>(time(nullptr))).getEncoded();
message.insert(message.end(), timestampVarint.begin(), timestampVarint.end()); message.insert(message.end(), timestampVarint.begin(), timestampVarint.end());
sendUdpAsync(&message[0], message.size()); sendUdpAsync(&message[0], static_cast<int>(message.size()));
} }
void mumlib::Transport::sendSsl(uint8_t *buff, int length) { void mumlib::Transport::sendSsl(uint8_t *buff, int length) {
@ -453,7 +463,7 @@ void mumlib::Transport::sendSsl(uint8_t *buff, int length) {
logger.debug("Sending %d bytes of data.", length); logger.debug("Sending %d bytes of data.", length);
try { try {
write(sslSocket, boost::asio::buffer(buff, length)); write(sslSocket, boost::asio::buffer(buff, static_cast<size_t>(length)));
} catch (boost::system::system_error &err) { } catch (boost::system::system_error &err) {
throwTransportException(std::string("SSL send failed: ") + err.what()); throwTransportException(std::string("SSL send failed: ") + err.what());
} }
@ -467,13 +477,13 @@ void mumlib::Transport::sendSslAsync(uint8_t *buff, int length) {
auto *asyncBuff = asyncBufferPool.malloc(); auto *asyncBuff = asyncBufferPool.malloc();
memcpy(asyncBuff, buff, length); memcpy(asyncBuff, buff, static_cast<size_t>(length));
logger.debug("Sending %d B of data asynchronously.", length); logger.debug("Sending %d B of data asynchronously.", length);
async_write( async_write(
sslSocket, sslSocket,
boost::asio::buffer(asyncBuff, length), boost::asio::buffer(asyncBuff, static_cast<size_t>(length)),
[this, asyncBuff](const boost::system::error_code &ec, size_t bytesTransferred) { [this, asyncBuff](const boost::system::error_code &ec, size_t bytesTransferred) {
asyncBufferPool.free(asyncBuff); asyncBufferPool.free(asyncBuff);
logger.debug("Sent %d B.", bytesTransferred); logger.debug("Sent %d B.", bytesTransferred);
@ -499,7 +509,7 @@ void mumlib::Transport::sendControlMessagePrivate(MessageType type, google::prot
const uint16_t type_network = htons(static_cast<uint16_t>(type)); const uint16_t type_network = htons(static_cast<uint16_t>(type));
const int size = message.ByteSize(); const int size = message.ByteSize();
const uint32_t size_network = htonl(size); const uint32_t size_network = htonl((uint32_t) size);
const int length = sizeof(type_network) + sizeof(size_network) + size; const int length = sizeof(type_network) + sizeof(size_network) + size;
@ -517,7 +527,7 @@ void mumlib::Transport::sendControlMessagePrivate(MessageType type, google::prot
void mumlib::Transport::throwTransportException(string message) { void mumlib::Transport::throwTransportException(string message) {
state = ConnectionState::FAILED; state = ConnectionState::FAILED;
throw TransportException(message); throw TransportException(std::move(message));
} }
void mumlib::Transport::sendEncodedAudioPacket(uint8_t *buffer, int length) { void mumlib::Transport::sendEncodedAudioPacket(uint8_t *buffer, int length) {
@ -534,7 +544,7 @@ void mumlib::Transport::sendEncodedAudioPacket(uint8_t *buffer, int length) {
const uint16_t netUdptunnelType = htons(static_cast<uint16_t>(MessageType::UDPTUNNEL)); const uint16_t netUdptunnelType = htons(static_cast<uint16_t>(MessageType::UDPTUNNEL));
const uint32_t netLength = htonl(length); const uint32_t netLength = htonl(static_cast<uint32_t>(length));
const int packet = sizeof(netUdptunnelType) + sizeof(netLength) + length; const int packet = sizeof(netUdptunnelType) + sizeof(netLength) + length;
@ -542,14 +552,14 @@ void mumlib::Transport::sendEncodedAudioPacket(uint8_t *buffer, int length) {
memcpy(packetBuff, &netUdptunnelType, sizeof(netUdptunnelType)); memcpy(packetBuff, &netUdptunnelType, sizeof(netUdptunnelType));
memcpy(packetBuff + sizeof(netUdptunnelType), &netLength, sizeof(netLength)); memcpy(packetBuff + sizeof(netUdptunnelType), &netLength, sizeof(netLength));
memcpy(packetBuff + sizeof(netUdptunnelType) + sizeof(netLength), buffer, length); memcpy(packetBuff + sizeof(netUdptunnelType) + sizeof(netLength), buffer, static_cast<size_t>(length));
sendSslAsync(packetBuff, length + sizeof(netUdptunnelType) + sizeof(netLength)); sendSslAsync(packetBuff, length + sizeof(netUdptunnelType) + sizeof(netLength));
} }
} }
void mumlib::Transport::processAudioPacket(uint8_t *buff, int length) { void mumlib::Transport::processAudioPacket(uint8_t *buff, int length) {
AudioPacketType type = static_cast<AudioPacketType >((buff[0] & 0xE0) >> 5); auto type = static_cast<AudioPacketType >((buff[0] & 0xE0) >> 5);
switch (type) { switch (type) {
case AudioPacketType::CELT_Alpha: case AudioPacketType::CELT_Alpha:
case AudioPacketType::Speex: case AudioPacketType::Speex:

View File

@ -12,7 +12,7 @@ mumlib::VarInt::VarInt(std::vector<uint8_t> encoded) : value(parseVariant(&encod
* This code was taken from Mumble source code * This code was taken from Mumble source code
* https://github.com/mumble-voip/mumble/blob/master/src/PacketDataStream.h * https://github.com/mumble-voip/mumble/blob/master/src/PacketDataStream.h
*/ */
int64_t mumlib::VarInt::parseVariant(uint8_t *buffer) { int64_t mumlib::VarInt::parseVariant(const uint8_t *buffer) {
int64_t v = buffer[0]; int64_t v = buffer[0];
if ((v & 0x80) == 0x00) { if ((v & 0x80) == 0x00) {
return (v & 0x7F); return (v & 0x7F);
@ -36,6 +36,7 @@ int64_t mumlib::VarInt::parseVariant(uint8_t *buffer) {
return (v & 0x1F) << 16 | buffer[1] << 8 | buffer[2]; return (v & 0x1F) << 16 | buffer[1] << 8 | buffer[2];
} }
throw VarIntException("invalid varint"); throw VarIntException("invalid varint");
} }
@ -46,7 +47,7 @@ std::vector<uint8_t> mumlib::VarInt::getEncoded() const {
if ((i & 0x8000000000000000LL) && (~i < 0x100000000LL)) { if ((i & 0x8000000000000000LL) && (~i < 0x100000000LL)) {
i = ~i; i = ~i;
if (i <= 0x3) { if (i <= 0x3) {
encoded.push_back(0xFC | i); encoded.push_back(static_cast<unsigned char &&>(0xFC | i));
return encoded; return encoded;
} else { } else {
encoded.push_back(0xF8); encoded.push_back(0xF8);
@ -54,29 +55,29 @@ std::vector<uint8_t> mumlib::VarInt::getEncoded() const {
} }
if (i < 0x80) { if (i < 0x80) {
encoded.push_back(i); encoded.push_back(static_cast<unsigned char &&>(i));
} else if (i < 0x4000) { } else if (i < 0x4000) {
encoded.push_back(0x80 | (i >> 8)); encoded.push_back(static_cast<unsigned char &&>(0x80 | (i >> 8)));
encoded.push_back(i & 0xFF); encoded.push_back(static_cast<unsigned char &&>(i & 0xFF));
} else if (i < 0x200000) { } else if (i < 0x200000) {
encoded.push_back(0xC0 | (i >> 16)); encoded.push_back(static_cast<unsigned char &&>(0xC0 | (i >> 16)));
encoded.push_back((i >> 8) & 0xFF); encoded.push_back(static_cast<unsigned char &&>((i >> 8) & 0xFF));
encoded.push_back(i & 0xFF); encoded.push_back(static_cast<unsigned char &&>(i & 0xFF));
} else if (i < 0x10000000) { } else if (i < 0x10000000) {
encoded.push_back(0xE0 | (i >> 24)); encoded.push_back(static_cast<unsigned char &&>(0xE0 | (i >> 24)));
encoded.push_back((i >> 16) & 0xFF); encoded.push_back(static_cast<unsigned char &&>((i >> 16) & 0xFF));
encoded.push_back((i >> 8) & 0xFF); encoded.push_back(static_cast<unsigned char &&>((i >> 8) & 0xFF));
encoded.push_back(i & 0xFF); encoded.push_back(static_cast<unsigned char &&>(i & 0xFF));
} else { } else {
encoded.push_back(0xF4); encoded.push_back(0xF4);
encoded.push_back((i >> 56) & 0xFF); encoded.push_back(static_cast<unsigned char &&>((i >> 56) & 0xFF));
encoded.push_back((i >> 48) & 0xFF); encoded.push_back(static_cast<unsigned char &&>((i >> 48) & 0xFF));
encoded.push_back((i >> 40) & 0xFF); encoded.push_back(static_cast<unsigned char &&>((i >> 40) & 0xFF));
encoded.push_back((i >> 32) & 0xFF); encoded.push_back(static_cast<unsigned char &&>((i >> 32) & 0xFF));
encoded.push_back((i >> 24) & 0xFF); encoded.push_back(static_cast<unsigned char &&>((i >> 24) & 0xFF));
encoded.push_back((i >> 16) & 0xFF); encoded.push_back(static_cast<unsigned char &&>((i >> 16) & 0xFF));
encoded.push_back((i >> 8) & 0xFF); encoded.push_back(static_cast<unsigned char &&>((i >> 8) & 0xFF));
encoded.push_back(i & 0xFF); encoded.push_back(static_cast<unsigned char &&>(i & 0xFF));
} }
return encoded; return encoded;

View File

@ -43,7 +43,8 @@ namespace mumlib {
ioService(ioService), ioService(ioService),
externalIoService(true), externalIoService(true),
transport(ioService, boost::bind(&_Mumlib_Private::processIncomingTcpMessage, this, _1, _2, _3), transport(ioService, boost::bind(&_Mumlib_Private::processIncomingTcpMessage, this, _1, _2, _3),
boost::bind(&_Mumlib_Private::processAudioPacket, this, _1, _2, _3)) { boost::bind(&_Mumlib_Private::processAudioPacket, this, _1, _2, _3)),
audio(configuration.opusSampleRate, configuration.opusEncoderBitrate) {
audio.setOpusEncoderBitrate(configuration.opusEncoderBitrate); audio.setOpusEncoderBitrate(configuration.opusEncoderBitrate);
} }
@ -363,6 +364,10 @@ namespace mumlib {
return impl->transport.getConnectionState(); return impl->transport.getConnectionState();
} }
int Mumlib::getChannelId() {
return impl->channelId;
}
void Mumlib::connect(string host, int port, string user, string password) { void Mumlib::connect(string host, int port, string user, string password) {
impl->transport.connect(host, port, user, password); impl->transport.connect(host, port, user, password);
} }
@ -376,6 +381,15 @@ namespace mumlib {
} }
} }
void Mumlib::reconnect() {
if (not impl->externalIoService) {
impl->ioService.reset();
}
if (impl->transport.getConnectionState() != ConnectionState::NOT_CONNECTED) {
impl->transport.disconnect();
}
}
void Mumlib::run() { void Mumlib::run() {
if (impl->externalIoService) { if (impl->externalIoService) {
throw MumlibException("can't call run() when using external io_service"); throw MumlibException("can't call run() when using external io_service");