museun / twitchchat

interface to the irc portion of Twitch's chat
Apache License 2.0
103 stars 23 forks source link

infinite `waiting for the connection to be ready` when using only `Capability::Tags` #209

Closed Chronophylos closed 4 years ago

Chronophylos commented 4 years ago

I'm trying to connect by only setting Capability::Tags.

The log when I try to run the following code:

[DEBUG twitchchat::runner::async_runner] connecting
[DEBUG twitchchat::runner::async_runner] connection established
[DEBUG twitchchat::runner::async_runner] registering
[DEBUG twitchchat::runner::async_runner] registered
[DEBUG twitchchat::runner::async_runner] waiting for the connection to be ready
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv CAP * ACK :twitch.tv/tags\r\n
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 001 chronophylos :Welcome, GLHF!\r\n
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 002 chronophylos :Your host is tmi.twitch.tv\r\n
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 003 chronophylos :This server is rather new\r\n
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 004 chronophylos :-\r\n
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 375 chronophylos :-\r\n
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 372 chronophylos :You are in a maze of twisty passages, all alike.\r\n
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 376 chronophylos :>\r\n

It hangs at this point and does not continue.

This is the code I used:

let connector = connector::SmolConnectorTls::twitch();
let user_config = UserConfig::builder()
    .name(env!("USERNAME"))
    .token(env!("TOKEN"))
    .capabilities(&[Capability::Tags])
    .build()
    .unwrap();
AsyncRunner::connect(connector, &user_config).await.unwrap();

When I remove the .capabilities(&[Capability::Tags]) line or use .anonymous() instead of providing a name and token it works:

[DEBUG twitchchat::runner::async_runner] connecting
[DEBUG twitchchat::runner::async_runner] connection established
[DEBUG twitchchat::runner::async_runner] registering
[DEBUG twitchchat::runner::async_runner] registered
[DEBUG twitchchat::runner::async_runner] waiting for the connection to be ready
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 001 chronophylos :Welcome, GLHF!\r\n
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 002 chronophylos :Your host is tmi.twitch.tv\r\n
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 003 chronophylos :This server is rather new\r\n
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 004 chronophylos :-\r\n
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 375 chronophylos :-\r\n
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 372 chronophylos :You are in a maze of twisty passages, all alike.\r\n
[TRACE twitchchat::decoder::r#async] < :tmi.twitch.tv 376 chronophylos :>\r\n
[DEBUG twitchchat::runner::async_runner] connection is ready: Basic { name: "chronophylos", caps: Capabilities { membership: false, commands: false, tags: false, unknown: {} } }
museun commented 4 years ago

This took a bit more effort than normal. Twitch has inconsistent documentation on this behavior, but I figured out these inconsistencies and corrected.

Twitch says you'll get a GlobalUserState if you send the Tags capability. This is actually false. They send GlobalUserState if you send Commands and atleast one other capability. If you send Commands and Membership but not Tags you'll, surprisingly, get a GlobalUserState without any Tags attached.

Some fun things: sending Commands alone doesn't trigger this. Neither does sending Tags and Membership sans Commands. I ended up figuring out which permutations cause this and handle it.

If you send just Tags this crate will give you a Basic identity with tags flagged -- which may be unexpected but everything else should just work.

museun commented 4 years ago

The changes are in 0.14.1. I noticed you're on 0.13.0 (because of no unwrap on Connector::twitch()). The only real public changes between 0.13.0 and 0.14.0 (and subseq. 0.14.1) is just handling the error returned by the 'twitch' method.

Previously DNS resolution could fail and that would panic. I had to bump the semver because that very public function really needed to return a result.

Chronophylos commented 4 years ago

I was using 0.14.0. See #211