Skip to content

Commit

Permalink
Update Mumble protocol to 1.5
Browse files Browse the repository at this point in the history
Beginnings of 1.4 and 1.5 client support.
Fixed mumble.client:transmit always sending data through TCP tunnel.
Added mumble.channel:set/getVolumeAdjustment.
Client will now authorize to the server as a bot.
Set priority on timers to try and help with issue #23.
Update OCB library to latest.
Break out of mumble.loop on SIGINT.
Added new mumble.buffer metatable.
  • Loading branch information
bkacjios committed May 7, 2024
1 parent 5b19c30 commit cdb54e3
Show file tree
Hide file tree
Showing 22 changed files with 1,363 additions and 270 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
*.o
proto/Mumble.pb-c.c
proto/Mumble.pb-c.h
proto/*.c
proto/*.h
config/
*.so
*.lua
*.pem
*.d
*.ogg
gitversion.h
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ mumble.user = mumble.client.me
mumble.user = mumble.client:getMe()
mumble.user = mumble.client:getSelf()

-- Run a script in a thread with its own separate Lua environment
mumble.thread = mumble.thread("filename.lua")

-- A new timer object
-- The timer itself will do a best-effort at avoiding drift, that is, if you configure a timer to trigger every 10 seconds, then it will normally trigger at exactly 10 second intervals. If, however, your program cannot keep up with the timer (because it takes longer than those 10 seconds to do stuff) the timer will not fire more than once per event loop iteration.
-- Timers will keep the reference active until mumble.timer:close() is called.
Expand Down
67 changes: 47 additions & 20 deletions mumble/audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "packet.h"
#include "audio.h"

int util_set_varint(uint8_t buffer[], const uint64_t value)
uint8_t util_set_varint(uint8_t buffer[], const uint64_t value)
{
if (value < 0x80) {
buffer[0] = value;
Expand Down Expand Up @@ -41,7 +41,7 @@ int util_set_varint(uint8_t buffer[], const uint64_t value)
buffer[8] = value & 0xFF;
return 9;
}
return -1;
return 0;
}

uint64_t util_get_varint(uint8_t buffer[], int *len)
Expand Down Expand Up @@ -127,10 +127,10 @@ int voicepacket_setframe(VoicePacket *packet, const uint8_t type, const uint16_t
return -2;
}

if (type == UDP_OPUS) {
if (type == LEGACY_UDP_OPUS) {
// Opus uses a varint for the frame header
offset = util_set_varint(packet->buffer + packet->header_length, frame_header);
} else if (type == UDP_SPEEX || type == UDP_CELT_ALPHA || type == UDP_CELT_BETA) {
} else if (type == LEGACY_UDP_SPEEX || type == LEGACY_UDP_CELT_ALPHA || type == LEGACY_UDP_CELT_BETA) {
// Every other codec uses a single byte as the frame header
offset += 1;
packet->buffer[packet->header_length] = frame_header;
Expand Down Expand Up @@ -282,24 +282,52 @@ void audio_transmission_event(lua_State* l, MumbleClient *client)

if (encoded_len <= 0) return;

uint32_t frame_header = encoded_len;
// If the largest PCM buffer is smaller than our frame size, it has to be the last frame available
if (!didLoop && biggest_read < frame_size) {
// Set 14th bit to 1 to signal end of stream.
frame_header = ((1 << 13) | frame_header);
}
bool end_frame = !didLoop && biggest_read < frame_size;

if (false) {
uint32_t frame_header = encoded_len;
// If the largest PCM buffer is smaller than our frame size, it has to be the last frame available
if (end_frame) {
// Set 14th bit to 1 to signal end of stream.
frame_header = ((1 << 13) | frame_header);
}

uint8_t packet_buffer[PAYLOAD_SIZE_MAX];
voicepacket_init(&packet, packet_buffer);
voicepacket_setheader(&packet, UDP_OPUS, client->audio_target, client->audio_sequence);
voicepacket_setframe(&packet, UDP_OPUS, frame_header, encoded, encoded_len);
uint8_t packet_buffer[PAYLOAD_SIZE_MAX];
voicepacket_init(&packet, packet_buffer);
voicepacket_setheader(&packet, LEGACY_UDP_OPUS, client->audio_target, client->audio_sequence);
voicepacket_setframe(&packet, LEGACY_UDP_OPUS, frame_header, encoded, encoded_len);

mumble_handle_speaking_hooks(l, client, packet.buffer + 1, UDP_OPUS, client->audio_target, client->session);
mumble_handle_speaking_hooks(l, client, packet.buffer + 1, LEGACY_UDP_OPUS, client->audio_target, client->session);

if (client->udp_tunnel) {
packet_sendex(client, PACKET_UDPTUNNEL, packet_buffer, voicepacket_getlength(&packet));
if (client->udp_tunnel) {
packet_sendex(client, PACKET_UDPTUNNEL, packet_buffer, voicepacket_getlength(&packet));
} else {
packet_sendudp(client, packet_buffer, voicepacket_getlength(&packet));
}
} else {
packet_sendudp(client, packet_buffer, voicepacket_getlength(&packet));
MumbleUDP__Audio audio = MUMBLE_UDP__AUDIO__INIT;

ProtobufCBinaryData audio_data;
audio_data.data = encoded;
audio_data.len = encoded_len;

audio.frame_number = client->audio_sequence;
audio.opus_data = audio_data;

audio.is_terminator = end_frame;

audio.target = client->audio_target;

unsigned char packet_buffer[UDP_BUFFER_MAX];
packet_buffer[0] = UDP_AUDIO;

int len = 1 + mumble_udp__audio__pack(&audio, packet_buffer + 1);

if (client->udp_tunnel) {
packet_sendex(client, PACKET_UDPTUNNEL, packet_buffer, len);
} else {
packet_sendudp(client, packet_buffer, len);
}
}

client->audio_sequence = (client->audio_sequence + 1) % 100000;
Expand Down Expand Up @@ -509,8 +537,7 @@ static int audiostream_gc(lua_State *l)

static int audiostream_tostring(lua_State *l)
{
AudioStream *sound = luaL_checkudata(l, 1, METATABLE_AUDIOSTREAM);
lua_pushfstring(l, "%s: %p", METATABLE_AUDIOSTREAM, sound);
lua_pushfstring(l, "%s: %p", METATABLE_AUDIOSTREAM, lua_topointer(l, 1));
return 1;
}

Expand Down
3 changes: 2 additions & 1 deletion mumble/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ extern const luaL_Reg mumble_audiostream[];
extern void audio_transmission_event(lua_State* l, MumbleClient *client);
extern void audio_transmission_stop(lua_State*l, MumbleClient *client, int channel);

extern int util_set_varint(uint8_t buffer[], const uint64_t value);
extern uint8_t util_set_varint_size(const uint64_t value);
extern uint8_t util_set_varint(uint8_t buffer[], const uint64_t value);
extern uint64_t util_get_varint(uint8_t buffer[], int *len);
extern VoicePacket * voicepacket_init(VoicePacket *packet, uint8_t *buffer);
extern int voicepacket_setheader(VoicePacket *packet, const uint8_t type, const uint8_t target, const uint32_t sequence);
Expand Down
6 changes: 2 additions & 4 deletions mumble/banentry.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,8 @@ static int banentry_getDuration(lua_State *l)
}

static int banentry_tostring(lua_State *l)
{
MumbleProto__BanList__BanEntry *entry = luaL_checkudata(l, 1, METATABLE_BANENTRY);

lua_pushfstring(l, "%s: %p", METATABLE_BANENTRY, entry);
{
lua_pushfstring(l, "%s: %p", METATABLE_BANENTRY, lua_topointer(l, 1));
return 1;
}

Expand Down
Loading

0 comments on commit cdb54e3

Please sign in to comment.