@@ -205,7 +205,18 @@ def updateusers(bot):
205205 return "Updating all channel data"
206206
207207
208- @hook .irc_raw ('JOIN' )
208+ @hook .irc_raw (['JOIN' , 'MODE' ], singlethread = True )
209+ def on_join_mode (chan , nick , user , host , conn , irc_command , irc_paramlist ):
210+ """
211+ Both JOIN and MODE are handled in one hook with Hook:singlethread=True
212+ to ensure they are handled in order, avoiding a possible race condition
213+ """
214+ if irc_command == 'JOIN' :
215+ return on_join (chan , nick , user , host , conn )
216+ elif irc_command == 'MODE' :
217+ return on_mode (chan , irc_paramlist , conn )
218+
219+
209220def on_join (chan , nick , user , host , conn ):
210221 if chan .startswith (':' ):
211222 chan = chan [1 :]
@@ -220,43 +231,6 @@ def on_join(chan, nick, user, host, conn):
220231 user_chans [chan .casefold ()] = memb_data
221232
222233
223- @hook .irc_raw ('PART' )
224- def on_part (chan , nick , conn ):
225- if chan .startswith (':' ):
226- chan = chan [1 :]
227-
228- channels = conn .memory ["chan_data" ]
229- nick_cf = nick .casefold ()
230- if nick_cf == conn .nick .casefold ():
231- try :
232- del channels [chan ]
233- except KeyError :
234- pass
235- else :
236- chan_data = channels [chan ]
237- try :
238- del chan_data ["users" ][nick_cf ]
239- except KeyError :
240- pass
241-
242-
243- @hook .irc_raw ('KICK' )
244- def on_kick (chan , target , conn ):
245- on_part (chan , target , conn )
246-
247-
248- @hook .irc_raw ('QUIT' )
249- def on_quit (nick , conn ):
250- nick_cf = nick .casefold ()
251- users = conn .memory ["users" ]
252- if nick_cf in users :
253- user = users [nick_cf ]
254- for memb in user .get ("channels" , {}).values ():
255- chan = memb ["chan" ]
256- chan ["users" ].pop (nick_cf )
257-
258-
259- @hook .irc_raw ('MODE' )
260234def on_mode (chan , irc_paramlist , conn ):
261235 if chan .startswith (':' ):
262236 chan = chan [1 :]
@@ -303,6 +277,42 @@ def on_mode(chan, irc_paramlist, conn):
303277 memb ["status" ].remove (status )
304278
305279
280+ @hook .irc_raw ('PART' )
281+ def on_part (chan , nick , conn ):
282+ if chan .startswith (':' ):
283+ chan = chan [1 :]
284+
285+ channels = conn .memory ["chan_data" ]
286+ nick_cf = nick .casefold ()
287+ if nick_cf == conn .nick .casefold ():
288+ try :
289+ del channels [chan ]
290+ except KeyError :
291+ pass
292+ else :
293+ chan_data = channels [chan ]
294+ try :
295+ del chan_data ["users" ][nick_cf ]
296+ except KeyError :
297+ pass
298+
299+
300+ @hook .irc_raw ('KICK' )
301+ def on_kick (chan , target , conn ):
302+ on_part (chan , target , conn )
303+
304+
305+ @hook .irc_raw ('QUIT' )
306+ def on_quit (nick , conn ):
307+ nick_cf = nick .casefold ()
308+ users = conn .memory ["users" ]
309+ if nick_cf in users :
310+ user = users [nick_cf ]
311+ for memb in user .get ("channels" , {}).values ():
312+ chan = memb ["chan" ]
313+ chan ["users" ].pop (nick_cf )
314+
315+
306316@hook .irc_raw ('NICK' )
307317def on_nick (nick , irc_paramlist , conn ):
308318 users = conn .memory ["users" ]
0 commit comments