async def strike(self, ctx, amount: int, tier, *, args):
     splitArgs = args.split(";")
     name = splitArgs[0].strip()
     reason = ""
     if len(splitArgs) > 1:
         reason = splitArgs[1].strip()
     if tier.upper() not in channels.keys():
         await ctx.send("Your tier is not valid! Valid tiers are: %s" %
                        list(channels.keys()))
         return
     if abs(amount) > 200:
         await ctx.send(
             "Individual penalties can only be 200 points or lower")
         return
     channel = ctx.guild.get_channel(channels[tier.upper()])
     success, pen = await API.post.createPenalty(name, abs(amount), True)
     if success is False:
         await ctx.send("An error occurred while giving the penalty:\n%s" %
                        pen)
         return
     penaltyID = pen["id"]
     e = discord.Embed(title="Penalty + strike added")
     e.add_field(name="Player", value=pen["playerName"], inline=False)
     e.add_field(name="Amount", value="-%d" % abs(amount), inline=False)
     e.add_field(name="ID", value=penaltyID)
     e.add_field(name="Tier", value=tier.upper())
     e.add_field(name="Given by", value=ctx.author.mention)
     if reason != "":
         e.add_field(name="Reason", value=reason, inline=False)
     recentStrikes = await API.get.getStrikes(name)
     if recentStrikes is not False:
         last3 = recentStrikes[::-1][0:3]
         strikeStr = ""
         if len(last3) > 0:
             for pen in last3:
                 strikeDate = dateutil.parser.isoparse(
                     pen["awardedOn"]).strftime('%m/%d/%Y')
                 strikeStr += "%s\n" % strikeDate
             e.add_field(name="Strikes", value=strikeStr, inline=False)
     rankChange = await self.updateRoles(ctx, pen["playerName"],
                                         pen["prevMmr"], pen["newMmr"])
     await channel.send(embed=e, content=rankChange)
     strike_log = ctx.guild.get_channel(strike_log_channel)
     if strike_log is not None:
         await strike_log.send(embed=e, content=rankChange)
     if ctx.channel.id == channel.id:
         await ctx.message.delete()
     else:
         await ctx.send("Added -%d penalty to %s in %s" %
                        (abs(amount), pen["playerName"], channel.mention))
 async def penalty(self, ctx, amount: int, tier, *, args):
     splitArgs = args.split(";")
     name = splitArgs[0].strip()
     reason = ""
     if len(splitArgs) > 1:
         reason = splitArgs[1].strip()
     if tier.upper() not in channels.keys():
         await ctx.send("Your tier is not valid! Valid tiers are: %s" %
                        list(channels.keys()))
         return
     if abs(amount) > 200:
         await ctx.send(
             "Individual penalties can only be 200 points or lower")
         return
     channel = ctx.guild.get_channel(channels[tier.upper()])
     success, pen = await API.post.createPenalty(name, abs(amount), False)
     if success is False:
         await ctx.send("An error occurred while giving the penalty:\n%s" %
                        pen)
         return
     #print(pen)
     penaltyID = pen["id"]
     e = discord.Embed(title="Penalty added")
     e.add_field(name="Player", value=name, inline=False)
     e.add_field(name="Amount", value="-%d" % abs(amount))
     e.add_field(name="ID", value=penaltyID)
     e.add_field(name="Tier", value=tier.upper())
     e.add_field(name="Given by", value=ctx.author.mention)
     if reason != "":
         e.add_field(name="Reason", value=reason, inline=False)
     rankChange = await self.updateRoles(ctx, pen["playerName"],
                                         pen["prevMmr"], pen["newMmr"])
     await channel.send(embed=e, content=rankChange)
     strike_log = ctx.guild.get_channel(strike_log_channel)
     if strike_log is not None:
         await strike_log.send(embed=e, content=rankChange)
     if ctx.channel.id == channel.id:
         await ctx.message.delete()
     else:
         await ctx.send("Added -%d penalty to %s in %s" %
                        (abs(amount), name, channel.mention))
 async def updateTier(self, ctx, tier):
     if tier.upper() not in channels.keys():
         await ctx.send("Invalid tier")
         return
     tables = await API.get.getPending()
     if tables is False:
         await ctx.send("There are no pending tables")
         return
     for table in tables:
         try:
             if tier.upper() != table["tier"]:
                 continue
             success = await self.update(ctx, table["id"])
             if success is False:
                 return
         except Exception as e:
             print(e)
     await ctx.send(f'Updated all tables in tier {tier.upper()}')
 async def pending(self, ctx):
     tables = await API.get.getPending()
     if len(tables) == 0:
         await ctx.send("There are no pending tables")
         return
     msg = ""
     for tier in channels.keys():
         count = 0
         ids = []
         for table in tables:
             if table["tier"] == tier:
                 ids.append(table["id"])
                 count += 1
         if count > 0:
             msg += "\nTier %s - %d tables\n" % (tier, count)
             msg += "\n".join(["\tID %d" % tableid for tableid in ids])
     if len(msg) > 0:
         await ctx.send(msg)
