Pycord-Development / pycord

Pycord is a modern, easy to use, feature-rich, and async ready API wrapper for Discord written in Python
https://docs.pycord.dev
MIT License
2.7k stars 458 forks source link

nacl.exceptions.CryptoError: Decryption failed. Ciphertext failed verification #2033

Open TheoBoyer opened 1 year ago

TheoBoyer commented 1 year ago

Summary

I'm using a bot based on pycord during long conversations on discord. Sometimes (it occur very rarely tho) a nacl.exceptions.CryptoError is raised, and i have no way to handle it other than monkey patch

Reproduction Steps

Well it occur so rarely, it's hard to reproduce... It happens often after the bot is being listening for a long time.

Minimal Reproducible Code

import discord
from discord.ext import commands
...

class STTSink(discord.sinks.WaveSink):
    def __init__(self, discussion: Discussion, get_name: Callable, **kwargs):
        self.discussion = discussion
        self.get_name = get_name
        super().__init__(**kwargs)

    def write(self, data, user):
        user = self.get_name(user)
        self.discussion.audio_sample(user, data)

class STTManager:
    def __init__(self, vc: discord.VoiceClient, guild: discord.Guild):
        self.guild = guild
        self.vc = vc
        self.transcription = Discussion()
        self.sink = STTSink(discussion=self.transcription, get_name=self.get_name)

    async def on_finish(self, sink: discord.sinks, channel: discord.TextChannel, *args):  # Our voice client already passes these in.
        if sink.vc.recording:  # If we're not recording, we're stopping the decoder.
            await sink.vc.stop_recording()
        await sink.vc.disconnect()  # Disconnect from the voice channel.
        print("Disconnected from voice channel.")
        #await channel.send(f"Merci pour l'invitation !")

    def start(self):
        self.vc.start_recording(
            self.sink,
            self.on_finish,
            self.vc.channel
        )
        self.transcription.start()

    def stop(self):
        print("Stopping recording...")
        if self.vc.recording:
            self.vc.stop_recording()
        else:
            self.vc.decoder.stop()
        print("Stopped recording.")
        self.transcription.stop()

TOKEN = open("token.txt", "r").read().strip()
intents = discord.Intents.default()
# Privileged message content intent
intents.message_content = True
# Guild members
intents.members = True

print("loading bot...")
bot = commands.Bot(intents=intents, command_prefix="/")
connections = {}

@bot.event
async def on_ready():
    print("Bot is ready")

@bot.command()
async def start(ctx: discord.ext.commands.Context):
    voice = ctx.author.voice
    # Check if user is in a voice channel
    if not voice:
        # Reply to the user with a message
        return await ctx.reply("Tu n'es pas dans un channel vocal !")

    vc = await voice.channel.connect()
    manager = STTManager(vc, ctx.guild)
    connections.update({ctx.guild.id: manager})
    try:
        manager.start()
    except TranscriptionNotAvailableError:
        manager.stop()
        await vc.disconnect()
        return await ctx.reply("Transcription not available")
    await ctx.reply(f"Starting transcription")

@bot.command()
async def stop(ctx):
    if ctx.guild.id in connections:  # Check if the guild is in the cache.
        manager = connections[ctx.guild.id]
        manager.stop()
        del connections[ctx.guild.id]  # Remove the guild from the cache.
    else:
        await ctx.reply("Je ne suis pas en train d'enregistrer ici")  # Respond with this if we aren't recording.

if __name__ == "__main__":
    bot.run(TOKEN)

Expected Results

That it doesn't crash

Actual Results

