8000 [LevelUp] Extend external API and add dynamic command cooldown and unlocking based on level by brandons209 · Pull Request #231 · vertyco/vrt-cogs · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

[LevelUp] Extend external API and add dynamic command cooldown and unlocking based on level #231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
8000 Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8000
43 changes: 43 additions & 0 deletions levelup/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ View User Profile<br/>
- Aliases: `pf`
- Cooldown: `3 per 10.0 seconds`
- Checks: `server_only`
# [p]lvlupnotify (Hybrid Command)
Toggles level up notifications for a user
- Usage: `[p]lvlupnotify`
- Slash Usage: `/lvlupnotify`
- Aliases: `notify`
- Checks: `server_only`
# [p]prestige (Hybrid Command)
Prestige your rank!<br/>
Once you have reached this servers prestige level requirement, you can<br/>
Expand Down Expand Up @@ -583,6 +589,37 @@ The following placeholders can be used:<br/>
### [p]levelset levelupmessages view
View the current level up alert messages<br/>
- Usage: `[p]levelset levelupmessages view`
## [p]levelset lvlreq
Manage level requirement for commands
### [p]levelset lvlreq add
Add a level requirement to the command
- Usage: `[p]levelset lvlreq add <level> <command>`
### [p]levelset lvlreq del
Remove a level requirement for a command
- Usage: `[p]levelset lvlreq del <command>`
### [p]levelset lvlreq list
List all commands and their level requirements
- Usage: `[p]levelset lvlreq list`
## [p]levelset cooldowns
Manage per level command cooldowns
### [p]levelset cooldowns add
Add a cooldown for a command based on level
Multiple cooldown levels can be set, the cooldown will be applied to members at the specified level and under
Warning: This will override any default cooldowns for the command

Example:
[p]lset cooldowns add 5 15 mycommand
[p]lset cooldowns add 10 5 mycommand
Members who are level [0, 5] will have a cooldown of 15 seconds for mycommand (including members at level 5)
Members who are level (5, 10] will have a cooldown of 5 seconds (level 6 to level 10)
Members above level 10 will have no cooldown
- Usage: `[p]levelset cooldowns add <level> <cooldown> <command>`
### [p]levelset cooldowns del
Remove a level cooldown for a command
- Usage: `[p]levelset cooldowns del <level> <command>`
### [p]levelset cooldowns list
List all commands and their cooldowns per level
- Usage: `[p]levelset cooldowns list`
## [p]levelset view
View all LevelUP settings<br/>
- Usage: `[p]levelset view`
Expand Down Expand Up @@ -710,6 +747,12 @@ Channels in the ignore list don't gain XP<br/>

Use the command with a channel already in the ignore list to remove it<br/>
- Usage: `[p]levelset ignore channel <channel>`
### [p]levelset ignore notify
Add/Remove a channel in the notify ignore list<br/>
Channels in the notify ignore list will have level up notifications suppressed<br/>

Use the command with a channel already in the notify ignore list to remove it<br/>
- Usage: `[p]levelset ignore notify <channel>`
### [p]levelset ignore role
Add/Remove a role in the ignore list<br/>
Members with roles in the ignore list don't gain XP<br/>
Expand Down
234 changes: 228 additions & 6 deletions levelup/commands/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,10 @@
from time import perf_counter

import discord
from discord.ext.commands import cooldowns
from redbot.core import commands
from redbot.core.i18n import Translator, cog_i18n
from redbot.core.utils.chat_formatting import (
box,
humanize_number,
humanize_timedelta,
pagify,
)
from redbot.core.utils.chat_formatting import box, humanize_number, humanize_timedelta, pagify, error, warning, info

from ..abc import MixinMeta
from ..common import const, utils
Expand All @@ -29,6 +25,200 @@ async def levelset(self, ctx: commands.Context):
"""Configure LevelUp Settings"""
pass

@levelset.group(name="bypass")
async def levelset_bypass(self, ctx: commands.Context):
"""Set roles/members that bypass level requirement and cooldowns set"""
pass

@levelset_bypass.command(name="member")
async def levelset_bypass_member(self, ctx: commands.Context, member: t.Optional[discord.Member] = None):
"""
Add a member to the bypass list.

Run with no arguments to see all the bypass members
Run with a member already in the list to remove them from the list
"""
conf = self.db.get_conf(ctx.guild)
if member is None:
if not conf.cmd_bypass_member:
await ctx.reply(
info("No members configured for bypassing command restrictions."),
delete_after=30,
mention_author=False,
)
return
text = "# Bypass Members:\n"
for member_id in conf.cmd_bypass_member.copy():
member = ctx.guild.get_member(member_id)
if member is None: # member left, remove from conf
conf.cmd_bypass_member.remove(member_id)
continue
text += f"- {member.mention}\n"
pages = list(pagify(text))
await ctx.send_interactive(pages)
return
if member.id not in conf.cmd_bypass_member:
conf.cmd_bypass_member.append(member.id)
else:
conf.cmd_bypass_member.remove(member.id)
await ctx.reply(
info(f"Member {member.mention} removed from command bypasses."), delete_after=30, mention_author=False
)
await ctx.tick()

