async def startglobal(self, ctx): # Check to see if it is already enabled async with sessionmaker() as session: server = (await session.get(ExternalServer, ctx.guild.id)) if not server.global_chat: async with sessionmaker() as session: server = (await session.get(ExternalServer, ctx.guild.id)) server.global_chat = True await session.commit() total_servers = (await session.execute(select(ExternalServer) )).scalars() global_active_servers = 0 server_info = [] for server in total_servers: if server.global_chat and server.server_id != ctx.guild.id: global_active_servers += 1 server_info.append(server.channel_id) send = "Global chat has been enabled, any messages you send in here will show up in all other servers that have global chat enabled.\n" send += f"There {'are' if global_active_servers != 1 else 'is'} currently {global_active_servers} other {'servers' if global_active_servers != 1 else 'server'} with global chat enabled." await ctx.send(send) if not str(ctx.channel.name).endswith("enabled"): new_name = ctx.channel.name + " enabled" await ctx.channel.edit(name=new_name) for name in server_info: channel = await self.find('c', name) await channel.send( f"{ctx.guild.name} has joined global chat, current (other) servers with global chat enabled: {global_active_servers}" ) else: await ctx.send( "global chat is already enabled. To turn it off run `!stopglobal`" )
async def stopglobal(self, ctx): # Check to see if it is already enabled async with sessionmaker() as session: server = (await session.get(ExternalServer, ctx.guild.id)) if server.global_chat: async with sessionmaker() as session: server = (await session.get(ExternalServer, ctx.guild.id)) server.global_chat = False await session.commit() await ctx.send("Global chat has been disabled.") new_name = ctx.channel.name if new_name.endswith("enabled"): await ctx.channel.edit(name=new_name[:-8]) total_servers = (await session.execute(select(ExternalServer) )).scalars() server_info = [] global_active_servers = 0 for server in total_servers: if server.global_chat and server.server_id != ctx.guild.id: global_active_servers += 1 server_info.append(server.channel_id) print("SERVER INFO", server_info) for name in server_info: channel = await self.find('c', name) await channel.send( f"{ctx.guild.name} has left global chat, current servers with global chat enabled: {global_active_servers}" ) else: await ctx.send( "global chat is already disabled. To turn it on run `!startglobal`" )
async def level(self, ctx, level, type, role): if type == "all" or type == "3/4" or type == "silent": async with sessionmaker() as session: server = await session.get(ExternalServer, ctx.guild.id) if server.min_rs <= int(level) <= server.max_rs: if type == "all": rs_level = "rs" + str(level) elif type == "3/4": rs_level = "rs" + str(level) + "_34" elif type == "silent": rs_level = "rs" + str(level) + "_silent" print("HERE IS THE RS LEVEL", rs_level) setattr(server, rs_level, int(role[3:-1])) await session.commit() saying = "RS" + str( level) if type == "all" else "RS" + str( level) + " 3/4" if type == "3/4" else "RS" + str( level) + " Silent" if type == "silent" else "" await ctx.send( f"```{saying} pings set to {role} (yes that is the right role, this is just the id of the role)```" ) else: if server.min_rs > int(level): await ctx.send( f"{level} is below your server's current min rs of rs{server.min_rs}. If you want to change this, run `!connect {level} {server.max_rs}`" ) else: await ctx.send( f"{level} is above your server's current max rs of rs{server.max_rs}. If you want to change this, run `!connect {server.min_rs} {level}`" ) else: await ctx.send( "Specify the type of role this is, i.e. `all`, `3/4`, or `silent`" )
async def current(self, ctx): async with sessionmaker() as session: server = await session.get(ExternalServer, ctx.guild.id) if server is not None: rs_types = ["rs", "rs_34", "rs_silent"] role_ids = [(i, (rs[:2].upper() + str(i) + (" 3/4" if rs == "rs_34" else " silent" if rs == "rs_silent" else "")), getattr(server, (rs[:2] + str(i) + rs[2:]))) for rs in rs_types for i in range(5, 12)] print_str = "Below is what roles are currently set up on this server. If you want to add more, use the `!level` command:\n```" print_str += f"Min RS: rs{server.min_rs}\n" role_ids = [ sub for sub in role_ids if not sub[2] == None if not sub[2] == 0 ] role_ids.sort() longest = 0 for sub in role_ids: if longest < len(sub[1]): longest = len(sub[1]) for (id, level, role) in role_ids: if role is not None or int(role) != 0: full_role = discord.utils.get(ctx.guild.roles, id=role) #print_str += f"{level} | {full_role.name}\n" print_str += f"{level}" print_str += " " * (longest - len(level)) + " | " print_str += full_role.name + "\n" print_str += f"Max RS: rs{server.max_rs} ```" await ctx.send(print_str) else: await ctx.send( "This server is currently not connected to the clubs")
async def off(self, ctx, mod): mods = [(str(column))[5:] for column in inspect(Data).c] mods = mods[1:] right_channel = False for club_channel in self.rs_channel: if club_channel == str(ctx.message.channel): right_channel = True if right_channel or ctx.guild.id != clubs_server_id: async with sessionmaker() as session: if mod in mods: user_mods = (await session.get(Data, ctx.author.id)) setattr(user_mods, mod, False) await ctx.send( f"{ctx.author.mention}, {mod} has been removed. When you enter a queue, you'll no longer see {str(discord.utils.get(self.bot.emojis, name=f'{mod}'))} next to your name" ) else: str_mods = "" for str_mod in mods: str_mods += "**" + str_mod + "**" + ", " await ctx.send( f"{mod} not found in list, current available mods: {str_mods[:-2]}" ) await session.commit() else: msg = await ctx.send( f"{ctx.author.mention}, this command can only be run in #bot-spam" ) await asyncio.sleep(15) await ctx.message.delete() await msg.delete()
async def talk(self): async with sessionmaker() as session: talking = (await session.execute(select(Talking))).scalars() for talk in talking: minutes = int((time.time() - talk.timestamp) / 60) if minutes > 5: await session.delete(talk) await session.commit()
async def check_ban_status(self): async with sessionmaker() as session: banned_users = (await session.execute(select(Banned))).scalars() current_time = int(time.time()) for user in banned_users: if user.unban_timestamp != -1: if user.unban_timestamp < current_time: await session.delete(user) await session.commit()
async def unban(self, ctx, user_id: int): async with sessionmaker() as session: person = await session.get(Banned, user_id) if person is None: await ctx.send("User is not banned") else: await session.delete(person) await session.commit() await ctx.send("User has been unbanned")
async def disconnect(self, ctx): async with sessionmaker() as session: server = await session.get(ExternalServer, ctx.guild.id) if server is None: await ctx.send( "This server is already not connected to The Clubs") else: await session.delete(server) await session.commit() await ctx.send( "The server has been disconnected from The Clubs")
async def update_leaderboard(self): async with sessionmaker() as session: all_events = (await session.execute( select(Event).where(Event.score != 0))).scalars() # Check each run in event player_data = [] for event in all_events: run_stats = (await session.execute( select(Stats).where(Stats.run_id == event.run_id) )).scalars() for run in run_stats: player_data.append([run.user_id, event.score]) # Add up all player data D = {} for (x, y) in player_data: if x not in D.keys(): D[x] = y else: D[x] += y full_data = [[x, D[x]] for x in D.keys()] full_data.sort(key=lambda x: x[1], reverse=True) # Work around the longest name longest_name = 0 guild = await self.bot.fetch_guild(guild_id) for i in range(len(full_data)): full_data[i][0] = (await guild.fetch_member(full_data[i][0] )).display_name if len(full_data[i][0]) > longest_name: longest_name = len(full_data[i][0]) # Now build the leaderboard max_players = 50 # String will be 5 long for position, longest_name + 2 (1 space on each side) for user, and 1+len(full_data[0][1]) if longest_name % 2 == 0: leaderboard_string = "```" + f"Rank |" + " " * (int( longest_name / 2)) + "User" + " " * (int(longest_name / 2) - 2) + "| Score\n" else: leaderboard_string = "```" + f"Rank |" + " " * (int( longest_name / 2)) + "User" + " " * (int(longest_name / 2) - 1) + "| Score\n" for i in range(len(full_data)): if i < max_players: leaderboard_string += f"#{i+1}" + " " * (int(5) - int( len(f"#{i}"))) + f"| " + f"{full_data[i][0]}" + " " * ( 1 + longest_name - int(len( full_data[i][0]))) + "| " + f"{full_data[i][1]}\n" leaderboard_string += "```" leaderboard_embed = discord.Embed(title=f"RS Event Leaderboard", description=leaderboard_string, color=discord.Color.green()) channel = await self.bot.fetch_channel(rs_leaderboard_channel_id) message = await channel.fetch_message(rs_leaderboard_message_id) await message.edit(embed=leaderboard_embed)
async def show(self, ctx): if ctx.guild.id != clubs_server_id: async with sessionmaker() as session: server = await session.get(ExternalServer, ctx.guild.id) if not server.show: server.show = True await session.commit() await ctx.send( "The bot will now display everything related to queues, pinging roles, queueing, etc." ) else: await ctx.send( "The bot is already set to display everything. If you want to turn this off, run the `!hide` command." ) else: await ctx.send( "You can't turn off the queue system on the clubs server 😠")
async def hide(self, ctx): if ctx.guild.id != clubs_server_id: async with sessionmaker() as session: server = await session.get(ExternalServer, ctx.guild.id) if server.show: server.show = False await session.commit() await ctx.send( "The bot will no longer display anything related to queues, pinging roles, queuing, etc." ) else: await ctx.send( "The bot is already set to not display anything. If you want the bot to display everyihing, run the `!show` command." ) else: await ctx.send( "You can't turn off the queue system on the clubs server 😠")
async def ban(self, ctx, user_id: int, days: int, *reason): # Check to see if they've already been banned async with sessionmaker() as session: person = await session.get(Banned, user_id) if person is None: user = await self.bot.fetch_user(user_id) unban_time = int(time.time()) + (days * 86400) str_reason = ' '.join(reason) ban_enter = Banned(user_id=user_id, nickname=user.display_name, unban_timestamp=unban_time, reason=str_reason) session.add(ban_enter) await session.commit() if days != -1: await ctx.send(f"User has been banned for {days} days") else: await ctx.send(f"User has been banned Indefinitely") else: await ctx.send("That user is already banned")
async def current_bans(self, ctx): current_time = int(time.time()) async with sessionmaker() as session: banned_users = (await session.execute(select(Banned))).scalars() ban_list = [] if len(banned_users.all()) != 0: for user in banned_users: if user.unban_timestamp != -1: ban_list.append(user.user_id, user.nickname, (user.unban_timestamp-current_time)/86400, user.reason) else: ban_list.append(user.user_id, user.nickname, -1, user.reason) for (id, name, days, reason) in ban_list: if days != -1: await ctx.send(f"User ID: {id} | Name: {name} | Days until unban: {format(days,'.2f')} | Reason for ban: {reason}") else: await ctx.send(f"User ID: {id} | Name: {name} | Days until unban: Indefinite | Reason for ban: {reason}") else: await ctx.send("There are currently no banned users.")
async def rsinput(self, ctx, id, score): id = int(id) score = int(score) async with sessionmaker() as session: event = await session.get(Event, id) users = (await session.execute(select(Stats).where(Stats.run_id == id) )).scalars() ids = [user.user_id for user in users] if ctx.author.id in ids: if event.score == 0: event.score = score await ctx.send(f"Score successfully set to {score}") else: await ctx.send( f"This run has already been counted with a score of {event.score}" ) else: await ctx.send( f"Only users in that rs can set the score of their rs.") await session.commit()
async def rsstats(self, ctx, name=None): async with sessionmaker() as session: if name is None: users = (await session.execute( select(Stats).where(Stats.user_id == ctx.author.id) )).scalars() else: users = (await session.execute( select(Stats).where(Stats.user_id == int(name)) )).scalars() stats = { 'rs5': 0, 'rs6': 0, 'rs7': 0, 'rs8': 0, 'rs9': 0, 'rs10': 0, 'rs11': 0 } for user in users: stats[f'rs{user.rs_level}'] += 1 stats_string = "```RS# | Amount\n" for i in range(5, 12): if stats[f'rs{i}'] != 0: stats_string += f"RS{i}" + " " * ( int(5) - int(len(f"RS{i}"))) + f"| {stats[f'rs{i}']}\n" stats_string += "```" if name is None: stats_embed = discord.Embed( title=f"RS Stats for {ctx.author.display_name}", description=stats_string, color=discord.Color.green()) else: full_user = await self.bot.fetch_user(int(name)) stats_embed = discord.Embed( title=f"RS Stats for {full_user.display_name}", description=stats_string, color=discord.Color.green()) await ctx.send(embed=stats_embed)
async def close(self, ctx): async with sessionmaker() as session: user_talking = await session.get(Talking, ctx.author.id) if user_talking is None: await ctx.send( "You are not currently connected to any servers.") else: run_id = user_talking.run_id servers = (await session.execute( select(Talking).where(Talking.run_id == run_id) )).scalars() list_servers = [server.channel_id for server in servers] list_servers = list(set(list_servers)) for server in list_servers: channel = await self.find('c', server) await channel.send( f"```The connection has been closed by {ctx.author.display_name}.```" ) servers = (await session.execute( select(Talking).where(Talking.run_id == run_id) )).scalars() for server in servers: await session.delete(server) await session.commit()
async def connect(self, ctx, min_rs=None, max_rs=None): await ctx.send("This feature has currently been disabled") if (False): if max_rs is None or min_rs is None: await ctx.send( "Please specify this server's min and max rs level in the `!connect` command, i.e. `!connect 5 9`" ) if int(max_rs) < int(min_rs): await ctx.send( "Your server's maximum rs level should be higher than your minimum." ) elif int(min_rs) > 4 and int(max_rs) < 12: async with sessionmaker( ) as session: # check to see if the server is already in the database data = (await session.execute( select(ExternalServer).where( ExternalServer.server_id == ctx.guild.id) )).scalars().all() if len(data ) == 0: # Add the server to the ExternalServer Database async with sessionmaker() as session: LOGGER.debug("Adding server to database") webhook = await ctx.channel.create_webhook( name="Global Chat Webhook (The Clubs)") Server_enter = ExternalServer( server_id=ctx.guild.id, server_name=ctx.guild.name, channel_id=ctx.channel.id, webhook=str(webhook.url), min_rs=int(min_rs), max_rs=int(max_rs), global_chat=False, show=True) session.add(Server_enter) await session.commit() print_str = "This server has been connected to The Clubs!\n" print_str += f"The min/max rs of this server has been set to: rs{min_rs}-rs{max_rs}\n" print_str += "If you messed up the max rs level of this server while running the `!connect` command, just run the command again with the correct rs level(s) and it will update the rs level of the server.\n" print_str += "Now comes the fun part, setting up the rs level of users on this server!\n" print_str += "Below is everything you'll need to know about setting this up, and if you need to see this again, run `!help external`, or to see all functions of this bot, `!help`\n" await ctx.send(print_str) external_embed = discord.Embed( title='External', color=discord.Color.green()) if TESTING: external_embed.add_field( name="Connecting your server to the clubs", value= f"If you want to connect your corporation's discord server to The Clubs so you can run Red Stars from the comfort of your discord server, simply add the bot to your discord server with [this link](https://discord.com/api/oauth2/authorize?client_id=805960284543385650&permissions=537193536&scope=bot) and follow the steps" ) else: # Fix this external_embed.add_field( name="Connecting your server to the clubs", value= f"If you want to connect your corporation's discord server to The Clubs so you can run Red Stars from the comfort of your discord server, simply add the bot to your discord server with [this link]() and follow the steps" ) external_embed.add_field( name="First Time Setup", value= f"Run `!connect # %` (where `#` is the minimum rs level of your server and `%` is the maximum), and your server will be connected to The Clubs." ) external_embed.add_field( name="Setting up max RS levels", value= f"To change the min/max RS level of your server, run `!connect # %` where `#` is the minimum rs level of your server and `%` is the maximum." ) external_embed.add_field( name="Users and Queues", value= f"To allow users to join queues, they'll need to have a role specifying their rs level. In order to do this, use the `!level # type @<>` command, where `#` is the rs level, and `type` is either `all`, `3/4`, or `silent`. This allows users to decide if how they want to get notified (everytime, when the queue is 3/4, or not at all) `@<>` is the role that players in that rs level have. If you want to change the role, simply run the command again." ) external_embed.add_field( name="Seeing Roles", value= f"Use the `!current` command to show what roles are currently connected to the bot. If you want to add more, use the `!level # type @<>` command." ) external_embed.add_field( name="Disconnecting", value= f"If you want this server to be disconnected from The Clubs, have an admin run the `!disconnect` command." ) external_embed.add_field( name="Joining/Leaving/Showing Queues", value= f"Go to the queue section of the `!help` command to get information on the queueing system (`!help q`)." ) await ctx.send(embed=external_embed) else: # They were found in the database, update their max rs level async with sessionmaker() as session: server = (await session.get(ExternalServer, ctx.guild.id)) server.max_rs = int(max_rs) await session.commit() await ctx.send( f"This server has already been connected to The Clubs, but now the max rs level of this server is {max_rs}" ) else: await ctx.send( f"The Clubs only support RS 5-11, {max_rs} is outside that range." )
async def on_message(self, message): # <Message id=859239790952185876 channel=<TextChannel id=858484759994040370 name='rs-queues' position=1 nsfw=False news=False category_id=858484643632381953> type=<MessageType.default: 0> # author=<Member id=384481151475122179 name='Conbonbot' discriminator='0680' bot=False nick=None guild=<Guild id=858484643632381952 name='Testing Server' shard_id=None chunked=False member_count=2>> flags=<MessageFlags value=0>> # See if the talking database has anything in it if not message.author.bot and not (message.content.startswith('!') or message.content.startswith('+') or message.content.startswith('-') or message.content.startswith('%')): active_global = False async with sessionmaker() as session: data_check = (await session.execute(select(Talking) )).scalars().all() if len(data_check) != 0: active_global = True if active_global: total_info = [] total_servers = [] club_server_info = () async with sessionmaker() as session: message_run_id = await session.get(Talking, message.author.id) if message_run_id is not None: current_talking = (await session.execute( select(Talking).where( Talking.run_id == message_run_id.run_id) )).scalars() for user in current_talking: total_info.append( (user.server_id, user.user_id, user.channel_id, user.timestamp)) total_servers.append(user.server_id) if user.server_id == clubs_server_id: club_server_info = (user.server_id, user.user_id, user.channel_id, user.timestamp) total_servers = list(set(total_servers)) # TOTAL INFO -> SERVER ID, USER_ID, CHANNEL_ID, TIMESTAMP # Check if the message was sent from the select people and in the right channel if message.guild.id in [ info[0] for info in total_info ] and message.author.id in [ info[1] for info in total_info ] and message.channel.id in [info[2] for info in total_info]: # cut out bot messages and commands async with sessionmaker() as session: total_stuff = [] print("Total server data", total_servers) for data in total_servers: if data == clubs_server_id: print("CLUBS", clubs_server_id) rs_level = (await session.get( Stats, (club_server_info[1], club_server_info[3]))).rs_level clubs_webhook_string = "RS" + str( rs_level) + "_WEBHOOK" total_stuff.append( (os.getenv(clubs_webhook_string), data)) else: server = await session.get( ExternalServer, data) total_stuff.append((server.webhook, data)) for webhook_url, server_id in total_stuff: if server_id != message.guild.id: # Send the message with webhooks user = await self.find('u', message.author.id) async with aiohttp.ClientSession( ) as webhook_session: webhook = Webhook.from_url( webhook_url, adapter=AsyncWebhookAdapter( webhook_session)) if len(message.attachments) == 0: await webhook.send( message.content, username=message.author. display_name, avatar_url=str(user.avatar_url)) else: for attachment in message.attachments: await webhook.send( content=None, username=message.author. display_name, avatar_url=str( user.avatar_url), file=(await attachment.to_file())) else: # Check global chat/Feedback async with sessionmaker() as session: # Sending from server to #feedback webhook_url = None server = (await session.execute(select(Feedback) )).scalars().first() if server is not None: check = int(message.channel.id) == int( os.getenv('FEEDBACK_CHANNEL')) if check: # sent in #feedback (send message to feedback server) user = await self.find('u', 384481151475122179) username = "******" ext_server = (await session.execute(select(Feedback) )).scalars().first() webhook_url = (await session.get( ExternalServer, ext_server.server_id)).webhook elif server.channel_id == message.channel.id: user = await self.find('u', message.author.id) username = user.display_name webhook_url = os.getenv("FEEDBACK_WEBHOOK") async with aiohttp.ClientSession() as webhook_session: if webhook_url is not None: webhook = Webhook.from_url( webhook_url, adapter=AsyncWebhookAdapter( webhook_session)) if len(message.attachments) == 0: await webhook.send(message.content, username=username, avatar_url=str( user.avatar_url)) else: for attachment in message.attachments: await webhook.send( content=None, username=username, avatar_url=str(user.avatar_url), file=(await attachment.to_file()))