package client import ( "encoding/binary" "log" "go-ts/pkg/protocol" ) func (c *Client) handleVoice(pkt *protocol.Packet) { // Parse Voice Header (Server -> Client) // VID(2) + CID(2) + Codec(1) + Data if len(pkt.Data) < 5 { return } vid := binary.BigEndian.Uint16(pkt.Data[0:2]) // cid := binary.BigEndian.Uint16(pkt.Data[2:4]) // Talking client ID (not needed for echo) codec := pkt.Data[4] voiceData := pkt.Data[5:] log.Printf("Voice Packet received. VID=%d, Codec=%d, Size=%d", vid, codec, len(voiceData)) // Build echo packet (Client -> Server) // Format: VID(2) + Codec(1) + Data echoData := make([]byte, 2+1+len(voiceData)) binary.BigEndian.PutUint16(echoData[0:2], vid) echoData[2] = codec copy(echoData[3:], voiceData) echoPkt := protocol.NewPacket(protocol.PacketTypeVoice, echoData) echoPkt.Header.PacketID = pkt.Header.PacketID // Use same ID for voice echoPkt.Header.ClientID = c.ClientID // Encrypt voice packet with SharedSecret if c.Handshake != nil && len(c.Handshake.SharedIV) > 0 { crypto := &protocol.CryptoState{ SharedIV: c.Handshake.SharedIV, SharedMac: c.Handshake.SharedMac, GenerationID: 0, } key, nonce := crypto.GenerateKeyNonce(&echoPkt.Header, true) // Meta for Client->Server: PID(2) + CID(2) + PT(1) meta := make([]byte, 5) binary.BigEndian.PutUint16(meta[0:2], echoPkt.Header.PacketID) binary.BigEndian.PutUint16(meta[2:4], echoPkt.Header.ClientID) meta[4] = echoPkt.Header.Type encData, mac, err := protocol.EncryptEAX(key, nonce, meta, echoPkt.Data) if err != nil { log.Printf("Voice encryption failed: %v", err) return } echoPkt.Data = encData copy(echoPkt.Header.MAC[:], mac) } else { // If no encryption keys, use SharedMac if available, otherwise HandshakeMac if c.Handshake != nil && len(c.Handshake.SharedMac) > 0 { copy(echoPkt.Header.MAC[:], c.Handshake.SharedMac) } else { echoPkt.Header.MAC = protocol.HandshakeMac } } c.Conn.SendPacket(echoPkt) }