Пример #1
0
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
}
Пример #2
0
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
}