|
@@ -1,11 +1,11 @@
|
|
|
-#include "mumlib.hpp"
|
|
|
-
|
|
|
#include "mumlib/CryptState.hpp"
|
|
|
#include "mumlib/VarInt.hpp"
|
|
|
#include "mumlib/enums.hpp"
|
|
|
#include "mumlib/Transport.hpp"
|
|
|
#include "mumlib/Audio.hpp"
|
|
|
|
|
|
+#include "mumlib.hpp"
|
|
|
+
|
|
|
#include <boost/asio/ssl.hpp>
|
|
|
#include <boost/bind.hpp>
|
|
|
#include <log4cpp/Category.hh>
|
|
@@ -35,7 +35,7 @@ namespace mumlib {
|
|
|
case MessageType::VERSION: {
|
|
|
MumbleProto::Version version;
|
|
|
version.ParseFromArray(buffer, length);
|
|
|
- callback->version_callback(
|
|
|
+ callback->version(
|
|
|
version.version() >> 16,
|
|
|
version.version() >> 8 & 0xff,
|
|
|
version.version() & 0xff,
|
|
@@ -47,7 +47,7 @@ namespace mumlib {
|
|
|
case MessageType::SERVERSYNC: {
|
|
|
MumbleProto::ServerSync serverSync;
|
|
|
serverSync.ParseFromArray(buffer, length);
|
|
|
- callback->serversync_callback(
|
|
|
+ callback->serverSync(
|
|
|
serverSync.welcome_text(),
|
|
|
serverSync.session(),
|
|
|
serverSync.max_bandwidth(),
|
|
@@ -58,7 +58,7 @@ namespace mumlib {
|
|
|
case MessageType::CHANNELREMOVE: {
|
|
|
MumbleProto::ChannelRemove channelRemove;
|
|
|
channelRemove.ParseFromArray(buffer, length);
|
|
|
- callback->channelremove_callback(channelRemove.channel_id());
|
|
|
+ callback->channelRemove(channelRemove.channel_id());
|
|
|
}
|
|
|
break;
|
|
|
case MessageType::CHANNELSTATE: {
|
|
@@ -83,7 +83,7 @@ namespace mumlib {
|
|
|
std::copy(channelState.links_remove().begin(), channelState.links_remove().end(),
|
|
|
links_remove.begin());
|
|
|
|
|
|
- callback->channelstate_callback(
|
|
|
+ callback->channelState(
|
|
|
channelState.name(),
|
|
|
channel_id,
|
|
|
parent,
|
|
@@ -104,7 +104,7 @@ namespace mumlib {
|
|
|
bool ban = user_remove.has_ban() ? user_remove.ban()
|
|
|
: false; //todo make sure it's correct to assume it's false
|
|
|
|
|
|
- callback->userremove_callback(
|
|
|
+ callback->userRemove(
|
|
|
user_remove.session(),
|
|
|
actor,
|
|
|
user_remove.reason(),
|
|
@@ -112,64 +112,150 @@ namespace mumlib {
|
|
|
);
|
|
|
}
|
|
|
break;
|
|
|
- case MessageType::USERSTATE: // 9
|
|
|
-// return MessageType::private_process_userstate(context, message, message_size);
|
|
|
-
|
|
|
+ case MessageType::USERSTATE: {
|
|
|
+ MumbleProto::UserState userState;
|
|
|
+ userState.ParseFromArray(buffer, length);
|
|
|
+
|
|
|
+ // There are far too many things in this structure. Culling to the ones that are probably important
|
|
|
+ int32_t session = userState.has_session() ? userState.session() : -1;
|
|
|
+ int32_t actor = userState.has_actor() ? userState.actor() : -1;
|
|
|
+ int32_t user_id = userState.has_user_id() ? userState.user_id() : -1;
|
|
|
+ int32_t channel_id = userState.has_channel_id() ? userState.channel_id() : -1;
|
|
|
+ int32_t mute = userState.has_mute() ? userState.mute() : -1;
|
|
|
+ int32_t deaf = userState.has_deaf() ? userState.deaf() : -1;
|
|
|
+ int32_t suppress = userState.has_suppress() ? userState.suppress() : -1;
|
|
|
+ int32_t self_mute = userState.has_self_mute() ? userState.self_mute() : -1;
|
|
|
+ int32_t self_deaf = userState.has_self_deaf() ? userState.self_deaf() : -1;
|
|
|
+ int32_t priority_speaker = userState.has_priority_speaker() ? userState.priority_speaker() : -1;
|
|
|
+ int32_t recording = userState.has_recording() ? userState.recording() : -1;
|
|
|
+
|
|
|
+ callback->userState(session,
|
|
|
+ actor,
|
|
|
+ userState.name(),
|
|
|
+ user_id,
|
|
|
+ channel_id,
|
|
|
+ mute,
|
|
|
+ deaf,
|
|
|
+ suppress,
|
|
|
+ self_mute,
|
|
|
+ self_deaf,
|
|
|
+ userState.comment(),
|
|
|
+ priority_speaker,
|
|
|
+ recording);
|
|
|
+ }
|
|
|
break;
|
|
|
- case MessageType::BANLIST: // 10
|
|
|
-// return MessageType::private_process_banlist(context, message, message_size);
|
|
|
-
|
|
|
+ case MessageType::BANLIST: {
|
|
|
+ MumbleProto::BanList ban_list;
|
|
|
+ ban_list.ParseFromArray(buffer, length);
|
|
|
+ for (int i = 0; i < ban_list.bans_size(); i++) {
|
|
|
+ auto ban = ban_list.bans(i);
|
|
|
+
|
|
|
+ const uint8_t *ip_data = reinterpret_cast<const uint8_t *>(ban.address().c_str());
|
|
|
+ uint32_t ip_data_size = ban.address().size();
|
|
|
+ int32_t duration = ban.has_duration() ? ban.duration() : -1;
|
|
|
+
|
|
|
+ callback->banList(
|
|
|
+ ip_data,
|
|
|
+ ip_data_size,
|
|
|
+ ban.mask(),
|
|
|
+ ban.name(),
|
|
|
+ ban.hash(),
|
|
|
+ ban.reason(),
|
|
|
+ ban.start(),
|
|
|
+ duration);
|
|
|
+ }
|
|
|
+ }
|
|
|
break;
|
|
|
- case MessageType::TEXTMESSAGE: // 11
|
|
|
-// return MessageType::private_process_textmessage(context, message, message_size);
|
|
|
+ case MessageType::TEXTMESSAGE: {
|
|
|
+ MumbleProto::TextMessage text_message;
|
|
|
+ text_message.ParseFromArray(buffer, length);
|
|
|
|
|
|
+ int32_t actor = text_message.has_actor() ? text_message.actor() : -1;
|
|
|
+
|
|
|
+ vector<uint32_t> sessions;
|
|
|
+ for (int i = 0; i < text_message.session_size(); ++i) {
|
|
|
+ sessions.push_back(text_message.session(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ vector<uint32_t> channel_ids;
|
|
|
+ for (int i = 0; i < text_message.channel_id_size(); ++i) {
|
|
|
+ channel_ids.push_back(text_message.channel_id(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ vector<uint32_t> tree_ids;
|
|
|
+ for (int i = 0; i < text_message.tree_id_size(); ++i) {
|
|
|
+ tree_ids.push_back(text_message.tree_id(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ callback->textMessage(actor, sessions, channel_ids, tree_ids, text_message.message());
|
|
|
+ }
|
|
|
break;
|
|
|
case MessageType::PERMISSIONDENIED: // 12
|
|
|
-// return MessageType::private_process_permissiondenied(context, message, message_size);
|
|
|
-
|
|
|
+ logger->warn("PermissionDenied Message: support not implemented yet");
|
|
|
break;
|
|
|
case MessageType::ACL: // 13
|
|
|
-// return MessageType::private_process_acl(context, message, message_size);
|
|
|
-
|
|
|
+ logger->warn("ACL Message: support not implemented yet.");
|
|
|
break;
|
|
|
case MessageType::QUERYUSERS: // 14
|
|
|
-// return MessageType::private_process_queryusers(context, message, message_size);
|
|
|
-
|
|
|
+ logger->warn("QueryUsers Message: support not implemented yet");
|
|
|
break;
|
|
|
case MessageType::CONTEXTACTIONMODIFY: // 16
|
|
|
-// return MessageType::private_process_contextactionmodify(context, message, message_size);
|
|
|
-
|
|
|
+ logger->warn("ContextActionModify Message: support not implemented yet");
|
|
|
break;
|
|
|
case MessageType::CONTEXTACTION: // 17
|
|
|
-// return MessageType::private_process_contextaction(context, message, message_size);
|
|
|
-
|
|
|
+ logger->warn("ContextAction Message: support not implemented yet");
|
|
|
break;
|
|
|
case MessageType::USERLIST: // 18
|
|
|
-// return MessageType::private_process_userlist(context, message, message_size);
|
|
|
-
|
|
|
+ logger->warn("UserList Message: support not implemented yet");
|
|
|
break;
|
|
|
- case MessageType::PERMISSIONQUERY: // 20
|
|
|
-// return MessageType::private_process_permission_query(context, message, message_size);
|
|
|
-
|
|
|
+ case MessageType::VOICETARGET:
|
|
|
+ logger->warn("VoiceTarget Message: I don't think the server ever sends this structure.");
|
|
|
break;
|
|
|
- case MessageType::CODECVERSION: // 21
|
|
|
-// return MessageType::private_process_codecversion(context, message, message_size);
|
|
|
+ case MessageType::PERMISSIONQUERY: {
|
|
|
+ MumbleProto::PermissionQuery permissionQuery;
|
|
|
+ permissionQuery.ParseFromArray(buffer, length);
|
|
|
+
|
|
|
+ int32_t channel_id = permissionQuery.has_channel_id() ? permissionQuery.channel_id() : -1;
|
|
|
+ uint32_t permissions = permissionQuery.has_permissions() ? permissionQuery.permissions() : 0;
|
|
|
+ uint32_t flush = permissionQuery.has_flush() ? permissionQuery.flush() : -1;
|
|
|
|
|
|
+ callback->permissionQuery(channel_id, permissions, flush);
|
|
|
+ }
|
|
|
break;
|
|
|
- case MessageType::USERSTATS: // 22
|
|
|
-// return MessageType::private_process_userstats(context, message, message_size);
|
|
|
+ case MessageType::CODECVERSION: {
|
|
|
+ MumbleProto::CodecVersion codecVersion;
|
|
|
+ codecVersion.ParseFromArray(buffer, length);
|
|
|
|
|
|
+ int32_t alpha = codecVersion.alpha();
|
|
|
+ int32_t beta = codecVersion.beta();
|
|
|
+ uint32_t prefer_alpha = codecVersion.prefer_alpha();
|
|
|
+ int32_t opus = codecVersion.has_opus() ? codecVersion.opus() : 0;
|
|
|
+
|
|
|
+ callback->codecVersion(alpha, beta, prefer_alpha, opus);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case MessageType::USERSTATS:
|
|
|
+ logger->warn("UserStats Message: support not implemented yet");
|
|
|
break;
|
|
|
case MessageType::REQUESTBLOB: // 23
|
|
|
-// return MessageType::private_process_requestblob(context, message, message_size);
|
|
|
-
|
|
|
+ logger->warn("RequestBlob Message: I don't think this is sent by the server.");
|
|
|
break;
|
|
|
- case MessageType::SERVERCONFIG: // 24
|
|
|
-// return MessageType::private_process_serverconfig(context, message, message_size);
|
|
|
-
|
|
|
+ case MessageType::SERVERCONFIG: {
|
|
|
+ MumbleProto::ServerConfig serverConfig;
|
|
|
+ serverConfig.ParseFromArray(buffer, length);
|
|
|
+
|
|
|
+ uint32_t max_bandwidth = serverConfig.has_max_bandwidth() ? serverConfig.max_bandwidth() : 0;
|
|
|
+ uint32_t allow_html = serverConfig.has_allow_html() ? serverConfig.allow_html() : 0;
|
|
|
+ uint32_t message_length = serverConfig.has_message_length() ? serverConfig.message_length() : 0;
|
|
|
+ uint32_t image_message_length = serverConfig.has_image_message_length()
|
|
|
+ ? serverConfig.image_message_length() : 0;
|
|
|
+
|
|
|
+ callback->serverConfig(max_bandwidth, serverConfig.welcome_text(), allow_html, message_length,
|
|
|
+ image_message_length);
|
|
|
+ }
|
|
|
break;
|
|
|
case MessageType::SUGGESTCONFIG: // 25
|
|
|
-// return MessageType::private_process_suggestconfig(context, message, message_size);
|
|
|
+ logger->warn("SuggestConfig Message: support not implemented yet");
|
|
|
break;
|
|
|
default:
|
|
|
throw MumlibException("unknown message type: " + to_string(static_cast<int>(messageType)));
|
|
@@ -179,8 +265,14 @@ namespace mumlib {
|
|
|
|
|
|
bool processAudioPacket(AudioPacketType type, uint8_t *buffer, int length) {
|
|
|
logger->info("Got %d B of encoded audio data.", length);
|
|
|
- int16_t pcmData[5000];
|
|
|
- audio->decodeAudioPacket(type, buffer, length, pcmData, 5000);
|
|
|
+ try {
|
|
|
+ int16_t pcmData[5000];
|
|
|
+ int pcmDataLength = audio->decodeAudioPacket(type, buffer, length, pcmData, 5000);
|
|
|
+ callback->audio(pcmData, pcmDataLength);
|
|
|
+ } catch (mumlib::AudioException &exp) {
|
|
|
+ logger->warn("Audio decode error: %s, calling unsupportedAudio callback.", exp.what());
|
|
|
+ callback->unsupportedAudio(buffer, length);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
};
|
|
@@ -192,7 +284,7 @@ namespace mumlib {
|
|
|
}
|
|
|
|
|
|
mumlib::Mumlib::Mumlib() : impl(new _Mumlib_Private) {
|
|
|
- impl->logger = &(log4cpp::Category::getInstance("Mumlib.Mumlib"));
|
|
|
+ impl->logger = &(log4cpp::Category::getInstance("mumlib.Mumlib"));
|
|
|
impl->externalIoService = false;
|
|
|
impl->ioService = new io_service();
|
|
|
impl->audio = new Audio();
|