async def handle(self, p: Player) -> None: if p.silenced: log(f'{p} sent a message while silenced.', Ansi.YELLOW) return msg = self.msg.msg target = self.msg.target if target == '#spectator': if p.spectating: # we are spectating someone spec_id = p.spectating.id elif p.spectators: # we are being spectated spec_id = p.id else: return t = glob.channels[f'#spec_{spec_id}'] elif target == '#multiplayer': if not p.match: # they're not in a match? return t = p.match.chat else: t = glob.channels[target] if not t: log(f'{p} wrote to non-existent {target}.', Ansi.YELLOW) return if not p.priv & t.write_priv: log(f'{p} wrote to {target} with insufficient privileges.') return # limit message length to 2048 characters msg = f'{msg[:2045]}...' if msg[2048:] else msg cmd = (msg.startswith(glob.config.command_prefix) and await commands.process_commands(p, t, msg)) if cmd: # a command was triggered. if not cmd['hidden']: await t.send(p, msg) if 'resp' in cmd: await t.send(glob.bot, cmd['resp']) else: staff = glob.players.staff await t.send_selective(p, msg, staff - {p}) if 'resp' in cmd: await t.send_selective(glob.bot, cmd['resp'], staff | {p}) else: # no commands were triggered # check if the user is /np'ing a map. # even though this is a public channel, # we'll update the player's last np stored. if _match := regexes.now_playing.match(msg): # the player is /np'ing a map. # save it to their player instance # so we can use this elsewhere owo.. p.last_np = await Beatmap.from_bid(int(_match['bid'])) await t.send(p, msg)
if t.id == 1: # Target is Aika, check if message is a command. cmd = msg.startswith(glob.config.command_prefix) \ and await commands.process_commands(p, t, msg) if cmd and 'resp' in cmd: # Command triggered and there is a response to send. p.enqueue(await packets.sendMessage(t.name, cmd['resp'], client, t.id)) else: # No command triggered. if match := regexes.now_playing.match(msg): # User is /np'ing a map. # Save it to their player instance # so we can use this elsewhere owo.. p.last_np = await Beatmap.from_bid(int(match['bid'])) if p.last_np: if match['mods']: # [1:] to remove leading whitespace mods = Mods.from_np(match['mods'][1:]) else: mods = Mods.NOMOD if mods not in p.last_np.pp_cache: await p.last_np.cache_pp(mods) # Since this is a DM to the bot, we should # send back a list of general PP values. # TODO: !acc and !mods in commands to # modify these values :P _msg = [p.last_np.embed]
async def handle(self, p: Player) -> None: if p.silenced: log(f'{p} sent a message while silenced.', Ansi.LYELLOW) return # remove leading/trailing whitespace msg = self.msg.msg.strip() target = self.msg.target if target == '#spectator': if p.spectating: # we are spectating someone spec_id = p.spectating.id elif p.spectators: # we are being spectated spec_id = p.id else: return t_chan = glob.channels[f'#spec_{spec_id}'] elif target == '#multiplayer': if not p.match: # they're not in a match? return t_chan = p.match.chat else: t_chan = glob.channels[target] if not t_chan: log(f'{p} wrote to non-existent {target}.', Ansi.LYELLOW) return if p.priv & t_chan.write_priv != t_chan.write_priv: log(f'{p} wrote to {target} with insufficient privileges.') return # limit message length to 2k chars # perhaps this could be dangerous with !py..? if len(msg) > 2000: msg = f'{msg[:2000]}... (truncated)' p.enqueue( packets.notification('Your message was truncated\n' '(exceeded 2000 characters).')) cmd = (msg.startswith(glob.config.command_prefix) and await commands.process_commands(p, t_chan, msg)) if cmd: # a command was triggered. if not cmd['hidden']: t_chan.send(msg, sender=p) if 'resp' in cmd: t_chan.send_bot(cmd['resp']) else: staff = glob.players.staff t_chan.send_selective(msg=msg, sender=p, targets=staff - {p}) if 'resp' in cmd: t_chan.send_selective(msg=cmd['resp'], sender=glob.bot, targets=staff | {p}) else: # no commands were triggered # check if the user is /np'ing a map. # even though this is a public channel, # we'll update the player's last np stored. if match := regexes.now_playing.match(msg): # the player is /np'ing a map. # save it to their player instance # so we can use this elsewhere owo.. bmap = await Beatmap.from_bid(int(match['bid'])) if bmap: # parse mode_vn int from regex if match['mode_vn'] is not None: mode_vn = { 'Taiko': 1, 'CatchTheBeat': 2, 'osu!mania': 3 }[match['mode_vn']] else: # use beatmap mode if not specified mode_vn = bmap.mode.as_vanilla p.last_np = { 'bmap': bmap, 'mode_vn': mode_vn, 'timeout': time.time() + 300 # 5mins } else: # time out their previous /np p.last_np['timeout'] = 0 t_chan.send(msg, sender=p)
if t.id == 1: # Target is Aika, check if message is a command. cmd = msg.startswith(glob.config.command_prefix) \ and await commands.process_commands(p, t, msg) if cmd and 'resp' in cmd: # Command triggered and there is a response to send. p.enqueue(await packets.sendMessage(t.name, cmd['resp'], client, t.id)) else: # No command triggered. if match := regexes.now_playing.match(msg): # User is /np'ing a map. # Save it to their player instance # so we can use this elsewhere owo.. p.last_np = await Beatmap.from_bid(int(match['bid']), cache_pp=True) # Since this is a DM to the bot, we should # send back a list of general PP values. # TODO: !acc and !mods in commands to # modify these values :P msg = 'PP Values: ' + ' | '.join( f'{acc}%: {pp:.2f}pp' for acc, pp in zip((90, 95, 98, 99, 100), p.last_np.pp_values) ) if p.last_np else 'Could not find map.' p.enqueue(await packets.sendMessage(t.name, msg, client, t.id)) else: # Not Aika t.enqueue(await packets.sendMessage(client, msg, target, client_id))