diff --git a/gumble/gumble/udp15.go b/gumble/gumble/udp15.go index 146d54a..1132c53 100644 --- a/gumble/gumble/udp15.go +++ b/gumble/gumble/udp15.go @@ -463,8 +463,9 @@ func (c *Client) WriteAudioUDP15(data []byte, final bool) (bool, error) { frameNum := nextFrameNumber() - // Build MumbleUDP.Audio protobuf. - payload := encodeUDPAudio(0, frameNum, data, final) + // Build MumbleUDP.Audio: type byte 0x00 + protobuf. + // Matches wumble: Bytes[0_u8] + Protobuf.field(4, ...) + Protobuf.bytes(5, ...) + payload := append([]byte{0x00}, encodeUDPAudio(0, frameNum, data, final)...) // Encrypt with 1.5 format. encrypted, err := cs.encrypt15(payload) @@ -512,6 +513,23 @@ func (c *Client) HandleUDPPacket15(packet []byte, pktNum uint64) { log.Debug("UDP15 #%d: decrypt OK, plaintext_len=%d", pktNum, len(plaintext)) + // Check type byte (0x00 = Audio, 0x01 = Ping) + if len(plaintext) < 1 { + return + } + msgType := plaintext[0] + plaintext = plaintext[1:] + + if msgType == 0x01 { + // Ping response — just a timestamp, no action needed. + log.Debug("UDP15 #%d: ping response", pktNum) + return + } + if msgType != 0x00 { + log.Debug("UDP15 #%d: unknown message type 0x%02x", pktNum, msgType) + return + } + // Parse MumbleUDP.Audio protobuf. session, frameNum, opusData, terminator := decodeUDPAudio(plaintext)