class Audit(commands.Cog): def __init__(self, client): self.client = client self._logger = Logger(self) async def print_audit(self, author, type, message): self._logger.trace("print_audit") usr = cassandra.get_user((author.guild.id, author.id)) # TODO: Passed user class # TODO: Check for user not found # Check if the server audit log is enabled if usr.server.audit_channel is None: return False # Check if the audit log channel exists ch = self.client.get_channel(usr.server.audit_channel) if ch is None: return False # TODO: Check if audits of this type are enabled # Send audit log await ch.send("<@!%s>: %s" % (usr.ID, message)) return True
class Main(commands.Cog): def __init__(self, client): self.client = client self._logger = Logger(self) @commands.command(name="profile", help="Shows the profile.") async def profile(self, ctx, name=None): self._logger.trace("profile") # Do not do anything on private messages if ctx.guild == None: return uid = ctx.author.id if name is not None: if name.startswith("<@!") and name.endswith(">"): uid = name[3:len(name) - 1] usr = cassandra.get_user((ctx.guild.id, uid)) if usr is None: await ctx.send("User not found.") return discord_user = self.client.get_user(usr.ID) if discord_user is None: await ctx.send("User not found.") return content = "" cecon = self.client.get_cog('Economy') if cecon is not None: content = content + ":moneybag: Coins: %s" % cecon.get_balance(usr) cxp = self.client.get_cog('Xp') if cxp is not None: content = content + "\n:star: XP: %s" % cxp.get_xp(usr) content = content + "\n:star2: Level: %s" % cxp.get_level(usr) embed = discord.Embed(title="Profile for %s on server %s" % (discord_user.name, ctx.guild.name), description=content, colour=discord.Colour.gold()) embed.set_thumbnail(url=discord_user.avatar_url) stats = self.client.get_cog('Stats') if stats is not None: embed.add_field(name=":writing_hand: Messages", value="Total: %s" % stats.get_msg(usr), inline=True) embed.add_field(name=":heart: Reactions", value="Total: %s" % stats.get_reaction(usr), inline=True) embed.add_field(name=":microphone2: Voice", value="Time: %s" % util.sec2human(stats.get_voice(usr)), inline=True) await ctx.send(embed=embed)
def __init__(self, client): self.client = client self._logger = Logger(self) self.wyr_data = [] self.whatami_data = [] self.eightball_data = [] self.fortunes = {} self._load_wyr_assets() self._load_fortune_assets() self._load_whatami_assets() self._load_8ball_assets()
class Economy(commands.Cog): def __init__(self, client): self.client = client self._logger = Logger(self) def get_balance(self, u): self._logger.trace("get_balance") usr = cassandra.get_user(u) return usr.balance # Balance def set_balance(self, u, amt): self._logger.trace("set_balance") usr = cassandra.get_user(u) old = usr.balance resp = cassandra.dispatch("balance-change", { "old": old, "new": amt, "user": usr }) usr.balance = resp.new return old # Old balance def add_balance(self, u, amt): self._logger.trace("add_balance") usr = cassandra.get_user(u) old = usr.balance resp = cassandra.dispatch("balance-change", { "old": old, "new": old + amt, "user": usr }) usr.balance = resp.new return usr.balance # New balance def has_balance(self, u, amt): self._logger.trace("has_balance") usr = cassandra.get_user(u) return usr.balance >= amt
class Fun(commands.Cog): def __init__(self, client): self.client = client self._logger = Logger(self) self.wyr_data = [] self.whatami_data = [] self.eightball_data = [] self.fortunes = {} self._load_wyr_assets() self._load_fortune_assets() self._load_whatami_assets() self._load_8ball_assets() def _load_wyr_assets(self): path = "assets/wyr.json" if not os.path.exists(path): return False with open(path) as f: jdata = json.load(f) self.wyr_data = jdata["questions"] self._logger.info("Loaded WYR Data") return True def _load_fortune_assets(self): dir_path = "assets/fortunes" if not os.path.exists(dir_path): return False for filename in os.listdir(dir_path): if not filename.endswith(".json"): continue path = dir_path + "/" + filename with open(path) as f: jdata = json.load(f) self.fortunes[filename[:-5]] = jdata["fortunes"] self._logger.info("Loaded fortune database %s" % filename) self._logger.info("Loaded fortune Data") return True def _load_whatami_assets(self): path = "assets/whatami.json" if not os.path.exists(path): return False with open(path) as f: jdata = json.load(f) self.whatami_data = jdata["quotes"] self._logger.info("Loaded whatami Data") return True def _load_8ball_assets(self): path = "assets/8ball.json" if not os.path.exists(path): return False with open(path) as f: jdata = json.load(f) self.eightball_data = jdata["answers"] self._logger.info("Loaded 8ball Data") return True def get_help_page(self): return { "title": "Fun Commands", "description": None, "content": { "8ball <Question ...>": "Ask the magic 8ball.", #"conn <User>": "Starts a game of connect-4 against the mentioned user.", "fortune": "Opens a fortune cookie.", #"rusr": "******", #"tord": "Play a game of truth or dare.", #"ttt <User>": "Starts a game of Tick-Tack-Toe.", "wyr": "Displays a would you rather question.", "whatami": "You better have thick skin...or a thick skull!" } } @commands.command(name="whatami") async def whatami(self, ctx): self._logger.trace("whatami") quote = random.choice(self.whatami_data) await ctx.send(quote) @commands.command(name="conn") async def conn(self, ctx): self._logger.trace("conn") await ctx.send("Not implemented") @commands.command(name="fortune") async def fortune(self, ctx): self._logger.trace("fortune") # TODO: Handle dictionary is empty db = random.choice(list(self.fortunes.keys())) # TODO: Handle db is empty line = random.choice(self.fortunes[db]) await ctx.send(line) @commands.command(name="tord") async def tord(self, ctx): self._logger.trace("tord") await ctx.send("Not implemented") @commands.command(name="ttt") async def ttt(self, ctx): self._logger.trace("ttt") await ctx.send("Not implemented") @commands.command(name="wyr") async def wyr(self, ctx): self._logger.trace("wyr") line = random.choice(self.wyr_data) embed = discord.Embed(title="Would You Rather", description="**" + line["question"] + "**\n\n\n" + EMOJI_A + " " + line["answer_1"] + "\n\n" + EMOJI_B + " " + line["answer_2"], colour=discord.Colour.red()) msg = await ctx.send(embed=embed) await msg.add_reaction(EMOJI_A) await msg.add_reaction(EMOJI_B) @commands.command(name="8ball") async def eightball(self, ctx): self._logger.trace("8ball") await ctx.send(EMOJI_8BALL + " " + random.choice(self.eightball_data))
import os import json import requests import time import sys from datetime import datetime from lib.logging import Logger from lib.readCfg import ConfigReader from lib.utilities import Utilities from pathlib import Path CHANNELS_PATH = "processor/data/html/channels/" HTML_PATH = 'processor/data/html/' readCfg = ConfigReader() util = Utilities() logging = Logger() log = logging.getLogger(__file__) class DownloadChannel: def __init__(self): log.info("Loading download Channel") def getdisplayTime(self, messagets): tsa = messagets.split(".") ts = int(tsa[0]) sentdt = datetime.utcfromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S') return sentdt def updateRawFile(self, path, msg, mode='a+t'): with open(path, mode) as rf:
def __init__(self, client): self.client = client self._logger = Logger(self)
class Stats(commands.Cog): def __init__(self, client): self.client = client self._logger = Logger(self) def get_msg(self, u): self._logger.trace("get_msg") usr = cassandra.get_user(u) return usr.msg_count def get_reaction(self, u): self._logger.trace("get_reaction") usr = cassandra.get_user(u) return usr.reaction_count def get_voice(self, u): self._logger.trace("get_voice") usr = cassandra.get_user(u) return usr.voice_time @commands.Cog.listener() async def on_ready(self): self.update_voice.start() @commands.Cog.listener() async def on_reaction_add(self, reaction, user): self._logger.trace("on_reaction_add") # Ignore reactions from bots if user.bot == True: return # Ignore private messages if reaction.message.guild is None: return # Ignore reactions made to messages written by bots if reaction.message.author.bot == True: return usr = cassandra.get_user((reaction.message.guild.id, user.id)) # TODO: Handle user not found ts = util.getts() usr.reaction_last = ts # if reaction timeout is reached award coins if ts - usr.reaction_awarded > REACTION_TIMEOUT: usr.reaction_awarded = ts # Add balance if economy cog is loaded cecon = self.client.get_cog('Economy') if cecon is not None: cecon.add_balance(usr, REACTION_BONUS_COINS) # Add xp if xp cog is loaded cxp = self.client.get_cog('Xp') if cxp is not None: cxp.add_xp(usr, REACTION_BONUS_XP) usr.reaction_count = usr.reaction_count + 1 cassandra.save_user(usr) @commands.Cog.listener() async def on_message(self, message): # Ignore messages from bots if message.author.bot == True: return # Ignore direct messages if message.guild is None: return self._logger.trace("on_message(%s)" % message.content) srv = cassandra.get_server(message.guild.id) # TODO: Check if server is not found # Ignore commands to cassandra if message.content.startswith(srv.prefix_used): return # Ignore commands to other bots for prefix in srv.prefix_blocked: if message.content.startswith(prefix): return usr = cassandra.get_user((srv, message.author.id)) # TODO: Check if user is not found ts = util.getts() usr.msg_last = ts usr.msg_count = usr.msg_count + 1 #if msg timeout is reached award coins if ts - usr.msg_awarded > MSG_TIMEOUT: usr.msg_awarded = ts # Add balance if economy cog is loaded cecon = self.client.get_cog('Economy') if cecon is not None: cecon.add_balance(usr, MSG_BONUS_COINS) # Add xp if xp cog is loaded cxp = self.client.get_cog('Xp') if cxp is not None: cxp.add_xp(usr, MSG_BONUS_XP) cassandra.save_user(usr) @tasks.loop(seconds=VOICE_TIMEOUT) async def update_voice(self): self._logger.trace("update_voice") # For all voice channels on each guild for guild in self.client.guilds: # Do not do anything for unavailable guilds if guild.unavailable == True: continue # For each voice channel in each guild for vchannel in guild.voice_channels: vchmem = len(vchannel.members) # No need to look into a voice channel with one or no active members if vchmem < 2: continue # For each current member for member in vchannel.members: if member.voice.afk: continue elif member.voice.deaf or member.voice.self_deaf: continue elif member.voice.mute or member.voice.self_mute: continue usr = cassandra.get_user((guild.id, member.id)) usr.voice_time = usr.voice_time + VOICE_TIMEOUT # Add balance if economy cog is loaded cecon = self.client.get_cog('Economy') if cecon is not None: cecon.add_balance(usr, VOICE_BONUS_COINS) # Add xp if xp cog is loaded cxp = self.client.get_cog('Xp') if cxp is not None: # Give an xp bonus for more people in the voicechat xp = VOICE_BONUS_XP + (vchmem - 2) cxp.add_xp(usr, xp) cassandra.save_user(usr)
from lib.api.wca import get_upcoming_wca_competitions, get_wcif_for_comp from lib.utils.user_input import get_password_mail, select_upcoming_competition, get_confirmation from lib.utils.directory_handling import check_for_local_csv_files from lib.utils.data_from_WCIF import get_nametag_data from lib.pdf_generation.genNametags import gen_nametags from lib.logging import Logger import os, sys l = Logger() def print_only_nametags(): # TODO: Check if access token already here, only ask for mail etc if not password, email = get_password_mail() upcomingJson = get_upcoming_wca_competitions(email=email, password=password) upcomingComps = sorted(upcomingJson, key=lambda x: x['start_date']) competition_name = select_upcoming_competition(upcomingComps) competition_name_stripped = competition_name.replace(" ", "") two_sided_nametags = False if os.path.exists(competition_name_stripped): (reg_file, grp_file, scr_file) = check_for_local_csv_files(competition_name_stripped) if grp_file and scr_file: two_sided_nametags = get_confirmation( "Create two-sided nametags? (grouping and scrambling information on the back) (y/n)" ) l.info("\nDownloading Competiton Data... \n")
class AutoChannel(commands.Cog): def __init__(self, client): self.client = client self._logger = Logger(self) async def create_autochannel(self, s, dguild, duser=None): srv = cassandra.get_server(s) # Check if autochannels are configured if srv.autochannel_router is None: self._logger.debug("router channel not configured") return False # Find router channel router = get(dguild.channels, id=srv.autochannel_router) if router is None: self._logger.debug("router channel not found") return False # Get category cat = router.category if cat is None: self._logger.debug("router channel has no category") return False name = "Autochannel" if duser is not None: name = "AC %s" % (duser.display_name) channel = await cat.create_voice_channel(name, reason="New AutoChannel") # Save changes srv.autochannel_channels.append(channel.id) cassandra.save_server(srv) # Move member to new channel if duser is not None: await duser.edit(voice_channel=channel) return True async def delete_autochannel(self, s, dguild, channel): srv = cassandra.get_server(s) if not channel.id in srv.autochannel_channels: self._logger.debug("channel not an autochannel") return False # Check if the channel is empty if len(channel.members) > 0: self._logger.debug("still users in channel") return False # Remove from server data srv.autochannel_channels.remove(channel.id) cassandra.save_server(srv) # Delete empty channel await channel.delete(reason="Empty AutoChannel") return True async def cleanup(self, guild=None): self._logger.trace("cleanup(%s)" % guild) if guild is None: # For all guilds for g in self.client.guilds: # Do not do anything for unavailable guilds if g.unavailable == True: continue await self.cleanup(g) else: srv = cassandra.get_server(guild.id) for ac in srv.autochannel_channels: channel = get(guild.channels, id=ac) if channel is None: continue await self.delete_autochannel(srv, guild, channel) @commands.command(name="autochannel") @commands.has_permissions(manage_channels=True) async def autochannel(self, ctx, action, router=None): self._logger.trace("autochannel") srv = cassandra.get_server(ctx.guild.id) if action in ["disable", "stop"]: srv.autochannel_router = None cassandra.save_server(srv) await self.cleanup() await ctx.send( "Autochannels are no longer active.\nIf you want to use them in the future, you need to configure them again." ) elif action in ["setup", "start", "enable"]: if router is None: return # TODO: Print help routerid = None try: routerid = int(router) except Exception: return # TODO: User feedback routerch = get(ctx.guild.channels, id=routerid) if routerch is None: return # TODO: User feedback if routerch.category is None: await ctx.send( "The autochannel router must be part of a channel category!" ) return srv.autochannel_router = routerid cassandra.save_server(srv) await ctx.send("Autochannels successfully configured.") @commands.Cog.listener() async def on_voice_state_update(self, member, before, after): srv = cassandra.get_server(member.guild.id) if after.channel is not None: if after.channel.id == srv.autochannel_router: self._logger.debug("user join router") await self.create_autochannel(srv, member.guild, member) if before.channel is not None: if before.channel.id in srv.autochannel_channels: self._logger.debug("user left autochannel") await self.delete_autochannel(srv, member.guild, before.channel) @commands.Cog.listener() async def on_ready(self): self._logger.trace("on_ready") await self.cleanup()
class Tracker(commands.Cog): def __init__(self, client): self.client = client self._logger = Logger(self) def get_nicknames(self, u): self._logger.trace("get_nicknames") usr = cassandra.get_user(u) return usr.nicknames def get_names(self, u): self._logger.trace("get_names") usr = cassandra.get_user(u) return usr.names def add_nickname(self, u, dusr): self._logger.trace("add_nickname") usr = cassandra.get_user(u) if dusr.nick is None: return False # Has no nick if dusr.nick in usr.nicknames: # Dispatch event cassandra.dispatch("nickname-change", { "user": usr, "nick": dusr.nick, "known": True }) return False # Known nick # Dispatch event cassandra.dispatch("nickname-change", { "user": usr, "nick": dusr.nick, "known": False }) usr.nicknames.append(dusr.nick) return True # New nick def add_name(self, u, dusr): self._logger.trace("add_name") usr = cassandra.get_user(u) name = dusr.name + "#" + dusr.discriminator if name in usr.names: # Dispatch event cassandra.dispatch("name-change", { "user": usr, "name": name, "known": True }) return False # Known name # Dispatch event cassandra.dispatch("name-change", { "user": usr, "name": dusr.nick, "known": False }) usr.names.append(name) return True # New name @commands.Cog.listener() async def on_ready(self): self.update.start() @commands.command(name="whois") @commands.has_permissions(manage_messages=True) async def whois(self, ctx, member: discord.Member): self._logger.trace("whois") usr = cassandra.get_user((ctx.guild.id, member.id)) if usr is None: await ctx.send("Couldn't get user information") return title = "%s#%s" % (member.name, member.discriminator) if member.nick is not None: title = title + ("(%s)" % member.nick) nicknames = "No nicknames tracked" nicklist = self.get_nicknames(usr) if len(nicklist) > 0: nicknames = "```" + ', '.join(nicklist) + '```' names = "No names tracked" namelist = self.get_names(usr) if len(namelist) > 0: names = "```" + ', '.join(namelist) + '```' embed = discord.Embed(title=title) embed.set_thumbnail(url=member.avatar_url) embed.add_field(name="ID", value=str(member.id)) embed.add_field(name="Account Created", value=str(member.created_at), inline=True) embed.add_field(name="Joined At", value=str(member.joined_at), inline=True) embed.add_field(name="Nicknames", value=nicknames) embed.add_field(name="Names", value=names) await ctx.send(embed=embed) @commands.Cog.listener() # Username, discriminator async def on_member_join(self, member): self._logger.trace("on_member_join") usr = cassandra.get_user((member.guild.id, member.id)) update = False if self.add_name(usr, member): update = True if self.add_nickname(usr, member): update = True if update: cassandra.save_user(usr) @commands.Cog.listener() # Nickname async def on_member_update(self, before, after): self._logger.trace("on_member_update") usr = cassandra.get_user((after.guild.id, after.id)) if self.add_nickname(usr, after): cassandra.save_user(usr) @commands.Cog.listener() # Username, discriminator async def on_user_join(self, member): usr = cassandra.get_user((member.guild.id, member.id)) if self.add_nickname(usr, member): cassandra.save_user(usr) @tasks.loop(seconds=UPDATE_TIMEOUT) async def update(self): self._logger.trace("update") for guild in self.client.guilds: # Do not do anything for unavailable guilds if guild.unavailable == True: continue for member in guild.members: # If member is a bot, ignore if member.bot: continue usr = cassandra.get_user((guild.id, member.id)) self.add_nickname(usr, member) self.add_name(usr, member)
class Moderation(commands.Cog): def __init__(self, client): self.client = client self._logger = Logger(self) def get_help_page(self): return { "title": "Moderation Commands", "description": "These commands require moderation or administrator permissions.", "content": { "clear [count = 10]": "Clears the chat.", "ban <user> [reason...]": "Bans a user from the server.", "kick <user> [reason...]": "Kicks a user from the server.", "warn <user> [reason...]": "Warns a user.", "quarantine <user> [reason...]": "Strips a user from all roles.", "unquarantine <user>": "Restores a users roles.", # "history <user>": "Gets the moderation history for a user.", "whois <user>": "Displays some extended information about a user." } } def is_user_quarantined(self, u): usr = cassandra.get_user(u) return usr.quarantine_status @commands.command(name="warn") @commands.has_permissions(manage_messages=True) async def warn(self, ctx, member: discord.Member, *, reason=None): self._logger.trace("warn") # Audit log caudit = self.client.get_cog('Audit') if caudit is not None: if reason is None: await caudit.print_audit( ctx.author, 'warning', "Warned %s#%s for no reason." % (member.name, member.discriminator)) else: await caudit.print_audit( ctx.author, 'warning', "Warned %s#%s for **\"%s\"**." % (member.name, member.discriminator, reason)) reason_str = reason if reason is None: reason_str = "No reason given" embed = discord.Embed(title="%s %s: You have been warned!" % (EMOJI_WARN, ctx.guild.name), description="Reason: %s" % reason_str, colour=discord.Colour.gold()) await member.send(embed=embed) usr = cassandra.get_user((guild.id, member.id)) # Dispatch event cassandra.dispatch("mod-warning", { "dauthor": ctx.author, "reason": reason, "duser": member, "user": usr }) # TODO: Append to user history # usr = load_user(ctx.guild.id, member.id) # histentry = { # "type": "warning", # "time": getts(), # "by": ctx.author.id, # "reason": reason # } # usr["history"].append(histentry) # save_user(usr) @commands.command(name="ban") @commands.has_permissions(ban_members=True) async def ban(self, ctx, member: discord.Member, *, reason=None): self._logger.trace("ban") # TODO: Tempban # Audit log caudit = self.client.get_cog('Audit') if caudit is not None: if reason is None: await caudit.print_audit( ctx.author, 'ban', "Baned %s#%s for no reason." % (member.name, member.discriminator)) else: await caudit.print_audit( ctx.author, 'ban', "Baned %s#%s for **\"%s\"**." % (member.name, member.discriminator, reason)) if reason is None: reason = "No reason given" embed = discord.Embed(title="%s %s: The BAN-HAMMER has spoken!" % (EMOJI_BAN, ctx.guild.name), description="Reason: %s" % reason, colour=discord.Colour.red()) # We need to send the message first because discord does not let you send messages to users that have no servers in common await member.send(embed=embed) usr = cassandra.get_user((guild.id, member.id)) # Dispatch event cassandra.dispatch("mod-ban", { "dauthor": ctx.author, "reason": reason, "duser": member, "user": usr }) await member.ban(reason=reason) # TODO: User history # usr = load_user(ctx.guild.id, member.id) # histentry = { # "type": "ban", # "time": getts(), # "by": ctx.author.id, # "reason": reason # } # usr["history"].append(histentry) # save_user(usr) @commands.command(name="qrole") @commands.has_permissions(manage_channels=True) async def qrole(self, ctx, action, role: discord.Role = None): self._logger.trace("qrole") srv = cassandra.get_server(ctx.guild.id) if action in ["unset", "remove", "delete", "del", "rem"]: srv.quarantine_role = None cassandra.save_server(srv) await ctx.send("Quarantine role unset.") elif action in ["set", "add"]: if role is None: return # TODO: Print help srv.quarantine_role = role.id cassandra.save_server(srv) await ctx.send("Quarantine role set.") @commands.command(name="quarantine") @commands.has_permissions(manage_roles=True) async def quarantine(self, ctx, member: discord.Member, *, reason=None): self._logger.trace("quarantine") usr = cassandra.get_user((ctx.guild.id, member.id)) if usr.quarantine_status == True: await ctx.send("This user is already in quarantine!") return # Audit log caudit = self.client.get_cog('Audit') if caudit is not None: if reason is None: await caudit.print_audit( ctx.author, 'quarantine', "Quarantined %s#%s for no reason." % (member.name, member.discriminator)) else: await caudit.print_audit( ctx.author, 'quarantine', "Quarantined %s#%s for **\"%s\"**." % (member.name, member.discriminator, reason)) old_roles = [] for role in member.roles: if role == ctx.guild.default_role: continue old_roles.append(role.id) try: await member.remove_roles(role, reason="Quarantine") except Exception as ex: self._logger.warn( "Failed to remove role %s from member %s: %s" % (role.name, member.name, ex)) if usr.server.quarantine_role is not None: qrole = get(ctx.guild.roles, id=usr.server.quarantine_role) if qrole is not None: try: await member.add_roles(qrole, reason="Quarantine") except Exception as ex: self._logger.warn( "Failed to add role %s to member %s: %s" % (qrole.name, member.name, ex)) # Dispatch event cassandra.dispatch("mod-quarantine", { "dauthor": ctx.author, "reason": reason, "duser": member, "user": usr }) usr.quarantine_status = True usr.quarantine_roles = old_roles cassandra.save_user(usr) await ctx.send("User %s#%s has been quarantined." % (member.name, member.discriminator)) @commands.command(name="unquarantine") @commands.has_permissions(manage_roles=True) async def unquarantine(self, ctx, member: discord.Member): self._logger.trace("unquarantine") usr = cassandra.get_user((ctx.guild.id, member.id)) if usr.quarantine_status == False: await ctx.send("This user is not in quarantine!") return # Audit log caudit = self.client.get_cog('Audit') if caudit is not None: if reason is None: await caudit.print_audit( ctx.author, 'unquarantine', "Unquarantined %s#%s." % (member.name, member.discriminator)) if usr.server.quarantine_role is not None: qrole = get(ctx.guild.roles, id=usr.server.quarantine_role) if qrole is not None: try: await member.remove_roles(qrole, reason="Unquarantine") except Exception as ex: self._logger.warn( "Failed to remove role %s from member %s: %s" % (qrole.name, member.name, ex)) for roleid in usr.quarantine_roles: role = get(ctx.guild.roles, id=roleid) if role is None: continue if role == ctx.guild.default_role: continue try: await member.add_roles(role, reason="Unquarantine") except Exception as ex: self._logger.warn("Failed to add role %s to member %s: %s" % (role.name, member.name, ex)) # Dispatch event cassandra.dispatch("mod-unquarantine", { "dauthor": ctx.author, "duser": member, "user": usr }) usr.quarantine_status = False usr.quarantine_roles = [] cassandra.save_user(usr) await ctx.send("User %s#%s has been released form quarantine." % (member.name, member.discriminator)) @commands.command(name="kick") @commands.has_permissions(kick_members=True) async def kick(self, ctx, member: discord.Member, *, reason=None): self._logger.trace("kick") # Audit log caudit = self.client.get_cog('Audit') if caudit is not None: if reason is None: await caudit.print_audit( ctx.author, 'kick', "Kicked %s#%s for no reason." % (member.name, member.discriminator)) else: await caudit.print_audit( ctx.author, 'kick', "Kicked %s#%s for **\"%s\"**." % (member.name, member.discriminator, reason)) if reason is None: reason = "No reason given" embed = discord.Embed(title="%s %s: You have beed kicked!" % (EMOJI_INFO, ctx.guild.name), description="Reason: %s" % reason, colour=discord.Colour.dark_orange()) # We need to send the message first because discord does not let you send messages to users that have no servers in common await member.send(embed=embed) usr = cassandra.get_user((guild.id, member.id)) # Dispatch event cassandra.dispatch("mod-kick", { "dauthor": ctx.author, "reason": reason, "duser": member, "user": usr }) await member.kick(reason=reason) # TODO: User history # usr = load_user(ctx.guild.id, member.id) # histentry = { # "type": "kick", # "time": getts(), # "by": ctx.author.id, # "reason": reason # } # usr["history"].append(histentry) # save_user(usr) @commands.command(name="clear") @commands.has_permissions(manage_messages=True) async def clear(self, ctx, amt=10): self._logger.trace("clear") if not type(amt) is int: try: amt = int(amt, 10) except ValueError: await ctx.send("Invalid number of messages given") return if amt < 1: await ctx.send("Can not remove %s messages" % amt) return elif amt > 100: amt = 100 await ctx.channel.purge(limit=amt + 1) # Audit log caudit = self.client.get_cog('Audit') if caudit is not None: await caudit.print_audit( ctx.author, 'clear', "Cleared %s messages from channel <#%s>" % (amt, ctx.channel.id)) # Dispatch event cassandra.dispatch("mod-clear", { "dauthor": ctx.author, "amount": amt, "channel": ctx.channel })
from socket import socket, AF_INET, SOCK_STREAM from lib.bridge import Bridge from lib.logging import Logger logger = Logger(__name__) class SocketManager: _SUCCESS = "HTTP/1.0 200 OK\r\nContent-type: application/json\r\n\r\n" _FAIL = "HTTP/1.0 404 OK\r\nContent-type: application/json\r\n\r\n" def __init__(self, url, port, listen, bridge: Bridge): """ Initialize socket server to allow client connections. :param url: Server url. :param port: Server port. :param listen: Simultaneous users. :param bridge: A bridge to serial communication and the paths of requests pattern. """ logger.info("Starting socket server...") self.soc = socket(AF_INET, SOCK_STREAM) self.soc.bind((url, port)) self.soc.listen(listen) self.client = None self.pins = bridge logger.info("Server has been started.")
class LevelRoles(commands.Cog): def __init__(self, client): self.client = client self._logger = Logger(self) self._cache_xp_upate = [] # Holds tuples for users to update def get_help_page(self): return { "title": "LevelRoles Commands", "description": "Some of these commands require moderation or administrator permissions.", "content": { "lvroles": "Lists all reward roles that can be gained by leveling up.", "lvrole <level>": "Removes a reward from the ladder. - Admin Only", "lvrole <level> <role>": "Adds a reward level to the ladder. - Admin Only" } } @commands.command(name="lvroles") async def lvroles(self, ctx): srv = cassandra.get_server(ctx.guild.id) if len(srv.level_roles) > 0: text = "**Level Roles**\n\n" lvrolecache = self._build_level_rank_cache(ctx.guild, srv) for lv, role in lvrolecache.items(): text = text + ("%s: <@&%s>\n" % (lv, role.id)) await ctx.send(text) else: await ctx.send("This server has no level roles configured.") @commands.command(name="lvrole") @commands.has_permissions(manage_roles=True) async def lvrole(self, ctx, lvstr, rolestr=None): lv = None try: lv = int(lvstr) except Exception: await ctx.send("<level> must be a positive number.") return if lv < 0: await ctx.send("<level> must be a positive number.") return srv = cassandra.get_server(ctx.guild.id) if rolestr is None: # Remove Level role if lv in srv.level_roles: srv.level_roles.pop(lv, None) await ctx.send("Removed level role for level %s." % lv) else: await ctx.send("No level role is set for level %s." % lv) else: if lvstr in srv.level_roles: await ctx.send( "Level %s currently has role %s.\nPlease remove it manualy first, if you want another role at this level." ) return if len(rolestr) == 22 and rolestr.startswith( "<@&") and rolestr.endswith(">"): try: roleid = int(rolestr[3:21]) except: await ctx.send("Role not found %s!" % rolestr) return role = get(ctx.guild.roles, id=int(roleid)) if role is None: await ctx.send("Role not found <@&%s>!" % roleid) return srv.level_roles[lvstr] = roleid cassandra.save_server(srv) await ctx.send("Role <@&%s> set for level %s." % (roleid, lv)) else: ctx.send("%s is not a vaild role!" % rolestr) return pass def _build_level_rank_cache(self, guild, srv=None): self._logger.trace("_build_level_rank_cache") if srv is None: srv = cassandra.get_server(guild.id) lv_role_cache = {} for lv in srv.level_roles: role = get(guild.roles, id=srv.level_roles[lv]) if role is None: continue lv_role_cache[int(lv)] = role return dict(sorted(lv_role_cache.items(), key=lambda item: item[0])) async def update_user(self, guild, user, lv_role_cache=None): self._logger.trace("update_user(%s)" % user.id) if lv_role_cache is None: lv_role_cache = self._build_level_rank_cache(guild) # If user is a bot, ignore if user.bot: return level = self.client.get_cog('Xp').get_level((guild.id, user.id)) highest_role = None for lv in lv_role_cache: role = lv_role_cache[lv] if level < lv: break highest_role = role if highest_role is None: return if highest_role in user.roles: return for urole in user.roles: if urole in lv_role_cache.values(): await user.remove_roles( urole, reason="Userlevel rank" ) # TODO: There must be a more efficient way to do this await user.add_roles(highest_role, reason="Userlevel change") # Dispatch event cassandra.dispatch( "lvrole-change", { "duser": user, "user": cassandra.get_user((guild.id, user.id)), "role": highest_role }) # TODO: Anounce async def update_guild(self, guild): self._logger.trace("update_guild(%s)" % guild.id) # Do not do anything for unavailable guilds if guild.unavailable == True: return srv = cassandra.load_server(guild.id) # If no level roles are configured, ignore if len(srv.level_roles) == 0: return # Get all groups into a dictionary lv_role_cache = self._build_level_rank_cache(guild, srv) for member in guild.members: await self.update_user(guild, member, lv_role_cache) @commands.Cog.listener() async def on_ready(self): self.update_slow.start() self.update_fast.start() cassandra.add_event_listener("xp-change", self, self.on_xp_change) def on_xp_change(self, args): self._logger.trace("on_xp_change") if args.old >= args.new: return if args.user in self._cache_xp_upate: return self._cache_xp_upate.append(args.user) @tasks.loop(seconds=UPDATE_TIMEOUT_FAST) async def update_fast(self): if len(self._cache_xp_upate) == 0: return self._logger.trace("update_fast") for entry in self._cache_xp_upate: guild = get(self.client.guilds, id=entry.server.ID) if guild is None: continue user = get(guild.members, id=entry.ID) if user is None: continue await self.update_user(guild, user) self._cache_xp_upate.clear() @tasks.loop(seconds=UPDATE_TIMEOUT_SLOW) async def update_slow(self): self._logger.trace("update_slow") for guild in self.client.guilds: await self.update_guild(guild)
class Cassino(commands.Cog): def __init__(self, client): self.client = client self._logger = Logger(self) def get_help_page(self): return { "title": "Casino Commands", "description": None, "content": { #"lottery": "Buy a lottery ticket.", "coinflip <heads|tails> [bet = 0]": "Flip a coin and bet on the outcome.", #"slots [bet = 0]": "Spin the slots for a chance to win the jackpot!", # "spin": "Spin the wheel every 5 minutes for a reward.", #"scratch": "Scratch a card for a chance to win a reward.", #"dice": Roll the dice, if you roll a 6 you'll get your bet x5!", # "snakeeyes": "Two dice are rolled. Roll a 1 on either one to win. Get both on 1 to recieve a special bonus reward.", # "blackjack": "Play a game of blackjack.", } } def _get_bet(self, bet): if bet is None: return 0 if not bet.isdigit(): return None # At this point the number can not be negative return int(bet) async def _can_afford(self, ctx, u, bet): cecon = self.client.get_cog('Economy') if cecon is None: await ctx.send(EMOJI_ERROR + " Betting for coins is not configured!") return False if not cecon.has_balance(u, bet): await ctx.send(EMOJI_ERROR + " You can't afford this bet!") return False return True async def _usage_coinflip(self, ctx): await ctx.send("Usage: $coinflip <heads|tails> [amt=0]") @commands.command(name="coinflip", help="Flip a coin and bet on the outcome.") async def coinflip(self, ctx, side=None, bet=None): self._logger.trace("coinflip") if side is None: await self._usage_coinflip(ctx) return bet = self._get_bet(bet) if bet is None: await self._usage_coinflip(ctx) return usr = None if bet > 0: usr = cassandra.get_user((ctx.guild.id, ctx.author.id)) # Check if the user of this command has that much money if not await self._can_afford(ctx, usr, bet): return rng_side = -1 if side == "heads": rng_side = 0 elif side == "tails": rng_side = 1 else: await self._usage_coinflip(ctx) return flip = random.randint(0, 1) thumbnail = None flip_str = None if flip == 1: flip_str = "tails" thumbnail = IMAGE_TAILS else: flip_str = "heads" thumbnail = IMAGE_HEADS won = (flip == rng_side) color = None description = "It's **%s**\n" % flip_str if won: color = discord.Colour.green() description = description + "You won" else: color = discord.Colour.red() description = description + "You lost" if bet > 0: cecon = self.client.get_cog( 'Economy' ) # This can always be found because of the _can_afford check if won: cecon.add_balance(usr, bet) else: cecon.add_balance(usr, -bet) description = description + (" %s " % bet) + EMOJI_MONEY + ( "\nYou now have %s " % usr.balance) + EMOJI_MONEY embed = discord.Embed(title="Coinflip", colour=color, description=description) embed.set_thumbnail(url=thumbnail) await ctx.send(embed=embed) if usr: cassandra.save_user(usr) @commands.command(name="lottery") async def lottery(self, ctx): self._logger.trace("lottery") await ctx.send("Not implemented") @commands.command(name="slots") async def slots(self, ctx): self._logger.trace("slots") await ctx.send("Not implemented") @commands.command(name="scratch") async def scratch(self, ctx): self._logger.trace("scratch") await ctx.send("Not implemented") @commands.command(name="dice") async def dice(self, ctx): self._logger.trace("dice") await ctx.send("Not implemented") @commands.command(name="snakeeyes") async def snakeeyes(self, ctx): self._logger.trace("snakeeyes") await ctx.send("Not implemented") @commands.command(name="blackjack") async def blackjack(self, ctx): self._logger.trace("blackjack") await ctx.send("Not implemented") # Casino @commands.command(name="spin", help="Spin the wheel every 5 minutes for a reward.") async def spin(self, ctx): self._logger.trace("spin") ods = [{ "symbol": "<:c500:710482148305403924>", "propbability": 1, "ods": 500, "name": "MYTHIC" }, { "symbol": "<:c100:710482154500653056>", "propbability": 2, "ods": 100, "name": "IMORTAL" }, { "symbol": "<:c50:710482156895469691>", "propbability": 4, "ods": 50, "name": "LEGENDARY" }, { "symbol": "<:c25:710482155310022758>", "propbability": 8, "ods": 25, "name": "EPIC" }, { "symbol": "<:c10:710482151484817439>", "propbability": 16, "ods": 10, "name": "RARE" }, { "symbol": "<:c5:710482137895403520>", "propbability": 24, "ods": 5, "name": "UNCOMMON" }, { "symbol": "<:c1:710482104705613845>", "propbability": 48, "ods": 1, "name": "COMMON" }] usr = cassandra.get_user((ctx.guild.id, ctx.author.id)) ts = util.getts() if ts - usr.casino_last_spin < 300: await ctx.send("You have to wait " + util.sec2human(300 - (ts - usr.casino_last_spin)) + " for your next chance of a reward.") return total = 0 for outcome in ods: total = total + outcome["propbability"] rand = random.randint(0, total) index = 0 out = None while rand > 0: outcome = ods[index] rand = rand - outcome["propbability"] if rand <= 0: out = outcome break index = index + 1 # FIX: This is a drity fix, as we should never end up here if out is None: out = ods[0] embed = discord.Embed( title=ctx.author.display_name + " spins the wheel ...", description="<a:spin:710491435006165032> | Spinning ...", colour=discord.Colour.green()) msg = await ctx.send(embed=embed) # FIX: Replace this with a timer, because this forces only one player (in al servers) to be able to spin at once time.sleep(1) description = "%s | Landed on **%s**" % (out["symbol"], out["name"]) cecon = self.client.get_cog('Economy') if cecon is not None: reward = out["ods"] # Multiply reward by user level cxp = self.client.get_cog('Xp') if cxp is not None: level = cxp.get_level(usr) if level > 1: reward = reward * level description = description + ("\nYou got a reward of %s coins" % reward) cecon.add_balance(usr, reward) else: description = description + ( "\n\n%s You did not get a reward, because the economy is not setup!" % EMOJI_WARN) embed = discord.Embed(title=ctx.author.display_name + " Spun the wheel", description=description, colour=discord.Colour.green()) await msg.edit(embed=embed) usr.casino_last_spin = ts cassandra.save_user(usr)
def __init__(self, client): self.client = client self._logger = Logger(self) self._cache_xp_upate = [] # Holds tuples for users to update
print("(*) Game mode: {}".format(args.mode)) print("(*) Bot: {}".format(args.bot)) print("(*) Number of games to play: {}".format(args.number)) # Setup a signal handler to catch ctrl-c signal shutdown_requested = False signal.signal(signal.SIGINT, sigint_handler) # Main loop of the script for game_number in range(1, args.number + 1): # Check if the user pressed ctrl-c if shutdown_requested: break logger = Logger(project_dir + "/run") try: print("=== Starting game {} (of {})".format(game_number, args.number)) if args.mode == "arena": print("(*) Waiting for opponents...") print("/!\ If you exit now we will lose the game") env = ArenaEnvironment(args.key) else: env = TrainingEnvironment(args.key) heurisitc = heuristic_class() bot = bot_class(env.hero_id, heurisitc) # Store bot settings logger.set_game_id(env.get_status().id)