@levelset_bypass.command(name="role")
async def levelset_bypass_role(self, ctx: commands.Context, role: t.Optional[discord.Role] = None):
"""
Add a role to the bypass list.

Run with no arguments to see all the bypass roles
Run with a role already in the list to remove it from the list
"""
conf = self.db.get_conf(ctx.guild)
if role is None:
if not conf.cmd_bypass_roles:
await ctx.reply(
info("No roles configured for bypassing command restrictions."),
delete_after=30,
mention_author=False,
)
return
text = "# Bypass Roles:\n"
for role_id in conf.cmd_bypass_roles.copy():
role = ctx.guild.get_role(role_id)
if role is None: # role gone, remove from conf
conf.cmd_bypass_roles.remove(role_id)
continue
text += f"- {role.mention}\n"
pages = list(pagify(text))
await ctx.send_interactive(pages)
return
if role.id not in conf.cmd_bypass_roles:
conf.cmd_bypass_roles.append(role.id)
else:
conf.cmd_bypass_roles.remove(role.id)
await ctx.reply(
info(f"Role {role.mention} removed from command bypasses."),
delete_after=30,
mention_author=False,
)
await ctx.tick()

@levelset.group(name="cooldowns")
async def levelset_cooldowns(self, ctx: commands.Context):
"""Manage per level command cooldowns"""
pass

@levelset_cooldowns.command(name="add")
async def levelset_cooldowns_add(self, ctx: commands.Context, level: int, cooldown: int, *, command: str):
"""
Add a cooldown for a command based on level
Multiple cooldown levels can be set, the cooldown will be applied to members at the specified level and under

**Warning:** This will override any default cooldowns for the command

Example:
[p]lset cooldowns add 5 15 mycommand
[p]lset cooldowns add 10 5 mycommand
Members who are level [0, 5] will have a cooldown of 15 seconds for mycommand (including members at level 5)
Members who are level (5, 10] will have a cooldown of 5 seconds
Members above level 10 will have no cooldown
"""
if self.bot.get_command(command) is None:
return await ctx.reply(error(f"Invalid command: `{command}`"), delete_after=30, mention_author=False)
conf = self.db.get_conf(ctx.guild)
command_cooldowns = conf.cmd_cooldowns.get(command, {})
command_cooldowns[level] = cooldown
conf.cmd_cooldowns[command] = command_cooldowns
self.save()
await ctx.tick()

@levelset_cooldowns.command(name="del")
async def levelset_cooldowns_del(self, ctx: commands.Context, level: int, *, command: str):
"""Delete a cooldown for a specific command and level"""
if self.bot.get_command(command) is None:
return await ctx.reply(error(f"Invalid command: `{command}`"), delete_after=30, mention_author=False)
conf = self.db.get_conf(ctx.guild)
command_cooldowns = conf.cmd_cooldowns.get(command, {})
if not command_cooldowns:
return await ctx.reply(
warning(f"No cooldowns are set for `{command}`"), delete_after=30, mention_author=False
)
if level not in command_cooldowns:
return await ctx.reply(
warning(f"There is no cooldown for level {level}"), delete_after=30, mention_author=False
)
del command_cooldowns[level]
conf.cmd_cooldowns[command] = command_cooldowns
if command_cooldowns == {}:
del conf.cmd_cooldowns[command]

self.save()
await ctx.tick()

@levelset_cooldowns.command(name="list")
async def levelset_cooldowns_list(self, ctx: commands.Context):
"""List cooldowns for all commands"""
conf = self.db.get_conf(ctx.guild)
cmds = conf.cmd_cooldowns
if not cmds:
await ctx.send(info("No commands configured."))
return

msg = f"# Cooldowns for {ctx.guild.name}\n"
for cmd, cooldowns in cmds.items():
msg += f"- `{cmd}`:\n"
for level, cooldown in cooldowns.items():
msg += f" - Level `{level}`: `{humanize_timedelta(seconds=cooldown)}`\n"

for page in pagify(msg):
await ctx.send(page)

@levelset.group(name="lvlreq")
async def levelset_lvlreq(self, ctx: commands.Context):
"""Manage level requirement for commands"""
pass

@levelset_lvlreq.command(name="add")
async def levelset_lvlreq_add(self, ctx: commands.Context, level: int, *, command: str):
"""Add a level requirement to a command."""
if self.bot.get_command(command) is None:
return await ctx.reply(error(f"Invalid command: `{command}`"), delete_after=30, mention_author=False)
conf = self.db.get_conf(ctx.guild)
conf.cmd_requirements[command] = level
self.save()
await ctx.tick()

