def user_left(self, server, line): """ Handles PARTs """ words = line.split() nick = Address(words[0]).nick channel = self.lower(words[2]) if self.eq(nick, self.nick): del self.channels[channel] else: self.channels[channel].remove(nick)
def user_quit(self, server, line): """ Handles QUITs""" words = line.split() nick = Address(words[0]).nick for i in self.channels: if self.isIn(nick, self.channels[i]): self.channels[i].remove( nick ) # Note: May error. This might indicate a logic error or a bastard server.
def respond(self, line, method="PRIVMSG"): """ Create a context manager which parses the input words and responds in PM if messaged, else in the channel. """ if line[2].startswith("#"): target = line[2] else: target = Address(line[0]).nick return PrinterBuffer(self, target, method)
def user_nickchange(self, server, line): """ Handles NICKs """ words = line.split() nick = Address(words[0]).nick newnick = words[2][1:] for i in self.channels: if nick in self.channels[i]: self.channels[i].remove(nick) self.channels[i].add(newnick) if self.eq(nick, self.nick): self.nick = newnick
def updateKnown(self, server, y) -> "privmsg": x = y.split(" ") newword = re.match( r":(%s[^\a]?\s*)?([^\s]+)( i|')s a( real)? word(!| FORCE| LOCK)?.*" % server.nick, " ".join(x[3:]), flags=re.IGNORECASE) notword = re.match( r":(%s[^\a]?\s*)?([^\s]+)( isn't| is not|'s not) a( real)? word(!| FORCE| LOCK)?.*" % server.nick, " ".join(x[3:]), flags=re.IGNORECASE) match = newword or notword if not match: return if not server.is_admin( x[0]) and match.group(2).lower() in self.locked: server.message("F**K OFF.", x[2] if x[2][0] == "#" else Address(x[0]).nick) return if newword: word = newword.group(2) if word.lower() == "that": word = self.last if server.is_admin(x[0]) and newword.group(5): self.locked.append(word.lower()) self.saveLocked() if not word: server.message( "What is?", x[2] if x[2][0] == "#" else Address(x[0]).nick) elif self.dictionary.check(word): server.message( "I KNOW.", x[2] if x[2][0] == "#" else Address(x[0]).nick) else: self.dictionary.add(word) server.message( "Oh, sorry, I'll remember that.", x[2] if x[2][0] == "#" else Address(x[0]).nick) self.last_correction = word if notword: word = notword.group(2) if word.lower() == "that": word = self.last_correction if server.is_admin(x[0]) and notword.group(5): self.locked.append(word.lower()) self.saveLocked() if self.dictionary.is_added(word): self.dictionary.remove(word) server.message( "Okay then.", x[2] if x[2][0] == "#" else Address(x[0]).nick) else: server.message( "I DON'T CARE.", x[2] if x[2][0] == "#" else Address(x[0]).nick)
def user_join(self, server, line): """ Handles JOINs """ words = line.split() nick = Address(words[0]).nick channel = self.lower(words[2][1:]) if self.eq(nick, self.nick): self.channels[channel] = set() self.sendline( "WHO %s" % words[2]) # TODO: replace with connection object shit. self.sendline("MODE %s" % words[2]) for i in self.server_settings["CHANMODES"].split(",")[0]: # Lists self.sendline("MODE %s %s" % (words[2][1:], i)) else: self.channels[channel].add(nick)
def update_active_kick(self, server, line) -> "kick": words = line.split(" ", 4) kicker = Address(words[0]).nick nick = words[3] lnick = server.lower(nick) channel = server.lower(words[2]) push = {"type": "note", "title": "* %s has kicked %s from %s" % (kicker, nick, words[2]), "body": cstrip(words[-1])} if (channel in self.watchers and channel in self.config["accounts"]): # Update watchers acc = self.config["accounts"][channel] watchers = self.watchers[channel] for email in watchers: push["email"] = email with self.pushlock: self.skip.add(self.push(push, acc["token"])) if lnick in self.active[channel]: del self.active[channel][lnick]
def update_active_part(self, server, line) -> "part": words = line.split(" ", 3) nick = Address(words[0]).nick lnick = server.lower(nick) channel = server.lower(words[2]) push = {"type": "note", "title": "* %s has left the channel" % nick, "body": cstrip(words[-1])} if lnick in self.active[channel]: if (time.time() - self.active[channel][lnick] < ACTIVITY_TIMEOUT and channel in self.watchers and channel in self.config["accounts"]): # Update watchers acc = self.config["accounts"][channel] watchers = self.watchers[channel] for email in watchers: push["email"] = email with self.pushlock: self.skip.add(self.push(push, acc["token"])) del self.active[channel][lnick]
def trigger(self, server, line) -> "ALL": words = line.split(" ") if not self.ipscan: return ips = re.findall( r"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[-.]){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)", words[0]) if not ips: return ip = "".join(x if x.isdigit() else "." for x in ips[0]) if ip in self.known: return self.known[server.lower(Address(words[0]).nick)] = ip self.savestate()
def update_active_join(self, server, line) -> "join": words = line.split(" ", 3) nick = Address(words[0]).nick lnick = server.lower(nick) channel = server.lower(cstrip(words[2])) push = {"type": "note", "title": "* %s has joined the channel" % nick} if ((lnick not in self.rejoin_ignore.setdefault(channel, {}) or (time.time() - self.rejoin_ignore[channel][lnick]) > ACTIVITY_TIMEOUT) and channel in self.watchers and channel in self.config["accounts"]): # Update watchers acc = self.config["accounts"][channel] watchers = self.watchers[channel] for email in watchers: push["email"] = email with self.pushlock: self.skip.add(self.push(push, acc["token"])) if lnick in self.rejoin_ignore[channel]: del self.rejoin_ignore[channel][lnick] self.active.setdefault(channel, {})[lnick] = time.time()
def update_active_quit(self, server, line) -> "quit": words = line.split(" ", 2) nick = Address(words[0]).nick lnick = server.lower(nick) requires_updates = [] for channel in self.active: if lnick in self.active[channel]: if time.time() - self.active[channel][lnick] < ACTIVITY_TIMEOUT: requires_updates.append(channel) else: self.rejoin_ignore.setdefault(channel, {})[lnick] = time.time() del self.active[channel][lnick] # Update watchers push = {"type": "note", "title": "* %s has disconnected" % nick, "body": cstrip(words[-1])} for channel in requires_updates: ctx = server.lower(channel) if ctx in self.watchers and ctx in self.config["accounts"]: acc = self.config["accounts"][ctx] watchers = self.watchers[ctx] for email in watchers: push["email"] = email with self.pushlock: self.skip.add(self.push(push, acc["token"]))
def update_active_nick(self, server, line) -> "nick": words = line.split(" ", 2) nick = Address(words[0]).nick lnick = server.lower(nick) newnick = words[2] requires_updates = [] for channel in self.active: if lnick in self.active[channel]: if time.time() - self.active[channel][lnick] < ACTIVITY_TIMEOUT: requires_updates.append(channel) del self.active[channel][lnick] self.active[channel][server.lower(newnick)] = time.time() # Update watchers push = {"type": "note", "title": "* %s is now known as %s" % (nick, newnick)} for channel in requires_updates: ctx = server.lower(channel) if ctx in self.watchers and ctx in self.config["accounts"]: acc = self.config["accounts"][ctx] watchers = self.watchers[ctx] for email in watchers: push["email"] = email with self.pushlock: self.skip.add(self.push(push, acc["token"]))
def joined(self, server, line): words = line.split() nick = server.lower(Address(words[0]).nick) if nick not in server.registered: server.registered[nick] = False
def part(self, server, line): words = line.split() channel = server.lower(words[2]) nick = Address(words[0]).nick if all(not server.isIn(nick, users) for chan, users in server.channels.items() if not server.eq(channel, chan)): del server.registered[server.lower(nick)]
def quit(self, server, line): words = line.split() del server.registered[server.lower(Address(words[0]).nick)]
def join_check(self, server, line) -> "join": hostmask, method, context = line.split() address = Address(hostmask) channel = context[1:] if server.lower(address.nick) in self.reminders: self.send_messages(address.nick, channel)
def trigger(self, server, line): printer = server.printer x = line.split() channel = x[2].lower() nick = Address(x[0]).nick if not channel.startswith("#"): return elif channel in self.games and not self.games[channel].failed(): game = self.games[channel] with game.lock: if x[3].lower() == ":!join": if game.addPlayer(nick): printer.message( CAHPREFIX + "%s is our %s player." % (nick, ordinal(len(game.players) - bool(game.rando))), channel) if game.state == "collect": printer.message( "01│00,01 %s " % re.sub("[*^]_+", "_______", game.question), nick, "NOTICE") player = game.getPlayer(nick) game.repopulate(player) player.printHand(printer) else: printer.message( CAHPREFIX + "%s is already in the game." % nick, channel) elif x[3].lower() == ":!score": game.printplayers() elif x[3].lower() == ":!rando": if game.rando: printer.message( CAHPREFIX + "Rando Cardrissian is now out of the game.", channel) game.removeRando() else: printer.message( CAHPREFIX + "Rando Cardrissian is now playing.", channel) game.addRando() elif game.state == "signups" and x[3][1:].lower() in [ "!start", "!go", "!begin" ]: if len(game.players) > 2 and nick in [ i.nick for i in game.players ]: game.start() elif len(game.players) > 2: printer.message( CAHPREFIX + "I don't care what you think.", channel) else: printer.message( CAHPREFIX + "The game can't begin without at least 3 players.", channel) elif nick in [i.nick for i in game.players]: player = game.getPlayer(nick) if x[3].lower() == ":!discard" and player.points: args = " ".join(x[4:]) args = args.replace(",", " ") cards = sorted({ int(i) for i in args.split() if i.isdigit() and 1 <= int(i) <= len(player.hand) })[::-1] if len(cards) > game.maxcards / 2: printer.message( CAHPREFIX + "You can't discard more than half your hand at once.", nick, "NOTICE") else: for i in cards: game.answers.append(player.hand.pop(i - 1)) random.shuffle(game.answers) game.repopulate(player) player.points -= 1 player.printHand(printer) elif x[3].lower() == ":!hand": game.repopulate(player) player.printHand(printer) elif x[3].lower() in [":!choose", ":!pick"]: if player != game.czar and game.state == "collect": args = line.split(" ", 4)[-1] if "," in args and game.bets: if player.points: args, bet = args.split(",") bet = [int(i) for i in bet.strip().split()] else: printer.message( CAHPREFIX + "Not enough points to bet, sorry.", nick, "NOTICE") else: bet = [] args = [int(i) for i in args.split()] if all((bet + args).count(i) == 1 and 1 <= i <= len(player.hand) for i in bet + args) and ( len(args) == game.numcards() and len(bet) in [game.numcards(), 0]): player.setResponses(args) player.setBet(bet) printer.message( CAHPREFIX + "00,01 Response 01,00 %s " % game.substitute(player.responses), nick, "NOTICE") if bet: printer.message( CAHPREFIX + "01,00 Backup 01,00 %s " % game.substitute(player.bets), nick, "NOTICE") else: printer.message( CAHPREFIX + "Invalid arguments.", nick, "NOTICE") if not [ i for i in game.players if i.responses is None and i != game.czar ]: game.judge() elif player == game.czar and game.state == "judge": if x[4].isdigit() and 1 <= int(x[4]) <= len( game.order) and game.ranked == False: # Logging try: game.logwinner([int(x[4]) - 1], self.expansiondir) except sqlite3.ProgrammingError: sys.stderr.write("sqlite3 error\n") game.pick(int(x[4])) elif len(x[4:]) == min( len(game.players) - 2, 3) and all([ str.isdigit and 1 <= int(n) <= len(game.order) and x[4:].count(n) == 1 for n in x[4:] ]) and game.ranked == True: # Logging try: game.logwinner([int(i) - 1 for i in x[4:]], self.expansiondir) except sqlite3.ProgrammingError: sys.stderr.write("sqlite3 error\n") game.pick([int(i) for i in x[4:]]) else: printer.message( CAHPREFIX + "Invalid arguments.", nick, "NOTICE") elif x[3].lower() in [":!leave", ":!quit"]: printer.message( CAHPREFIX + "%s is quitting the game, quitter." % player.nick, channel) game.remove(player) if game.state != 'failed': if player == game.czar: game.czar = game.players.pop() game.players.insert(0, game.czar) if game.czar == game.rando: game.czar = game.players.pop() game.players.insert(0, game.czar) game.czar.responses = None game.czar.bets = None if game.state == "judge": game.state = "collect" printer.message( CAHPREFIX + "%s is the new czar." % game.czar.nick, channel) game.judge() elif x[3].lower() == ":!score": game.printplayers() elif x[3].lower() in [":!cah", ":!cards"]: args = self.parseSettings(line.split(" ", 4)[-1]) self.games[channel] = CardsAgainstHumanity(printer, channel, **args) deck = ("(%s) " % self.games[channel].deck ) if self.games[channel].deck is not None else "" printer.message( "01│00,01 Cards Against Humanity %s will begin in a minute. Want to !join us?" % deck, channel) threading.Timer(150, self.games[channel].start).start()
def nick(self, server, line): words = line.split() del server.registered[server.lower(Address(words[0]).nick)] server.registered[server.lower(words[2][1:])] = False