func (c *Client) handleUdpTunnel(buffer []byte) error { reader := bytes.NewReader(buffer) var bytesRead int64 var audioType byte var audioTarget byte var user *User var audioLength int // Header byte typeTarget, err := varint.ReadByte(reader) if err != nil { return err } audioType = (typeTarget >> 5) & 0x7 audioTarget = typeTarget & 0x1F // Opus only // TODO: add handling for other packet types if audioType != audioCodecIDOpus { return errUnsupportedAudio } bytesRead++ // Session session, n, err := varint.ReadFrom(reader) if err != nil { return err } user = c.Users[uint32(session)] if user == nil { return errInvalidProtobuf } bytesRead += n decoder := user.decoder if decoder == nil { return nil } // Sequence sequence, n, err := varint.ReadFrom(reader) if err != nil { return err } bytesRead += n // Length length, n, err := varint.ReadFrom(reader) if err != nil { return err } // Opus audio packets set the 13th bit in the size field as the terminator. audioLength = int(length) &^ 0x2000 if audioLength > reader.Len() { return errInvalidProtobuf } audioLength64 := int64(audioLength) bytesRead += n raw := buffer[bytesRead : bytesRead+audioLength64] pcm, err := decoder.Decode(raw, AudioMaximumFrameSize) if err != nil { return err } event := AudioPacketEvent{ Client: c, } event.AudioPacket.Sender = user event.AudioPacket.Target = int(audioTarget) event.AudioPacket.Sequence = int(sequence) event.AudioPacket.PositionalAudioBuffer.AudioBuffer = pcm reader.Seek(audioLength64, 1) binary.Read(reader, binary.LittleEndian, &event.AudioPacket.PositionalAudioBuffer.X) binary.Read(reader, binary.LittleEndian, &event.AudioPacket.PositionalAudioBuffer.Y) binary.Read(reader, binary.LittleEndian, &event.AudioPacket.PositionalAudioBuffer.Z) c.audioListeners.OnAudioPacket(&event) return nil }
func handleUdpTunnel(c *Client, buffer []byte) error { reader := bytes.NewReader(buffer) var bytesRead int64 var audioType byte var audioTarget byte var user *User var audioLength int // Header byte typeTarget, err := varint.ReadByte(reader) if err != nil { return err } audioType = (typeTarget >> 5) & 0x7 audioTarget = typeTarget & 0x1F // Opus only if audioType != 4 { return errInvalidProtobuf } bytesRead++ // Session session, n, err := varint.ReadFrom(reader) if err != nil { return err } user = c.users[uint(session)] if user == nil { return errInvalidProtobuf } bytesRead += n // Sequence sequence, n, err := varint.ReadFrom(reader) if err != nil { return err } bytesRead += n // Length length, n, err := varint.ReadFrom(reader) if err != nil { return err } // Opus audio packets set the 13th bit in the size field as the terminator. audioLength = int(length) &^ 0x2000 if audioLength > reader.Len() { return errInvalidProtobuf } bytesRead += n opus := buffer[bytesRead : bytesRead+int64(audioLength)] pcm, err := user.decoder.Decode(opus, AudioMaximumFrameSize, false) if err != nil { return err } event := AudioPacketEvent{ Client: c, AudioPacket: AudioPacket{ Sender: user, Target: int(audioTarget), Sequence: int(sequence), Pcm: pcm, }, } c.audioListeners.OnAudioPacket(&event) return nil }