Beispiel #5
0
    async def submit(self, ctx, size: int, tier, *, data):
        #basic parameter checks
        if ctx.guild.id != ctx.bot.config["server"]:
            await ctx.send("You cannot use this command in this server!")
            return
        VALID_SIZES = [1, 2, 3, 4, 6]
        if size not in VALID_SIZES:
            await ctx.send("Your size is not valid. Correct sizes are: %s" %
                           (VALID_SIZES))
            return

        if tier.upper() not in channels.keys():
            await ctx.send("Your tier is not valid. Correct tiers are: %s" %
                           (list(channels.keys())))
            return
        #functions for parsing lorenzi table data
        def isGps(scores: str):
            gps = re.split("[|+]", scores)
            for gp in gps:
                if gp.strip().isdigit() == False:
                    return False

        def sumGps(scores: str):
            gps = re.split("[|+]", scores)
            sum = 0
            for gp in gps:
                sum += int(gp.strip())
            return sum

        def removeExtra(line):
            splitLine = line.split()
            if line.strip() == "":
                return False
            if len(splitLine) == 1:
                return False
            scores = splitLine[len(splitLine) - 1]
            if scores.isdigit() == False and isGps(scores) == False:
                return False
            else:
                return True

        lines = filter(removeExtra, data.split("\n"))
        names = []
        scores = []
        for line in lines:
            # removes country flag brackets
            newline = re.sub("[\[].*?[\]]", "", line).split()
            names.append(" ".join(newline[0:len(newline) - 1]))
            gps = newline[len(newline) - 1]
            scores.append(sumGps(gps))
        if len(names) != 12:
            await ctx.send(
                "Your table does not contain 12 valid score lines, try again!")
            return
        #checking names with the leaderboard API
        nameAPIchecks = await API.get.checkNames(names)
        err_str = ""
        for i in range(12):
            if nameAPIchecks[i] is False:
                if len(err_str) == 0:
                    err_str += "The following players cannot be found on the leaderboard:\n"
                err_str += "%s\n" % names[i]
        if len(err_str) > 0:
            await ctx.send(err_str)
            return

        is984 = sum(scores)
        teamscores = []
        teamnames = []
        teamplayerscores = []
        for i in range(int(12 / size)):
            teamscore = 0
            tnames = []
            pscores = []
            for j in range(size):
                teamscore += scores[i * size + j]
                tnames.append(nameAPIchecks[i * size + j])
                pscores.append(scores[i * size + j])
            teamscores.append(teamscore)
            teamnames.append(tnames)
            teamplayerscores.append(pscores)

        sortedScoresTeams = sorted(zip(teamscores, teamnames,
                                       teamplayerscores),
                                   reverse=True)
        sortedScores = [x for x, _, _ in sortedScoresTeams]
        sortedTeams = [x for _, x, _ in sortedScoresTeams]
        sortedpScores = [x for _, _, x in sortedScoresTeams]
        sortedNames = []
        tableScores = []
        placements = []
        for i in range(len(sortedScores)):
            sortedNames += sortedTeams[i]
            tableScores += sortedpScores[i]
            if i == 0:
                placements.append(1)
                continue
            if sortedScores[i] == sortedScores[i - 1]:
                placements.append(placements[i - 1])
                continue
            placements.append(i + 1)

        base_url_lorenzi = "https://gb.hlorenzi.com/table.png?data="
        if size > 1:
            table_text = ("#title Tier %s %dv%d\n" %
                          (tier.upper(), size, size))
        else:
            table_text = ("#title Tier %s FFA\n" % (tier.upper()))
        if size == 1:
            table_text += "FFA - Free for All #4A82D0\n"
        for i in range(int(12 / size)):
            if size != 1:
                if i % 2 == 0:
                    teamcolor = "#1D6ADE"
                else:
                    teamcolor = "#4A82D0"
                table_text += "%d %s\n" % (placements[i], teamcolor)
            for j in range(size):
                index = size * i + j
                table_text += ("%s %d\n" %
                               (sortedTeams[i][j], sortedpScores[i][j]))

        url_table_text = urllib.parse.quote(table_text)
        image_url = base_url_lorenzi + url_table_text

        e = discord.Embed(title="Table")
        e.set_image(url=image_url)
        content = "Please react to this message with \U00002611 within the next 30 seconds to confirm the table is correct"
        if is984 != 984:
            warning = (
                "The total score of %d might be incorrect! Most tables should add up to 984 points"
                % is984)
            e.add_field(name="Warning", value=warning)
        embedded = await ctx.send(content=content, embed=e)
        #ballot box with check emoji
        CHECK_BOX = "\U00002611"
        X_MARK = "\U0000274C"
        await embedded.add_reaction(CHECK_BOX)
        await embedded.add_reaction(X_MARK)

        def check(reaction, user):
            if user != ctx.author:
                return False
            if reaction.message != embedded:
                return False
            if str(reaction.emoji) == X_MARK:
                return True
            if str(reaction.emoji) == CHECK_BOX:
                return True

        try:
            reaction, user = await self.bot.wait_for('reaction_add',
                                                     timeout=30.0,
                                                     check=check)
        except:
            await embedded.delete()
            return

        if str(reaction.emoji) == X_MARK:
            await embedded.delete()
            return

        success, sentTable = await API.post.createTable(
            tier.upper(), sortedTeams, sortedpScores, ctx.author.id)
        if success is False:
            await ctx.send(
                "An error occurred trying to send the table to the website!\n%s"
                % sentTable)
            return
        newid = sentTable["id"]
        tableurl = ctx.bot.site_creds["website_url"] + sentTable["url"]

        e = discord.Embed(title="Mogi Table", colour=int("0A2D61", 16))

        e.add_field(name="ID", value=newid)
        e.add_field(name="Tier", value=tier.upper())
        e.add_field(name="Submitted by", value=ctx.author.mention)
        e.add_field(name="View on website",
                    value=(ctx.bot.site_creds["website_url"] +
                           "/TableDetails/%d" % newid))

        e.set_image(url=tableurl)
        channel = ctx.guild.get_channel(channels[tier.upper()])

        tableMsg = await channel.send(embed=e)

        await API.post.setTableMessageId(newid, tableMsg.id)
        await embedded.delete()
        if channel == ctx.channel:
            await ctx.message.delete()
        else:
            await ctx.send("Successfully sent table to %s `(ID: %d)`" %
                           (channel.mention, newid))