Exception in thread Thread-4: Traceback (most recent call last): File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner self.run() File "/usr/lib/python3.9/threading.py", line 892, in run self._target(*self._args, *self._kwargs) File "/home/ubuntu/.local/lib/python3.9/site-packages/discord/voice_client.py", line 814, in recv_audio self.unpack_audio(data) File "/home/ubuntu/.local/lib/python3.9/site-packages/discord/voice_client.py", line 696, in unpack_audio data = RawData(data, self) File "/home/ubuntu/.local/lib/python3.9/site-packages/discord/sinks/core.py", line 112, in init self.decrypted_data = getattr(self.client, f"decrypt{self.client.mode}")( File "/home/ubuntu/.local/lib/python3.9/site-packages/discord/voice_client.py", line 611, in _decrypt_xsalsa20_poly1305_lite return self.strip_header_ext(box.decrypt(bytes(data), bytes(nonce))) File "/home/ubuntu/.local/lib/python3.9/site-packages/nacl/secret.py", line 149, in decrypt plaintext = nacl.bindings.crypto_secretbox_open( File "/home/ubuntu/.local/lib/python3.9/site-packages/nacl/bindings/crypto_secretbox.py", line 79, in crypto_secretbox_open ensure( File "/home/ubuntu/.local/lib/python3.9/site-packages/nacl/exceptions.py", line 88, in ensure raise raising(args) nacl.exceptions.CryptoError: Decryption failed. Ciphertext failed verification

Intents

intents = discord.Intents.default() # Privileged message content intent intents.message_content = True # Guild members intents.members = True

System Information

Checklist

Additional Context

No response

Loukious commented 1 year ago

I'm having the same issue.

CrackerHax commented 4 months ago

I am getting this too with voice chat bot when it tries to speak. It is happening quite a lot when it opens the text-to-speech generated .wav file and tries to broadcast it to voice chat. It doesn't happen every single time but it happens often, maybe one in 20 times.

` File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner self.run()

File "/usr/lib/python3.9/threading.py", line 892, in run self._target(*self._args, **self._kwargs)

File "/home/user/.local/lib/python3.9/site-packages/discord/voice_client.py", line 863, in recv_audio self.unpack_audio(data)

File "/home/user/.local/lib/python3.9/site-packages/discord/voice_client.py", line 740, in unpack_audio data = RawData(data, self)

File "/home/user/.local/lib/python3.9/site-packages/discord/sinks/core.py", line 113, in init self.decrypted_data = getattr(self.client, f"decrypt{self.client.mode}")(

File "/home/user/.local/lib/python3.9/site-packages/discord/voice_client.py", line 611, in _decrypt_xsalsa20_poly1305_lite return self.strip_header_ext(box.decrypt(bytes(data), bytes(nonce)))

File "/home/user/.local/lib/python3.9/site-packages/nacl/secret.py", line 149, in decrypt plaintext = nacl.bindings.crypto_secretbox_open(

File "/home/user/.local/lib/python3.9/site-packages/nacl/bindings/crypto_secretbox.py", line 79, in crypto_secretbox_open ensure(

File "/home/user/.local/lib/python3.9/site-packages/nacl/exceptions.py", line 88, in ensure raise raising(*args)

nacl.exceptions.CryptoError: Decryption failed. Ciphertext failed verification`

amcglathery commented 1 month ago

I'm running into this same bug as well, in the same type of situation (shows up partway through long recordings and kills the recording)

It seems to be happening after I get this error and a subsequent reconnect:

2024-07-18 01:28:16,700 - discord.voice_client - ERROR - Disconnected from voice... Reconnecting in 1.04s.
Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/discord/voice_client.py", line 467, in poll_voice_ws
await self.ws.poll_event()
File "/usr/local/lib/python3.11/site-packages/discord/gateway.py", line 955, in poll_event
raise ConnectionClosed(self.ws, shard_id=None, code=self._close_code)
discord.errors.ConnectionClosed: Shard ID None WebSocket closed with 1006
2024-07-18 01:28:17,745 - discord.voice_client - INFO - The voice handshake is being terminated for Channel ID ##### (Guild ID ######)
2024-07-18 01:28:17,746 - discord.voice_client - INFO - Connecting to voice...
2024-07-18 01:28:17,746 - discord.voice_client - INFO - Starting voice handshake... (connection attempt 2)
2024-07-18 01:28:17,862 - discord.voice_client - INFO - Voice handshake complete. Endpoint found newark5620.discord.media
Exception in thread Thread-1721 (recv_audio):
Traceback (most recent call last):
File "/usr/local/lib/python3.11/threading.py", line 1045, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.11/threading.py", line 982, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/lib/python3.11/site-packages/discord/voice_client.py", line 863, in recv_audio
self.unpack_audio(data)
File "/usr/local/lib/python3.11/site-packages/discord/voice_client.py", line 740, in unpack_audio
data = RawData(data, self)
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/discord/sinks/core.py", line 115, in __init__
self.decrypted_data = getattr(self.client, f"_decrypt_{self.client.mode}")(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/discord/voice_client.py", line 611, in _decrypt_xsalsa20_poly1305_lite
return self.strip_header_ext(box.decrypt(bytes(data), bytes(nonce)))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/nacl/secret.py", line 149, in decrypt
plaintext = nacl.bindings.crypto_secretbox_open(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/nacl/bindings/crypto_secretbox.py", line 79, in crypto_secretbox_open
ensure(
File "/usr/local/lib/python3.11/site-packages/nacl/exceptions.py", line 88, in ensure
raise raising(*args)
nacl.exceptions.CryptoError: Decryption failed. Ciphertext failed verification
2024-07-18 01:29:17,932 - discord.gateway - WARNING - Shard ID None has stopped responding to the gateway. Closing and restarting.

Maybe the client mode or something else isn't getting re-initialized properly on reconnect?