meebey / SmartIrc4net

IRC C# Library
http://www.meebey.net/projects/smartirc4net/
Other
127 stars 52 forks source link

How to get the `IrcClient` to delay long enough to identify a nick before attempting to join a channel? #54

Open Rouneq opened 4 weeks ago

Rouneq commented 4 weeks ago

Too much code to include here, I've uploaded as a LINQPad share

https://share.linqpad.net/bfrmhwpe.linq

Trying to get the code to identify a nick prior to joining a channel. Nothing I do seems to get it to work. I can comment out the RfcJoin call and manually join, but this defeats the purpose of writing the app in the first place.

With the call, the order of the displayed text is

Query Notice This nickname is registered and protected. If it is your nick, type "/msg NickServ IDENTIFY password". Otherwise, please choose a different nick. If you do not change within 1 minute, I will change your nick. Error Message [#IRC-Channel]: You need a registered nick to join that channel. Query Notice Password accepted - you are now recognized. Raw Message :NickServ MODE systemtrackr_test_bot :+r {UserModeChange}

The code is set to specifically wait for a response to the IDENTIFY message. And furthermore wait five seconds after this before attempting to join the channel.

What am I missing here?

Rouneq commented 3 weeks ago

Alright. It seems you just can't do anything until after Listen. Which leaves the question: How am I supposed to know when (programmatically) it's ok to attempt doing things like identifying a nick with the server?

meebey commented 3 weeks ago

Either you just delay your RfcJoin() with Thread.Sleep() for 2 seconds (quick and dirty) or you listen to the event that you get back when the NickServ identification was completed and then send the RfcJoin(). OnRawMessage allows you to hook into any response/message from the IRC servers.

You can also use Smuxi for inspiration, a fully featured IRC client that uses SmartIrc4net. It does the quick and dirty approach and expects the user to do

/msg NickServ IDENTIFY ...
/sleep 5
/join #restricted_channel

The /sleep calls Thread.Sleep() before calling RfcJoin()

In https://github.com/meebey/smuxi/blob/master/src/Engine-IRC/Protocols/Irc/IrcProtocolManager.cs#L3801 you can see an event-based approach that hooks into OnRegistered to send the NickServ command out.

Rouneq commented 3 weeks ago

Thread.Sleep is unhelpful here. Nothing happens to respond to until Listen is called. And once Listen is called, it prevents further code running on the thread. What's the recommended practice for listening on a separate thread?