@levelset_lvlreq.command(name="del")
async def levelset_lvlreq_del(self, ctx: commands.Context, *, command: str):
"""Delete a level requirement for a command."""
conf = self.db.get_conf(ctx.guild)
if command not in conf.cmd_requirements:
return await ctx.reply(
warning(f"No level requirement was set for `{command}`"),
delete_after=30,
mention_author=False,
)
del conf.cmd_requirements[command]
self.save()
await ctx.tick()

@levelset_lvlreq.command(name="list")
async def levelset_lvlreq_list(self, ctx: commands.Context):
"""List all command level requirements"""
conf = self.db.get_conf(ctx.guild)
cmds = conf.cmd_requirements
if not cmds:
await ctx.send(info("No commands configured."))
return

msg = f"# Command Level Requirements for {ctx.guild.name}\n"
for cmd, level in cmds.items():
msg += f"- `{cmd}`: `{level}`\n"

for page in pagify(msg):
await ctx.send(page)

@levelset.command(name="view")
@commands.bot_has_permissions(embed_links=True)
async def view_settings(self, ctx: commands.Context):
Expand Down Expand Up @@ -181,6 +371,15 @@ def add_field(embed: discord.Embed, name: str, value: str):
[f"<#{channel_id}>" for channel_id in conf.ignoredchannels if ctx.guild.get_channel(channel_id)]
)
add_field(embed, _("Ignored Channels"), joined)
if conf.ignore_notification_channels:
joined = ", ".join(
[
f"<#{channel_id}>"
for channel_id in conf.ignore_notification_channels
if ctx.guild.get_channel(channel_id)
]
)
add_field(embed, _("Notification Ignored Channels"), joined)
if conf.ignoredusers:
joined = ", ".join([f"<@{user_id}>" for user_id in conf.ignoredusers if ctx.guild.get_member(user_id)])
add_field(embed, _("Ignored Users"), joined)
Expand Down Expand Up @@ -694,6 +893,29 @@ async def ignore(self, ctx: commands.Context):
"""Base command for all ignore lists"""
pass

@ignore.command(name="notify")
async def ignore_notify(
self,
ctx: commands.Context,
*,
channel: t.Union[discord.TextChannel, discord.VoiceChannel, discord.CategoryChannel, discord.ForumChannel],
):
"""
Add/Remove a channel in the notify ignore list
Channels in the notify ignore list won't have level up notifications sent there

Use the command with a channel already in the notify ignore list to remove it
"""
conf = self.db.get_conf(ctx.guild)
if channel.id in conf.ignore_notification_channels:
conf.ignore_notification_channels.remove(channel.id)
txt = _("Channel {} has been removed from the notify ignore list").format(channel.mention)
else:
conf.ignore_notification_channels.append(channel.id)
txt = _("Channel {} has been added to the notify ignore list").format(channel.mention)
self.save()
await ctx.send(txt)

@ignore.command(name="channel")
async def ignore_channel(
self,
Expand Down
45 changes: 38 additions & 7 deletions levelup/commands/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,33 @@ async def profile_data(self, ctx: commands.Context, user_id: int):
)
await ctx.send(txt)

@commands.hybrid_command(name="lvlupnotify", aliases=["notify"])
@commands.guild_only()
@commands.cooldown(3, 10, commands.BucketType.user)
async def level_up_notify(self, ctx: commands.Context):< CAA0 /td>
"""
If enabled, level up notifications won't be sent for you in the server
"""
conf = self.db.get_conf(ctx.guild)
profile = conf.get_profile(ctx.author.id)

profile.ignore_level_up_notification = not profile.ignore_level_up_notification

if profile.ignore_level_up_notification:
await ctx.reply(
"Level up notifications are now **disabled** for you.",
mention_author=False,
delete_after=30,
)
else:
await ctx.reply(
"Level up notifications are now **enabled** for you.",
mention_author=False,
delete_after=30,
)

self.save()

@commands.hybrid_command(name="profile", aliases=["pf"])
@commands.guild_only()
@commands.cooldown(3, 10, commands.BucketType.user)
Expand Down Expand Up @@ -226,13 +253,17 @@ async def prestige(self, ctx: commands.Context):
if not role:
return await ctx.send(_("The prestige role for this level no longer exists, please contact an admin!"))

current_xp = int(profile.xp)
xp_at_prestige = conf.algorithm.get_xp(conf.prestigelevel)
leftover_xp = current_xp - xp_at_prestige if current_xp > xp_at_prestige else 0
newlevel = conf.algorithm.get_level(leftover_xp)

profile.level = newlevel
profile.xp = leftover_xp
# current_xp = int(profile.xp)
# xp_at_prestige = conf.algorithm.get_xp(conf.prestigelevel)
# leftover_xp = current_xp - xp_at_prestige if current_xp > xp_at_prestige else 0
# newlevel = conf.algorithm.get_level(leftover_xp)
# change prestige to work by levels instead of exp
current_level = profile.level
new_level = max(1, current_level - conf.prestigelevel)
new_xp = conf.algorithm.get_xp(new_level)

profile.level = new_level
profile.xp = new_xp
profile.prestige = next_prestige
self.save()

Expand Down
Loading
0