def vidente_observa(self, bot, update, user_data): usuario = conseguir_usuario(update, user_data, self.jugadores) data_split = update.callback_query.data.split("*") id_victima, id_grupo = filter(lambda x: data_split.index(x) % 2 != 0, data_split) victima = self.jugadores[int(id_victima)] partida = self.partidas[int(id_grupo)] # Comprobamos si hay una partida if not partida: update.effective_message.edit_text(Lang.get_text("no_game_error")) update.callback_query.answer(Lang.get_text("no_game_error")) return # Nos aseguramos de que no haya votado ya if usuario.personaje.esta_noche_ha_visto_a: update.effective_message.edit_reply_markup( InlineKeyboardMarkup([[]])) return # Votamos y eliminamos el teclado para que no vuelva a votar. usuario.personaje.ve_a(victima) update.callback_query.answer(Lang.get_text("objetivo_seleccionado")) update.callback_query.message.edit_reply_markup( reply_markup=InlineKeyboardMarkup([[]]))
async def user_voice_moved(self, userid, before, after): user = self.members[userid] if after.id == self.afk_channel_id: user.lock.acquire() user.last_active_xp = None user.active_since = None user.lock.release() await self.print_admin_log( f'{User.get_at_mention(user.id)} ({ user.id }) moved from :sound:**{before.name}** and is now :zzz:**AFK**' ) if user.afk_mentions is True: await self.print_bot_message( Lang.get('USER_IS_AFK', self.lang).replace( cfg.get_value('TEXTFILE_USER_MENTION'), User.get_at_mention(user.id))) elif before.id == self.afk_channel_id: user.lock.acquire() user.last_active_xp = None user.active_since = datetime.datetime.now() user.lock.release() await self.print_admin_log( f'{User.get_at_mention(user.id)} ({user.id}) moved to :loud_sound:**{after.name}** and is no longer ~~**afk**~~' ) if user.afk_mentions is True: await self.print_bot_message( Lang.get('USER_NO_MORE_AFK', self.lang).replace( cfg.get_value('TEXTFILE_USER_MENTION'), User.get_at_mention(user.id))) else: await self.print_admin_log( f"{User.get_at_mention(user.id)} ({user.id}) moved from :sound:**{before.name}** to :loud_sound:**{after.name}**" )
async def cmd_mute(server, userid, channel, message): split_content = str(message.content).split() if len(message.mentions) < 1: await channel.send( f"{Lang.get('CMD_WRONG_SYNTAX', server.lang)}\r\n`{server.cmd_prefix}mute <users> (<time>)`" ) return False time = -1 if len(split_content) > len(message.mentions) + 1: time = int(split_content[-1]) for mention in message.mentions: if mention.id not in server.members.keys(): raise Exception(f'Cannot find user ({ mention.id }) in server') pass server.members[mention.id].lock.acquire() server.members[mention.id].muted = True if mention.voice is not None: await mention.edit(mute=True) if time > 0: server.members[mention.id].muted_until = datetime.now( ) + timedelta(seconds=time) await channel.send( Lang.get('CMD_MUTE_TIME', server.lang).format(User.get_at_mention(mention.id), User.get_at_mention(userid), time)) else: server.members[mention.id].muted_until = None await channel.send( Lang.get('CMD_MUTE', server.lang).format(User.get_at_mention(mention.id), User.get_at_mention(userid))) server.members[mention.id].lock.release() return True
def _iniciar_anuncios(self, bot, job): """Lanza los mensajes cuando todo el mundo despierda, anuncia los muertos.""" partida = job.context["partida"] chat = job.context["chat"] # Seleccionamos el mensaje apropiado para la cantidad de muertos # TODO: el mensaje contiene una lista de los jugadores if len(partida.esta_noche_muere) > 1: text = Lang.get_text_inserted( "amanece_plural", nombres_y_personajes=Lang.enumerar([ "%s (%s)" % (jugador.nombre_completo, jugador.personaje.nombre) for jugador in partida.esta_noche_muere ])) elif partida.esta_noche_muere: text = Lang.get_text_inserted( "amanece_singular", nombre=partida.esta_noche_muere[0].nombre_completo, personaje=partida.esta_noche_muere[0].personaje.nombre) else: text = Lang.get_text("amanece_ninguno") # Marcamos a los muertos y reiniciamos la lista for jugador in partida.esta_noche_muere: jugador.personaje.vivo = False partida.esta_noche_muere = [] # Enviamos el mensaje bot.send_message(chat_id=chat.id, text=text, parse_mode="Markdown", disable_web_page_preview=True) # TODO: ejecutar esto en un método a parte # Decimos a la vidente qué ha visto for jugador in partida.jugadores: if jugador.personaje.nombre == "La Vidente": if jugador.personaje.esta_noche_ha_visto_a: bot.send_message( jugador.id, Lang.get_text_inserted( "vidente_ha_visto", objetivo=jugador.personaje.esta_noche_ha_visto_a. nombre_completo, objetivo_personaje=jugador.personaje.nombre)) jugador.personaje.esta_noche_ha_visto_a = None # Solo hay una vidente break victoria = partida.comprobar_victoria() if victoria: bot.send_message(chat.id, "Han ganado %s" % victoria) if DEBUGGING: bot.send_message( chat_id=job.context["chat"].id, text="lOS ANUNCIOS se ha inciado correctamente lol")
async def cmd_toggle_accept(server, userid, channel, message): server.use_accept_command = not server.use_accept_command accept = ':green_circle: ' + Lang.get('YES', server.lang) refuse = ':red_circle: ' + Lang.get('NO', server.lang) await channel.send( Lang.get('CMD_ACCEPT_TOGGLE', server.lang).format( accept if server.use_accept_command else refuse, server.cmd_prefix)) return True
def lobo_mata(self, bot, update, user_data): usuario = conseguir_usuario(update, user_data, self.jugadores) data_split = update.callback_query.data.split("*") id_victima, id_grupo = filter(lambda x: data_split.index(x) % 2 != 0, data_split) victima = self.jugadores[int(data_split[1])] partida = self.partidas[int(data_split[3])] # Comprobamos que haya una partida if not partida: update.effective_message.edit_text(Lang.get_text("no_game_error")) update.callback_query.answer(Lang.get_text("no_game_error")) return # Nos aseguramos de que no haya votado ya if usuario.personaje.esta_noche_ha_matado_a: return # Votamos y eliminamos el teclado para que no vuelva a votar. usuario.personaje.mata_a(victima) update.callback_query.answer(Lang.get_text("objetivo_seleccionado")) update.callback_query.message.edit_reply_markup( reply_markup=InlineKeyboardMarkup([[]])) # Comprobamos si el resto de los lobos han votado para eliminar al jugador. lobos_vivos = [] han_votado_todas = True for jugador in partida.jugadores: if jugador.personaje.nombre == "un Hombrelobo" and jugador.personaje.vivo: lobos_vivos.append(jugador) if not jugador.personaje.esta_noche_ha_matado_a: han_votado_todas = False bot.send_message(chat_id=jugador.id, text=Lang.get_text_inserted( "x_a_votado_lobos_a_y", x=usuario.nombre_completo, y=victima.nombre_completo), parse_mode="Markdown", disable_web_page_preview=True) if not han_votado_todas: return # Comprobamos quién es la víctima más votada y la marcamos. victimas = [] mas_votada = None empate = False for lobo in lobos_vivos: victimas.append(lobo.personaje.esta_noche_ha_matado_a) lobo.personaje.esta_noche_ha_matado_a = None for victima in set(victimas): if victimas.count(victima) > victimas.count(mas_votada): empate = False mas_votada = victima elif victimas.count(victima) == victimas.count(mas_votada): empate = True if not empate: partida.esta_noche_muere.append(mas_votada)
def _finalizar_votacion_de_linchamiento(self, bot, job): """Contamos los votos y se lincha al más votado :)""" partida = job.context["partida"] chat = job.context["chat"] partida.linchando = False # Contamos los votos votos = [] for jugador in partida.jugadores: if jugador.personaje.hoy_ha_votado_a: votos.append(jugador.personaje.hoy_ha_votado_a) jugador.personaje.hoy_ha_votado_a = None # Comprobamos si ha votado al menos la mitad de los ciudadanos if votos.count(None) > len(votos) // 2: bot.send_message( chat_id=chat.id, text=Lang.get_text("fin_linchamiento_insuficientes_votos")) return # Hacemos el recuento recuento = list(set([(n, v) for v in votos for n in [votos.count(v)]])) recuento.sort(reverse=True) # Comprobamos si hay un empate if recuento.__len__() > 1 and recuento[1][0] == recuento[0][0]: mas_votado = None else: mas_votado = recuento[0][1] # Decimos quién es el linchado, si no hay mas_votado es un empate. if mas_votado: mas_votado.personaje.vivo = False bot.send_message(chat_id=chat.id, text=Lang.get_text_inserted( "fin_linchamiento", linchado=mas_votado.nombre_completo)) else: empates = [] for recuento_voto in recuento: if recuento_voto[0] == recuento[0][0]: empates.append(recuento_voto[1].nombre_completo) else: break bot.send_message(chat_id=chat.id, text=Lang.get_text_inserted( "fin_linchamiento_empate", empates=Lang.enumerar(empates))) # Comprobamos si algun bando ha ganado victoria = partida.comprobar_victoria() if victoria: bot.send_message(chat.id, "Han ganado %s" % victoria)
async def cmd_set_perm(server, userid, channel, message): perks = str(message.content).split()[len(message.role_mentions) + 1:] if not Perks.is_valid([perk[1:] if perk.startswith(('+', '-')) else perk for perk in perks]): await channel.send(Lang.get('INVALID_PERK', server.lang)) return False else: for role in message.role_mentions: remove_perks = [perk[1:] for perk in perks if perk.startswith('-')] add_perks = [perk.replace('+', '') for perk in perks if not perk.startswith('-') and perk.replace('+', '') not in remove_perks] if str(role.id) in server.group_perks.keys(): old_perks = [perk for perk in server.group_perks[str(role.id)] if perk not in add_perks and perk not in remove_perks] add_perks = old_perks + add_perks server.group_perks[str(role.id)] = add_perks await channel.send(Lang.get('CMD_PERM_UPDATE', server.lang).format(' '.join([r.mention for r in message.role_mentions]))) return True
async def user_voice_connected(self, userid, channel): await self.print_admin_log( f'{User.get_at_mention(userid)} ({userid}) connected to :loud_sound:**{channel.name}**' ) if userid in self.members.keys(): member = self.members[userid] member.lock.acquire() member.last_login = datetime.datetime.now() member.active_since = datetime.datetime.now() member.last_active_xp = None if member.check_daily_reward() is True: await self.print_bot_message( Lang.get('DAILY_XP_REWARD_LOGIN', self.lang).replace( cfg.get_value('TEXTFILE_USER_MENTION'), User.get_at_mention(userid)).format( cfg.get_value('DAILY_REWARD_XP'))) member.lock.release() if self.members[userid].muted is True: await self.guild.get_member(userid).edit(mute=True) else: await self.guild.get_member(userid).edit(mute=False) if self.members[userid].deaf is True: await self.guild.get_member(userid).edit(deafen=True) else: await self.guild.get_member(userid).edit(deafen=False)
async def cmd_router(self, msg, userid, channel): content = str(msg.content) commands = [ ToggleAcceptCmd, AcceptGroupCmd, AcceptCmd, VersionCmd, HelpCmd, CommandsCmd, AfkCmd, StopAfkCmd, WarnsCmd, WarnCmd, PrefixCmd, PermCmd, MuteCmd, UnmuteCmd, DeafenCmd, UndeafenCmd, LangCmd, XpCmd, TFTCmd, ForceSaveCmd, DailyRewardCmd, DailyRewardAliasCmd, DiceCmd ] found_valid_command = False for cmd in commands: if content == self.cmd_prefix + cmd.name or content.startswith( self.cmd_prefix + cmd.name + ' '): found_valid_command = True if await cmd.run_cmd(self, userid, channel, msg) is True: await self.print_admin_log( f"{User.get_at_mention(userid)} used **{self.cmd_prefix}{cmd.name}** command (||{msg.content}||)" ) else: await self.print_admin_log( f"{User.get_at_mention(userid)} tried to use **{self.cmd_prefix}{cmd.name}** command but failed (||{msg.content}||)" ) break if not found_valid_command and content.startswith(self.cmd_prefix): await channel.send(embed=simple_embed(value=Lang.get( 'UNKNOWN_CMD', self.lang).format(content, self.cmd_prefix), color=COLOR.LIGHT_RED))
def new_game( self, bot, update, user_data, chat_data): # TODO comprobar si el usuario ya está en una partida if DEBUGGING and update.effective_user.id != 254234845: return usuario = conseguir_usuario(update, user_data, self.jugadores) chat = conseguir_chat(update, chat_data) if not chat.partida: nueva_partida = Partida(usuario) self.partidas[update.effective_chat.id] = nueva_partida chat.partida = nueva_partida keyboard = [[ InlineKeyboardButton("Unirse a la partida", callback_data="join_game") ]] update.message.reply_text(Lang.get_text_inserted( "start_game_successful", player_list=chat.partida.text_player_list()), reply_markup=InlineKeyboardMarkup(keyboard), quote=False, disable_web_page_preview=True, parse_mode=ParseMode.MARKDOWN)
def _text_baraja(self): if not self.baraja: return "\nNo se ha hecho una baraja todavía" else: txt = "\n" + Lang.get_text("baraja") + "\n" for personaje in self.baraja: txt += "\n" + personaje.nombre return txt
def _iniciar_busqueda_de_candidatos(self, bot, job): partida = job.context["partida"] chat = job.context["chat"] keyboard = [[""]] for jugador in partida.jugadores: bot.send_message(jugador.id, Lang.get_text("presentese_candidato"))
async def cmd_stop_afk(server, userid, channel, message): # stop afk mentions (but keep admin logs) user = server.members[userid] user.afk_mentions = False await channel.send( Lang.get('CMD_STOPAFK', server.lang).replace(cfg.get_value('TEXTFILE_USER_MENTION'), User.get_at_mention(user.id))) return True
async def run_cmd(self, server, userid, channel, message): if not self.can_execute(server, userid): await channel.send(embed=simple_embed(value=Lang.get( 'MISSING_PERM', server.lang).replace( cfg.get_value('TEXTFILE_USER_MENTION'), User.get_at_mention(userid)), color=COLOR.RED)) return False else: return await self.action(server, userid, channel, message)
async def cmd_user_xp_get_self(server, userid, channel, message): if userid not in server.members.keys(): raise Exception( f'Cannot self display user xp ({userid}) : user id not found in this guild' ) await channel.send( Lang.get('CMD_XP_SELF', server.lang).format(User.get_at_mention(userid), server.members[userid].xp)) return True
def text_player_list(self): # TODO soportar post-game y también langs txt = u"" if not self.partida_empezada: if self.jugadores: txt = Lang.get_text("player_list") for jugador in self.jugadores: txt += u"\n" + jugador.nombre_completo else: txt = Lang.get_text("player_list") for jugador in self.jugadores: if jugador.personaje.vivo: txt += u"\n" + jugador.nombre_completo for jugador in self.jugadores: if not jugador.personaje.vivo: txt += u"\n" + jugador.nombre_completo_simple + u" ☠️ " + jugador.personaje.nombre return txt
def grant_connected_user_daily_reward(server, member): global bot_loop member.lock.acquire() if member.active_since is not None and member.check_daily_reward() is True: asyncio.run_coroutine_threadsafe( server.print_bot_message( Lang.get('DAILY_XP_REWARD_ACTIVE', server.lang).replace( cfg.get_value('TEXTFILE_USER_MENTION'), User.get_at_mention(member.id)).format( cfg.get_value('DAILY_REWARD_XP'))), bot_loop) member.lock.release()
def _iniciar_votacion_de_linchamiento(self, bot, job): """Envia los mensajes de votación a todos los jugadores vivos.""" partida = job.context["partida"] chat = job.context["chat"] partida.linchando = True # Avisamos de que empieza la votación bot.send_message(chat_id=chat.id, text=Lang.get_text_inserted( "comienza_la_votacion", player_list=partida.text_player_list()), parse_mode="Markdown", disable_web_page_preview=True) # Enviamos un mensaje a los jugadores vivos para que voten jugadores_vivos = [] for jugador in partida.jugadores: if jugador.personaje.vivo: jugadores_vivos.append(jugador) text = Lang.get_text("vota_pofabo") for jugador in jugadores_vivos: keyboard = [] tmp = list(jugadores_vivos) tmp.remove(jugador) for opcion in tmp: keyboard.append([ InlineKeyboardButton( text=opcion.nombre_completo_simple, callback_data="ciudadano_vota_a*%s*partida_en*%s" % (opcion.id, chat.id)) ]) bot.send_message(jugador.id, text=text, reply_markup=InlineKeyboardMarkup(keyboard), parse_mode="Markdown") if DEBUGGING: bot.send_message( chat_id=job.context["chat"].id, text="La iniciar linchamiento se ha inciado correctamente lol")
async def cmd_accept_group_set(server, userid, channel, message): if len(message.role_mentions) < 1: await channel.send( f"{Lang.get('CMD_WRONG_SYNTAX', server.lang)}\r\n`{server.cmd_prefix}acceptgroup <group>`" ) return False server.accept_rank = message.role_mentions[0].name await channel.send( Lang.get('CMD_ACCEPT_GROUP_SET', server.lang).format(message.role_mentions[0].mention, server.cmd_prefix)) return True
def ciudadano_vota(self, bot, update, user_data): usuario = conseguir_usuario(update, user_data, self.jugadores) data_split = update.callback_query.data.split("*") id_victima, id_grupo = filter(lambda x: data_split.index(x) % 2 != 0, data_split) victima = self.jugadores[int(id_victima)] partida = self.partidas[int(id_grupo)] # Comprobamos si hay una partida if not partida: update.effective_message.edit_text(Lang.get_text("no_game_error")) update.callback_query.answer(Lang.get_text("no_game_error")) return # Nos aseguramos de que no haya votado ya if usuario.personaje.hoy_ha_votado_a: return # Nos aseguramos de que la partida esté en fase de linchamiento if not partida.linchando: update.effective_message.edit_reply_markup( InlineKeyboardMarkup([[]])) return # Votamos y eliminamos el teclado para que no vuelva a votar. usuario.personaje.vota_a(victima) update.callback_query.answer(Lang.get_text("objetivo_seleccionado")) update.callback_query.message.edit_reply_markup( reply_markup=InlineKeyboardMarkup([[]])) # Avisamos en el grupo del voto bot.send_message(chat_id=id_grupo, text=Lang.get_text_inserted( "x_a_votado_ciudadanos_a_y", x=usuario.nombre_completo, y=victima.nombre_completo), parse_mode="Markdown", disable_web_page_preview=True)
def iniciar_partida( self, bot, grupo): # todo: nombrar alguacil al que tiene que serlo self._repartir_cartas() lista_manada = self._text_lista_manada() self.partida_empezada = True for jugador in self.jugadores: jugador.lanzar_explicacion_inicial(bot, lista_manada=lista_manada) bot.send_message(text=Lang.get_text_inserted( "game_started", baraja=self._text_baraja()), chat_id=grupo.id, parse_mode="Markdown", disable_web_page_preview=True)
async def cmd_daily_reward(server, userid, channel, message): if userid in server.members.keys(): member = server.members[userid] now = datetime.now() daily_time = 86400 - (now - member.last_daily_reward).total_seconds() seconds = floor(daily_time % 60) minutes = floor(daily_time / 60) hours = floor(minutes / 60) minutes = minutes % 60 display = f"{str(hours) + Lang.get('HOURS', server.lang) + ' ' if hours > 0 else ''}{str(minutes) + Lang.get('MINUTES', server.lang) + ' ' if minutes > 0 else ''}{str(seconds) + Lang.get('SECONDS', server.lang) + ' ' if seconds > 0 else ''}" await channel.send( Lang.get('NEXT_DAILY_XP_REWARD', server.lang).format(User.get_at_mention(userid), display)) return True return False
async def cmd_unmute(server, userid, channel, message): split_content = str(message.content).split() if len(message.mentions) < 1: await channel.send(Lang.get('CMD_WRONG_SYNTAX', server.lang)) await channel.send(f"`{server.cmd_prefix}unmute <users>`") return False for mention in message.mentions: if mention.id not in server.members.keys(): raise Exception(f'Cannot find user ({ mention.id }) in server') pass server.members[mention.id].lock.acquire() server.members[mention.id].muted = False server.members[mention.id].muted_until = None if mention.voice is not None: await mention.edit(mute=False) await channel.send( f"{User.get_at_mention(mention.id)} has been unmuted by {User.get_at_mention(userid)}" ) server.members[mention.id].lock.release() return True
def _iniciar_noche_vidente(bot, job): for jugador in job.context["partida"].jugadores: if jugador.personaje.nombre == "La Vidente": potenciales_victimas = [] keyboard = [] text = Lang.get_text("vidente_noche") for p_p_victima in job.context["partida"].jugadores: if p_p_victima is not jugador: potenciales_victimas.append(p_p_victima) for p_victima in potenciales_victimas: keyboard.append([ InlineKeyboardButton( p_victima.nombre_completo_simple, callback_data="vidente_observa_a*%s*partida_en*%s") ]) bot.send_message(text=text, reply_markup=InlineKeyboardMarkup(keyboard))
async def cmd_set_lang(server, userid, channel, message): splited_message = str(message.content).split() new_lang = splited_message[1].lower() server.lang = new_lang await channel.send(Lang.get('CMD_LANG_SET', server.lang).format(new_lang)) return True
async def cmd_get_lang(server, userid, channel, message): await channel.send( Lang.get('CMD_LANG_GET', server.lang).format(server.lang)) return True
def testun_elemento(self): resultado = Lang.enumerar(["hola"]) self.assertEqual(resultado, "hola", "El resulado no es el esperado para un elemento")
def testcuatro_elementos(self): resultado = Lang.enumerar(["hola", "lol", "no", "creo"]) self.assertEqual( resultado, "hola, lol, no y creo", "El resulado no es el esperado para cuatro elementos")
def testtres_elementos(self): resultado = Lang.enumerar(["hola", "lol", "no"]) self.assertEqual(resultado, "hola, lol y no", "El resulado no es el esperado para tres elementos")