Exemplo n.º 1
0
class Points(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        #Initialise instances of the DB and calc auxiliary class
        self.db = DBHandle()
        self.calc = Calc()

        #Define the leaderboard command
        @bot.command(name="leaderboard",
                     description=formatHelp("leaderboard", "desc"),
                     usage=formatHelp("leaderboard", "usage"))
        async def leaderboard(ctx):
            #If the user has used the command recently and is not an admin, given them an error message (hopefully this will prevent HTB's shitty API from blocking us)
            if not self.db.checkTime(
                    ctx.message.author.id
            ) and ctx.message.author.id not in config["admins"]:
                print(type(ctx.message.author.id))
                await ctx.channel.send(
                    strings["errors"]["leaderboardCooldown"].format(
                        config["prefix"],
                        config["leaderboard"]["cooldown"] // 60))
                return
            #Log a points update then update all the points
            log.updateAllPoints(ctx.message.author.id)
            self.calc.updateAllPoints()
            #Set up the leaderboard embed then send it
            embed = discord.Embed(colour=discord.Colour.blue())
            embed.title = "Leaderboard"
            raw = self.db.leaderboard()
            leaderboard = []
            for index, value in enumerate(raw):
                temp = [index + 1]
                temp.append(bot.get_user(int(value[0])).name)
                temp.append(value[1])
                leaderboard.append(temp)
            leaderboard = tabulate(leaderboard, ["Rank", "Username", "Points"],
                                   tablefmt="fancy_grid")
            embed.description = f"```\n{leaderboard}```"
            await ctx.channel.send(embed=embed)

        #Get an individual's points. No rate limit on this, but may need to implement one
        @bot.command(name="points",
                     description=formatHelp("points", "desc"),
                     usage=formatHelp("points", "usage"))
        async def points(ctx):
            self.calc.updatePoints(ctx.message.author.id)
            points = self.db.getPoints(ctx.message.author.id)
            await ctx.channel.send(strings["points"].format(
                bot.get_user(ctx.message.author.id).name, points))
Exemplo n.º 2
0
class Calc():
	def __init__(self):
		self.db = DBHandle()
		self.api = Api()


	#Update points for a single user
	def updatePoints(self, discordID):
		db = DBHandle()
		userHandle = db.getUser(discordID)
		points = self.getPoints(userHandle["thmUser"], userHandle["thmPoints"], userHandle["htbID"], userHandle["htbPoints"])
		if(points != userHandle["points"]):
			db.updatePoints(discordID, points)

	#Do the actual calculation
	def getPoints(self, thmUser, thmPoints, htbID, htbPoints):
		points = 0
		if(thmUser != None):
			newTHMPoints = self.api.getTHMPoints(thmUser)
			points += (newTHMPoints - thmPoints)
		if(htbID != None):
			newHTBPoints = self.api.getHTBPoints(htbID)
			if(newHTBPoints != None):
				points += (newHTBPoints - htbPoints)
		return points

	#Simultaneously update all points -- use with caution!
	def updateAllPoints(self):
		users = self.db.getUserIDs()
		if not users:
			return False
		with ThreadPool(processes=5) as p:
			p.map(self.updatePoints, users)
		return True
Exemplo n.º 3
0
	def __init__(self, bot):
		self.bot = bot
		#Initialises instances of the DB and api auxiliary class
		self.db = DBHandle()
		self.api = Api()

		#Link a THM account
		@bot.command(name="thmlink", description=formatHelp("thmlink", "desc"), usage=formatHelp("thmlink", "usage"))
		async def thmlink(ctx, token = None):
			#Sort out the token to ensure that it's sanitised (and exists)
			discordID, token = await preprocess(ctx, token)	
			if not discordID:
				return

			#Get the user info
			userHandle = self.db.getUser(discordID)
			if userHandle["thmUser"] != None:
				await ctx.channel.send(strings["errors"]["alreadyLinked"])
				return

			#Get requisite variables
			username = self.api.getTHMProfile(token)
			points = self.api.getTHMPoints(username)
			self.db.addTHMUser(discordID, username, points, token)
			await ctx.channel.send(strings["success"]["linked"])
		
		

		@bot.command(name="htblink", description=formatHelp("htblink", "desc"), usage=formatHelp("htblink", "usage"))
		async def htblink(ctx, token = None):
			#Same as the thmlink command from here on out
			discordID, token = await preprocess(ctx, token)	
			if not discordID:
				return
			
			#Get user info
			userHandle = self.db.getUser(discordID)
			if userHandle["htbID"] != None:
				await ctx.channel.send(strings["errors"]["alreadyLinked"])
				return

			username, userid = self.api.getHTBProfile(token)
			points = self.api.getHTBPoints(userid)
			#If it wasn't possible to retrieve points then the user hasn't set their HTB profile to public. Yes, this is a shitty way to scrape points, but HTB haven't bothered publishing API docs
			#and I already called in my favours to get the user endpoint ¯\_(ツ)_/¯
			if(points == None):
				await ctx.channel.send(strings["errors"]["profileNotPublic"])
				return
			self.db.addHTBUser(discordID, username, userid, points, token)
			await ctx.channel.send(strings["success"]["linked"])



		##Helper Funcs
		def stripToken(token):
			return re.sub("[\W_]", "", token)

		async def checkDM(ctx):
			if not isinstance(ctx.channel, discord.channel.DMChannel):
				await ctx.message.delete() 
				res = await ctx.channel.send(strings["errors"]["noDM"])			
				await asyncio.sleep(5)
				await res.delete()
				return False
			return True

		async def preprocess(ctx, token):
			if not await checkDM(ctx):
				return False, False
			elif not token:
				await ctx.channel.send(strings["errors"]["noToken"])
				return False, False
			discordID = ctx.message.author.id
			token = stripToken(token)
			return discordID, token
Exemplo n.º 4
0
	def updatePoints(self, discordID):
		db = DBHandle()
		userHandle = db.getUser(discordID)
		points = self.getPoints(userHandle["thmUser"], userHandle["thmPoints"], userHandle["htbID"], userHandle["htbPoints"])
		if(points != userHandle["points"]):
			db.updatePoints(discordID, points)
Exemplo n.º 5
0
	def __init__(self):
		self.db = DBHandle()
		self.api = Api()