async def handle(self, params, message, mentioned_user, client): messagetext = "" for discordUser in message.guild.members: if destinyID := lookupDestinyID(discordUser.id): messagetext += f'{discordUser.name} ({discordUser.nick}): https://raid.report/pc/{destinyID}\n' #TODO make console-flexible else: messagetext += f'{discordUser.name} ({discordUser.nick}): Not found\n'
async def handle(self, params, message, mentioned_user, client): # check if user has permission to use this command if not await hasAdminOrDevPermissions(message): return await message.channel.send('Updating DB...') update = updateActivityDB() await update.run(client) await message.channel.send('Assigning roles...') donemessage = "" for discordUser in message.guild.members: destinyID = lookupDestinyID(discordUser.id) if not destinyID: #await message.channel.send(f'No destinyID found for {discordUser.name}') continue async with message.channel.typing(): (newRoles, removeRoles) = await getPlayerRoles( destinyID, [role.name for role in discordUser.roles]) await assignRolesToUser(newRoles, discordUser, message.guild, reason="Role Update") await removeRolesFromUser(removeRoles, discordUser, message.guild, reason="Role Update") roletext = ', '.join(newRoles) donemessage += f'Assigned roles {roletext} to {discordUser.name}\n' await message.channel.send(donemessage)
async def handle(self, params, message, mentioned_user, client): # users = getEverything() # notokenlist = [] # for (discordSnowflake, destinyID, serverID, systemID, token, _refresh_token, token_expiry, refresh_token_expiry) in users: # if not token_expiry or not refresh_token_expiry: # if not _refresh_token: # notokenlist.append(str(discordSnowflake)) # continue # ret = await refresh_token(discordSnowflake) # if ret: # await message.channel.send(f"Updated tokens from discordID {discordSnowflake} destinyID {destinyID}") # else: # await message.channel.send(f"__**Update tokens from discordID {discordSnowflake} destinyID {destinyID} failed**__") # broketext = ", ".join(notokenlist) # await message.channel.send(f'following users did not have a token to refresh {broketext[:1900]}') # await message.channel.send(f'{broketext[1900:]}') # await message.channel.send("Done") userlist = [] for member in message.guild.members: if message.guild.get_role( 670384239489056768) in member.roles: #isdescend destinyid = lookupDestinyID(member.id) if await hasCollectible(destinyid, 2273453972): userlist.append(member.name) await message.channel.send(", ".join(userlist))
async def handle(self, params, message, mentioned_user, client): destinyID = lookupDestinyID(mentioned_user.id) system = lookupSystem(destinyID) if not (destinyID and system): await message.channel.send(embed=embed_message( 'Error', f'Problem getting your data, please `!registerdesc` to fix this' )) await message.channel.send(embed=embed_message( 'Nightfall Report', f'https://nightfall.report/guardian/{system}/{destinyID}'))
async def handle(self, params, message, mentioned_user, client): # check perm for other user mention, otherwise abort if not (await hasMentionPermission(message, mentioned_user)): return discordID = mentioned_user.id destinyID = lookupDestinyID(discordID) anyCharID = (await getCharacterList(destinyID))[1][0] async with message.channel.typing(): materialtext = await getSpiderMaterials(discordID, destinyID, anyCharID) if 'embed' in materialtext: await message.reply(embed=materialtext['embed']) elif materialtext['result']: await message.reply(materialtext['result']) else: await message.channel.send(materialtext['error'])
async def handle(self, params, message, mentioned_user, client): given_role = " ".join(params) f_year = "" f_role = "" found = False for topic, roles in requirementHashes.items(): if found: break else: for role, roledata in roles.items(): if given_role.lower() == role.lower(): found = True f_year = topic f_role = role break if not found: await message.channel.send(embed=embed_message( 'Error', f"I don't know that role, please make sure it's spelled correctly!" )) return #Get user details and run analysis async with message.channel.typing(): destinyID = lookupDestinyID(mentioned_user.id) wait_msg = await message.channel.send( embed=embed_message(f'Hi, {mentioned_user.display_name}', "Your data will be available shortly")) await updateDB(destinyID) reqs = await hasRole(destinyID, f_role, f_year, br=False) print(reqs[1]) embed = embed_message( f"{mentioned_user.display_name}'s '{f_role}' Eligibility") for req in reqs[1]: embed.add_field(name=req, value=reqs[1][req], inline=True) await wait_msg.delete() await message.channel.send(embed=embed, reference=message, mention_author=True)
async def handle(self, params, message, mentioned_user, client): # check if user has permission to use this command if not await hasAdminOrDevPermissions(message): return # if disord info is given if mentioned_user is not message.author: discordID = mentioned_user.id destinyID = lookupDestinyID(discordID) # if destinyID is given else: destinyID = params[0] discordID = lookupDiscordID(destinyID) mentioned_user = client.get_user(discordID) if not mentioned_user: await message.reply( f"I don't know a user with the destinyID `{destinyID}`") await message.reply(embed=embed_message( f'DB infos for {mentioned_user.name}', f"""DiscordID - `{discordID}` \nDestinyID: `{destinyID}` \nSystem - `{lookupSystem(destinyID)}` \nSteamName - `{(await getProfile(destinyID, 100))["profile"]["data"]["userInfo"]["displayName"]}` \nHasToken - `{bool((await handleAndReturnToken(discordID))["result"])}`""" ))
async def handle(self, params, message, mentioned_user, client): name = params[0] destinyID = lookupDestinyID(mentioned_user.id) if not destinyID: await message.channel.send( f'Unable to get your destiny-stats. Please contact a {message.guild.get_role(dev_role_id)}' ) return if name == 'resurrections': given = await getIntStat(destinyID, 'resurrectionsPerformed') received = await getIntStat(destinyID, 'resurrectionsReceived') await message.channel.send( f'{mentioned_user.mention}, you have revived **{given}** people and got revived **{received}** times! 🚑' ) elif name == 'meleekills': melees = await getIntStat(destinyID, 'weaponKillsMelee') await message.channel.send( f'{mentioned_user.mention}, you have punched **{melees}** enemies to death! 🖍️' ) elif name == 'superkills': melees = await getIntStat(destinyID, 'weaponKillsSuper') await message.channel.send( f'{mentioned_user.mention}, you have used your supers to extinguish **{melees}** enemies! <a:PepoCheer:670678495923273748>' ) elif name == 'longrangekill': snips = await getIntStat(destinyID, 'longestKillDistance') await message.channel.send( f'{mentioned_user.mention}, you sniped an enemy as far as **{snips}** meters away <:Kapp:670369121808154645>' ) elif name == 'deaths': stats = [] for charid, chardesc in await getCharactertypeList(destinyID): stats.append((chardesc, await getCharStats(destinyID, charid, 'deaths'))) printout = "\n".join([ f'Your {chardesc} has {"{:,}".format(count)} deaths' for chardesc, count in stats ]) await message.channel.send(printout) elif name == 'help': await message.channel.send(f''' {message.author.mention}, use those arguments for !stat *<argument>*: > **resurrections**: *Shows how many players you revived and how many times you got revived* > **meleekills**: *Shows how many enemies you've punched to death* > **superkills**: *Shows how many enemies you've killed with your super* > **longrangekill**: *Shows how far you've sniped* > **top10raidguns**: *Shows a piechart of your favourite guns* other possible stats include {", ".join(await getPossibleStats())} ''') elif name in await getPossibleStats(): stats = [] for charid, chardesc in await getCharactertypeList(destinyID): stats.append((chardesc, await getCharStats(destinyID, charid, name))) printout = "\n".join([ f'Your {chardesc} has {"{:,}".format(int(count))} {name}' for chardesc, count in stats ]) await message.channel.send(printout) else: await message.channel.send( 'Use !stat help for a list of commands :)')
async def handle(self, params, message, mentioned_user, client): async with message.channel.typing(): # get basic user data destinyID = lookupDestinyID(mentioned_user.id) system = lookupSystem(destinyID) heatmap_url = f"https://chrisfried.github.io/secret-scrublandeux/guardian/{system}/{destinyID}" characterIDs, character_data = await getCharacterInfoList(destinyID ) character_playtime = {} # in seconds for characterID in characterIDs: character_playtime[characterID] = await getCharStats( destinyID, characterID, "secondsPlayed") embed = embed_message( f"{mentioned_user.display_name}'s Destiny Stats", f"**Total Playtime:** {str(datetime.timedelta(seconds=sum(character_playtime.values())))} \n[Click to see your heatmap]({heatmap_url})", "For info on achievable discord roles, type !roles") """ char info field """ embed.add_field(name="", value=f"__**Characters:**__", inline=False) for characterID in characterIDs: text = f"""Playtime: {str(datetime.timedelta(seconds=character_playtime[characterID]))} \n\nPower: {int(await getCharStats(destinyID, characterID, "highestLightLevel")):,} \nActivities: {int(await getCharStats(destinyID, characterID, "activitiesCleared")):,} \nKills: {int(await getCharStats(destinyID, characterID, "kills")):,} \nDeaths: {int(await getCharStats(destinyID, characterID, "deaths")):,} \nEfficiency: {round(await getCharStats(destinyID, characterID, "efficiency"), 2)}""" embed.add_field( name= f"""{character_data[characterID]["class"]} ({character_data[characterID]["race"]} / {character_data[characterID]["gender"]})""", value=text, inline=True) """ triumph info field """ embed.add_field(name="", value=f"__**Triumphs:**__", inline=False) # get triumph data triumphs = await getProfile(destinyID, 900) embed.add_field( name="Lifetime Triumph Score", value= f"""{triumphs["profileRecords"]["data"]["lifetimeScore"]:,}""", inline=True) embed.add_field( name="Active Triumph Score", value= f"""{triumphs["profileRecords"]["data"]["activeScore"]:,}""", inline=True) embed.add_field( name="Legacy Triumph Score", value= f"""{triumphs["profileRecords"]["data"]["legacyScore"]:,}""", inline=True) # get triumph completion rate triumphs_data = triumphs["profileRecords"]["data"]["records"] triumphs_completed = 0 triumphs_no_data = 0 for triumph in triumphs_data.values(): status = True if "objectives" in triumph: for part in triumph['objectives']: status &= part['complete'] elif "intervalObjectives" in triumph: for part in triumph['intervalObjectives']: status &= part['complete'] else: triumphs_no_data += 1 continue if status: triumphs_completed += 1 embed.add_field( name="Triumphs", value= f"{triumphs_completed} / {len(triumphs_data) - triumphs_no_data}", inline=True) # get seal completion rate seals, completed_seals = await getPlayerSeals(destinyID) embed.add_field(name="Seals", value=f"{len(completed_seals)} / {len(seals)}", inline=True) # collection completion data collections_data = (await getProfile( destinyID, 800))["profileCollectibles"]["data"]["collectibles"] collectibles_completed = 0 for collectible in collections_data.values(): if collectible['state'] & 1 == 0: collectibles_completed += 1 embed.add_field( name="Collections", value=f"{collectibles_completed} / {len(collections_data)}", inline=True) await message.reply(embed=embed)
async def handle(self, params, message, mentioned_user, client): async with message.channel.typing(): destinyID = lookupDestinyID(mentioned_user.id) await updateDB(destinyID) await message.channel.send(await getFlawlessList(destinyID))
async def handle(self, params, message, mentioned_user, client): destinyID = lookupDestinyID(mentioned_user.id) await updateDB(destinyID) await message.channel.send(getLastActivity(destinyID, mode=4))
async def handle(self, params, message, mentioned_user, client): # check perm for mention, otherwise abort if not (await hasMentionPermission(message, mentioned_user)): return destinyID = lookupDestinyID(mentioned_user.id) if not destinyID: await message.channel.send(embed=embed_message( 'Error', 'Didn\'t find your destiny profile, sorry')) return wait_msg = await message.channel.send( embed=embed_message(f'Hi, {mentioned_user.display_name}', "Your data will be available soon™")) await updateDB(destinyID) print('done updating db') async with message.channel.typing(): roles_at_start = [role.name for role in mentioned_user.roles] (roleList, removeRoles) = await getPlayerRoles(destinyID, roles_at_start) roles_assignable = await assignRolesToUser(roleList, mentioned_user, message.guild, reason="Role Update") await removeRolesFromUser(removeRoles, mentioned_user, message.guild, reason="Role Update") if not roles_assignable: await wait_msg.delete() await message.channel.send(embed=embed_message( 'Error', f'You seem to have been banned from acquiring any roles.\nIf you believe this is a mistake, refer to the admin team or DM <@386490723223994371>' )) return #roles_now = [role.name for role in mentioned_user.roles] old_roles = {} updated_roles_member = await mentioned_user.guild.fetch_member( mentioned_user.id) roles_now = [role.name for role in updated_roles_member.roles] new_roles = {} for topic, topicroles in requirementHashes.items(): topic = topic.replace("Y1", "Year One") topic = topic.replace("Y2", "Year Two") topic = topic.replace("Y3", "Year Three") topic = topic.replace("Y4", "Year Four") topic = topic.replace("Addition", "Miscellaneous") for role in topicroles.keys(): if role in roles_at_start: try: old_roles[topic].append(role) except KeyError: old_roles[topic] = [role] elif (role not in roles_at_start) and (role in roles_now): try: new_roles[topic].append(role) except KeyError: new_roles[topic] = [role] if not roleList: await wait_msg.delete() await message.channel.send(embed=embed_message( 'Error', f'You don\'t seem to have any roles.\nIf you believe this is an Error, refer to one of the <@&{dev_role_id}>\nOtherwise check <#686568386590802000> to see what you could acquire' )) return embed = embed_message(f"{mentioned_user.display_name}'s new Roles", f'__Previous Roles:__') if not old_roles: embed.add_field(name=f"You didn't have any roles before", value="", inline=True) for topic in old_roles: roles = [] for role in topic: roles.append(role) embed.add_field(name=topic, value="\n".join(old_roles[topic]), inline=True) embed.add_field(name="", value=f"__New Roles:__", inline=False) if not new_roles: embed.add_field(name="No new roles have been achieved", value="", inline=True) for topic in new_roles: roles = [] for role in topic: roles.append(role) embed.add_field(name=topic, value="\n".join(new_roles[topic]), inline=True) await wait_msg.delete() await message.channel.send(embed=embed, reference=message, mention_author=True)
async def handle(self, params, message, mentioned_user, client, old_message=None, seasonal_challenges=None, user_triumphs=None, week=None): # recursive commmand. if this is the first time this command is called get the data if not old_message: async with message.channel.typing(): # get seasonal challenge info seasonal_challenges = await getSeasonalChallengeInfo() index = list(seasonal_challenges) # get the week (or the default - whatever is first) week = f"Week {params[0]}" if params else "" if week not in seasonal_challenges: week = index[0] # get player triumphs destinyID = lookupDestinyID(mentioned_user.id) user_triumphs = await getTriumphsJSON(destinyID) else: index = list(seasonal_challenges) embed = embed_message( f"{mentioned_user.display_name}'s Seasonal Challenges - {week}") # add the triumphs and what the user has done for triumph in seasonal_challenges[week]: user_triumph = user_triumphs[str(triumph["referenceID"])] # calculate completion rate rate = [] for objective in user_triumph["objectives"]: rate.append(objective["progress"] / objective["completionValue"] if not objective["complete"] else 1) rate = sum(rate) / len(rate) # make emoji art for completion rate rate_text = "|" if rate > 0: rate_text += "🟩" else: rate_text += "🟥" if rate > 0.25: rate_text += "🟩" else: rate_text += "🟥" if rate > 0.5: rate_text += "🟩" else: rate_text += "🟥" if rate == 1: rate_text += "🟩" else: rate_text += "🟥" rate_text += "|" # add field to embed embed.add_field(name=f"""{triumph["name"]} {rate_text}""", value=triumph["description"], inline=False) # send message if not old_message: old_message = await message.reply(embed=embed) else: await old_message.edit(embed=embed) # get current indexes - to look whether to add arrows to right current_index = index.index(week) max_index = len(index) - 1 # add reactions if current_index > 0: await old_message.add_reaction("⬅") if current_index < max_index: await old_message.add_reaction("➡") # wait 60s for reaction def check(reaction_reaction, reaction_user): return (str(reaction_reaction.emoji) == "⬅" or str(reaction_reaction.emoji) == "➡") \ and (reaction_reaction.message.id == old_message.id) \ and (message.author == reaction_user) try: reaction, _ = await client.wait_for('reaction_add', check=check, timeout=60) except asyncio.TimeoutError: # clear reactions await old_message.clear_reactions() else: # clear reactions await old_message.clear_reactions() # recursively call this function new_index = index[current_index - 1] if str( reaction.emoji) == "⬅" else index[current_index + 1] new_call = challenges() await new_call.handle(params, message, mentioned_user, client, old_message, seasonal_challenges, user_triumphs, new_index)
async def handle(self, params, message, mentioned_user, client): async with message.channel.typing(): # get params weapon_name, showcase, mode, activity_hash, start, end, char_class, stat = await compute_parameters( message, params, self.activities, self.classes, self.stats) destinyID = lookupDestinyID(mentioned_user.id) charID = await getCharacterID( destinyID, self.classes[char_class]) if char_class else None # get weapon info weapon_name, weapon_hashes = await searchForItem( client, message, weapon_name) if not weapon_name: return # get all weapon infos kwargs = { "characterID": charID, "mode": mode, "activityID": activity_hash, "start": start, "end": end } # loop through every variant of the weapon and add that together result = [] for entry in weapon_hashes: result.extend( getWeaponInfo( destinyID, entry, **{k: v for k, v in kwargs.items() if v is not None})) # throw error if no weapon if not result: await message.reply(embed=embed_message( "Error", f'No weapon stats found for {weapon_name}')) return if showcase == "number": # get data kills = 0 precision_kills = 0 max_kills = 0 max_kills_id = None for instanceID, uniqueweaponkills, uniqueweaponprecisionkills in result: kills += uniqueweaponkills precision_kills += uniqueweaponprecisionkills if uniqueweaponkills > max_kills: max_kills = uniqueweaponkills max_kills_id = instanceID percent_precision_kills = precision_kills / kills if kills else 0 avg_kills = kills / len(result) res = await getPgcrActivity(max_kills_id) max_kills_date = res[3] max_kills_mode = getDestinyDefinition( "DestinyActivityModeDefinition", res[5])[2] max_kills_name = getDestinyDefinition( "DestinyActivityDefinition", res[2])[2] # make and post embed embed = embed_message( f"{weapon_name} stats for {mentioned_user.display_name}", f"", f"""mode={mode}, start={start.strftime('%d/%m/%Y')}, end={end.strftime('%d/%m/%Y')}{", activityHash=" + str(activity_hash) if activity_hash else ""}{", class=" + str(char_class) if char_class else ""}""" ) embed.add_field(name="Total Kills", value=f"**{kills:,}**", inline=True) embed.add_field(name="Total Precision Kills", value=f"**{precision_kills:,}**", inline=True) embed.add_field( name="% Precision Kills", value=f"**{round(percent_precision_kills*100, 2)}%**", inline=True) embed.add_field( name="Average Kills", value= f"**{round(avg_kills, 2)}**\nIn {len(result)} Activities", inline=True) embed.add_field( name="Maximum Kills", value= f"**{max_kills:,}**\nIn Activity ID: {max_kills_id}\n{max_kills_mode} - {max_kills_name}\nOn: {max_kills_date.strftime('%d/%m/%y')}", inline=True) await message.reply(embed=embed) elif showcase == "graph": # get the time instead of the instance id and sort it so the earliest date is first weapon_hashes = [] for instanceID, uniqueweaponkills, uniqueweaponprecisionkills in result: instance_time = await getPgcrActivity(instanceID)[3] weapon_hashes.append((instance_time, uniqueweaponkills, uniqueweaponprecisionkills)) weapon_hashes = sorted(weapon_hashes, key=lambda x: x[0]) # get clean, relevant data in a DF. easier for the graph later df = pd.DataFrame(columns=["datetime", "statistic"]) name = "" statistic1 = 0 statistic2 = 0 time = weapon_hashes[0][0] for instance_time, uniqueweaponkills, uniqueweaponprecisionkills in weapon_hashes: if instance_time.date() == time.date(): if stat == "kills": statistic1 += uniqueweaponkills name = "Kills" elif stat == "precisionkills": statistic1 += uniqueweaponprecisionkills name = "Precision Kills" elif stat == "precisionkillspercent": statistic1 += uniqueweaponkills statistic2 += uniqueweaponprecisionkills name = "% Precision Kills" time = instance_time else: # append to DF entry = { 'datetime': time.date(), 'statistic': statistic2 / statistic1 if stat == "precisionkillspercent" else statistic1 } df = df.append(entry, ignore_index=True) # save new data if stat == "kills": statistic1 = uniqueweaponkills name = "Kills" elif stat == "precisionkills": statistic1 = uniqueweaponprecisionkills name = "Precision Kills" elif stat == "precisionkillspercent": statistic1 = uniqueweaponkills statistic2 = uniqueweaponprecisionkills name = "% Precision Kills" time = instance_time # append to DF entry = { 'datetime': time, 'statistic': statistic2 / statistic1 if stat == "precisionkillspercent" else statistic1 } df = df.append(entry, ignore_index=True) # convert to correct file types df['datetime'] = pd.to_datetime(df['datetime']) df['statistic'] = pd.to_numeric(df['statistic']) # building the graph # Create figure and plot space fig, ax = plt.subplots(figsize=(20, 10)) ax.yaxis.grid(True) # filling bar chart ax.bar(df['datetime'], df['statistic'], color="#45b6fe") # Set title and labels for axes ax.set_title( f"{weapon_name} stats for {mentioned_user.display_name}", fontweight="bold", size=30, pad=20) ax.set_xlabel("Date", fontsize=20) ax.set_ylabel(name, fontsize=20) # saving file title = "weapon.png" plt.savefig(title) # sending them the file await message.reply( f"""*mode={mode}, start={start.strftime('%d/%m/%Y')}, end={end.strftime('%d/%m/%Y')}{", activityHash=" + str(activity_hash) if activity_hash else ""}{", class=" + str(char_class) if char_class else ""}*""", file=discord.File(title)) # delete file os.remove(title)
async def handle(self, params, message, mentioned_user, client): async with message.channel.typing(): # get params weapon_name, _, mode, activity_hash, start, end, char_class, stat = await compute_parameters( message, params, self.activities, self.classes, self.stats) destinyID = lookupDestinyID(mentioned_user.id) charID = await getCharacterID( destinyID, self.classes[char_class]) if char_class else None # get the real weapon name if weapon_name: weapon_name, _ = await searchForItem(client, message, weapon_name) if not weapon_name: return # get all weaponID infos kwargs = { "characterID": charID, "mode": mode, "activityID": activity_hash, "start": start, "end": end } result = getTopWeapons( destinyID, **{k: v for k, v in kwargs.items() if v is not None}) # loop through that and get data data = [] for weaponID, uniqueweaponkills, uniqueweaponprecisionkills in result: # get the name weapon_data = [ (await getDestinyDefinition("DestinyInventoryItemDefinition", weaponID))[2] ] if stat == "kills": statistic = uniqueweaponkills weapon_data.append(statistic) weapon_data.append(f"{statistic:,}") elif stat == "precisionkills": statistic = uniqueweaponprecisionkills weapon_data.append(statistic) weapon_data.append(f"{statistic:,}") elif stat == "precisionkillspercent": statistic = uniqueweaponkills / uniqueweaponprecisionkills if uniqueweaponprecisionkills != 0 else 0 weapon_data.append(statistic) weapon_data.append(f"{round(statistic*100, 2)}%") data.append(tuple(weapon_data)) # sort by index specified sorted_data = sorted(data, key=lambda x: x[1], reverse=True) # get the data for the embed i = 0 ranking = [] found = False if weapon_name else True for name, _, statistic in sorted_data: i += 1 if len(ranking) < 12: # setting a flag if name is in list if weapon_name == name: found = True ranking.append( write_line(i, f"""[{name}]""", stat.capitalize(), statistic)) else: ranking.append( write_line(i, name, stat.capitalize(), statistic)) # looping through rest until original user is found elif (len(ranking) >= 12) and (not found): # adding only this name if weapon_name == name: ranking.append("...") ranking.append( write_line(i, name, stat.capitalize(), statistic)) found = True break else: break # write "0" as data, since it is not in there if not found: ranking.append("...") ranking.append(write_line(i, weapon_name, stat.capitalize(), 0)) # make and post embed embed = embed_message( f"Top Weapons for {mentioned_user.display_name}", "\n".join(ranking), f"""mode={mode}, start={start.strftime('%d/%m/%Y')}, end={end.strftime('%d/%m/%Y')}{", activityHash=" + str(activity_hash) if activity_hash else ""}{", class=" + str(char_class) if char_class else ""}""" ) await message.reply(embed=embed)