fix lock and lockdown cogs
This commit is contained in:
parent
54dd6f40a8
commit
e80afc97ad
2 changed files with 252 additions and 190 deletions
|
@ -1,113 +1,117 @@
|
||||||
"""J.A.R.V.I.S. LockCog."""
|
"""J.A.R.V.I.S. LockCog."""
|
||||||
# from dis_snek import Scale
|
from typing import Union
|
||||||
#
|
|
||||||
# # TODO: Uncomment 99% of code once implementation is figured out
|
from dis_snek import InteractionContext, Scale
|
||||||
# from contextlib import suppress
|
from dis_snek.client.utils.misc_utils import get
|
||||||
# from typing import Union
|
from dis_snek.models.discord.channel import GuildText, GuildVoice
|
||||||
#
|
from dis_snek.models.discord.enums import Permissions
|
||||||
# from dis_snek import InteractionContext, Scale, Snake
|
from dis_snek.models.snek.application_commands import (
|
||||||
# from dis_snek.models.discord.enums import Permissions
|
OptionTypes,
|
||||||
# from dis_snek.models.discord.role import Role
|
slash_command,
|
||||||
# from dis_snek.models.discord.user import User
|
slash_option,
|
||||||
# from dis_snek.models.discord.channel import GuildText, GuildVoice, PermissionOverwrite
|
)
|
||||||
# from dis_snek.models.snek.application_commands import (
|
from dis_snek.models.snek.command import check
|
||||||
# OptionTypes,
|
from jarvis_core.db import q
|
||||||
# PermissionTypes,
|
from jarvis_core.db.models import Lock, Permission
|
||||||
# slash_command,
|
|
||||||
# slash_option,
|
from jarvis.utils.permissions import admin_or_permissions
|
||||||
# )
|
|
||||||
# from dis_snek.models.snek.command import check
|
|
||||||
#
|
class LockCog(Scale):
|
||||||
# from jarvis.db.models import Lock
|
"""J.A.R.V.I.S. LockCog."""
|
||||||
# from jarvis.utils.permissions import admin_or_permissions
|
|
||||||
#
|
@slash_command(name="lock", description="Lock a channel")
|
||||||
#
|
@slash_option(
|
||||||
# class LockCog(Scale):
|
name="reason",
|
||||||
# """J.A.R.V.I.S. LockCog."""
|
description="Lock Reason",
|
||||||
#
|
opt_type=3,
|
||||||
# @slash_command(name="lock", description="Lock a channel")
|
required=True,
|
||||||
# @slash_option(name="reason",
|
)
|
||||||
# description="Lock Reason",
|
@slash_option(
|
||||||
# opt_type=3,
|
name="duration",
|
||||||
# required=True,)
|
description="Lock duration in minutes (default 10)",
|
||||||
# @slash_option(name="duration",
|
opt_type=4,
|
||||||
# description="Lock duration in minutes (default 10)",
|
required=False,
|
||||||
# opt_type=4,
|
)
|
||||||
# required=False,)
|
@slash_option(
|
||||||
# @slash_option(name="channel",
|
name="channel",
|
||||||
# description="Channel to lock",
|
description="Channel to lock",
|
||||||
# opt_type=7,
|
opt_type=7,
|
||||||
# required=False,)
|
required=False,
|
||||||
# @check(admin_or_permissions(Permissions.MANAGE_CHANNELS))
|
)
|
||||||
# async def _lock(
|
@check(admin_or_permissions(Permissions.MANAGE_CHANNELS))
|
||||||
# self,
|
async def _lock(
|
||||||
# ctx: InteractionContext,
|
self,
|
||||||
# reason: str,
|
ctx: InteractionContext,
|
||||||
# duration: int = 10,
|
reason: str,
|
||||||
# channel: Union[GuildText, GuildVoice] = None,
|
duration: int = 10,
|
||||||
# ) -> None:
|
channel: Union[GuildText, GuildVoice] = None,
|
||||||
# await ctx.defer(ephemeral=True)
|
) -> None:
|
||||||
# if duration <= 0:
|
await ctx.defer(ephemeral=True)
|
||||||
# await ctx.send("Duration must be > 0", ephemeral=True)
|
if duration <= 0:
|
||||||
# return
|
await ctx.send("Duration must be > 0", ephemeral=True)
|
||||||
#
|
return
|
||||||
# elif duration > 60 * 12:
|
|
||||||
# await ctx.send("Duration must be <= 12 hours", ephemeral=True)
|
elif duration > 60 * 12:
|
||||||
# return
|
await ctx.send("Duration must be <= 12 hours", ephemeral=True)
|
||||||
#
|
return
|
||||||
# if len(reason) > 100:
|
|
||||||
# await ctx.send("Reason must be <= 100 characters", ephemeral=True)
|
if len(reason) > 100:
|
||||||
# return
|
await ctx.send("Reason must be <= 100 characters", ephemeral=True)
|
||||||
# if not channel:
|
return
|
||||||
# channel = ctx.channel
|
if not channel:
|
||||||
#
|
channel = ctx.channel
|
||||||
# # role = ctx.guild.default_role # Uncomment once implemented
|
|
||||||
# if isinstance(channel, GuildText):
|
# role = ctx.guild.default_role # Uncomment once implemented
|
||||||
# to_deny = Permissions.SEND_MESSAGES
|
if isinstance(channel, GuildText):
|
||||||
# elif isinstance(channel, GuildVoice):
|
to_deny = Permissions.SEND_MESSAGES
|
||||||
# to_deny = Permissions.CONNECT | Permissions.SPEAK
|
elif isinstance(channel, GuildVoice):
|
||||||
#
|
to_deny = Permissions.CONNECT | Permissions.SPEAK
|
||||||
# overwrite = PermissionOverwrite(type=PermissionTypes.ROLE, deny=to_deny)
|
|
||||||
# # TODO: Get original permissions
|
current = get(channel.permission_overwrites, id=ctx.guild.id)
|
||||||
# # TODO: Apply overwrite
|
if current:
|
||||||
# overwrite = overwrite
|
current = Permission(id=ctx.guild.id, allow=int(current.allow), deny=int(current.deny))
|
||||||
# _ = Lock(
|
role = await ctx.guild.fetch_role(ctx.guild.id)
|
||||||
# channel=channel.id,
|
|
||||||
# guild=ctx.guild.id,
|
await channel.add_permission(target=role, deny=to_deny, reason="Locked")
|
||||||
# admin=ctx.author.id,
|
await Lock(
|
||||||
# reason=reason,
|
channel=channel.id,
|
||||||
# duration=duration,
|
guild=ctx.guild.id,
|
||||||
# ) # .save() # Uncomment once implemented
|
admin=ctx.author.id,
|
||||||
# # await ctx.send(f"{channel.mention} locked for {duration} minute(s)")
|
reason=reason,
|
||||||
# await ctx.send("Unfortunately, this is not yet implemented", hidden=True)
|
duration=duration,
|
||||||
#
|
original_perms=current,
|
||||||
# @cog_ext.cog_slash(
|
).commit()
|
||||||
# name="unlock",
|
await ctx.send(f"{channel.mention} locked for {duration} minute(s)")
|
||||||
# description="Unlocks a channel",
|
|
||||||
# choices=[
|
@slash_command(name="unlock", description="Unlock a channel")
|
||||||
# create_option(
|
@slash_option(
|
||||||
# name="channel",
|
name="channel",
|
||||||
# description="Channel to lock",
|
description="Channel to unlock",
|
||||||
# opt_type=7,
|
opt_type=OptionTypes.CHANNEL,
|
||||||
# required=False,
|
required=False,
|
||||||
# ),
|
)
|
||||||
# ],
|
@check(admin_or_permissions(Permissions.MANAGE_CHANNELS))
|
||||||
# )
|
async def _unlock(
|
||||||
# @check(admin_or_permissions(Permissions.MANAGE_CHANNELS))
|
self,
|
||||||
# async def _unlock(
|
ctx: InteractionContext,
|
||||||
# self,
|
channel: Union[GuildText, GuildVoice] = None,
|
||||||
# ctx: InteractionContext,
|
) -> None:
|
||||||
# channel: Union[GuildText, GuildVoice] = None,
|
if not channel:
|
||||||
# ) -> None:
|
channel = ctx.channel
|
||||||
# if not channel:
|
lock = await Lock.find_one(q(guild=ctx.guild.id, channel=channel.id, active=True))
|
||||||
# channel = ctx.channel
|
if not lock:
|
||||||
# lock = Lock.objects(guild=ctx.guild.id, channel=channel.id, active=True).first()
|
await ctx.send(f"{channel.mention} not locked.", ephemeral=True)
|
||||||
# if not lock:
|
return
|
||||||
# await ctx.send(f"{channel.mention} not locked.", ephemeral=True)
|
|
||||||
# return
|
overwrite = get(channel.permission_overwrites, id=ctx.guild.id)
|
||||||
# for role in ctx.guild.roles:
|
if overwrite and lock.original_perms:
|
||||||
# with suppress(Exception):
|
overwrite.allow = lock.original_perms.allow
|
||||||
# await self._unlock_channel(channel, role, ctx.author)
|
overwrite.deny = lock.original_perms.deny
|
||||||
# lock.active = False
|
await channel.edit_permission(overwrite, reason="Unlock")
|
||||||
# lock.save()
|
elif overwrite and not lock.original_perms:
|
||||||
# await ctx.send(f"{channel.mention} unlocked")
|
await channel.delete_permission(target=overwrite, reason="Unlock")
|
||||||
|
|
||||||
|
lock.active = False
|
||||||
|
await lock.commit()
|
||||||
|
await ctx.send(f"{channel.mention} unlocked")
|
||||||
|
|
|
@ -1,101 +1,159 @@
|
||||||
"""J.A.R.V.I.S. LockdownCog."""
|
"""J.A.R.V.I.S. LockdownCog."""
|
||||||
from contextlib import suppress
|
from dis_snek import InteractionContext, Scale, Snake
|
||||||
from datetime import datetime
|
from dis_snek.client.utils.misc_utils import find_all, get
|
||||||
|
from dis_snek.models.discord.channel import GuildCategory, GuildChannel
|
||||||
from discord.ext import commands
|
from dis_snek.models.discord.enums import Permissions
|
||||||
from discord_slash import SlashContext, cog_ext
|
from dis_snek.models.discord.guild import Guild
|
||||||
from discord_slash.utils.manage_commands import create_option
|
from dis_snek.models.discord.user import Member
|
||||||
|
from dis_snek.models.snek.application_commands import (
|
||||||
from jarvis.db.models import Lock
|
OptionTypes,
|
||||||
from jarvis.utils.cachecog import CacheCog
|
slash_command,
|
||||||
|
slash_option,
|
||||||
# from jarvis.utils.permissions import admin_or_permissions
|
|
||||||
|
|
||||||
|
|
||||||
class LockdownCog(CacheCog):
|
|
||||||
"""J.A.R.V.I.S. LockdownCog."""
|
|
||||||
|
|
||||||
def __init__(self, bot: commands.Bot):
|
|
||||||
super().__init__(bot)
|
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(
|
|
||||||
base="lockdown",
|
|
||||||
name="start",
|
|
||||||
description="Locks a server",
|
|
||||||
choices=[
|
|
||||||
create_option(
|
|
||||||
name="reason",
|
|
||||||
description="Lockdown Reason",
|
|
||||||
opt_type=3,
|
|
||||||
required=True,
|
|
||||||
),
|
|
||||||
create_option(
|
|
||||||
name="duration",
|
|
||||||
description="Lockdown duration in minutes (default 10)",
|
|
||||||
opt_type=4,
|
|
||||||
required=False,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
# @check(admin_or_permissions(manage_channels=True))
|
from dis_snek.models.snek.command import check
|
||||||
|
from jarvis_core.db import q
|
||||||
|
from jarvis_core.db.models import Lock, Lockdown, Permission
|
||||||
|
|
||||||
|
from jarvis.utils.permissions import admin_or_permissions
|
||||||
|
|
||||||
|
|
||||||
|
async def lock(bot: Snake, target: GuildChannel, admin: Member, reason: str, duration: int) -> None:
|
||||||
|
"""
|
||||||
|
Lock an existing channel
|
||||||
|
|
||||||
|
Args:
|
||||||
|
bot: Bot instance
|
||||||
|
target: Target channel
|
||||||
|
admin: Admin who initiated lockdown
|
||||||
|
"""
|
||||||
|
to_deny = Permissions.SEND_MESSAGES | Permissions.CONNECT | Permissions.SPEAK
|
||||||
|
current = get(target.permission_overwrites, id=target.guild.id)
|
||||||
|
if current:
|
||||||
|
current = Permission(id=target.guild.id, allow=int(current.allow), deny=int(current.deny))
|
||||||
|
role = await target.guild.fetch_role(target.guild.id)
|
||||||
|
await target.add_permission(target=role, deny=to_deny, reason="Lockdown")
|
||||||
|
await Lock(
|
||||||
|
channel=target.id,
|
||||||
|
guild=target.guild.id,
|
||||||
|
admin=admin.id,
|
||||||
|
reason=reason,
|
||||||
|
duration=duration,
|
||||||
|
original_perms=current,
|
||||||
|
).commit()
|
||||||
|
|
||||||
|
|
||||||
|
async def lock_all(bot: Snake, guild: Guild, admin: Member, reason: str, duration: int) -> None:
|
||||||
|
"""
|
||||||
|
Lock all channels
|
||||||
|
|
||||||
|
Args:
|
||||||
|
bot: Bot instance
|
||||||
|
guild: Target guild
|
||||||
|
admin: Admin who initiated lockdown
|
||||||
|
"""
|
||||||
|
role = await guild.fetch_role(guild.id)
|
||||||
|
categories = find_all(lambda x: isinstance(x, GuildCategory), guild.channels)
|
||||||
|
for category in categories:
|
||||||
|
await lock(bot, category, admin, reason, duration)
|
||||||
|
perms = category.permissions_for(role)
|
||||||
|
|
||||||
|
for channel in category.channels:
|
||||||
|
if perms != channel.permissions_for(role):
|
||||||
|
await lock(bot, channel, admin, reason, duration)
|
||||||
|
|
||||||
|
|
||||||
|
async def unlock_all(bot: Snake, guild: Guild, admin: Member) -> None:
|
||||||
|
"""
|
||||||
|
Unlock all locked channels
|
||||||
|
|
||||||
|
Args:
|
||||||
|
bot: Bot instance
|
||||||
|
target: Target channel
|
||||||
|
admin: Admin who ended lockdown
|
||||||
|
"""
|
||||||
|
locks = Lock.find(q(guild=guild.id, active=True))
|
||||||
|
async for lock in locks:
|
||||||
|
target = await guild.fetch_channel(lock.channel)
|
||||||
|
if target:
|
||||||
|
overwrite = get(target.permission_overwrites, id=guild.id)
|
||||||
|
if overwrite and lock.original_perms:
|
||||||
|
overwrite.allow = lock.original_perms.allow
|
||||||
|
overwrite.deny = lock.original_perms.deny
|
||||||
|
await target.edit_permission(overwrite, reason="Lockdown end")
|
||||||
|
elif overwrite and not lock.original_perms:
|
||||||
|
await target.delete_permission(target=overwrite, reason="Lockdown end")
|
||||||
|
lock.active = False
|
||||||
|
await lock.commit()
|
||||||
|
lockdown = await Lockdown.find_one(q(guild=guild.id, active=True))
|
||||||
|
if lockdown:
|
||||||
|
lockdown.active = False
|
||||||
|
await lockdown.commit()
|
||||||
|
|
||||||
|
|
||||||
|
class LockdownCog(Scale):
|
||||||
|
"""J.A.R.V.I.S. LockdownCog."""
|
||||||
|
|
||||||
|
@slash_command(
|
||||||
|
name="lockdown",
|
||||||
|
description="Manage server-wide lockdown",
|
||||||
|
sub_cmd_name="start",
|
||||||
|
sub_cmd_description="Lockdown the server",
|
||||||
|
)
|
||||||
|
@slash_option(
|
||||||
|
name="reason", description="Lockdown reason", opt_type=OptionTypes.STRING, required=True
|
||||||
|
)
|
||||||
|
@slash_option(
|
||||||
|
name="duration",
|
||||||
|
description="Duration in minutes",
|
||||||
|
opt_type=OptionTypes.INTEGER,
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
@check(admin_or_permissions(Permissions.MANAGE_CHANNELS))
|
||||||
async def _lockdown_start(
|
async def _lockdown_start(
|
||||||
self,
|
self,
|
||||||
ctx: SlashContext,
|
ctx: InteractionContext,
|
||||||
reason: str,
|
reason: str,
|
||||||
duration: int = 10,
|
duration: int = 10,
|
||||||
) -> None:
|
) -> None:
|
||||||
await ctx.defer(ephemeral=True)
|
await ctx.defer()
|
||||||
if duration <= 0:
|
if duration <= 0:
|
||||||
await ctx.send("Duration must be > 0", ephemeral=True)
|
await ctx.send("Duration must be > 0", ephemeral=True)
|
||||||
return
|
return
|
||||||
elif duration >= 300:
|
elif duration >= 300:
|
||||||
await ctx.send("Duration must be < 5 hours", ephemeral=True)
|
await ctx.send("Duration must be < 5 hours", ephemeral=True)
|
||||||
return
|
return
|
||||||
channels = ctx.guild.channels
|
|
||||||
roles = ctx.guild.roles
|
|
||||||
updates = []
|
|
||||||
for channel in channels:
|
|
||||||
for role in roles:
|
|
||||||
with suppress(Exception):
|
|
||||||
await self._lock_channel(channel, role, ctx.author, reason)
|
|
||||||
updates.append(
|
|
||||||
Lock(
|
|
||||||
channel=channel.id,
|
|
||||||
guild=ctx.guild.id,
|
|
||||||
admin=ctx.author.id,
|
|
||||||
reason=reason,
|
|
||||||
duration=duration,
|
|
||||||
active=True,
|
|
||||||
created_at=datetime.utcnow(),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if updates:
|
|
||||||
Lock.objects().insert(updates)
|
|
||||||
await ctx.send(f"Server locked for {duration} minute(s)")
|
|
||||||
|
|
||||||
@cog_ext.cog_subcommand(
|
exists = await Lockdown.find_one(q(guild=ctx.guild.id, active=True))
|
||||||
base="lockdown",
|
if exists:
|
||||||
name="end",
|
await ctx.send("Server already in lockdown", ephemeral=True)
|
||||||
description="Unlocks a server",
|
return
|
||||||
)
|
|
||||||
@commands.has_permissions(administrator=True)
|
await lock_all(self.bot, ctx.guild, ctx.author, reason, duration)
|
||||||
|
role = await ctx.guild.fetch_role(ctx.guild.id)
|
||||||
|
original_perms = role.permissions
|
||||||
|
new_perms = role.permissions & ~Permissions.SEND_MESSAGES
|
||||||
|
await role.edit(permissions=new_perms)
|
||||||
|
await Lockdown(
|
||||||
|
admin=ctx.author.id,
|
||||||
|
duration=duration,
|
||||||
|
guild=ctx.guild.id,
|
||||||
|
reason=reason,
|
||||||
|
original_perms=int(original_perms),
|
||||||
|
).commit()
|
||||||
|
await ctx.send("Server now in lockdown.")
|
||||||
|
|
||||||
|
@slash_command(name="lockdown", sub_cmd_name="end", sub_cmd_description="End a lockdown")
|
||||||
|
@check(admin_or_permissions(Permissions.MANAGE_CHANNELS))
|
||||||
async def _lockdown_end(
|
async def _lockdown_end(
|
||||||
self,
|
self,
|
||||||
ctx: SlashContext,
|
ctx: InteractionContext,
|
||||||
) -> None:
|
) -> None:
|
||||||
channels = ctx.guild.channels
|
|
||||||
roles = ctx.guild.roles
|
|
||||||
update = False
|
|
||||||
locks = Lock.objects(guild=ctx.guild.id, active=True)
|
|
||||||
if not locks:
|
|
||||||
await ctx.send("No lockdown detected.", ephemeral=True)
|
|
||||||
return
|
|
||||||
await ctx.defer()
|
await ctx.defer()
|
||||||
for channel in channels:
|
|
||||||
for role in roles:
|
lockdown = await Lockdown.find_one(q(guild=ctx.guild.id, active=True))
|
||||||
with suppress(Exception):
|
if not lockdown:
|
||||||
await self._unlock_channel(channel, role, ctx.author)
|
await ctx.send("Server not in lockdown", ephemeral=True)
|
||||||
update = True
|
return
|
||||||
if update:
|
|
||||||
Lock.objects(guild=ctx.guild.id, active=True).update(set__active=False)
|
await unlock_all(self.bot, ctx.guild, ctx.author)
|
||||||
await ctx.send("Server unlocked")
|
await ctx.send("Server no longer in lockdown.")
|
||||||
|
|
Loading…
Add table
Reference in a new issue