async def givebonuses(self, ctx): wb = openpyxl.load_workbook("tourney bonus.xlsx", data_only=True) ws = wb["Sheet1"] for i in range(429, 737): loungename = ws[f"F{i}"].value bonus = ws[f"D{i}"].value p = await API.get.getPlayer(loungename) a, b = await API.post.createBonus(loungename, bonus) if a is False: await ctx.send(f"{loungename}: {b}") else: ws[f"G{i}"] = "yes" mmr1 = p["mmr"] mmr2 = mmr1 + bonus ws[f"H{i}"] = mmr1 ws[f"I{i}"] = mmr2 oldRank = getRank(mmr1) newRank = getRank(mmr2) if oldRank != newRank: ws[f"J{i}"] = "yes" if 'discordId' in p.keys(): member = ctx.guild.get_member(int(p['discordId'])) oldRole = ctx.guild.get_role(ranks[oldRank]["roleid"]) newRole = ctx.guild.get_role(ranks[newRank]["roleid"]) if member is not None and oldRole is not None and newRole is not None: if oldRole in member.roles: await member.remove_roles(oldRole) if newRole not in member.roles: await member.add_roles(newRole) ws[f"K{i}"] = "yes" if i % 100 == 0: await ctx.send(i) await asyncio.sleep(0.1) wb.save("tourney bonus.xlsx") await ctx.send("done")
async def fixRole(self, ctx, member: discord.Member): player = await API.get.getPlayerFromDiscord(member.id) if player is None: await ctx.send("Player could not be found on lounge site") return for role in member.roles: for rank in ranks.values(): if role.id == rank['roleid']: await member.remove_roles(role) if role.id == placementRoleID: await member.remove_roles(role) player_role = ctx.guild.get_role(player_role_ID) roles_to_add = [] if player_role not in member.roles: roles_to_add.append(player_role) if 'mmr' not in player.keys(): role = member.guild.get_role(placementRoleID) #await member.add_roles(role) roles_to_add.append(role) else: rank = getRank(player['mmr']) role = member.guild.get_role(ranks[rank]['roleid']) #await member.add_roles(role) roles_to_add.append(role) await member.add_roles(*roles_to_add) if member.display_name != player['name']: await member.edit(nick=player['name']) await ctx.send("Fixed player's roles")
async def updateRoles(self, ctx, name, oldMMR: int, newMMR: int): oldRank = getRank(oldMMR) newRank = getRank(newMMR) rankChanges = "" if oldRank != newRank: member = findmember(ctx, name, ranks[oldRank]["roleid"]) if member is not None: memName = member.mention else: memName = name rankChanges = ("%s -> %s\n" % (memName, ranks[newRank]["emoji"])) oldRole = ctx.guild.get_role(ranks[oldRank]["roleid"]) newRole = ctx.guild.get_role(ranks[newRank]["roleid"]) if member is not None and oldRole is not None and newRole is not None: if oldRole in member.roles: await member.remove_roles(oldRole) if newRole not in member.roles: await member.add_roles(newRole) return rankChanges
async def addAllDiscords(self, ctx): players = await API.get.getPlayerList() for player in players['players']: if "discordId" not in player.keys(): if 'mmr' not in player.keys(): continue rank = getRank(player['mmr']) role = ranks[rank]['roleid'] member = findmember(ctx, player['name'], role) if member is None: print( f"could not find member with name {player['name']} and rank {rank}" ) continue success, txt = await API.post.updateDiscord( player['name'], member.id) if success is True: print( f"Added discord id for {player['name']}: {member.id}")
async def addAll(self, ctx): apiplayers = await API.get.getPlayerList() players = apiplayers['players'] print('added:') for player in players: if 'discordId' not in player.keys(): continue if 'mmr' not in player.keys(): continue rank = getRank(player['mmr']) role = ctx.guild.get_role(ranks[rank]['roleid']) member = ctx.guild.get_member(int(player['discordId'])) if member is None: continue for mrole in member.roles: if mrole.id == role.id: continue await member.add_roles(role) print(f"{player['name']} - {role.name}")
async def fixAllRoles(self, ctx): i = 0 for member in ctx.guild.members: i += 1 if i % 100 == 0: await ctx.send(f"{i}/{len(ctx.guild.members)}") playerRoles = [] for role in member.roles: for rank in ranks.values(): if role.id == rank['roleid']: playerRoles.append(role) if role.id == placementRoleID: playerRoles.append(role) player = await API.get.getPlayerFromDiscord(member.id) if player is None: for role in playerRoles: try: await member.remove_roles(role) except Exception as e: print(e) continue continue if 'mmr' not in player.keys(): role = member.guild.get_role(placementRoleID) else: rank = getRank(player['mmr']) role = member.guild.get_role(ranks[rank]['roleid']) for currRole in playerRoles: if currRole.id != role.id: try: await member.remove_roles(currRole) except Exception as e: print(e) if role not in playerRoles: try: await member.add_roles(role) except Exception as e: print(e) await ctx.send("done")
async def on_member_join(self, member): if member.bot: return if member.guild.id != self.bot.config['server']: return player = await API.get.getPlayerFromDiscord(member.id) if player is None: return player_role = member.guild.get_role(player_role_ID) if member.display_name != player['name']: await member.edit(nick=player['name']) if 'mmr' not in player.keys(): role = member.guild.get_role(placementRoleID) roles_to_add = [role, player_role] await member.add_roles(*roles_to_add) return rank = getRank(player['mmr']) role = member.guild.get_role(ranks[rank]['roleid']) roles_to_add = [role, player_role] await member.add_roles(*roles_to_add)
async def givePlacementRole(self, ctx, player, placeMMR): oldRoleID = placementRoleID newRoleID = ranks[getRank(placeMMR)]["roleid"] oldRole = ctx.guild.get_role(oldRoleID) newRole = ctx.guild.get_role(newRoleID) #member = findmember(ctx, name, oldRole) if 'discordId' not in player.keys(): await ctx.send( "Player does not have a discord ID on the site, please give them one to give them placement roles" ) return member = ctx.guild.get_member(int(player['discordId'])) if member is None: await ctx.send( f"Couldn't find member {player['name']}, please give them roles manually" ) return if oldRole in member.roles: await member.remove_roles(oldRole) if newRole not in member.roles: await member.add_roles(newRole) await ctx.send( f"Managed to find member {member.display_name} and edit their roles" )
def createMMRTable(size:int, tier, placements, names, scores, oldMMRs, newMMRs, tableID, peakMMRs, races=12): #dark red, gray, and green mapcolors = ["#C00000", "#D9D9D9", "#548235"] #basically the same thing as a color scale in excel. used for mmr changes cmap = LinearSegmentedColormap.from_list("gainloss", mapcolors) #used later to change cell colors in promotions column promotions = [False, False] peakMMRs2 = [False, False] if size == 1: mogiText = "Free for All" elif size > 1 and size < 6: mogiText = "%dv%d Mogi" % (size, size) else: mogiText = "6 vs 6" if tier == "SQ": tierText = "Squad Queue" else: tierText = "Tier %s" % tier colLabels = ["", mogiText, "", "", "", tierText, ""] #top row color colColors = ["#0a2d61", "#0a2d61", "#0a2d61", "#0a2d61", "#0a2d61", "#0a2d61", "#0a2d61"] if size > 1: #num of blank rows + num players + num extra rows numRows = int(12/size - 1 + 12+3) else: #num players + num extra rows (no blank rows since FFA) numRows = 12+3 data = [] cellColors = [] #2nd row of the MMR Table data.append(["Rank", "Player", "Score", "MMR", "+/-", "New MMR", "Promotions"]) cellColors.append(["#1e2630", "#1e2630", "#1e2630", "#1e2630", "#1e2630", "#1e2630", "#1e2630"]) #adding in rows for each player for i in range(12): #adding black rows between teams for non-FFA events if i > 0 and i % size == 0 and size > 1: data.append(["", "", "", "", "", "", ""]) cellColors.append(["#000000", "#000000", "#000000", "#000000", "#000000", "#000000", "#000000"]) promotions.append(False) peakMMRs2.append(False) ad = [] change = newMMRs[i] - oldMMRs[i] #colors for each column of the row #cols = ["#273c5a", "#212121", "#273c5a", cmap(change/350+0.5), "#273c5a", "#273c5a"] cols = ["#273c5a", "#212121", "#273c5a", "#273c5a", cmap(change/350+0.5), "#273c5a", "#273c5a"] if i % size == math.ceil(size/2-1): ad.append(placements[int(i/(12/len(placements)))]) else: ad.append("") ad.append(names[i]) ad.append(scores[i]) ad.append(oldMMRs[i]) ad.append("%+d" % change) ad.append(newMMRs[i]) if getRank(newMMRs[i]) != getRank(oldMMRs[i]): if change > 0: updown = "+" else: updown = "-" ad.append("%s %s" % (updown, getRank(newMMRs[i]))) promotions.append(True) else: ad.append("") promotions.append(False) peakMMRs2.append(peakMMRs[i]) data.append(ad) cellColors.append(cols) data.append(["Races:", races, "", "", "", "ID:", tableID]) cellColors.append(["#1e2630", "#1e2630", "#1e2630", "#1e2630", "#1e2630", "#1e2630", "#1e2630"]) table = plt.table(cellText=data, colWidths = [.13, .3, .13, .16, .12, .16, .25], colLabels=colLabels, colColours=colColors, cellColours=cellColors, loc='center', cellLoc='center', edges='closed') table.auto_set_font_size(False) table.scale(1.15, 1.75) cells = table.get_celld() for i in range(numRows): rowindex = i cells[(rowindex, 6)].set_text_props(color='white') if i > 1 and i < (numRows - 1): if promotions[i] is True: #print(data[i-1][5]) #print(int(data[i-1][5])) newrank = getRank(int(data[i-1][5])) #print(newrank) rankdata = ranks[newrank] cells[(rowindex, 6)].set_text_props(color=ranks[newrank]["color"]) if peakMMRs2[i] is True: cells[(rowindex, 5)].set_text_props( color="#F1C232", fontproperties=FontProperties(weight='bold', style='italic') ) else: cells[(rowindex, 5)].set_text_props( color="white" ) for j in range(7): #kill me if (i == 1 or j != 4) and (j != 6) and (i < 2 or i >= (numRows-1) or j != 5): cells[(rowindex, j)].set_text_props(color='white') cells[(rowindex, j)].set_text_props(fontfamily="Titillium Web") #this is dumb but it's needed so that the border colors on empty rows arent changed isNotEmptyRow = (data[i-1][1] != "") if size > 1 and i > 1 and i < numRows - 1 and j == 0 and isNotEmptyRow: cells[(rowindex, j)].set_edgecolor("#273c5a") if i == numRows - 1: cells[(rowindex, j)].set_edgecolor("#1E2630") if i > 0: cells[(rowindex, j)].set_fontsize(14) if i < numRows - 1 and j > 0: cells[(rowindex, j)].set_linewidth(0.5) else: cells[(rowindex, j)].set_fontsize(20) cells[(rowindex, j)].set_height(0.1) cells[(rowindex, j)].set_edgecolor("#0a2d61") for i in range(7): cells[(0, i)].set_text_props(color='white') if tierText == "Squad Queue": cells[(0, 5)].set_fontsize(16) ax = plt.gca() ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) plt.axis('off') b = BytesIO() plt.savefig(b, format='png', bbox_inches='tight', transparent=True) b.seek(0) plt.close() return b
async def undo(self, ctx, tableID: int): table = await API.get.getTable(tableID) if table is False: await ctx.send("Table not found") return tier = table['tier'] rankChanges = "" if 'verifiedOn' in table.keys(): names = [] oldMMRs = [] newMMRs = [] peakMMRs = [] discordids = [] channel = ctx.guild.get_channel(channels[tier.upper()]) for team in table['teams']: team['scores'].sort(key=lambda p: p['score'], reverse=True) for player in team['scores']: names.append(player['playerName']) oldMMRs.append(player['newMmr']) newMMRs.append(player['prevMmr']) if 'discordId' not in player.keys(): discordids.append(None) else: discordids.append(player['discordId']) for i in range(len(names)): oldRank = getRank(oldMMRs[i]) newRank = getRank(newMMRs[i]) if discordids[i] is None: member = findmember(ctx, names[i], ranks[oldRank]["roleid"]) if member is not None: await API.post.updateDiscord(names[i], member.id) if oldRank != newRank: if discordids[i] is None: member = findmember(ctx, names[i], ranks[oldRank]["roleid"]) else: member = ctx.guild.get_member(int(discordids[i])) if member is not None: memName = member.mention else: memName = names[i] rankChanges += ("%s -> %s\n" % (memName, ranks[newRank]["emoji"])) oldRole = ctx.guild.get_role(ranks[oldRank]["roleid"]) newRole = ctx.guild.get_role(ranks[newRank]["roleid"]) if member is not None and oldRole is not None and newRole is not None: if oldRole in member.roles: await member.remove_roles(oldRole) if newRole not in member.roles: await member.add_roles(newRole) channel = ctx.guild.get_channel(channels[tier]) if 'tableMessageId' in table.keys(): try: deleteMsg = await channel.fetch_message(table['tableMessageId'] ) if deleteMsg is not None: await deleteMsg.delete() except: pass if 'updateMessageId' in table.keys(): try: deleteMsg = await channel.fetch_message( table['updateMessageId']) if deleteMsg is not None: await deleteMsg.delete() except: pass success = await API.post.deleteTable(tableID) if success is True: await ctx.send("Successfully deleted table with ID %d\n%s" % (tableID, rankChanges)) else: await ctx.send("Table not found: Error %d" % success)
async def update(self, ctx, tableid: int, *, extraArgs=""): table = await API.get.getTable(tableid) if table is False: await ctx.send("Table couldn't be found") return workmsg = await ctx.send("Working...") success, multipliers = parseMultipliers(extraArgs) if success is False: await ctx.send(multipliers) return False if success is True and multipliers != {}: updatedMultipliers = await API.post.setMultipliers( tableid, multipliers) if updatedMultipliers is not True: await ctx.send("Error setting multipliers:\n%s" % updatedMultipliers) return False if table["tier"] == "F": await self.check_placements(ctx, table) success, table = await API.post.verifyTable(tableid) if success is False: await ctx.send(table) return False sizes = {'FFA': 1, '2v2': 2, '3v3': 3, '4v4': 4, '6v6': 6} size = sizes[table['format']] tier = table['tier'] tid = table['id'] if 'tableMessageId' in table.keys(): tableMsg = int(table['tableMessageId']) else: tableMsg = None placements = [] names = [] oldMMRs = [] newMMRs = [] peakMMRs = [] scores = [] discordids = [] channel = ctx.guild.get_channel(channels[tier.upper()]) for team in table['teams']: placements.append(team['rank']) team['scores'].sort(key=lambda p: p['score'], reverse=True) for player in team['scores']: names.append(player['playerName']) oldMMRs.append(player['prevMmr']) newMMRs.append(player['newMmr']) scores.append(player['score']) peakMMRs.append(player['isNewPeakMmr']) if 'discordId' not in player.keys(): discordids.append(None) else: discordids.append(player['discordId']) mmrTable = mmrTables.createMMRTable(size, tier, placements, names, scores, oldMMRs, newMMRs, tid, peakMMRs) rankChanges = "" for i in range(len(names)): oldRank = getRank(oldMMRs[i]) newRank = getRank(newMMRs[i]) if discordids[i] is None: member = findmember(ctx, names[i], ranks[oldRank]["roleid"]) if member is not None: await API.post.updateDiscord(names[i], member.id) if oldRank != newRank: if discordids[i] is None: member = findmember(ctx, names[i], ranks[oldRank]["roleid"]) else: member = ctx.guild.get_member(int(discordids[i])) if member is not None: memName = member.mention else: memName = names[i] rankChanges += ("%s -> %s\n" % (memName, ranks[newRank]["emoji"])) oldRole = ctx.guild.get_role(ranks[oldRank]["roleid"]) newRole = ctx.guild.get_role(ranks[newRank]["roleid"]) if member is not None and oldRole is not None and newRole is not None: if oldRole in member.roles: await member.remove_roles(oldRole) if newRole not in member.roles: await member.add_roles(newRole) f = discord.File(fp=mmrTable, filename='MMRTable.png', description=" ".join(names)) e = discord.Embed(title="MMR Table") idField = str(tid) if tableMsg is not None: try: reactMsg = await channel.fetch_message(tableMsg) except: reactMsg = None if reactMsg is not None: idField = "[%d](%s)" % (tid, reactMsg.jump_url) CHECK_BOX = "\U00002611" await reactMsg.add_reaction(CHECK_BOX) else: reactMsg = None e.add_field(name="ID", value=idField) e.add_field(name="Tier", value=tier.upper()) e.add_field(name="Updated by", value=ctx.author.mention) e.set_image(url="attachment://MMRTable.png") if reactMsg is not None: updateMsg = await reactMsg.reply(content=rankChanges, embed=e, file=f) else: updateMsg = await channel.send(content=rankChanges, embed=e, file=f) await workmsg.delete() if ctx.channel.id != channel.id: await ctx.send( f"Table ID `{tableid}` updated successfully; check {channel.mention} to view" ) else: try: await ctx.message.delete() except Exception as e: pass await API.post.setUpdateMessageId(tid, updateMsg.id) return True
async def addAndPlace(self, ctx, mkcid: int, mmr: int, member: discord.Member, *, name): if len(name) > 16: await ctx.send( "Names can only be up to 16 characters! Please tell the player to choose a different name" ) return if name.startswith("_") or name.endswith("_"): await ctx.send( "Nicknames cannot start or end with `_` (underscore)") return content = "Please confirm the player details within 30 seconds" e = discord.Embed(title="New Player") e.add_field(name="Name", value=name) e.add_field(name="MKC ID", value=mkcid) e.add_field(name="Placement MMR", value=mmr) e.add_field(name="Discord", value=member.mention) embedded = await ctx.send(content=content, embed=e) 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, player = await API.post.createPlayerWithMMR( mkcid, mmr, name, member.id) rank = getRank(mmr) rank_role_id = ranks[rank]["roleid"] rank_role = ctx.guild.get_role(rank_role_id) player_role = ctx.guild.get_role(player_role_ID) roleGiven = "" try: await member.add_roles(*[rank_role, player_role]) if member.display_name != name: await member.edit(nick=name) roleGiven += f"\nAlso gave {member.mention} {rank} role" except Exception as e: roleGiven += f"\nCould not give {rank} role to the player due to the following: {e}" pass await embedded.delete() if success is False: await ctx.send( "An error occurred while trying to add the player: %s" % player ) return url = ctx.bot.site_creds["website_url"] + "/PlayerDetails/%d" % int( player["id"]) await ctx.send(f"Successfully added the new player: {url}{roleGiven}")