<commit_before>package gumble

import (
	"bytes"
	"errors"

	"code.google.com/p/goprotobuf/proto"
	"github.com/bontibon/gopus"
	"github.com/bontibon/gumble/gumble/MumbleProto"
	"github.com/bontibon/gumble/gumble/varint"
)

type handlerFunc func(*Client, []byte) error

var (
	errUnimplementedHandler = errors.New("the handler has not been implemented")
	errIncompleteProtobuf   = errors.New("protobuf message is missing a required field")
	errInvalidProtobuf      = errors.New("protobuf message has an invalid field")
)

var handlers map[uint16]handlerFunc

func init() {
	handlers = map[uint16]handlerFunc{
		0:  handleVersion,
		1:  handleUdpTunnel,
		2:  handleAuthenticate,
		3:  handlePing,
		4:  handleReject,
		5:  handleServerSync,
		6:  handleChannelRemove,
		7:  handleChannelState,
		8:  handleUserRemove,
		9:  handleUserState,
		10: handleBanList,
		11: handleTextMessage,
		12: handlePermissionDenied,
		13: handleAcl,
		14: handleQueryUsers,
		15: handleCryptSetup,
		16: handleContextActionModify,
		17: handleContextAction,
		18: handleUserList,
		19: handleVoiceTarget,
		20: handlePermissionQuery,
		21: handleCodecVersion,
		22: handleUserStats,
		23: handleRequestBlob,
		24: handleServerConfig,
		25: handleSuggestConfig,
	}
}

func handleVersion(client *Client, buffer []byte) error {
	var packet MumbleProto.Version
	if err := proto.Unmarshal(buffer, &packet); err != nil {
		return err
	}

	var version Version
	if packet.Version != nil {
		version.version = *packet.Version
	}
	if packet.Release != nil {
		version.release = *packet.Release
	}
	if packet.Os != nil {
		version.os = *packet.Os
	}
	if packet.OsVersion != nil {
		version.osVersion = *packet.OsVersion
	}
	client.server.version = version

	return nil
}

func handleUdpTunnel(client *Client, buffer []byte) error {
	if client.audio == nil || !client.audio.IsSink() {
		return nil
	}

	reader := bytes.NewReader(buffer)
	var bytesRead int64

	var audioType byte
	var audioTarget byte
	var sequence int64
	var user *User
	var audioLength int

	// Header byte
	if typeTarget, err := varint.ReadByte(reader); err != nil {
		return err
	} else {
		audioType = (typeTarget >> 5) & 0x7
		audioTarget = typeTarget & 0x1F
		// Opus only
		if audioType != 4 {
			return errInvalidProtobuf
		}
		bytesRead += 1
	}

	// Session
	if session, n, err := varint.ReadFrom(reader); err != nil {
		return err
	} else {
		user = client.users[uint(session)]
		if user == nil {
			return errInvalidProtobuf
		}
		bytesRead += n
	}

	// Sequence
	if seq, n, err := varint.ReadFrom(reader); err != nil {
		return err
	} else {
		sequence = seq
		bytesRead += n
	}

	// Length
	if length, n, err := varint.ReadFrom(reader); err != nil {
		return err
	} else {
		audioLength = int(length)
		if audioLength > reader.Len() {
			return errInvalidProtobuf
		}
		bytesRead += n
	}

	opus := buffer[bytesRead : bytesRead+int64(audioLength)]
	if pcm, err := user.decoder.Decode(opus, 1920, false); err != nil {
		return err
	} else {
		_ = audioTarget
		packet := AudioPacket{
			Sender:   user,
			Sequence: int(sequence),
			Pcm:      pcm,
		}
		client.audio.incoming <- packet
	}
	return nil<commit_msg>increase maximum audio frame size<commit_after>package gumble

import (
	"bytes"
	"errors"

	"code.google.com/p/goprotobuf/proto"
	"github.com/bontibon/gopus"
	"github.com/bontibon/gumble/gumble/MumbleProto"
	"github.com/bontibon/gumble/gumble/varint"
)

type handlerFunc func(*Client, []byte) error

var (
	errUnimplementedHandler = errors.New("the handler has not been implemented")
	errIncompleteProtobuf   = errors.New("protobuf message is missing a required field")
	errInvalidProtobuf      = errors.New("protobuf message has an invalid field")
)

var handlers map[uint16]handlerFunc

func init() {
	handlers = map[uint16]handlerFunc{
		0:  handleVersion,
		1:  handleUdpTunnel,
		2:  handleAuthenticate,
		3:  handlePing,
		4:  handleReject,
		5:  handleServerSync,
		6:  handleChannelRemove,
		7:  handleChannelState,
		8:  handleUserRemove,
		9:  handleUserState,
		10: handleBanList,
		11: handleTextMessage,
		12: handlePermissionDenied,
		13: handleAcl,
		14: handleQueryUsers,
		15: handleCryptSetup,
		16: handleContextActionModify,
		17: handleContextAction,
		18: handleUserList,
		19: handleVoiceTarget,
		20: handlePermissionQuery,
		21: handleCodecVersion,
		22: handleUserStats,
		23: handleRequestBlob,
		24: handleServerConfig,
		25: handleSuggestConfig,
	}
}

func handleVersion(client *Client, buffer []byte) error {
	var packet MumbleProto.Version
	if err := proto.Unmarshal(buffer, &packet); err != nil {
		return err
	}

	var version Version
	if packet.Version != nil {
		version.version = *packet.Version
	}
	if packet.Release != nil {
		version.release = *packet.Release
	}
	if packet.Os != nil {
		version.os = *packet.Os
	}
	if packet.OsVersion != nil {
		version.osVersion = *packet.OsVersion
	}
	client.server.version = version

	return nil
}

func handleUdpTunnel(client *Client, buffer []byte) error {
	if client.audio == nil || !client.audio.IsSink() {
		return nil
	}

	reader := bytes.NewReader(buffer)
	var bytesRead int64

	var audioType byte
	var audioTarget byte
	var sequence int64
	var user *User
	var audioLength int

	// Header byte
	if typeTarget, err := varint.ReadByte(reader); err != nil {
		return err
	} else {
		audioType = (typeTarget >> 5) & 0x7
		audioTarget = typeTarget & 0x1F
		// Opus only
		if audioType != 4 {
			return errInvalidProtobuf
		}
		bytesRead += 1
	}

	// Session
	if session, n, err := varint.ReadFrom(reader); err != nil {
		return err
	} else {
		user = client.users[uint(session)]
		if user == nil {
			return errInvalidProtobuf
		}
		bytesRead += n
	}

	// Sequence
	if seq, n, err := varint.ReadFrom(reader); err != nil {
		return err
	} else {
		sequence = seq
		bytesRead += n
	}

	// Length
	if length, n, err := varint.ReadFrom(reader); err != nil {
		return err
	} else {
		audioLength = int(length)
		if audioLength > reader.Len() {
			return errInvalidProtobuf
		}
		bytesRead += n
	}

	opus := buffer[bytesRead : bytesRead+int64(audioLength)]
	if pcm, err := user.decoder.Decode(opus, 4800, false); err != nil {
		return err
	} else {
		_ = audioTarget
		packet := AudioPacket{
			Sender:   user,
			Sequence: int(sequence),
			Pcm:      pcm,
		}
		client.audio.incoming <- packet
	}
	return nil
{'fraction_non_alphanumeric': 0.11191677175283733, 'fraction_numerical': 0.01986128625472888, 'mean_word_length': 3.696521095484826, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1411824', 'n_tokens_mistral': 2425, 'n_tokens_neox': 2182, 'n_words': 565}